1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=-popcnt,+sse2 | FileCheck %s --check-prefix=NOPOPCNT 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+popcnt,+sse2 | FileCheck %s --check-prefix=POPCNT 4 5define i1 @noncanonical_parity(<16 x i1> %x) { 6; NOPOPCNT-LABEL: noncanonical_parity: 7; NOPOPCNT: # %bb.0: 8; NOPOPCNT-NEXT: psllw $7, %xmm0 9; NOPOPCNT-NEXT: pmovmskb %xmm0, %eax 10; NOPOPCNT-NEXT: xorb %ah, %al 11; NOPOPCNT-NEXT: setnp %al 12; NOPOPCNT-NEXT: retq 13; 14; POPCNT-LABEL: noncanonical_parity: 15; POPCNT: # %bb.0: 16; POPCNT-NEXT: psllw $7, %xmm0 17; POPCNT-NEXT: pmovmskb %xmm0, %eax 18; POPCNT-NEXT: popcntl %eax, %eax 19; POPCNT-NEXT: andl $1, %eax 20; POPCNT-NEXT: # kill: def $al killed $al killed $eax 21; POPCNT-NEXT: retq 22 %r = call i1 @llvm.vector.reduce.xor.v16i1(<16 x i1> %x) 23 ret i1 %r 24} 25define i1 @canonical_parity(<16 x i1> %x) { 26; NOPOPCNT-LABEL: canonical_parity: 27; NOPOPCNT: # %bb.0: 28; NOPOPCNT-NEXT: psllw $7, %xmm0 29; NOPOPCNT-NEXT: pmovmskb %xmm0, %eax 30; NOPOPCNT-NEXT: xorb %ah, %al 31; NOPOPCNT-NEXT: setnp %al 32; NOPOPCNT-NEXT: retq 33; 34; POPCNT-LABEL: canonical_parity: 35; POPCNT: # %bb.0: 36; POPCNT-NEXT: psllw $7, %xmm0 37; POPCNT-NEXT: pmovmskb %xmm0, %eax 38; POPCNT-NEXT: popcntl %eax, %eax 39; POPCNT-NEXT: andl $1, %eax 40; POPCNT-NEXT: # kill: def $al killed $al killed $eax 41; POPCNT-NEXT: retq 42 %i1 = bitcast <16 x i1> %x to i16 43 %i2 = call i16 @llvm.ctpop.i16(i16 %i1) 44 %i3 = and i16 %i2, 1 45 %i4 = icmp ne i16 %i3, 0 46 ret i1 %i4 47} 48define i1 @canonical_parity_noncanonical_pred(<16 x i1> %x) { 49; NOPOPCNT-LABEL: canonical_parity_noncanonical_pred: 50; NOPOPCNT: # %bb.0: 51; NOPOPCNT-NEXT: psllw $7, %xmm0 52; NOPOPCNT-NEXT: pmovmskb %xmm0, %eax 53; NOPOPCNT-NEXT: movl %eax, %ecx 54; NOPOPCNT-NEXT: shrl %ecx 55; NOPOPCNT-NEXT: andl $21845, %ecx # imm = 0x5555 56; NOPOPCNT-NEXT: subl %ecx, %eax 57; NOPOPCNT-NEXT: movl %eax, %ecx 58; NOPOPCNT-NEXT: andl $13107, %ecx # imm = 0x3333 59; NOPOPCNT-NEXT: shrl $2, %eax 60; NOPOPCNT-NEXT: andl $13107, %eax # imm = 0x3333 61; NOPOPCNT-NEXT: addl %ecx, %eax 62; NOPOPCNT-NEXT: movl %eax, %ecx 63; NOPOPCNT-NEXT: shrl $4, %ecx 64; NOPOPCNT-NEXT: addl %eax, %ecx 65; NOPOPCNT-NEXT: andl $3855, %ecx # imm = 0xF0F 66; NOPOPCNT-NEXT: movl %ecx, %eax 67; NOPOPCNT-NEXT: shrl $8, %eax 68; NOPOPCNT-NEXT: addl %ecx, %eax 69; NOPOPCNT-NEXT: # kill: def $al killed $al killed $eax 70; NOPOPCNT-NEXT: retq 71; 72; POPCNT-LABEL: canonical_parity_noncanonical_pred: 73; POPCNT: # %bb.0: 74; POPCNT-NEXT: psllw $7, %xmm0 75; POPCNT-NEXT: pmovmskb %xmm0, %eax 76; POPCNT-NEXT: popcntl %eax, %eax 77; POPCNT-NEXT: # kill: def $al killed $al killed $eax 78; POPCNT-NEXT: retq 79 %i1 = bitcast <16 x i1> %x to i16 80 %i2 = call i16 @llvm.ctpop.i16(i16 %i1) 81 %i3 = and i16 %i2, 1 82 %i4 = icmp eq i16 %i3, 1 83 ret i1 %i4 84} 85 86define i1 @noncanonical_nonparity(<16 x i1> %x) { 87; NOPOPCNT-LABEL: noncanonical_nonparity: 88; NOPOPCNT: # %bb.0: 89; NOPOPCNT-NEXT: psllw $7, %xmm0 90; NOPOPCNT-NEXT: pmovmskb %xmm0, %eax 91; NOPOPCNT-NEXT: xorb %ah, %al 92; NOPOPCNT-NEXT: setp %al 93; NOPOPCNT-NEXT: retq 94; 95; POPCNT-LABEL: noncanonical_nonparity: 96; POPCNT: # %bb.0: 97; POPCNT-NEXT: psllw $7, %xmm0 98; POPCNT-NEXT: pmovmskb %xmm0, %eax 99; POPCNT-NEXT: popcntl %eax, %eax 100; POPCNT-NEXT: andl $1, %eax 101; POPCNT-NEXT: xorb $1, %al 102; POPCNT-NEXT: # kill: def $al killed $al killed $eax 103; POPCNT-NEXT: retq 104 %r.inv = call i1 @llvm.vector.reduce.xor.v16i1(<16 x i1> %x) 105 %r = xor i1 %r.inv, -1 106 ret i1 %r 107} 108define i1 @canonical_nonparity(<16 x i1> %x) { 109; NOPOPCNT-LABEL: canonical_nonparity: 110; NOPOPCNT: # %bb.0: 111; NOPOPCNT-NEXT: psllw $7, %xmm0 112; NOPOPCNT-NEXT: pmovmskb %xmm0, %eax 113; NOPOPCNT-NEXT: xorb %ah, %al 114; NOPOPCNT-NEXT: setp %al 115; NOPOPCNT-NEXT: retq 116; 117; POPCNT-LABEL: canonical_nonparity: 118; POPCNT: # %bb.0: 119; POPCNT-NEXT: psllw $7, %xmm0 120; POPCNT-NEXT: pmovmskb %xmm0, %eax 121; POPCNT-NEXT: popcntl %eax, %eax 122; POPCNT-NEXT: testb $1, %al 123; POPCNT-NEXT: sete %al 124; POPCNT-NEXT: retq 125 %i1 = bitcast <16 x i1> %x to i16 126 %i2 = call i16 @llvm.ctpop.i16(i16 %i1) 127 %i3 = and i16 %i2, 1 128 %i4 = icmp eq i16 %i3, 0 129 ret i1 %i4 130} 131define i1 @canonical_nonparity_noncanonical_pred(<16 x i1> %x) { 132; NOPOPCNT-LABEL: canonical_nonparity_noncanonical_pred: 133; NOPOPCNT: # %bb.0: 134; NOPOPCNT-NEXT: psllw $7, %xmm0 135; NOPOPCNT-NEXT: pmovmskb %xmm0, %eax 136; NOPOPCNT-NEXT: xorb %ah, %al 137; NOPOPCNT-NEXT: setp %al 138; NOPOPCNT-NEXT: retq 139; 140; POPCNT-LABEL: canonical_nonparity_noncanonical_pred: 141; POPCNT: # %bb.0: 142; POPCNT-NEXT: psllw $7, %xmm0 143; POPCNT-NEXT: pmovmskb %xmm0, %eax 144; POPCNT-NEXT: popcntl %eax, %eax 145; POPCNT-NEXT: andl $1, %eax 146; POPCNT-NEXT: xorb $1, %al 147; POPCNT-NEXT: # kill: def $al killed $al killed $eax 148; POPCNT-NEXT: retq 149 %i1 = bitcast <16 x i1> %x to i16 150 %i2 = call i16 @llvm.ctpop.i16(i16 %i1) 151 %i3 = and i16 %i2, 1 152 %i4 = icmp ne i16 %i3, 1 153 ret i1 %i4 154} 155 156declare i1 @llvm.vector.reduce.xor.v16i1(<16 x i1>) 157declare i16 @llvm.ctpop.i16(i16) 158