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