1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s --check-prefix=CHECK 3 4declare i1 @llvm.vector.reduce.and.v1i1(<1 x i1> %a) 5declare i1 @llvm.vector.reduce.and.v2i1(<2 x i1> %a) 6declare i1 @llvm.vector.reduce.and.v4i1(<4 x i1> %a) 7declare i1 @llvm.vector.reduce.and.v8i1(<8 x i1> %a) 8declare i1 @llvm.vector.reduce.and.v16i1(<16 x i1> %a) 9declare i1 @llvm.vector.reduce.and.v32i1(<32 x i1> %a) 10 11declare i1 @llvm.vector.reduce.or.v1i1(<1 x i1> %a) 12declare i1 @llvm.vector.reduce.or.v2i1(<2 x i1> %a) 13declare i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %a) 14declare i1 @llvm.vector.reduce.or.v8i1(<8 x i1> %a) 15declare i1 @llvm.vector.reduce.or.v16i1(<16 x i1> %a) 16declare i1 @llvm.vector.reduce.or.v32i1(<32 x i1> %a) 17 18define i32 @reduce_and_v1(<1 x i8> %a0, i32 %a1, i32 %a2) nounwind { 19; CHECK-LABEL: reduce_and_v1: 20; CHECK: // %bb.0: 21; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 22; CHECK-NEXT: smov w8, v0.b[0] 23; CHECK-NEXT: cmp w8, #0 24; CHECK-NEXT: csel w0, w0, w1, lt 25; CHECK-NEXT: ret 26 %x = icmp slt <1 x i8> %a0, zeroinitializer 27 %y = call i1 @llvm.vector.reduce.and.v1i1(<1 x i1> %x) 28 %z = select i1 %y, i32 %a1, i32 %a2 29 ret i32 %z 30} 31 32define i32 @reduce_and_v2(<2 x i8> %a0, i32 %a1, i32 %a2) nounwind { 33; CHECK-LABEL: reduce_and_v2: 34; CHECK: // %bb.0: 35; CHECK-NEXT: shl v0.2s, v0.2s, #24 36; CHECK-NEXT: sshr v0.2s, v0.2s, #24 37; CHECK-NEXT: cmlt v0.2s, v0.2s, #0 38; CHECK-NEXT: uminp v0.2s, v0.2s, v0.2s 39; CHECK-NEXT: fmov w8, s0 40; CHECK-NEXT: tst w8, #0x1 41; CHECK-NEXT: csel w0, w0, w1, ne 42; CHECK-NEXT: ret 43 %x = icmp slt <2 x i8> %a0, zeroinitializer 44 %y = call i1 @llvm.vector.reduce.and.v2i1(<2 x i1> %x) 45 %z = select i1 %y, i32 %a1, i32 %a2 46 ret i32 %z 47} 48 49define i32 @reduce_and_v4(<4 x i8> %a0, i32 %a1, i32 %a2) nounwind { 50; CHECK-LABEL: reduce_and_v4: 51; CHECK: // %bb.0: 52; CHECK-NEXT: shl v0.4h, v0.4h, #8 53; CHECK-NEXT: sshr v0.4h, v0.4h, #8 54; CHECK-NEXT: cmlt v0.4h, v0.4h, #0 55; CHECK-NEXT: uminv h0, v0.4h 56; CHECK-NEXT: fmov w8, s0 57; CHECK-NEXT: tst w8, #0x1 58; CHECK-NEXT: csel w0, w0, w1, ne 59; CHECK-NEXT: ret 60 %x = icmp slt <4 x i8> %a0, zeroinitializer 61 %y = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> %x) 62 %z = select i1 %y, i32 %a1, i32 %a2 63 ret i32 %z 64} 65 66define i32 @reduce_and_v8(<8 x i8> %a0, i32 %a1, i32 %a2) nounwind { 67; CHECK-LABEL: reduce_and_v8: 68; CHECK: // %bb.0: 69; CHECK-NEXT: cmlt v0.8b, v0.8b, #0 70; CHECK-NEXT: uminv b0, v0.8b 71; CHECK-NEXT: fmov w8, s0 72; CHECK-NEXT: tst w8, #0x1 73; CHECK-NEXT: csel w0, w0, w1, ne 74; CHECK-NEXT: ret 75 %x = icmp slt <8 x i8> %a0, zeroinitializer 76 %y = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> %x) 77 %z = select i1 %y, i32 %a1, i32 %a2 78 ret i32 %z 79} 80 81define i32 @reduce_and_v16(<16 x i8> %a0, i32 %a1, i32 %a2) nounwind { 82; CHECK-LABEL: reduce_and_v16: 83; CHECK: // %bb.0: 84; CHECK-NEXT: cmlt v0.16b, v0.16b, #0 85; CHECK-NEXT: uminv b0, v0.16b 86; CHECK-NEXT: fmov w8, s0 87; CHECK-NEXT: tst w8, #0x1 88; CHECK-NEXT: csel w0, w0, w1, ne 89; CHECK-NEXT: ret 90 %x = icmp slt <16 x i8> %a0, zeroinitializer 91 %y = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> %x) 92 %z = select i1 %y, i32 %a1, i32 %a2 93 ret i32 %z 94} 95 96define i32 @reduce_and_v32(<32 x i8> %a0, i32 %a1, i32 %a2) nounwind { 97; CHECK-LABEL: reduce_and_v32: 98; CHECK: // %bb.0: 99; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 100; CHECK-NEXT: cmlt v0.16b, v0.16b, #0 101; CHECK-NEXT: uminv b0, v0.16b 102; CHECK-NEXT: fmov w8, s0 103; CHECK-NEXT: tst w8, #0x1 104; CHECK-NEXT: csel w0, w0, w1, ne 105; CHECK-NEXT: ret 106 %x = icmp slt <32 x i8> %a0, zeroinitializer 107 %y = call i1 @llvm.vector.reduce.and.v32i1(<32 x i1> %x) 108 %z = select i1 %y, i32 %a1, i32 %a2 109 ret i32 %z 110} 111 112define i32 @reduce_or_v1(<1 x i8> %a0, i32 %a1, i32 %a2) nounwind { 113; CHECK-LABEL: reduce_or_v1: 114; CHECK: // %bb.0: 115; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 116; CHECK-NEXT: smov w8, v0.b[0] 117; CHECK-NEXT: cmp w8, #0 118; CHECK-NEXT: csel w0, w0, w1, lt 119; CHECK-NEXT: ret 120 %x = icmp slt <1 x i8> %a0, zeroinitializer 121 %y = call i1 @llvm.vector.reduce.or.v1i1(<1 x i1> %x) 122 %z = select i1 %y, i32 %a1, i32 %a2 123 ret i32 %z 124} 125 126define i32 @reduce_or_v2(<2 x i8> %a0, i32 %a1, i32 %a2) nounwind { 127; CHECK-LABEL: reduce_or_v2: 128; CHECK: // %bb.0: 129; CHECK-NEXT: shl v0.2s, v0.2s, #24 130; CHECK-NEXT: sshr v0.2s, v0.2s, #24 131; CHECK-NEXT: cmlt v0.2s, v0.2s, #0 132; CHECK-NEXT: umaxp v0.2s, v0.2s, v0.2s 133; CHECK-NEXT: fmov w8, s0 134; CHECK-NEXT: tst w8, #0x1 135; CHECK-NEXT: csel w0, w0, w1, ne 136; CHECK-NEXT: ret 137 %x = icmp slt <2 x i8> %a0, zeroinitializer 138 %y = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> %x) 139 %z = select i1 %y, i32 %a1, i32 %a2 140 ret i32 %z 141} 142 143define i32 @reduce_or_v4(<4 x i8> %a0, i32 %a1, i32 %a2) nounwind { 144; CHECK-LABEL: reduce_or_v4: 145; CHECK: // %bb.0: 146; CHECK-NEXT: shl v0.4h, v0.4h, #8 147; CHECK-NEXT: sshr v0.4h, v0.4h, #8 148; CHECK-NEXT: cmlt v0.4h, v0.4h, #0 149; CHECK-NEXT: umaxv h0, v0.4h 150; CHECK-NEXT: fmov w8, s0 151; CHECK-NEXT: tst w8, #0x1 152; CHECK-NEXT: csel w0, w0, w1, ne 153; CHECK-NEXT: ret 154 %x = icmp slt <4 x i8> %a0, zeroinitializer 155 %y = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %x) 156 %z = select i1 %y, i32 %a1, i32 %a2 157 ret i32 %z 158} 159 160define i32 @reduce_or_v8(<8 x i8> %a0, i32 %a1, i32 %a2) nounwind { 161; CHECK-LABEL: reduce_or_v8: 162; CHECK: // %bb.0: 163; CHECK-NEXT: cmlt v0.8b, v0.8b, #0 164; CHECK-NEXT: umaxv b0, v0.8b 165; CHECK-NEXT: fmov w8, s0 166; CHECK-NEXT: tst w8, #0x1 167; CHECK-NEXT: csel w0, w0, w1, ne 168; CHECK-NEXT: ret 169 %x = icmp slt <8 x i8> %a0, zeroinitializer 170 %y = call i1 @llvm.vector.reduce.or.v8i1(<8 x i1> %x) 171 %z = select i1 %y, i32 %a1, i32 %a2 172 ret i32 %z 173} 174 175define i32 @reduce_or_v16(<16 x i8> %a0, i32 %a1, i32 %a2) nounwind { 176; CHECK-LABEL: reduce_or_v16: 177; CHECK: // %bb.0: 178; CHECK-NEXT: cmlt v0.16b, v0.16b, #0 179; CHECK-NEXT: umaxv b0, v0.16b 180; CHECK-NEXT: fmov w8, s0 181; CHECK-NEXT: tst w8, #0x1 182; CHECK-NEXT: csel w0, w0, w1, ne 183; CHECK-NEXT: ret 184 %x = icmp slt <16 x i8> %a0, zeroinitializer 185 %y = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> %x) 186 %z = select i1 %y, i32 %a1, i32 %a2 187 ret i32 %z 188} 189 190define i32 @reduce_or_v32(<32 x i8> %a0, i32 %a1, i32 %a2) nounwind { 191; CHECK-LABEL: reduce_or_v32: 192; CHECK: // %bb.0: 193; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b 194; CHECK-NEXT: cmlt v0.16b, v0.16b, #0 195; CHECK-NEXT: umaxv b0, v0.16b 196; CHECK-NEXT: fmov w8, s0 197; CHECK-NEXT: tst w8, #0x1 198; CHECK-NEXT: csel w0, w0, w1, ne 199; CHECK-NEXT: ret 200 %x = icmp slt <32 x i8> %a0, zeroinitializer 201 %y = call i1 @llvm.vector.reduce.or.v32i1(<32 x i1> %x) 202 %z = select i1 %y, i32 %a1, i32 %a2 203 ret i32 %z 204} 205