1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -target-abi=ilp32d -mattr=+experimental-v,+experimental-zfh,+f,+d -verify-machineinstrs -riscv-v-vector-bits-min=128 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV32 3; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+experimental-v,+experimental-zfh,+f,+d -verify-machineinstrs -riscv-v-vector-bits-min=128 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV64 4 5; FIXME: This codegen needs to be improved. These tests previously asserted 6; type legalizing the i64 type on RV32. 7 8define void @insertelt_v4i64(<4 x i64>* %x, i64 %y) { 9; RV32-LABEL: insertelt_v4i64: 10; RV32: # %bb.0: 11; RV32-NEXT: vsetivli a3, 4, e64,m2,ta,mu 12; RV32-NEXT: vle64.v v26, (a0) 13; RV32-NEXT: vsetivli a3, 2, e32,m2,ta,mu 14; RV32-NEXT: vmv.v.i v28, 0 15; RV32-NEXT: vslide1up.vx v30, v28, a2 16; RV32-NEXT: vslide1up.vx v28, v30, a1 17; RV32-NEXT: vsetivli a1, 4, e64,m2,tu,mu 18; RV32-NEXT: vslideup.vi v26, v28, 3 19; RV32-NEXT: vsetivli a1, 4, e64,m2,ta,mu 20; RV32-NEXT: vse64.v v26, (a0) 21; RV32-NEXT: ret 22; 23; RV64-LABEL: insertelt_v4i64: 24; RV64: # %bb.0: 25; RV64-NEXT: vsetivli a2, 4, e64,m2,ta,mu 26; RV64-NEXT: vle64.v v26, (a0) 27; RV64-NEXT: vmv.s.x v28, a1 28; RV64-NEXT: vsetivli a1, 4, e64,m2,tu,mu 29; RV64-NEXT: vslideup.vi v26, v28, 3 30; RV64-NEXT: vsetivli a1, 4, e64,m2,ta,mu 31; RV64-NEXT: vse64.v v26, (a0) 32; RV64-NEXT: ret 33 %a = load <4 x i64>, <4 x i64>* %x 34 %b = insertelement <4 x i64> %a, i64 %y, i32 3 35 store <4 x i64> %b, <4 x i64>* %x 36 ret void 37} 38 39; This uses a non-power of 2 type so that it isn't an MVT. 40; The align keeps the type legalizer from using a 256 bit load so we must split 41; it. This some operations that weren't support for scalable vectors when 42; this test was written. 43define void @insertelt_v3i64(<3 x i64>* %x, i64 %y) { 44; RV32-LABEL: insertelt_v3i64: 45; RV32: # %bb.0: 46; RV32-NEXT: vsetivli a3, 2, e64,m1,ta,mu 47; RV32-NEXT: vle64.v v26, (a0) 48; RV32-NEXT: vsetivli a3, 8, e32,m2,ta,mu 49; RV32-NEXT: vmv.v.i v28, 0 50; RV32-NEXT: vsetivli a3, 2, e64,m2,tu,mu 51; RV32-NEXT: vslideup.vi v28, v26, 0 52; RV32-NEXT: lw a3, 16(a0) 53; RV32-NEXT: addi a4, a0, 20 54; RV32-NEXT: vsetivli a5, 4, e32,m1,ta,mu 55; RV32-NEXT: vlse32.v v26, (a4), zero 56; RV32-NEXT: vmv.s.x v26, a3 57; RV32-NEXT: vsetivli a3, 4, e64,m2,tu,mu 58; RV32-NEXT: vslideup.vi v28, v26, 2 59; RV32-NEXT: vsetivli a3, 2, e32,m2,ta,mu 60; RV32-NEXT: vmv.v.i v26, 0 61; RV32-NEXT: vslide1up.vx v30, v26, a2 62; RV32-NEXT: vslide1up.vx v26, v30, a1 63; RV32-NEXT: vsetivli a3, 3, e64,m2,tu,mu 64; RV32-NEXT: vslideup.vi v28, v26, 2 65; RV32-NEXT: sw a1, 16(a0) 66; RV32-NEXT: sw a2, 20(a0) 67; RV32-NEXT: vsetivli a1, 2, e64,m1,ta,mu 68; RV32-NEXT: vse64.v v28, (a0) 69; RV32-NEXT: ret 70; 71; RV64-LABEL: insertelt_v3i64: 72; RV64: # %bb.0: 73; RV64-NEXT: sd a1, 16(a0) 74; RV64-NEXT: ret 75 %a = load <3 x i64>, <3 x i64>* %x, align 8 76 %b = insertelement <3 x i64> %a, i64 %y, i32 2 77 store <3 x i64> %b, <3 x i64>* %x 78 ret void 79} 80 81define void @insertelt_v16i8(<16 x i8>* %x, i8 %y) { 82; CHECK-LABEL: insertelt_v16i8: 83; CHECK: # %bb.0: 84; CHECK-NEXT: vsetivli a2, 16, e8,m1,ta,mu 85; CHECK-NEXT: vle8.v v25, (a0) 86; CHECK-NEXT: vmv.s.x v26, a1 87; CHECK-NEXT: vsetivli a1, 15, e8,m1,tu,mu 88; CHECK-NEXT: vslideup.vi v25, v26, 14 89; CHECK-NEXT: vsetivli a1, 16, e8,m1,ta,mu 90; CHECK-NEXT: vse8.v v25, (a0) 91; CHECK-NEXT: ret 92 %a = load <16 x i8>, <16 x i8>* %x 93 %b = insertelement <16 x i8> %a, i8 %y, i32 14 94 store <16 x i8> %b, <16 x i8>* %x 95 ret void 96} 97 98define void @insertelt_v32i16(<32 x i16>* %x, i16 %y, i32 %idx) { 99; RV32-LABEL: insertelt_v32i16: 100; RV32: # %bb.0: 101; RV32-NEXT: addi a3, zero, 32 102; RV32-NEXT: vsetvli a4, a3, e16,m4,ta,mu 103; RV32-NEXT: vle16.v v28, (a0) 104; RV32-NEXT: vmv.s.x v8, a1 105; RV32-NEXT: addi a1, a2, 1 106; RV32-NEXT: vsetvli a1, a1, e16,m4,tu,mu 107; RV32-NEXT: vslideup.vx v28, v8, a2 108; RV32-NEXT: vsetvli a1, a3, e16,m4,ta,mu 109; RV32-NEXT: vse16.v v28, (a0) 110; RV32-NEXT: ret 111; 112; RV64-LABEL: insertelt_v32i16: 113; RV64: # %bb.0: 114; RV64-NEXT: addi a3, zero, 32 115; RV64-NEXT: vsetvli a4, a3, e16,m4,ta,mu 116; RV64-NEXT: vle16.v v28, (a0) 117; RV64-NEXT: vmv.s.x v8, a1 118; RV64-NEXT: sext.w a1, a2 119; RV64-NEXT: addi a2, a1, 1 120; RV64-NEXT: vsetvli a2, a2, e16,m4,tu,mu 121; RV64-NEXT: vslideup.vx v28, v8, a1 122; RV64-NEXT: vsetvli a1, a3, e16,m4,ta,mu 123; RV64-NEXT: vse16.v v28, (a0) 124; RV64-NEXT: ret 125 %a = load <32 x i16>, <32 x i16>* %x 126 %b = insertelement <32 x i16> %a, i16 %y, i32 %idx 127 store <32 x i16> %b, <32 x i16>* %x 128 ret void 129} 130 131define void @insertelt_v8f32(<8 x float>* %x, float %y, i32 %idx) { 132; RV32-LABEL: insertelt_v8f32: 133; RV32: # %bb.0: 134; RV32-NEXT: vsetivli a2, 8, e32,m2,ta,mu 135; RV32-NEXT: vle32.v v26, (a0) 136; RV32-NEXT: vfmv.s.f v28, fa0 137; RV32-NEXT: addi a2, a1, 1 138; RV32-NEXT: vsetvli a2, a2, e32,m2,tu,mu 139; RV32-NEXT: vslideup.vx v26, v28, a1 140; RV32-NEXT: vsetivli a1, 8, e32,m2,ta,mu 141; RV32-NEXT: vse32.v v26, (a0) 142; RV32-NEXT: ret 143; 144; RV64-LABEL: insertelt_v8f32: 145; RV64: # %bb.0: 146; RV64-NEXT: vsetivli a2, 8, e32,m2,ta,mu 147; RV64-NEXT: vle32.v v26, (a0) 148; RV64-NEXT: vfmv.s.f v28, fa0 149; RV64-NEXT: sext.w a1, a1 150; RV64-NEXT: addi a2, a1, 1 151; RV64-NEXT: vsetvli a2, a2, e32,m2,tu,mu 152; RV64-NEXT: vslideup.vx v26, v28, a1 153; RV64-NEXT: vsetivli a1, 8, e32,m2,ta,mu 154; RV64-NEXT: vse32.v v26, (a0) 155; RV64-NEXT: ret 156 %a = load <8 x float>, <8 x float>* %x 157 %b = insertelement <8 x float> %a, float %y, i32 %idx 158 store <8 x float> %b, <8 x float>* %x 159 ret void 160} 161 162define void @insertelt_v8i64_0(<8 x i64>* %x) { 163; CHECK-LABEL: insertelt_v8i64_0: 164; CHECK: # %bb.0: 165; CHECK-NEXT: vsetivli a1, 8, e64,m4,ta,mu 166; CHECK-NEXT: vle64.v v28, (a0) 167; CHECK-NEXT: addi a1, zero, -1 168; CHECK-NEXT: vmv.s.x v28, a1 169; CHECK-NEXT: vse64.v v28, (a0) 170; CHECK-NEXT: ret 171 %a = load <8 x i64>, <8 x i64>* %x 172 %b = insertelement <8 x i64> %a, i64 -1, i32 0 173 store <8 x i64> %b, <8 x i64>* %x 174 ret void 175} 176 177define void @insertelt_v8i64(<8 x i64>* %x, i32 %idx) { 178; RV32-LABEL: insertelt_v8i64: 179; RV32: # %bb.0: 180; RV32-NEXT: vsetivli a2, 8, e64,m4,ta,mu 181; RV32-NEXT: vle64.v v28, (a0) 182; RV32-NEXT: addi a2, zero, -1 183; RV32-NEXT: vmv.s.x v8, a2 184; RV32-NEXT: addi a2, a1, 1 185; RV32-NEXT: vsetvli a2, a2, e64,m4,tu,mu 186; RV32-NEXT: vslideup.vx v28, v8, a1 187; RV32-NEXT: vsetivli a1, 8, e64,m4,ta,mu 188; RV32-NEXT: vse64.v v28, (a0) 189; RV32-NEXT: ret 190; 191; RV64-LABEL: insertelt_v8i64: 192; RV64: # %bb.0: 193; RV64-NEXT: vsetivli a2, 8, e64,m4,ta,mu 194; RV64-NEXT: vle64.v v28, (a0) 195; RV64-NEXT: addi a2, zero, -1 196; RV64-NEXT: vmv.s.x v8, a2 197; RV64-NEXT: sext.w a1, a1 198; RV64-NEXT: addi a2, a1, 1 199; RV64-NEXT: vsetvli a2, a2, e64,m4,tu,mu 200; RV64-NEXT: vslideup.vx v28, v8, a1 201; RV64-NEXT: vsetivli a1, 8, e64,m4,ta,mu 202; RV64-NEXT: vse64.v v28, (a0) 203; RV64-NEXT: ret 204 %a = load <8 x i64>, <8 x i64>* %x 205 %b = insertelement <8 x i64> %a, i64 -1, i32 %idx 206 store <8 x i64> %b, <8 x i64>* %x 207 ret void 208} 209 210define void @insertelt_c6_v8i64_0(<8 x i64>* %x) { 211; CHECK-LABEL: insertelt_c6_v8i64_0: 212; CHECK: # %bb.0: 213; CHECK-NEXT: vsetivli a1, 8, e64,m4,ta,mu 214; CHECK-NEXT: vle64.v v28, (a0) 215; CHECK-NEXT: addi a1, zero, 6 216; CHECK-NEXT: vmv.s.x v28, a1 217; CHECK-NEXT: vse64.v v28, (a0) 218; CHECK-NEXT: ret 219 %a = load <8 x i64>, <8 x i64>* %x 220 %b = insertelement <8 x i64> %a, i64 6, i32 0 221 store <8 x i64> %b, <8 x i64>* %x 222 ret void 223} 224 225define void @insertelt_c6_v8i64(<8 x i64>* %x, i32 %idx) { 226; RV32-LABEL: insertelt_c6_v8i64: 227; RV32: # %bb.0: 228; RV32-NEXT: vsetivli a2, 8, e64,m4,ta,mu 229; RV32-NEXT: vle64.v v28, (a0) 230; RV32-NEXT: addi a2, zero, 6 231; RV32-NEXT: vmv.s.x v8, a2 232; RV32-NEXT: addi a2, a1, 1 233; RV32-NEXT: vsetvli a2, a2, e64,m4,tu,mu 234; RV32-NEXT: vslideup.vx v28, v8, a1 235; RV32-NEXT: vsetivli a1, 8, e64,m4,ta,mu 236; RV32-NEXT: vse64.v v28, (a0) 237; RV32-NEXT: ret 238; 239; RV64-LABEL: insertelt_c6_v8i64: 240; RV64: # %bb.0: 241; RV64-NEXT: vsetivli a2, 8, e64,m4,ta,mu 242; RV64-NEXT: vle64.v v28, (a0) 243; RV64-NEXT: addi a2, zero, 6 244; RV64-NEXT: vmv.s.x v8, a2 245; RV64-NEXT: sext.w a1, a1 246; RV64-NEXT: addi a2, a1, 1 247; RV64-NEXT: vsetvli a2, a2, e64,m4,tu,mu 248; RV64-NEXT: vslideup.vx v28, v8, a1 249; RV64-NEXT: vsetivli a1, 8, e64,m4,ta,mu 250; RV64-NEXT: vse64.v v28, (a0) 251; RV64-NEXT: ret 252 %a = load <8 x i64>, <8 x i64>* %x 253 %b = insertelement <8 x i64> %a, i64 6, i32 %idx 254 store <8 x i64> %b, <8 x i64>* %x 255 ret void 256} 257 258; Test that using a insertelement at element 0 by a later operation doesn't 259; crash the compiler. 260define void @insertelt_c6_v8i64_0_add(<8 x i64>* %x, <8 x i64>* %y) { 261; CHECK-LABEL: insertelt_c6_v8i64_0_add: 262; CHECK: # %bb.0: 263; CHECK-NEXT: vsetivli a2, 8, e64,m4,ta,mu 264; CHECK-NEXT: vle64.v v28, (a0) 265; CHECK-NEXT: vle64.v v8, (a1) 266; CHECK-NEXT: addi a1, zero, 6 267; CHECK-NEXT: vmv.s.x v28, a1 268; CHECK-NEXT: vadd.vv v28, v28, v8 269; CHECK-NEXT: vse64.v v28, (a0) 270; CHECK-NEXT: ret 271 %a = load <8 x i64>, <8 x i64>* %x 272 %b = insertelement <8 x i64> %a, i64 6, i32 0 273 %c = load <8 x i64>, <8 x i64>* %y 274 %d = add <8 x i64> %b, %c 275 store <8 x i64> %d, <8 x i64>* %x 276 ret void 277} 278