1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -O3 -mtriple=riscv64 -mattr=+v < %s | FileCheck %s 3 4define void @constant_splat_fixed(ptr %p) { 5; CHECK-LABEL: constant_splat_fixed: 6; CHECK: # %bb.0: 7; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 8; CHECK-NEXT: vmv.v.i v8, 0 9; CHECK-NEXT: vse32.v v8, (a0) 10; CHECK-NEXT: ret 11 store <4 x i32> zeroinitializer, ptr %p 12 ret void 13} 14 15define void @constant_splat_scalable(ptr %p) { 16; CHECK-LABEL: constant_splat_scalable: 17; CHECK: # %bb.0: 18; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma 19; CHECK-NEXT: vmv.v.i v8, 0 20; CHECK-NEXT: vse32.v v8, (a0) 21; CHECK-NEXT: ret 22 store <vscale x 1 x i32> zeroinitializer, ptr %p 23 ret void 24} 25 26; FIXME: We should be able to use the earlier splat of zero here 27; since VLMAX >= 4. 28define void @constant_splat_scalable_then_fixed(ptr %p, ptr %p2) { 29; CHECK-LABEL: constant_splat_scalable_then_fixed: 30; CHECK: # %bb.0: 31; CHECK-NEXT: vsetvli a2, zero, e32, mf2, ta, ma 32; CHECK-NEXT: vmv.v.i v8, 0 33; CHECK-NEXT: vse32.v v8, (a0) 34; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 35; CHECK-NEXT: vmv.v.i v8, 0 36; CHECK-NEXT: vse32.v v8, (a1) 37; CHECK-NEXT: ret 38 store <vscale x 1 x i32> zeroinitializer, ptr %p 39 store <4 x i32> zeroinitializer, ptr %p2 40 ret void 41} 42 43; We could widen the first splat to VLMAX, but this might not 44; be generally profitable. 45define void @constant_splat_fixed_then_scalable(ptr %p, ptr %p2) { 46; CHECK-LABEL: constant_splat_fixed_then_scalable: 47; CHECK: # %bb.0: 48; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 49; CHECK-NEXT: vmv.v.i v8, 0 50; CHECK-NEXT: vse32.v v8, (a1) 51; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma 52; CHECK-NEXT: vmv.v.i v8, 0 53; CHECK-NEXT: vse32.v v8, (a0) 54; CHECK-NEXT: ret 55 store <4 x i32> zeroinitializer, ptr %p2 56 store <vscale x 1 x i32> zeroinitializer, ptr %p 57 ret void 58} 59 60define void @splat_scalable(ptr %p, i32 %v) { 61; CHECK-LABEL: splat_scalable: 62; CHECK: # %bb.0: 63; CHECK-NEXT: vsetvli a2, zero, e32, mf2, ta, ma 64; CHECK-NEXT: vmv.v.x v8, a1 65; CHECK-NEXT: vse32.v v8, (a0) 66; CHECK-NEXT: ret 67 %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0 68 %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer 69 store <vscale x 1 x i32> %splat, ptr %p 70 ret void 71} 72 73define void @splat_fixed(ptr %p, i32 %v) { 74; CHECK-LABEL: splat_fixed: 75; CHECK: # %bb.0: 76; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 77; CHECK-NEXT: vmv.v.x v8, a1 78; CHECK-NEXT: vse32.v v8, (a0) 79; CHECK-NEXT: ret 80 %elt.head = insertelement <4 x i32> poison, i32 %v, i32 0 81 %splat = shufflevector <4 x i32> %elt.head, <4 x i32> poison, <4 x i32> zeroinitializer 82 store <4 x i32> %splat, ptr %p 83 ret void 84} 85 86; FIXME: We should reschedule the first splat to reduce the need 87; for toggling VL 88define void @mixed_splats1(ptr %p, i32 %v) { 89; CHECK-LABEL: mixed_splats1: 90; CHECK: # %bb.0: 91; CHECK-NEXT: vsetvli a2, zero, e32, mf2, ta, ma 92; CHECK-NEXT: vmv.v.x v8, a1 93; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 94; CHECK-NEXT: vmv.v.i v9, 0 95; CHECK-NEXT: vse32.v v9, (a0) 96; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma 97; CHECK-NEXT: vse32.v v8, (a0) 98; CHECK-NEXT: ret 99 %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0 100 %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer 101 102 store <4 x i32> zeroinitializer, ptr %p 103 store <vscale x 1 x i32> %splat, ptr %p 104 ret void 105} 106 107define void @mixed_splats2(ptr %p, i32 %v) { 108; CHECK-LABEL: mixed_splats2: 109; CHECK: # %bb.0: 110; CHECK-NEXT: vsetvli a2, zero, e32, mf2, ta, ma 111; CHECK-NEXT: vmv.v.x v8, a1 112; CHECK-NEXT: vse32.v v8, (a0) 113; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 114; CHECK-NEXT: vmv.v.i v8, 0 115; CHECK-NEXT: vse32.v v8, (a0) 116; CHECK-NEXT: ret 117 %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0 118 %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer 119 120 store <vscale x 1 x i32> %splat, ptr %p 121 store <4 x i32> zeroinitializer, ptr %p 122 ret void 123} 124 125define void @extract_vector(ptr %p, i32 %v) { 126; CHECK-LABEL: extract_vector: 127; CHECK: # %bb.0: 128; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 129; CHECK-NEXT: vmv.v.x v8, a1 130; CHECK-NEXT: vse32.v v8, (a0) 131; CHECK-NEXT: ret 132 %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0 133 %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer 134 135 %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0) 136 store <4 x i32> %fv, ptr %p 137 ret void 138} 139 140define void @extract_vector_multiuse1(ptr %p, ptr %p2, i32 %v) { 141; CHECK-LABEL: extract_vector_multiuse1: 142; CHECK: # %bb.0: 143; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 144; CHECK-NEXT: vmv.v.x v8, a2 145; CHECK-NEXT: vse32.v v8, (a0) 146; CHECK-NEXT: vse32.v v8, (a1) 147; CHECK-NEXT: ret 148 %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0 149 %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer 150 151 %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0) 152 store <4 x i32> %fv, ptr %p 153 store <4 x i32> %fv, ptr %p2 154 ret void 155} 156 157define <vscale x 1 x i32> @extract_vector_multiuse2(ptr %p, ptr %p2, i32 %v) { 158; CHECK-LABEL: extract_vector_multiuse2: 159; CHECK: # %bb.0: 160; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma 161; CHECK-NEXT: vmv.v.x v8, a2 162; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 163; CHECK-NEXT: vse32.v v8, (a0) 164; CHECK-NEXT: ret 165 %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0 166 %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer 167 168 %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0) 169 store <4 x i32> %fv, ptr %p 170 ret <vscale x 1 x i32> %splat 171} 172 173define void @extract_vector_mixed1(ptr %p, ptr %p2, i32 %v) { 174; CHECK-LABEL: extract_vector_mixed1: 175; CHECK: # %bb.0: 176; CHECK-NEXT: vsetvli a3, zero, e32, mf2, ta, ma 177; CHECK-NEXT: vmv.v.x v8, a2 178; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 179; CHECK-NEXT: vse32.v v8, (a0) 180; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma 181; CHECK-NEXT: vse32.v v8, (a1) 182; CHECK-NEXT: ret 183 %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0 184 %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer 185 186 %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0) 187 188 store <4 x i32> %fv, ptr %p 189 store <vscale x 1 x i32> %splat, ptr %p2 190 ret void 191} 192 193define void @extract_vector_mixed2(ptr %p, ptr %p2, i32 %v) { 194; CHECK-LABEL: extract_vector_mixed2: 195; CHECK: # %bb.0: 196; CHECK-NEXT: vsetvli a3, zero, e32, mf2, ta, ma 197; CHECK-NEXT: vmv.v.x v8, a2 198; CHECK-NEXT: vse32.v v8, (a0) 199; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 200; CHECK-NEXT: vse32.v v8, (a1) 201; CHECK-NEXT: ret 202 %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0 203 %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer 204 store <vscale x 1 x i32> %splat, ptr %p 205 206 %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0) 207 store <4 x i32> %fv, ptr %p2 208 ret void 209} 210 211define void @extract_vector_mixed3(ptr %p, ptr %p2, i32 %v) { 212; CHECK-LABEL: extract_vector_mixed3: 213; CHECK: # %bb.0: 214; CHECK-NEXT: vsetvli a3, zero, e32, mf2, ta, ma 215; CHECK-NEXT: vmv.v.x v8, a2 216; CHECK-NEXT: vse32.v v8, (a0) 217; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma 218; CHECK-NEXT: vse32.v v8, (a1) 219; CHECK-NEXT: ret 220 %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0 221 %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer 222 %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0) 223 224 store <vscale x 1 x i32> %splat, ptr %p 225 store <4 x i32> %fv, ptr %p2 226 ret void 227} 228 229 230declare <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %vec, i64 %idx) 231