brintos

brintos / llvm-project-archived public Read only

0
0
Text · 31.1 KiB · 4da6e10 Raw
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