930 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -mattr=+v,+m,+zbb -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV323; RUN: llc -mtriple=riscv64 -mattr=+v,+m,+zbb -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV644 5define i32 @reduce_sum_2xi32(<2 x i32> %v) {6; CHECK-LABEL: reduce_sum_2xi32:7; CHECK: # %bb.0:8; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma9; CHECK-NEXT: vmv.s.x v9, zero10; CHECK-NEXT: vredsum.vs v8, v8, v911; CHECK-NEXT: vmv.x.s a0, v812; CHECK-NEXT: ret13 %e0 = extractelement <2 x i32> %v, i32 014 %e1 = extractelement <2 x i32> %v, i32 115 %add0 = add i32 %e0, %e116 ret i32 %add017}18 19define i32 @reduce_sum_4xi32(<4 x i32> %v) {20; CHECK-LABEL: reduce_sum_4xi32:21; CHECK: # %bb.0:22; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma23; CHECK-NEXT: vmv.s.x v9, zero24; CHECK-NEXT: vredsum.vs v8, v8, v925; CHECK-NEXT: vmv.x.s a0, v826; CHECK-NEXT: ret27 %e0 = extractelement <4 x i32> %v, i32 028 %e1 = extractelement <4 x i32> %v, i32 129 %e2 = extractelement <4 x i32> %v, i32 230 %e3 = extractelement <4 x i32> %v, i32 331 %add0 = add i32 %e0, %e132 %add1 = add i32 %add0, %e233 %add2 = add i32 %add1, %e334 ret i32 %add235}36 37define i32 @reduce_sum_8xi32(<8 x i32> %v) {38; CHECK-LABEL: reduce_sum_8xi32:39; CHECK: # %bb.0:40; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma41; CHECK-NEXT: vmv.s.x v10, zero42; CHECK-NEXT: vredsum.vs v8, v8, v1043; CHECK-NEXT: vmv.x.s a0, v844; CHECK-NEXT: ret45 %e0 = extractelement <8 x i32> %v, i32 046 %e1 = extractelement <8 x i32> %v, i32 147 %e2 = extractelement <8 x i32> %v, i32 248 %e3 = extractelement <8 x i32> %v, i32 349 %e4 = extractelement <8 x i32> %v, i32 450 %e5 = extractelement <8 x i32> %v, i32 551 %e6 = extractelement <8 x i32> %v, i32 652 %e7 = extractelement <8 x i32> %v, i32 753 %add0 = add i32 %e0, %e154 %add1 = add i32 %add0, %e255 %add2 = add i32 %add1, %e356 %add3 = add i32 %add2, %e457 %add4 = add i32 %add3, %e558 %add5 = add i32 %add4, %e659 %add6 = add i32 %add5, %e760 ret i32 %add661}62 63define i32 @reduce_sum_16xi32(<16 x i32> %v) {64; CHECK-LABEL: reduce_sum_16xi32:65; CHECK: # %bb.0:66; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma67; CHECK-NEXT: vmv.s.x v12, zero68; CHECK-NEXT: vredsum.vs v8, v8, v1269; CHECK-NEXT: vmv.x.s a0, v870; CHECK-NEXT: ret71 %e0 = extractelement <16 x i32> %v, i32 072 %e1 = extractelement <16 x i32> %v, i32 173 %e2 = extractelement <16 x i32> %v, i32 274 %e3 = extractelement <16 x i32> %v, i32 375 %e4 = extractelement <16 x i32> %v, i32 476 %e5 = extractelement <16 x i32> %v, i32 577 %e6 = extractelement <16 x i32> %v, i32 678 %e7 = extractelement <16 x i32> %v, i32 779 %e8 = extractelement <16 x i32> %v, i32 880 %e9 = extractelement <16 x i32> %v, i32 981 %e10 = extractelement <16 x i32> %v, i32 1082 %e11 = extractelement <16 x i32> %v, i32 1183 %e12 = extractelement <16 x i32> %v, i32 1284 %e13 = extractelement <16 x i32> %v, i32 1385 %e14 = extractelement <16 x i32> %v, i32 1486 %e15 = extractelement <16 x i32> %v, i32 1587 %add0 = add i32 %e0, %e188 %add1 = add i32 %add0, %e289 %add2 = add i32 %add1, %e390 %add3 = add i32 %add2, %e491 %add4 = add i32 %add3, %e592 %add5 = add i32 %add4, %e693 %add6 = add i32 %add5, %e794 %add7 = add i32 %add6, %e895 %add8 = add i32 %add7, %e996 %add9 = add i32 %add8, %e1097 %add10 = add i32 %add9, %e1198 %add11 = add i32 %add10, %e1299 %add12 = add i32 %add11, %e13100 %add13 = add i32 %add12, %e14101 %add14 = add i32 %add13, %e15102 ret i32 %add14103}104 105define i32 @reduce_sum_16xi32_prefix2(ptr %p) {106; CHECK-LABEL: reduce_sum_16xi32_prefix2:107; CHECK: # %bb.0:108; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma109; CHECK-NEXT: vle32.v v8, (a0)110; CHECK-NEXT: vmv.s.x v9, zero111; CHECK-NEXT: vredsum.vs v8, v8, v9112; CHECK-NEXT: vmv.x.s a0, v8113; CHECK-NEXT: ret114 %v = load <16 x i32>, ptr %p, align 256115 %e0 = extractelement <16 x i32> %v, i32 0116 %e1 = extractelement <16 x i32> %v, i32 1117 %add0 = add i32 %e0, %e1118 ret i32 %add0119}120 121define i32 @reduce_sum_16xi32_prefix3(ptr %p) {122; CHECK-LABEL: reduce_sum_16xi32_prefix3:123; CHECK: # %bb.0:124; CHECK-NEXT: vsetivli zero, 3, e32, m1, ta, ma125; CHECK-NEXT: vle32.v v8, (a0)126; CHECK-NEXT: vmv.s.x v9, zero127; CHECK-NEXT: vredsum.vs v8, v8, v9128; CHECK-NEXT: vmv.x.s a0, v8129; CHECK-NEXT: ret130 %v = load <16 x i32>, ptr %p, align 256131 %e0 = extractelement <16 x i32> %v, i32 0132 %e1 = extractelement <16 x i32> %v, i32 1133 %e2 = extractelement <16 x i32> %v, i32 2134 %add0 = add i32 %e0, %e1135 %add1 = add i32 %add0, %e2136 ret i32 %add1137}138 139define i32 @reduce_sum_16xi32_prefix4(ptr %p) {140; CHECK-LABEL: reduce_sum_16xi32_prefix4:141; CHECK: # %bb.0:142; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma143; CHECK-NEXT: vle32.v v8, (a0)144; CHECK-NEXT: vmv.s.x v9, zero145; CHECK-NEXT: vredsum.vs v8, v8, v9146; CHECK-NEXT: vmv.x.s a0, v8147; CHECK-NEXT: ret148 %v = load <16 x i32>, ptr %p, align 256149 %e0 = extractelement <16 x i32> %v, i32 0150 %e1 = extractelement <16 x i32> %v, i32 1151 %e2 = extractelement <16 x i32> %v, i32 2152 %e3 = extractelement <16 x i32> %v, i32 3153 %add0 = add i32 %e0, %e1154 %add1 = add i32 %add0, %e2155 %add2 = add i32 %add1, %e3156 ret i32 %add2157}158 159define i32 @reduce_sum_16xi32_prefix5(ptr %p) {160; CHECK-LABEL: reduce_sum_16xi32_prefix5:161; CHECK: # %bb.0:162; CHECK-NEXT: vsetivli zero, 5, e32, m2, ta, ma163; CHECK-NEXT: vle32.v v8, (a0)164; CHECK-NEXT: vmv.s.x v10, zero165; CHECK-NEXT: vredsum.vs v8, v8, v10166; CHECK-NEXT: vmv.x.s a0, v8167; CHECK-NEXT: ret168 %v = load <16 x i32>, ptr %p, align 256169 %e0 = extractelement <16 x i32> %v, i32 0170 %e1 = extractelement <16 x i32> %v, i32 1171 %e2 = extractelement <16 x i32> %v, i32 2172 %e3 = extractelement <16 x i32> %v, i32 3173 %e4 = extractelement <16 x i32> %v, i32 4174 %add0 = add i32 %e0, %e1175 %add1 = add i32 %add0, %e2176 %add2 = add i32 %add1, %e3177 %add3 = add i32 %add2, %e4178 ret i32 %add3179}180 181define i32 @reduce_sum_16xi32_prefix6(ptr %p) {182; CHECK-LABEL: reduce_sum_16xi32_prefix6:183; CHECK: # %bb.0:184; CHECK-NEXT: vsetivli zero, 6, e32, m2, ta, ma185; CHECK-NEXT: vle32.v v8, (a0)186; CHECK-NEXT: vmv.s.x v10, zero187; CHECK-NEXT: vredsum.vs v8, v8, v10188; CHECK-NEXT: vmv.x.s a0, v8189; CHECK-NEXT: ret190 %v = load <16 x i32>, ptr %p, align 256191 %e0 = extractelement <16 x i32> %v, i32 0192 %e1 = extractelement <16 x i32> %v, i32 1193 %e2 = extractelement <16 x i32> %v, i32 2194 %e3 = extractelement <16 x i32> %v, i32 3195 %e4 = extractelement <16 x i32> %v, i32 4196 %e5 = extractelement <16 x i32> %v, i32 5197 %add0 = add i32 %e0, %e1198 %add1 = add i32 %add0, %e2199 %add2 = add i32 %add1, %e3200 %add3 = add i32 %add2, %e4201 %add4 = add i32 %add3, %e5202 ret i32 %add4203}204 205define i32 @reduce_sum_16xi32_prefix7(ptr %p) {206; CHECK-LABEL: reduce_sum_16xi32_prefix7:207; CHECK: # %bb.0:208; CHECK-NEXT: vsetivli zero, 7, e32, m2, ta, ma209; CHECK-NEXT: vle32.v v8, (a0)210; CHECK-NEXT: vmv.s.x v10, zero211; CHECK-NEXT: vredsum.vs v8, v8, v10212; CHECK-NEXT: vmv.x.s a0, v8213; CHECK-NEXT: ret214 %v = load <16 x i32>, ptr %p, align 256215 %e0 = extractelement <16 x i32> %v, i32 0216 %e1 = extractelement <16 x i32> %v, i32 1217 %e2 = extractelement <16 x i32> %v, i32 2218 %e3 = extractelement <16 x i32> %v, i32 3219 %e4 = extractelement <16 x i32> %v, i32 4220 %e5 = extractelement <16 x i32> %v, i32 5221 %e6 = extractelement <16 x i32> %v, i32 6222 %add0 = add i32 %e0, %e1223 %add1 = add i32 %add0, %e2224 %add2 = add i32 %add1, %e3225 %add3 = add i32 %add2, %e4226 %add4 = add i32 %add3, %e5227 %add5 = add i32 %add4, %e6228 ret i32 %add5229}230 231define i32 @reduce_sum_16xi32_prefix8(ptr %p) {232; CHECK-LABEL: reduce_sum_16xi32_prefix8:233; CHECK: # %bb.0:234; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma235; CHECK-NEXT: vle32.v v8, (a0)236; CHECK-NEXT: vmv.s.x v10, zero237; CHECK-NEXT: vredsum.vs v8, v8, v10238; CHECK-NEXT: vmv.x.s a0, v8239; CHECK-NEXT: ret240 %v = load <16 x i32>, ptr %p, align 256241 %e0 = extractelement <16 x i32> %v, i32 0242 %e1 = extractelement <16 x i32> %v, i32 1243 %e2 = extractelement <16 x i32> %v, i32 2244 %e3 = extractelement <16 x i32> %v, i32 3245 %e4 = extractelement <16 x i32> %v, i32 4246 %e5 = extractelement <16 x i32> %v, i32 5247 %e6 = extractelement <16 x i32> %v, i32 6248 %e7 = extractelement <16 x i32> %v, i32 7249 %add0 = add i32 %e0, %e1250 %add1 = add i32 %add0, %e2251 %add2 = add i32 %add1, %e3252 %add3 = add i32 %add2, %e4253 %add4 = add i32 %add3, %e5254 %add5 = add i32 %add4, %e6255 %add6 = add i32 %add5, %e7256 ret i32 %add6257}258 259define i32 @reduce_sum_16xi32_prefix9(ptr %p) {260; CHECK-LABEL: reduce_sum_16xi32_prefix9:261; CHECK: # %bb.0:262; CHECK-NEXT: vsetivli zero, 9, e32, m4, ta, ma263; CHECK-NEXT: vle32.v v8, (a0)264; CHECK-NEXT: vmv.s.x v12, zero265; CHECK-NEXT: vredsum.vs v8, v8, v12266; CHECK-NEXT: vmv.x.s a0, v8267; CHECK-NEXT: ret268 %v = load <16 x i32>, ptr %p, align 256269 %e0 = extractelement <16 x i32> %v, i32 0270 %e1 = extractelement <16 x i32> %v, i32 1271 %e2 = extractelement <16 x i32> %v, i32 2272 %e3 = extractelement <16 x i32> %v, i32 3273 %e4 = extractelement <16 x i32> %v, i32 4274 %e5 = extractelement <16 x i32> %v, i32 5275 %e6 = extractelement <16 x i32> %v, i32 6276 %e7 = extractelement <16 x i32> %v, i32 7277 %e8 = extractelement <16 x i32> %v, i32 8278 %add0 = add i32 %e0, %e1279 %add1 = add i32 %add0, %e2280 %add2 = add i32 %add1, %e3281 %add3 = add i32 %add2, %e4282 %add4 = add i32 %add3, %e5283 %add5 = add i32 %add4, %e6284 %add6 = add i32 %add5, %e7285 %add7 = add i32 %add6, %e8286 ret i32 %add7287}288 289define i32 @reduce_sum_16xi32_prefix13(ptr %p) {290; CHECK-LABEL: reduce_sum_16xi32_prefix13:291; CHECK: # %bb.0:292; CHECK-NEXT: vsetivli zero, 13, e32, m4, ta, ma293; CHECK-NEXT: vle32.v v8, (a0)294; CHECK-NEXT: vmv.s.x v12, zero295; CHECK-NEXT: vredsum.vs v8, v8, v12296; CHECK-NEXT: vmv.x.s a0, v8297; CHECK-NEXT: ret298 %v = load <16 x i32>, ptr %p, align 256299 %e0 = extractelement <16 x i32> %v, i32 0300 %e1 = extractelement <16 x i32> %v, i32 1301 %e2 = extractelement <16 x i32> %v, i32 2302 %e3 = extractelement <16 x i32> %v, i32 3303 %e4 = extractelement <16 x i32> %v, i32 4304 %e5 = extractelement <16 x i32> %v, i32 5305 %e6 = extractelement <16 x i32> %v, i32 6306 %e7 = extractelement <16 x i32> %v, i32 7307 %e8 = extractelement <16 x i32> %v, i32 8308 %e9 = extractelement <16 x i32> %v, i32 9309 %e10 = extractelement <16 x i32> %v, i32 10310 %e11 = extractelement <16 x i32> %v, i32 11311 %e12 = extractelement <16 x i32> %v, i32 12312 %add0 = add i32 %e0, %e1313 %add1 = add i32 %add0, %e2314 %add2 = add i32 %add1, %e3315 %add3 = add i32 %add2, %e4316 %add4 = add i32 %add3, %e5317 %add5 = add i32 %add4, %e6318 %add6 = add i32 %add5, %e7319 %add7 = add i32 %add6, %e8320 %add8 = add i32 %add7, %e9321 %add9 = add i32 %add8, %e10322 %add10 = add i32 %add9, %e11323 %add11 = add i32 %add10, %e12324 ret i32 %add11325}326 327define i32 @reduce_sum_16xi32_prefix14(ptr %p) {328; CHECK-LABEL: reduce_sum_16xi32_prefix14:329; CHECK: # %bb.0:330; CHECK-NEXT: vsetivli zero, 14, e32, m4, ta, ma331; CHECK-NEXT: vle32.v v8, (a0)332; CHECK-NEXT: vmv.s.x v12, zero333; CHECK-NEXT: vredsum.vs v8, v8, v12334; CHECK-NEXT: vmv.x.s a0, v8335; CHECK-NEXT: ret336 %v = load <16 x i32>, ptr %p, align 256337 %e0 = extractelement <16 x i32> %v, i32 0338 %e1 = extractelement <16 x i32> %v, i32 1339 %e2 = extractelement <16 x i32> %v, i32 2340 %e3 = extractelement <16 x i32> %v, i32 3341 %e4 = extractelement <16 x i32> %v, i32 4342 %e5 = extractelement <16 x i32> %v, i32 5343 %e6 = extractelement <16 x i32> %v, i32 6344 %e7 = extractelement <16 x i32> %v, i32 7345 %e8 = extractelement <16 x i32> %v, i32 8346 %e9 = extractelement <16 x i32> %v, i32 9347 %e10 = extractelement <16 x i32> %v, i32 10348 %e11 = extractelement <16 x i32> %v, i32 11349 %e12 = extractelement <16 x i32> %v, i32 12350 %e13 = extractelement <16 x i32> %v, i32 13351 %add0 = add i32 %e0, %e1352 %add1 = add i32 %add0, %e2353 %add2 = add i32 %add1, %e3354 %add3 = add i32 %add2, %e4355 %add4 = add i32 %add3, %e5356 %add5 = add i32 %add4, %e6357 %add6 = add i32 %add5, %e7358 %add7 = add i32 %add6, %e8359 %add8 = add i32 %add7, %e9360 %add9 = add i32 %add8, %e10361 %add10 = add i32 %add9, %e11362 %add11 = add i32 %add10, %e12363 %add12 = add i32 %add11, %e13364 ret i32 %add12365}366 367define i32 @reduce_sum_16xi32_prefix15(ptr %p) {368; CHECK-LABEL: reduce_sum_16xi32_prefix15:369; CHECK: # %bb.0:370; CHECK-NEXT: vsetivli zero, 15, e32, m4, ta, ma371; CHECK-NEXT: vle32.v v8, (a0)372; CHECK-NEXT: vmv.s.x v12, zero373; CHECK-NEXT: vredsum.vs v8, v8, v12374; CHECK-NEXT: vmv.x.s a0, v8375; CHECK-NEXT: ret376 %v = load <16 x i32>, ptr %p, align 256377 %e0 = extractelement <16 x i32> %v, i32 0378 %e1 = extractelement <16 x i32> %v, i32 1379 %e2 = extractelement <16 x i32> %v, i32 2380 %e3 = extractelement <16 x i32> %v, i32 3381 %e4 = extractelement <16 x i32> %v, i32 4382 %e5 = extractelement <16 x i32> %v, i32 5383 %e6 = extractelement <16 x i32> %v, i32 6384 %e7 = extractelement <16 x i32> %v, i32 7385 %e8 = extractelement <16 x i32> %v, i32 8386 %e9 = extractelement <16 x i32> %v, i32 9387 %e10 = extractelement <16 x i32> %v, i32 10388 %e11 = extractelement <16 x i32> %v, i32 11389 %e12 = extractelement <16 x i32> %v, i32 12390 %e13 = extractelement <16 x i32> %v, i32 13391 %e14 = extractelement <16 x i32> %v, i32 14392 %add0 = add i32 %e0, %e1393 %add1 = add i32 %add0, %e2394 %add2 = add i32 %add1, %e3395 %add3 = add i32 %add2, %e4396 %add4 = add i32 %add3, %e5397 %add5 = add i32 %add4, %e6398 %add6 = add i32 %add5, %e7399 %add7 = add i32 %add6, %e8400 %add8 = add i32 %add7, %e9401 %add9 = add i32 %add8, %e10402 %add10 = add i32 %add9, %e11403 %add11 = add i32 %add10, %e12404 %add12 = add i32 %add11, %e13405 %add13 = add i32 %add12, %e14406 ret i32 %add13407}408 409; Check that we can match with the operand ordered reversed, but the410; reduction order unchanged.411define i32 @reduce_sum_4xi32_op_order(<4 x i32> %v) {412; CHECK-LABEL: reduce_sum_4xi32_op_order:413; CHECK: # %bb.0:414; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma415; CHECK-NEXT: vmv.s.x v9, zero416; CHECK-NEXT: vredsum.vs v8, v8, v9417; CHECK-NEXT: vmv.x.s a0, v8418; CHECK-NEXT: ret419 %e0 = extractelement <4 x i32> %v, i32 0420 %e1 = extractelement <4 x i32> %v, i32 1421 %e2 = extractelement <4 x i32> %v, i32 2422 %e3 = extractelement <4 x i32> %v, i32 3423 %add0 = add i32 %e1, %e0424 %add1 = add i32 %e2, %add0425 %add2 = add i32 %add1, %e3426 ret i32 %add2427}428 429; Negative test - Reduction order isn't compatibile with current430; incremental matching scheme.431define i32 @reduce_sum_4xi32_reduce_order(<4 x i32> %v) {432; RV32-LABEL: reduce_sum_4xi32_reduce_order:433; RV32: # %bb.0:434; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma435; RV32-NEXT: vmv.x.s a0, v8436; RV32-NEXT: vslidedown.vi v9, v8, 1437; RV32-NEXT: vmv.x.s a1, v9438; RV32-NEXT: vslidedown.vi v9, v8, 2439; RV32-NEXT: vslidedown.vi v8, v8, 3440; RV32-NEXT: vmv.x.s a2, v9441; RV32-NEXT: vmv.x.s a3, v8442; RV32-NEXT: add a1, a1, a2443; RV32-NEXT: add a0, a0, a3444; RV32-NEXT: add a0, a0, a1445; RV32-NEXT: ret446;447; RV64-LABEL: reduce_sum_4xi32_reduce_order:448; RV64: # %bb.0:449; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma450; RV64-NEXT: vmv.x.s a0, v8451; RV64-NEXT: vslidedown.vi v9, v8, 1452; RV64-NEXT: vmv.x.s a1, v9453; RV64-NEXT: vslidedown.vi v9, v8, 2454; RV64-NEXT: vslidedown.vi v8, v8, 3455; RV64-NEXT: vmv.x.s a2, v9456; RV64-NEXT: vmv.x.s a3, v8457; RV64-NEXT: add a1, a1, a2458; RV64-NEXT: add a0, a0, a3459; RV64-NEXT: addw a0, a0, a1460; RV64-NEXT: ret461 %e0 = extractelement <4 x i32> %v, i32 0462 %e1 = extractelement <4 x i32> %v, i32 1463 %e2 = extractelement <4 x i32> %v, i32 2464 %e3 = extractelement <4 x i32> %v, i32 3465 %add0 = add i32 %e1, %e2466 %add1 = add i32 %e0, %add0467 %add2 = add i32 %add1, %e3468 ret i32 %add2469}470 471;; Most of the cornercases are exercised above, the following just472;; makes sure that other opcodes work as expected.473 474define i32 @reduce_xor_16xi32_prefix2(ptr %p) {475; CHECK-LABEL: reduce_xor_16xi32_prefix2:476; CHECK: # %bb.0:477; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma478; CHECK-NEXT: vle32.v v8, (a0)479; CHECK-NEXT: vmv.s.x v9, zero480; CHECK-NEXT: vredxor.vs v8, v8, v9481; CHECK-NEXT: vmv.x.s a0, v8482; CHECK-NEXT: ret483 %v = load <16 x i32>, ptr %p, align 256484 %e0 = extractelement <16 x i32> %v, i32 0485 %e1 = extractelement <16 x i32> %v, i32 1486 %xor0 = xor i32 %e0, %e1487 ret i32 %xor0488}489 490define i32 @reduce_xor_16xi32_prefix5(ptr %p) {491; CHECK-LABEL: reduce_xor_16xi32_prefix5:492; CHECK: # %bb.0:493; CHECK-NEXT: vsetivli zero, 5, e32, m2, ta, ma494; CHECK-NEXT: vle32.v v8, (a0)495; CHECK-NEXT: vmv.s.x v10, zero496; CHECK-NEXT: vredxor.vs v8, v8, v10497; CHECK-NEXT: vmv.x.s a0, v8498; CHECK-NEXT: ret499 %v = load <16 x i32>, ptr %p, align 256500 %e0 = extractelement <16 x i32> %v, i32 0501 %e1 = extractelement <16 x i32> %v, i32 1502 %e2 = extractelement <16 x i32> %v, i32 2503 %e3 = extractelement <16 x i32> %v, i32 3504 %e4 = extractelement <16 x i32> %v, i32 4505 %xor0 = xor i32 %e0, %e1506 %xor1 = xor i32 %xor0, %e2507 %xor2 = xor i32 %xor1, %e3508 %xor3 = xor i32 %xor2, %e4509 ret i32 %xor3510}511 512define i32 @reduce_and_16xi32_prefix2(ptr %p) {513; CHECK-LABEL: reduce_and_16xi32_prefix2:514; CHECK: # %bb.0:515; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma516; CHECK-NEXT: vle32.v v8, (a0)517; CHECK-NEXT: vredand.vs v8, v8, v8518; CHECK-NEXT: vmv.x.s a0, v8519; CHECK-NEXT: ret520 %v = load <16 x i32>, ptr %p, align 256521 %e0 = extractelement <16 x i32> %v, i32 0522 %e1 = extractelement <16 x i32> %v, i32 1523 %and0 = and i32 %e0, %e1524 ret i32 %and0525}526 527define i32 @reduce_and_16xi32_prefix5(ptr %p) {528; CHECK-LABEL: reduce_and_16xi32_prefix5:529; CHECK: # %bb.0:530; CHECK-NEXT: vsetivli zero, 5, e32, m2, ta, ma531; CHECK-NEXT: vle32.v v8, (a0)532; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma533; CHECK-NEXT: vmv.v.i v10, -1534; CHECK-NEXT: vsetivli zero, 5, e32, m2, ta, ma535; CHECK-NEXT: vredand.vs v8, v8, v10536; CHECK-NEXT: vmv.x.s a0, v8537; CHECK-NEXT: ret538 %v = load <16 x i32>, ptr %p, align 256539 %e0 = extractelement <16 x i32> %v, i32 0540 %e1 = extractelement <16 x i32> %v, i32 1541 %e2 = extractelement <16 x i32> %v, i32 2542 %e3 = extractelement <16 x i32> %v, i32 3543 %e4 = extractelement <16 x i32> %v, i32 4544 %and0 = and i32 %e0, %e1545 %and1 = and i32 %and0, %e2546 %and2 = and i32 %and1, %e3547 %and3 = and i32 %and2, %e4548 ret i32 %and3549}550 551define i32 @reduce_or_16xi32_prefix2(ptr %p) {552; CHECK-LABEL: reduce_or_16xi32_prefix2:553; CHECK: # %bb.0:554; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma555; CHECK-NEXT: vle32.v v8, (a0)556; CHECK-NEXT: vredor.vs v8, v8, v8557; CHECK-NEXT: vmv.x.s a0, v8558; CHECK-NEXT: ret559 %v = load <16 x i32>, ptr %p, align 256560 %e0 = extractelement <16 x i32> %v, i32 0561 %e1 = extractelement <16 x i32> %v, i32 1562 %or0 = or i32 %e0, %e1563 ret i32 %or0564}565 566define i32 @reduce_or_16xi32_prefix5(ptr %p) {567; CHECK-LABEL: reduce_or_16xi32_prefix5:568; CHECK: # %bb.0:569; CHECK-NEXT: vsetivli zero, 5, e32, m2, ta, ma570; CHECK-NEXT: vle32.v v8, (a0)571; CHECK-NEXT: vmv.s.x v10, zero572; CHECK-NEXT: vredor.vs v8, v8, v10573; CHECK-NEXT: vmv.x.s a0, v8574; CHECK-NEXT: ret575 %v = load <16 x i32>, ptr %p, align 256576 %e0 = extractelement <16 x i32> %v, i32 0577 %e1 = extractelement <16 x i32> %v, i32 1578 %e2 = extractelement <16 x i32> %v, i32 2579 %e3 = extractelement <16 x i32> %v, i32 3580 %e4 = extractelement <16 x i32> %v, i32 4581 %or0 = or i32 %e0, %e1582 %or1 = or i32 %or0, %e2583 %or2 = or i32 %or1, %e3584 %or3 = or i32 %or2, %e4585 ret i32 %or3586}587 588define i32 @reduce_smax_16xi32_prefix2(ptr %p) {589; CHECK-LABEL: reduce_smax_16xi32_prefix2:590; CHECK: # %bb.0:591; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma592; CHECK-NEXT: vle32.v v8, (a0)593; CHECK-NEXT: vredmax.vs v8, v8, v8594; CHECK-NEXT: vmv.x.s a0, v8595; CHECK-NEXT: ret596 %v = load <16 x i32>, ptr %p, align 256597 %e0 = extractelement <16 x i32> %v, i32 0598 %e1 = extractelement <16 x i32> %v, i32 1599 %smax0 = call i32 @llvm.smax.i32(i32 %e0, i32 %e1)600 ret i32 %smax0601}602 603define i32 @reduce_smax_16xi32_prefix5(ptr %p) {604; CHECK-LABEL: reduce_smax_16xi32_prefix5:605; CHECK: # %bb.0:606; CHECK-NEXT: vsetivli zero, 5, e32, m2, ta, ma607; CHECK-NEXT: vle32.v v8, (a0)608; CHECK-NEXT: lui a0, 524288609; CHECK-NEXT: vmv.s.x v10, a0610; CHECK-NEXT: vredmax.vs v8, v8, v10611; CHECK-NEXT: vmv.x.s a0, v8612; CHECK-NEXT: ret613 %v = load <16 x i32>, ptr %p, align 256614 %e0 = extractelement <16 x i32> %v, i32 0615 %e1 = extractelement <16 x i32> %v, i32 1616 %e2 = extractelement <16 x i32> %v, i32 2617 %e3 = extractelement <16 x i32> %v, i32 3618 %e4 = extractelement <16 x i32> %v, i32 4619 %smax0 = call i32 @llvm.smax.i32(i32 %e0, i32 %e1)620 %smax1 = call i32 @llvm.smax.i32(i32 %smax0, i32 %e2)621 %smax2 = call i32 @llvm.smax.i32(i32 %smax1, i32 %e3)622 %smax3 = call i32 @llvm.smax.i32(i32 %smax2, i32 %e4)623 ret i32 %smax3624}625 626define i32 @reduce_smin_16xi32_prefix2(ptr %p) {627; CHECK-LABEL: reduce_smin_16xi32_prefix2:628; CHECK: # %bb.0:629; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma630; CHECK-NEXT: vle32.v v8, (a0)631; CHECK-NEXT: vredmin.vs v8, v8, v8632; CHECK-NEXT: vmv.x.s a0, v8633; CHECK-NEXT: ret634 %v = load <16 x i32>, ptr %p, align 256635 %e0 = extractelement <16 x i32> %v, i32 0636 %e1 = extractelement <16 x i32> %v, i32 1637 %smin0 = call i32 @llvm.smin.i32(i32 %e0, i32 %e1)638 ret i32 %smin0639}640 641define i32 @reduce_smin_16xi32_prefix5(ptr %p) {642; CHECK-LABEL: reduce_smin_16xi32_prefix5:643; CHECK: # %bb.0:644; CHECK-NEXT: vsetivli zero, 5, e32, m2, ta, ma645; CHECK-NEXT: vle32.v v8, (a0)646; CHECK-NEXT: lui a0, 524288647; CHECK-NEXT: addi a0, a0, -1648; CHECK-NEXT: vmv.s.x v10, a0649; CHECK-NEXT: vredmin.vs v8, v8, v10650; CHECK-NEXT: vmv.x.s a0, v8651; CHECK-NEXT: ret652 %v = load <16 x i32>, ptr %p, align 256653 %e0 = extractelement <16 x i32> %v, i32 0654 %e1 = extractelement <16 x i32> %v, i32 1655 %e2 = extractelement <16 x i32> %v, i32 2656 %e3 = extractelement <16 x i32> %v, i32 3657 %e4 = extractelement <16 x i32> %v, i32 4658 %smin0 = call i32 @llvm.smin.i32(i32 %e0, i32 %e1)659 %smin1 = call i32 @llvm.smin.i32(i32 %smin0, i32 %e2)660 %smin2 = call i32 @llvm.smin.i32(i32 %smin1, i32 %e3)661 %smin3 = call i32 @llvm.smin.i32(i32 %smin2, i32 %e4)662 ret i32 %smin3663}664 665define i32 @reduce_umax_16xi32_prefix2(ptr %p) {666; CHECK-LABEL: reduce_umax_16xi32_prefix2:667; CHECK: # %bb.0:668; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma669; CHECK-NEXT: vle32.v v8, (a0)670; CHECK-NEXT: vredmaxu.vs v8, v8, v8671; CHECK-NEXT: vmv.x.s a0, v8672; CHECK-NEXT: ret673 %v = load <16 x i32>, ptr %p, align 256674 %e0 = extractelement <16 x i32> %v, i32 0675 %e1 = extractelement <16 x i32> %v, i32 1676 %umax0 = call i32 @llvm.umax.i32(i32 %e0, i32 %e1)677 ret i32 %umax0678}679 680define i32 @reduce_umax_16xi32_prefix5(ptr %p) {681; CHECK-LABEL: reduce_umax_16xi32_prefix5:682; CHECK: # %bb.0:683; CHECK-NEXT: vsetivli zero, 5, e32, m2, ta, ma684; CHECK-NEXT: vle32.v v8, (a0)685; CHECK-NEXT: vmv.s.x v10, zero686; CHECK-NEXT: vredmaxu.vs v8, v8, v10687; CHECK-NEXT: vmv.x.s a0, v8688; CHECK-NEXT: ret689 %v = load <16 x i32>, ptr %p, align 256690 %e0 = extractelement <16 x i32> %v, i32 0691 %e1 = extractelement <16 x i32> %v, i32 1692 %e2 = extractelement <16 x i32> %v, i32 2693 %e3 = extractelement <16 x i32> %v, i32 3694 %e4 = extractelement <16 x i32> %v, i32 4695 %umax0 = call i32 @llvm.umax.i32(i32 %e0, i32 %e1)696 %umax1 = call i32 @llvm.umax.i32(i32 %umax0, i32 %e2)697 %umax2 = call i32 @llvm.umax.i32(i32 %umax1, i32 %e3)698 %umax3 = call i32 @llvm.umax.i32(i32 %umax2, i32 %e4)699 ret i32 %umax3700}701 702define i32 @reduce_umin_16xi32_prefix2(ptr %p) {703; CHECK-LABEL: reduce_umin_16xi32_prefix2:704; CHECK: # %bb.0:705; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma706; CHECK-NEXT: vle32.v v8, (a0)707; CHECK-NEXT: vredminu.vs v8, v8, v8708; CHECK-NEXT: vmv.x.s a0, v8709; CHECK-NEXT: ret710 %v = load <16 x i32>, ptr %p, align 256711 %e0 = extractelement <16 x i32> %v, i32 0712 %e1 = extractelement <16 x i32> %v, i32 1713 %umin0 = call i32 @llvm.umin.i32(i32 %e0, i32 %e1)714 ret i32 %umin0715}716 717define i32 @reduce_umin_16xi32_prefix5(ptr %p) {718; RV32-LABEL: reduce_umin_16xi32_prefix5:719; RV32: # %bb.0:720; RV32-NEXT: vsetivli zero, 5, e32, m2, ta, ma721; RV32-NEXT: vle32.v v8, (a0)722; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma723; RV32-NEXT: vmv.v.i v10, -1724; RV32-NEXT: vsetivli zero, 5, e32, m2, ta, ma725; RV32-NEXT: vredminu.vs v8, v8, v10726; RV32-NEXT: vmv.x.s a0, v8727; RV32-NEXT: ret728;729; RV64-LABEL: reduce_umin_16xi32_prefix5:730; RV64: # %bb.0:731; RV64-NEXT: vsetivli zero, 5, e32, m2, ta, ma732; RV64-NEXT: vle32.v v8, (a0)733; RV64-NEXT: li a0, -1734; RV64-NEXT: vmv.s.x v10, a0735; RV64-NEXT: vredminu.vs v8, v8, v10736; RV64-NEXT: vmv.x.s a0, v8737; RV64-NEXT: ret738 %v = load <16 x i32>, ptr %p, align 256739 %e0 = extractelement <16 x i32> %v, i32 0740 %e1 = extractelement <16 x i32> %v, i32 1741 %e2 = extractelement <16 x i32> %v, i32 2742 %e3 = extractelement <16 x i32> %v, i32 3743 %e4 = extractelement <16 x i32> %v, i32 4744 %umin0 = call i32 @llvm.umin.i32(i32 %e0, i32 %e1)745 %umin1 = call i32 @llvm.umin.i32(i32 %umin0, i32 %e2)746 %umin2 = call i32 @llvm.umin.i32(i32 %umin1, i32 %e3)747 %umin3 = call i32 @llvm.umin.i32(i32 %umin2, i32 %e4)748 ret i32 %umin3749}750 751define float @reduce_fadd_16xf32_prefix2(ptr %p) {752; CHECK-LABEL: reduce_fadd_16xf32_prefix2:753; CHECK: # %bb.0:754; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma755; CHECK-NEXT: vle32.v v8, (a0)756; CHECK-NEXT: vmv.s.x v9, zero757; CHECK-NEXT: vfredusum.vs v8, v8, v9758; CHECK-NEXT: vfmv.f.s fa0, v8759; CHECK-NEXT: ret760 %v = load <16 x float>, ptr %p, align 256761 %e0 = extractelement <16 x float> %v, i32 0762 %e1 = extractelement <16 x float> %v, i32 1763 %fadd0 = fadd fast float %e0, %e1764 ret float %fadd0765}766 767define float @reduce_fadd_16xi32_prefix5(ptr %p) {768; CHECK-LABEL: reduce_fadd_16xi32_prefix5:769; CHECK: # %bb.0:770; CHECK-NEXT: vsetivli zero, 5, e32, m2, ta, ma771; CHECK-NEXT: vle32.v v8, (a0)772; CHECK-NEXT: lui a0, 524288773; CHECK-NEXT: vmv.s.x v10, a0774; CHECK-NEXT: vfredusum.vs v8, v8, v10775; CHECK-NEXT: vfmv.f.s fa0, v8776; CHECK-NEXT: ret777 %v = load <16 x float>, ptr %p, align 256778 %e0 = extractelement <16 x float> %v, i32 0779 %e1 = extractelement <16 x float> %v, i32 1780 %e2 = extractelement <16 x float> %v, i32 2781 %e3 = extractelement <16 x float> %v, i32 3782 %e4 = extractelement <16 x float> %v, i32 4783 %fadd0 = fadd fast float %e0, %e1784 %fadd1 = fadd fast float %fadd0, %e2785 %fadd2 = fadd fast float %fadd1, %e3786 %fadd3 = fadd fast float %fadd2, %e4787 ret float %fadd3788}789 790;; Corner case tests for fadd associativity791 792; Negative test, not associative. Would need strict opcode.793define float @reduce_fadd_2xf32_non_associative(ptr %p) {794; CHECK-LABEL: reduce_fadd_2xf32_non_associative:795; CHECK: # %bb.0:796; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma797; CHECK-NEXT: vle32.v v8, (a0)798; CHECK-NEXT: vfmv.f.s fa5, v8799; CHECK-NEXT: vslidedown.vi v8, v8, 1800; CHECK-NEXT: vfmv.f.s fa4, v8801; CHECK-NEXT: fadd.s fa0, fa5, fa4802; CHECK-NEXT: ret803 %v = load <2 x float>, ptr %p, align 256804 %e0 = extractelement <2 x float> %v, i32 0805 %e1 = extractelement <2 x float> %v, i32 1806 %fadd0 = fadd float %e0, %e1807 ret float %fadd0808}809 810; Positive test - minimal set of fast math flags811define float @reduce_fadd_2xf32_reassoc_only(ptr %p) {812; CHECK-LABEL: reduce_fadd_2xf32_reassoc_only:813; CHECK: # %bb.0:814; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma815; CHECK-NEXT: vle32.v v8, (a0)816; CHECK-NEXT: lui a0, 524288817; CHECK-NEXT: vmv.s.x v9, a0818; CHECK-NEXT: vfredusum.vs v8, v8, v9819; CHECK-NEXT: vfmv.f.s fa0, v8820; CHECK-NEXT: ret821 %v = load <2 x float>, ptr %p, align 256822 %e0 = extractelement <2 x float> %v, i32 0823 %e1 = extractelement <2 x float> %v, i32 1824 %fadd0 = fadd reassoc float %e0, %e1825 ret float %fadd0826}827 828; Negative test - wrong fast math flag.829define float @reduce_fadd_2xf32_ninf_only(ptr %p) {830; CHECK-LABEL: reduce_fadd_2xf32_ninf_only:831; CHECK: # %bb.0:832; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma833; CHECK-NEXT: vle32.v v8, (a0)834; CHECK-NEXT: vfmv.f.s fa5, v8835; CHECK-NEXT: vslidedown.vi v8, v8, 1836; CHECK-NEXT: vfmv.f.s fa4, v8837; CHECK-NEXT: fadd.s fa0, fa5, fa4838; CHECK-NEXT: ret839 %v = load <2 x float>, ptr %p, align 256840 %e0 = extractelement <2 x float> %v, i32 0841 %e1 = extractelement <2 x float> %v, i32 1842 %fadd0 = fadd ninf float %e0, %e1843 ret float %fadd0844}845 846; Negative test - last fadd is not associative847define float @reduce_fadd_4xi32_non_associative(ptr %p) {848; CHECK-LABEL: reduce_fadd_4xi32_non_associative:849; CHECK: # %bb.0:850; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma851; CHECK-NEXT: vle32.v v8, (a0)852; CHECK-NEXT: lui a0, 524288853; CHECK-NEXT: vmv.s.x v9, a0854; CHECK-NEXT: vsetivli zero, 3, e32, m1, ta, ma855; CHECK-NEXT: vfredusum.vs v9, v8, v9856; CHECK-NEXT: vslidedown.vi v8, v8, 3857; CHECK-NEXT: vfmv.f.s fa5, v8858; CHECK-NEXT: vfmv.f.s fa4, v9859; CHECK-NEXT: fadd.s fa0, fa4, fa5860; CHECK-NEXT: ret861 %v = load <4 x float>, ptr %p, align 256862 %e0 = extractelement <4 x float> %v, i32 0863 %e1 = extractelement <4 x float> %v, i32 1864 %e2 = extractelement <4 x float> %v, i32 2865 %e3 = extractelement <4 x float> %v, i32 3866 %fadd0 = fadd fast float %e0, %e1867 %fadd1 = fadd fast float %fadd0, %e2868 %fadd2 = fadd float %fadd1, %e3869 ret float %fadd2870}871 872; Negative test - first fadd is not associative873; We could form a reduce for elements 2 and 3.874define float @reduce_fadd_4xi32_non_associative2(ptr %p) {875; CHECK-LABEL: reduce_fadd_4xi32_non_associative2:876; CHECK: # %bb.0:877; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma878; CHECK-NEXT: vle32.v v8, (a0)879; CHECK-NEXT: vfmv.f.s fa5, v8880; CHECK-NEXT: vslidedown.vi v9, v8, 1881; CHECK-NEXT: vfmv.f.s fa4, v9882; CHECK-NEXT: vslidedown.vi v9, v8, 2883; CHECK-NEXT: vslidedown.vi v8, v8, 3884; CHECK-NEXT: vfmv.f.s fa3, v9885; CHECK-NEXT: vfmv.f.s fa2, v8886; CHECK-NEXT: fadd.s fa5, fa5, fa4887; CHECK-NEXT: fadd.s fa4, fa3, fa2888; CHECK-NEXT: fadd.s fa0, fa5, fa4889; CHECK-NEXT: ret890 %v = load <4 x float>, ptr %p, align 256891 %e0 = extractelement <4 x float> %v, i32 0892 %e1 = extractelement <4 x float> %v, i32 1893 %e2 = extractelement <4 x float> %v, i32 2894 %e3 = extractelement <4 x float> %v, i32 3895 %fadd0 = fadd float %e0, %e1896 %fadd1 = fadd fast float %fadd0, %e2897 %fadd2 = fadd fast float %fadd1, %e3898 ret float %fadd2899}900 901define float @reduce_fmaxnum_16xf32_prefix2(ptr %p) {902; CHECK-LABEL: reduce_fmaxnum_16xf32_prefix2:903; CHECK: # %bb.0:904; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma905; CHECK-NEXT: vle32.v v8, (a0)906; CHECK-NEXT: vfredmax.vs v8, v8, v8907; CHECK-NEXT: vfmv.f.s fa0, v8908; CHECK-NEXT: ret909 %v = load <16 x float>, ptr %p, align 256910 %e0 = extractelement <16 x float> %v, i32 0911 %e1 = extractelement <16 x float> %v, i32 1912 %fmax0 = call float @llvm.maxnum.f32(float %e0, float %e1)913 ret float %fmax0914}915 916define float @reduce_fminnum_16xf32_prefix2(ptr %p) {917; CHECK-LABEL: reduce_fminnum_16xf32_prefix2:918; CHECK: # %bb.0:919; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma920; CHECK-NEXT: vle32.v v8, (a0)921; CHECK-NEXT: vfredmin.vs v8, v8, v8922; CHECK-NEXT: vfmv.f.s fa0, v8923; CHECK-NEXT: ret924 %v = load <16 x float>, ptr %p, align 256925 %e0 = extractelement <16 x float> %v, i32 0926 %e1 = extractelement <16 x float> %v, i32 1927 %fmax0 = call float @llvm.minnum.f32(float %e0, float %e1)928 ret float %fmax0929}930