1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-linux-gnu | FileCheck %s 3 4define i4 @parity_4(i4 %x) { 5; CHECK-LABEL: parity_4: 6; CHECK: // %bb.0: 7; CHECK-NEXT: and w8, w0, #0xf 8; CHECK-NEXT: eor w8, w8, w8, lsr #2 9; CHECK-NEXT: eor w8, w8, w8, lsr #1 10; CHECK-NEXT: and w0, w8, #0x1 11; CHECK-NEXT: ret 12 %1 = tail call i4 @llvm.ctpop.i4(i4 %x) 13 %2 = and i4 %1, 1 14 ret i4 %2 15} 16 17define i8 @parity_8(i8 %x) { 18; CHECK-LABEL: parity_8: 19; CHECK: // %bb.0: 20; CHECK-NEXT: and w8, w0, #0xff 21; CHECK-NEXT: eor w8, w8, w8, lsr #4 22; CHECK-NEXT: eor w8, w8, w8, lsr #2 23; CHECK-NEXT: eor w8, w8, w8, lsr #1 24; CHECK-NEXT: and w0, w8, #0x1 25; CHECK-NEXT: ret 26 %1 = tail call i8 @llvm.ctpop.i8(i8 %x) 27 %2 = and i8 %1, 1 28 ret i8 %2 29} 30 31define i16 @parity_16(i16 %x) { 32; CHECK-LABEL: parity_16: 33; CHECK: // %bb.0: 34; CHECK-NEXT: and w8, w0, #0xffff 35; CHECK-NEXT: eor w8, w8, w8, lsr #8 36; CHECK-NEXT: eor w8, w8, w8, lsr #4 37; CHECK-NEXT: eor w8, w8, w8, lsr #2 38; CHECK-NEXT: eor w8, w8, w8, lsr #1 39; CHECK-NEXT: and w0, w8, #0x1 40; CHECK-NEXT: ret 41 %1 = tail call i16 @llvm.ctpop.i16(i16 %x) 42 %2 = and i16 %1, 1 43 ret i16 %2 44} 45 46define i17 @parity_17(i17 %x) { 47; CHECK-LABEL: parity_17: 48; CHECK: // %bb.0: 49; CHECK-NEXT: and w8, w0, #0x1ffff 50; CHECK-NEXT: eor w8, w8, w8, lsr #16 51; CHECK-NEXT: eor w8, w8, w8, lsr #8 52; CHECK-NEXT: eor w8, w8, w8, lsr #4 53; CHECK-NEXT: eor w8, w8, w8, lsr #2 54; CHECK-NEXT: eor w8, w8, w8, lsr #1 55; CHECK-NEXT: and w0, w8, #0x1 56; CHECK-NEXT: ret 57 %1 = tail call i17 @llvm.ctpop.i17(i17 %x) 58 %2 = and i17 %1, 1 59 ret i17 %2 60} 61 62define i32 @parity_32(i32 %x) { 63; CHECK-LABEL: parity_32: 64; CHECK: // %bb.0: 65; CHECK-NEXT: eor w8, w0, w0, lsr #16 66; CHECK-NEXT: eor w8, w8, w8, lsr #8 67; CHECK-NEXT: eor w8, w8, w8, lsr #4 68; CHECK-NEXT: eor w8, w8, w8, lsr #2 69; CHECK-NEXT: eor w8, w8, w8, lsr #1 70; CHECK-NEXT: and w0, w8, #0x1 71; CHECK-NEXT: ret 72 %1 = tail call i32 @llvm.ctpop.i32(i32 %x) 73 %2 = and i32 %1, 1 74 ret i32 %2 75} 76 77define i64 @parity_64(i64 %x) { 78; CHECK-LABEL: parity_64: 79; CHECK: // %bb.0: 80; CHECK-NEXT: fmov d0, x0 81; CHECK-NEXT: cnt v0.8b, v0.8b 82; CHECK-NEXT: uaddlv h0, v0.8b 83; CHECK-NEXT: fmov w8, s0 84; CHECK-NEXT: and w0, w8, #0x1 85; CHECK-NEXT: ret 86 %1 = tail call i64 @llvm.ctpop.i64(i64 %x) 87 %2 = and i64 %1, 1 88 ret i64 %2 89} 90 91define i128 @parity_128(i128 %x) { 92; CHECK-LABEL: parity_128: 93; CHECK: // %bb.0: 94; CHECK-NEXT: fmov d0, x0 95; CHECK-NEXT: mov v0.d[1], x1 96; CHECK-NEXT: mov x1, xzr 97; CHECK-NEXT: cnt v0.16b, v0.16b 98; CHECK-NEXT: uaddlv h0, v0.16b 99; CHECK-NEXT: fmov w8, s0 100; CHECK-NEXT: and w0, w8, #0x1 101; CHECK-NEXT: ret 102 %1 = tail call i128 @llvm.ctpop.i128(i128 %x) 103 %2 = and i128 %1, 1 104 ret i128 %2 105} 106 107define i32 @parity_64_trunc(i64 %x) { 108; CHECK-LABEL: parity_64_trunc: 109; CHECK: // %bb.0: 110; CHECK-NEXT: fmov d0, x0 111; CHECK-NEXT: cnt v0.8b, v0.8b 112; CHECK-NEXT: uaddlv h0, v0.8b 113; CHECK-NEXT: fmov w8, s0 114; CHECK-NEXT: and w0, w8, #0x1 115; CHECK-NEXT: ret 116 %1 = tail call i64 @llvm.ctpop.i64(i64 %x) 117 %2 = trunc i64 %1 to i32 118 %3 = and i32 %2, 1 119 ret i32 %3 120} 121 122define i8 @parity_32_trunc(i32 %x) { 123; CHECK-LABEL: parity_32_trunc: 124; CHECK: // %bb.0: 125; CHECK-NEXT: eor w8, w0, w0, lsr #16 126; CHECK-NEXT: eor w8, w8, w8, lsr #8 127; CHECK-NEXT: eor w8, w8, w8, lsr #4 128; CHECK-NEXT: eor w8, w8, w8, lsr #2 129; CHECK-NEXT: eor w8, w8, w8, lsr #1 130; CHECK-NEXT: and w0, w8, #0x1 131; CHECK-NEXT: ret 132 %1 = tail call i32 @llvm.ctpop.i32(i32 %x) 133 %2 = trunc i32 %1 to i8 134 %3 = and i8 %2, 1 135 ret i8 %3 136} 137 138define i32 @parity_8_zext(i8 %x) { 139; CHECK-LABEL: parity_8_zext: 140; CHECK: // %bb.0: 141; CHECK-NEXT: and w8, w0, #0xff 142; CHECK-NEXT: eor w8, w8, w8, lsr #4 143; CHECK-NEXT: eor w8, w8, w8, lsr #2 144; CHECK-NEXT: eor w8, w8, w8, lsr #1 145; CHECK-NEXT: and w0, w8, #0x1 146; CHECK-NEXT: ret 147 %a = zext i8 %x to i32 148 %b = tail call i32 @llvm.ctpop.i32(i32 %a) 149 %c = and i32 %b, 1 150 ret i32 %c 151} 152 153define i32 @parity_8_mask(i32 %x) { 154; CHECK-LABEL: parity_8_mask: 155; CHECK: // %bb.0: 156; CHECK-NEXT: and w8, w0, #0xff 157; CHECK-NEXT: eor w8, w8, w8, lsr #4 158; CHECK-NEXT: eor w8, w8, w8, lsr #2 159; CHECK-NEXT: eor w8, w8, w8, lsr #1 160; CHECK-NEXT: and w0, w8, #0x1 161; CHECK-NEXT: ret 162 %a = and i32 %x, 255 163 %b = tail call i32 @llvm.ctpop.i32(i32 %a) 164 %c = and i32 %b, 1 165 ret i32 %c 166} 167 168declare i4 @llvm.ctpop.i4(i4 %x) 169declare i8 @llvm.ctpop.i8(i8 %x) 170declare i16 @llvm.ctpop.i16(i16 %x) 171declare i17 @llvm.ctpop.i17(i17 %x) 172declare i32 @llvm.ctpop.i32(i32 %x) 173declare i64 @llvm.ctpop.i64(i64 %x) 174declare i128 @llvm.ctpop.i128(i128 %x) 175