brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.4 KiB · 6c6a691 Raw
348 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s -o - | FileCheck %s3 4; Extracting a legal fixed-length vector from an illegal subvector5 6define <4 x i32> @extract_v4i32_nxv16i32_12(<vscale x 16 x i32> %arg) {7; CHECK-LABEL: extract_v4i32_nxv16i32_12:8; CHECK:       // %bb.0:9; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill10; CHECK-NEXT:    addvl sp, sp, #-411; CHECK-NEXT:    .cfi_escape 0x0f, 0x09, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x11, 0x20, 0x1e, 0x22 // sp + 16 + 32 * VG12; CHECK-NEXT:    .cfi_offset w29, -1613; CHECK-NEXT:    str z3, [sp, #3, mul vl]14; CHECK-NEXT:    str z2, [sp, #2, mul vl]15; CHECK-NEXT:    str z1, [sp, #1, mul vl]16; CHECK-NEXT:    str z0, [sp]17; CHECK-NEXT:    ldr q0, [sp, #48]18; CHECK-NEXT:    addvl sp, sp, #419; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload20; CHECK-NEXT:    ret21  %ext = call <4 x i32> @llvm.vector.extract.v4i32.nxv16i32(<vscale x 16 x i32> %arg, i64 12)22  ret <4 x i32> %ext23}24 25define <8 x i16> @extract_v8i16_nxv32i16_8(<vscale x 32 x i16> %arg) {26; CHECK-LABEL: extract_v8i16_nxv32i16_8:27; CHECK:       // %bb.0:28; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill29; CHECK-NEXT:    addvl sp, sp, #-230; CHECK-NEXT:    .cfi_escape 0x0f, 0x08, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x40, 0x1e, 0x22 // sp + 16 + 16 * VG31; CHECK-NEXT:    .cfi_offset w29, -1632; CHECK-NEXT:    str z1, [sp, #1, mul vl]33; CHECK-NEXT:    str z0, [sp]34; CHECK-NEXT:    ldr q0, [sp, #16]35; CHECK-NEXT:    addvl sp, sp, #236; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload37; CHECK-NEXT:    ret38  %ext = call <8 x i16> @llvm.vector.extract.v8i16.nxv32i16(<vscale x 32 x i16> %arg, i64 8)39  ret <8 x i16> %ext40}41 42define <4 x i16> @extract_v4i16_nxv32i16_8(<vscale x 32 x i16> %arg) {43; CHECK-LABEL: extract_v4i16_nxv32i16_8:44; CHECK:       // %bb.0:45; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill46; CHECK-NEXT:    addvl sp, sp, #-447; CHECK-NEXT:    .cfi_escape 0x0f, 0x09, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x11, 0x20, 0x1e, 0x22 // sp + 16 + 32 * VG48; CHECK-NEXT:    .cfi_offset w29, -1649; CHECK-NEXT:    str z3, [sp, #3, mul vl]50; CHECK-NEXT:    str z2, [sp, #2, mul vl]51; CHECK-NEXT:    str z1, [sp, #1, mul vl]52; CHECK-NEXT:    str z0, [sp]53; CHECK-NEXT:    ldr d0, [sp, #32]54; CHECK-NEXT:    addvl sp, sp, #455; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload56; CHECK-NEXT:    ret57  %ext = call <4 x i16> @llvm.vector.extract.v4i16.nxv32i16(<vscale x 32 x i16> %arg, i64 16)58  ret <4 x i16> %ext59}60 61; The result type gets promoted, leading to us extracting 2 elements from a nxv32i16.62; Hence we don't end up in SplitVecOp_EXTRACT_SUBVECTOR, but in SplitVecOp_EXTRACT_VECTOR_ELT instead.63define <2 x i16> @extract_v2i16_nxv32i16_8(<vscale x 32 x i16> %arg) {64; CHECK-LABEL: extract_v2i16_nxv32i16_8:65; CHECK:       // %bb.0:66; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill67; CHECK-NEXT:    addvl sp, sp, #-868; CHECK-NEXT:    .cfi_escape 0x0f, 0x0a, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x11, 0xc0, 0x00, 0x1e, 0x22 // sp + 16 + 64 * VG69; CHECK-NEXT:    .cfi_offset w29, -1670; CHECK-NEXT:    mov x8, sp71; CHECK-NEXT:    str z3, [sp, #3, mul vl]72; CHECK-NEXT:    str z2, [sp, #2, mul vl]73; CHECK-NEXT:    add x8, x8, #3274; CHECK-NEXT:    str z1, [sp, #1, mul vl]75; CHECK-NEXT:    str z0, [sp]76; CHECK-NEXT:    str z3, [sp, #7, mul vl]77; CHECK-NEXT:    str z2, [sp, #6, mul vl]78; CHECK-NEXT:    str z1, [sp, #5, mul vl]79; CHECK-NEXT:    str z0, [sp, #4, mul vl]80; CHECK-NEXT:    ld1 { v0.h }[0], [x8]81; CHECK-NEXT:    addvl x8, sp, #482; CHECK-NEXT:    add x8, x8, #3483; CHECK-NEXT:    ld1 { v0.h }[2], [x8]84; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q085; CHECK-NEXT:    addvl sp, sp, #886; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload87; CHECK-NEXT:    ret88  %ext = call <2 x i16> @llvm.vector.extract.v2i16.nxv32i16(<vscale x 32 x i16> %arg, i64 16)89  ret <2 x i16> %ext90}91 92define <2 x i64> @extract_v2i64_nxv8i64_8(<vscale x 8 x i64> %arg) {93; CHECK-LABEL: extract_v2i64_nxv8i64_8:94; CHECK:       // %bb.0:95; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill96; CHECK-NEXT:    addvl sp, sp, #-497; CHECK-NEXT:    .cfi_escape 0x0f, 0x09, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x11, 0x20, 0x1e, 0x22 // sp + 16 + 32 * VG98; CHECK-NEXT:    .cfi_offset w29, -1699; CHECK-NEXT:    cnth x8100; CHECK-NEXT:    mov w9, #8 // =0x8101; CHECK-NEXT:    str z3, [sp, #3, mul vl]102; CHECK-NEXT:    sub x8, x8, #2103; CHECK-NEXT:    str z2, [sp, #2, mul vl]104; CHECK-NEXT:    cmp x8, #8105; CHECK-NEXT:    str z1, [sp, #1, mul vl]106; CHECK-NEXT:    csel x8, x8, x9, lo107; CHECK-NEXT:    str z0, [sp]108; CHECK-NEXT:    mov x9, sp109; CHECK-NEXT:    lsl x8, x8, #3110; CHECK-NEXT:    ldr q0, [x9, x8]111; CHECK-NEXT:    addvl sp, sp, #4112; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload113; CHECK-NEXT:    ret114  %ext = call <2 x i64> @llvm.vector.extract.v2i64.nxv8i64(<vscale x 8 x i64> %arg, i64 8)115  ret <2 x i64> %ext116}117 118define <4 x float> @extract_v4f32_nxv16f32_12(<vscale x 16 x float> %arg) {119; CHECK-LABEL: extract_v4f32_nxv16f32_12:120; CHECK:       // %bb.0:121; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill122; CHECK-NEXT:    addvl sp, sp, #-4123; CHECK-NEXT:    .cfi_escape 0x0f, 0x09, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x11, 0x20, 0x1e, 0x22 // sp + 16 + 32 * VG124; CHECK-NEXT:    .cfi_offset w29, -16125; CHECK-NEXT:    str z3, [sp, #3, mul vl]126; CHECK-NEXT:    str z2, [sp, #2, mul vl]127; CHECK-NEXT:    str z1, [sp, #1, mul vl]128; CHECK-NEXT:    str z0, [sp]129; CHECK-NEXT:    ldr q0, [sp, #48]130; CHECK-NEXT:    addvl sp, sp, #4131; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload132; CHECK-NEXT:    ret133  %ext = call <4 x float> @llvm.vector.extract.v4f32.nxv16f32(<vscale x 16 x float> %arg, i64 12)134  ret <4 x float> %ext135}136 137define <2 x float> @extract_v2f32_nxv16f32_2(<vscale x 16 x float> %arg) {138; CHECK-LABEL: extract_v2f32_nxv16f32_2:139; CHECK:       // %bb.0:140; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8141; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0142; CHECK-NEXT:    ret143  %ext = call <2 x float> @llvm.vector.extract.v2f32.nxv16f32(<vscale x 16 x float> %arg, i64 2)144  ret <2 x float> %ext145}146 147define <4 x i1> @extract_v4i1_nxv32i1_0(<vscale x 32 x i1> %arg) {148; CHECK-LABEL: extract_v4i1_nxv32i1_0:149; CHECK:       // %bb.0:150; CHECK-NEXT:    mov z1.b, p0/z, #1 // =0x1151; CHECK-NEXT:    umov w8, v1.b[1]152; CHECK-NEXT:    mov v0.16b, v1.16b153; CHECK-NEXT:    umov w9, v1.b[2]154; CHECK-NEXT:    mov v0.h[1], w8155; CHECK-NEXT:    umov w8, v1.b[3]156; CHECK-NEXT:    mov v0.h[2], w9157; CHECK-NEXT:    mov v0.h[3], w8158; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0159; CHECK-NEXT:    ret160  %ext = call <4 x i1> @llvm.vector.extract.v4i1.nxv32i1(<vscale x 32 x i1> %arg, i64 0)161  ret <4 x i1> %ext162}163 164; The result type gets promoted, leading to us extracting 4 elements from a nxv32i16.165; Hence we don't end up in SplitVecOp_EXTRACT_SUBVECTOR, but in SplitVecOp_EXTRACT_VECTOR_ELT instead.166define <4 x i1> @extract_v4i1_nxv32i1_16(<vscale x 32 x i1> %arg) {167; CHECK-LABEL: extract_v4i1_nxv32i1_16:168; CHECK:       // %bb.0:169; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill170; CHECK-NEXT:    addvl sp, sp, #-8171; CHECK-NEXT:    .cfi_escape 0x0f, 0x0a, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x11, 0xc0, 0x00, 0x1e, 0x22 // sp + 16 + 64 * VG172; CHECK-NEXT:    .cfi_offset w29, -16173; CHECK-NEXT:    mov z0.b, p1/z, #1 // =0x1174; CHECK-NEXT:    mov z1.b, p0/z, #1 // =0x1175; CHECK-NEXT:    mov x8, sp176; CHECK-NEXT:    add x8, x8, #16177; CHECK-NEXT:    str z0, [sp, #1, mul vl]178; CHECK-NEXT:    str z1, [sp]179; CHECK-NEXT:    str z0, [sp, #3, mul vl]180; CHECK-NEXT:    str z1, [sp, #2, mul vl]181; CHECK-NEXT:    str z0, [sp, #5, mul vl]182; CHECK-NEXT:    str z1, [sp, #4, mul vl]183; CHECK-NEXT:    str z0, [sp, #7, mul vl]184; CHECK-NEXT:    str z1, [sp, #6, mul vl]185; CHECK-NEXT:    ld1 { v0.b }[0], [x8]186; CHECK-NEXT:    addvl x8, sp, #2187; CHECK-NEXT:    add x8, x8, #17188; CHECK-NEXT:    ld1 { v0.b }[2], [x8]189; CHECK-NEXT:    addvl x8, sp, #4190; CHECK-NEXT:    add x8, x8, #18191; CHECK-NEXT:    ld1 { v0.b }[4], [x8]192; CHECK-NEXT:    addvl x8, sp, #6193; CHECK-NEXT:    add x8, x8, #19194; CHECK-NEXT:    ld1 { v0.b }[6], [x8]195; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0196; CHECK-NEXT:    addvl sp, sp, #8197; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload198; CHECK-NEXT:    ret199  %ext = call <4 x i1> @llvm.vector.extract.v4i1.nxv32i1(<vscale x 32 x i1> %arg, i64 16)200  ret <4 x i1> %ext201}202 203define <4 x i1> @extract_v4i1_v32i1_16(<32 x i1> %arg) {204; CHECK-LABEL: extract_v4i1_v32i1_16:205; CHECK:       // %bb.0:206; CHECK-NEXT:    ldr w8, [sp, #64]207; CHECK-NEXT:    ldr w9, [sp, #72]208; CHECK-NEXT:    fmov s0, w8209; CHECK-NEXT:    ldr w8, [sp, #80]210; CHECK-NEXT:    mov v0.h[1], w9211; CHECK-NEXT:    mov v0.h[2], w8212; CHECK-NEXT:    ldr w8, [sp, #88]213; CHECK-NEXT:    mov v0.h[3], w8214; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0215; CHECK-NEXT:    ret216  %ext = call <4 x i1> @llvm.vector.extract.v4i1.v32i1(<32 x i1> %arg, i64 16)217  ret <4 x i1> %ext218}219 220; The result type gets promoted, leading to us extracting 4 elements from a nxv32i3.221; Hence we don't end up in SplitVecOp_EXTRACT_SUBVECTOR, but in SplitVecOp_EXTRACT_VECTOR_ELT instead.222define <4 x i3> @extract_v4i3_nxv32i3_16(<vscale x 32 x i3> %arg) {223; CHECK-LABEL: extract_v4i3_nxv32i3_16:224; CHECK:       // %bb.0:225; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill226; CHECK-NEXT:    addvl sp, sp, #-8227; CHECK-NEXT:    .cfi_escape 0x0f, 0x0a, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x11, 0xc0, 0x00, 0x1e, 0x22 // sp + 16 + 64 * VG228; CHECK-NEXT:    .cfi_offset w29, -16229; CHECK-NEXT:    mov x8, sp230; CHECK-NEXT:    str z1, [sp, #1, mul vl]231; CHECK-NEXT:    str z0, [sp]232; CHECK-NEXT:    add x8, x8, #16233; CHECK-NEXT:    str z1, [sp, #3, mul vl]234; CHECK-NEXT:    str z0, [sp, #2, mul vl]235; CHECK-NEXT:    str z1, [sp, #5, mul vl]236; CHECK-NEXT:    str z0, [sp, #4, mul vl]237; CHECK-NEXT:    str z1, [sp, #7, mul vl]238; CHECK-NEXT:    str z0, [sp, #6, mul vl]239; CHECK-NEXT:    ld1 { v0.b }[0], [x8]240; CHECK-NEXT:    addvl x8, sp, #2241; CHECK-NEXT:    add x8, x8, #17242; CHECK-NEXT:    ld1 { v0.b }[2], [x8]243; CHECK-NEXT:    addvl x8, sp, #4244; CHECK-NEXT:    add x8, x8, #18245; CHECK-NEXT:    ld1 { v0.b }[4], [x8]246; CHECK-NEXT:    addvl x8, sp, #6247; CHECK-NEXT:    add x8, x8, #19248; CHECK-NEXT:    ld1 { v0.b }[6], [x8]249; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0250; CHECK-NEXT:    addvl sp, sp, #8251; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload252; CHECK-NEXT:    ret253  %ext = call <4 x i3> @llvm.vector.extract.v4i3.nxv32i3(<vscale x 32 x i3> %arg, i64 16)254  ret <4 x i3> %ext255}256 257; Extracting an illegal fixed-length vector from an illegal subvector258 259define <2 x i32> @extract_v2i32_nxv16i32_2(<vscale x 16 x i32> %arg) {260; CHECK-LABEL: extract_v2i32_nxv16i32_2:261; CHECK:       // %bb.0:262; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8263; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0264; CHECK-NEXT:    ret265  %ext = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32> %arg, i64 2)266  ret <2 x i32> %ext267}268 269define <4 x i64> @extract_v4i64_nxv8i64_0(<vscale x 8 x i64> %arg) {270; CHECK-LABEL: extract_v4i64_nxv8i64_0:271; CHECK:       // %bb.0:272; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill273; CHECK-NEXT:    addvl sp, sp, #-2274; CHECK-NEXT:    .cfi_escape 0x0f, 0x08, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x40, 0x1e, 0x22 // sp + 16 + 16 * VG275; CHECK-NEXT:    .cfi_offset w29, -16276; CHECK-NEXT:    str z1, [sp, #1, mul vl]277; CHECK-NEXT:    str z0, [sp]278; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0279; CHECK-NEXT:    ldr q1, [sp, #16]280; CHECK-NEXT:    addvl sp, sp, #2281; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload282; CHECK-NEXT:    ret283  %ext = call <4 x i64> @llvm.vector.extract.v4i64.nxv8i64(<vscale x 8 x i64> %arg, i64 0)284  ret <4 x i64> %ext285}286 287define <4 x half> @extract_v4f16_nxv2f16_0(<vscale x 2 x half> %arg) {288; CHECK-LABEL: extract_v4f16_nxv2f16_0:289; CHECK:       // %bb.0:290; CHECK-NEXT:    uzp1 z0.h, z0.h, z0.h291; CHECK-NEXT:    uzp1 z0.h, z0.h, z0.h292; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0293; CHECK-NEXT:    ret294  %ext = call <4 x half> @llvm.vector.extract.v4f16.nxv2f16(<vscale x 2 x half> %arg, i64 0)295  ret <4 x half> %ext296}297 298define <4 x half> @extract_v4f16_nxv2f16_4(<vscale x 2 x half> %arg) {299; CHECK-LABEL: extract_v4f16_nxv2f16_4:300; CHECK:       // %bb.0:301; CHECK-NEXT:    uzp1 z0.h, z0.h, z0.h302; CHECK-NEXT:    uzp1 z0.h, z0.h, z0.h303; CHECK-NEXT:    ext z0.b, z0.b, z0.b, #8304; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0305; CHECK-NEXT:    ret306  %ext = call <4 x half> @llvm.vector.extract.v4f16.nxv2f16(<vscale x 2 x half> %arg, i64 4)307  ret <4 x half> %ext308}309 310define <2 x half> @extract_v2f16_nxv4f16_2(<vscale x 4 x half> %arg) {311; CHECK-LABEL: extract_v2f16_nxv4f16_2:312; CHECK:       // %bb.0:313; CHECK-NEXT:    mov z1.s, z0.s[3]314; CHECK-NEXT:    mov z0.s, z0.s[2]315; CHECK-NEXT:    mov v0.h[1], v1.h[0]316; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0317; CHECK-NEXT:    ret318  %ext = call <2 x half> @llvm.vector.extract.v2f16.nxv4f16(<vscale x 4 x half> %arg, i64 2)319  ret <2 x half> %ext320}321 322define <2 x half> @extract_v2f16_nxv4f16_6(<vscale x 4 x half> %arg) {323; CHECK-LABEL: extract_v2f16_nxv4f16_6:324; CHECK:       // %bb.0:325; CHECK-NEXT:    mov z1.s, z0.s[7]326; CHECK-NEXT:    mov z0.s, z0.s[6]327; CHECK-NEXT:    mov v0.h[1], v1.h[0]328; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0329; CHECK-NEXT:    ret330  %ext = call <2 x half> @llvm.vector.extract.v2f16.nxv4f16(<vscale x 4 x half> %arg, i64 6)331  ret <2 x half> %ext332}333 334declare <4 x float> @llvm.vector.extract.v4f32.nxv16f32(<vscale x 16 x float>, i64)335declare <2 x float> @llvm.vector.extract.v2f32.nxv16f32(<vscale x 16 x float>, i64)336declare <4 x half> @llvm.vector.extract.v4f16.nxv2f16(<vscale x 2 x half>, i64);337declare <2 x half> @llvm.vector.extract.v2f16.nxv4f16(<vscale x 4 x half>, i64);338declare <2 x i64> @llvm.vector.extract.v2i64.nxv8i64(<vscale x 8 x i64>, i64)339declare <4 x i64> @llvm.vector.extract.v4i64.nxv8i64(<vscale x 8 x i64>, i64)340declare <4 x i32> @llvm.vector.extract.v4i32.nxv16i32(<vscale x 16 x i32>, i64)341declare <2 x i32> @llvm.vector.extract.v2i32.nxv16i32(<vscale x 16 x i32>, i64)342declare <8 x i16> @llvm.vector.extract.v8i16.nxv32i16(<vscale x 32 x i16>, i64)343declare <4 x i16> @llvm.vector.extract.v4i16.nxv32i16(<vscale x 32 x i16>, i64)344declare <2 x i16> @llvm.vector.extract.v2i16.nxv32i16(<vscale x 32 x i16>, i64)345declare <4 x i1> @llvm.vector.extract.v4i1.nxv32i1(<vscale x 32 x i1>, i64)346declare <4 x i1> @llvm.vector.extract.v4i1.v32i1(<32 x i1>, i64)347declare <4 x i3> @llvm.vector.extract.v4i3.nxv32i3(<vscale x 32 x i3>, i64)348