Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ llvm/lib/Target/X86/X86ISelLowering.cpp @@ -425,6 +425,10 @@ setTruncStoreAction(MVT::f128, MVT::f16, Expand); setOperationAction(ISD::PARITY, MVT::i8, Custom); + setOperationAction(ISD::PARITY, MVT::i16, Custom); + setOperationAction(ISD::PARITY, MVT::i32, Custom); + if (Subtarget.is64Bit()) + setOperationAction(ISD::PARITY, MVT::i64, Custom); if (Subtarget.hasPOPCNT()) { setOperationPromotedToType(ISD::CTPOP, MVT::i8, MVT::i32); } else { @@ -435,11 +439,6 @@ setOperationAction(ISD::CTPOP , MVT::i64 , Expand); else setOperationAction(ISD::CTPOP , MVT::i64 , Custom); - - setOperationAction(ISD::PARITY, MVT::i16, Custom); - setOperationAction(ISD::PARITY, MVT::i32, Custom); - if (Subtarget.is64Bit()) - setOperationAction(ISD::PARITY, MVT::i64, Custom); } setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom); @@ -30466,6 +30465,10 @@ return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Setnp); } + // If we have POPCNT, use the default expansion. + if (Subtarget.hasPOPCNT()) + return SDValue(); + if (VT == MVT::i64) { // Xor the high and low 16-bits together using a 32-bit operation. SDValue Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Index: llvm/test/CodeGen/X86/parity.ll =================================================================== --- llvm/test/CodeGen/X86/parity.ll +++ llvm/test/CodeGen/X86/parity.ll @@ -373,17 +373,17 @@ ; ; X86-POPCNT-LABEL: parity_16_zexti8: ; X86-POPCNT: # %bb.0: -; X86-POPCNT-NEXT: movzbl {{[0-9]+}}(%esp), %eax -; X86-POPCNT-NEXT: popcntw %ax, %ax -; X86-POPCNT-NEXT: andl $1, %eax +; X86-POPCNT-NEXT: xorl %eax, %eax +; X86-POPCNT-NEXT: cmpb $0, {{[0-9]+}}(%esp) +; X86-POPCNT-NEXT: setnp %al ; X86-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax ; X86-POPCNT-NEXT: retl ; ; X64-POPCNT-LABEL: parity_16_zexti8: ; X64-POPCNT: # %bb.0: -; X64-POPCNT-NEXT: movzbl %dil, %eax -; X64-POPCNT-NEXT: popcntw %ax, %ax -; X64-POPCNT-NEXT: andl $1, %eax +; X64-POPCNT-NEXT: xorl %eax, %eax +; X64-POPCNT-NEXT: testb %dil, %dil +; X64-POPCNT-NEXT: setnp %al ; X64-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax ; X64-POPCNT-NEXT: retq %a = zext i8 %x to i16 @@ -411,17 +411,17 @@ ; ; X86-POPCNT-LABEL: parity_16_mask255: ; X86-POPCNT: # %bb.0: -; X86-POPCNT-NEXT: movzbl {{[0-9]+}}(%esp), %eax -; X86-POPCNT-NEXT: popcntw %ax, %ax -; X86-POPCNT-NEXT: andl $1, %eax +; X86-POPCNT-NEXT: xorl %eax, %eax +; X86-POPCNT-NEXT: cmpb $0, {{[0-9]+}}(%esp) +; X86-POPCNT-NEXT: setnp %al ; X86-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax ; X86-POPCNT-NEXT: retl ; ; X64-POPCNT-LABEL: parity_16_mask255: ; X64-POPCNT: # %bb.0: -; X64-POPCNT-NEXT: movzbl %dil, %eax -; X64-POPCNT-NEXT: popcntw %ax, %ax -; X64-POPCNT-NEXT: andl $1, %eax +; X64-POPCNT-NEXT: xorl %eax, %eax +; X64-POPCNT-NEXT: testb %dil, %dil +; X64-POPCNT-NEXT: setnp %al ; X64-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax ; X64-POPCNT-NEXT: retq %a = and i16 %x, 255 @@ -450,18 +450,18 @@ ; ; X86-POPCNT-LABEL: parity_16_mask15: ; X86-POPCNT: # %bb.0: -; X86-POPCNT-NEXT: movzwl {{[0-9]+}}(%esp), %eax -; X86-POPCNT-NEXT: andl $15, %eax -; X86-POPCNT-NEXT: popcntw %ax, %ax -; X86-POPCNT-NEXT: andl $1, %eax +; X86-POPCNT-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-POPCNT-NEXT: xorl %eax, %eax +; X86-POPCNT-NEXT: testb $15, %cl +; X86-POPCNT-NEXT: setnp %al ; X86-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax ; X86-POPCNT-NEXT: retl ; ; X64-POPCNT-LABEL: parity_16_mask15: ; X64-POPCNT: # %bb.0: -; X64-POPCNT-NEXT: andl $15, %edi -; X64-POPCNT-NEXT: popcntw %di, %ax -; X64-POPCNT-NEXT: andl $1, %eax +; X64-POPCNT-NEXT: xorl %eax, %eax +; X64-POPCNT-NEXT: testb $15, %dil +; X64-POPCNT-NEXT: setnp %al ; X64-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax ; X64-POPCNT-NEXT: retq %a = and i16 %x, 15 @@ -529,16 +529,16 @@ ; ; X86-POPCNT-LABEL: parity_32_zexti8: ; X86-POPCNT: # %bb.0: -; X86-POPCNT-NEXT: movzbl {{[0-9]+}}(%esp), %eax -; X86-POPCNT-NEXT: popcntl %eax, %eax -; X86-POPCNT-NEXT: andl $1, %eax +; X86-POPCNT-NEXT: xorl %eax, %eax +; X86-POPCNT-NEXT: cmpb $0, {{[0-9]+}}(%esp) +; X86-POPCNT-NEXT: setnp %al ; X86-POPCNT-NEXT: retl ; ; X64-POPCNT-LABEL: parity_32_zexti8: ; X64-POPCNT: # %bb.0: -; X64-POPCNT-NEXT: movzbl %dil, %eax -; X64-POPCNT-NEXT: popcntl %eax, %eax -; X64-POPCNT-NEXT: andl $1, %eax +; X64-POPCNT-NEXT: xorl %eax, %eax +; X64-POPCNT-NEXT: testb %dil, %dil +; X64-POPCNT-NEXT: setnp %al ; X64-POPCNT-NEXT: retq %a = zext i8 %x to i32 %b = tail call i32 @llvm.ctpop.i32(i32 %a) @@ -563,16 +563,16 @@ ; ; X86-POPCNT-LABEL: parity_32_mask255: ; X86-POPCNT: # %bb.0: -; X86-POPCNT-NEXT: movzbl {{[0-9]+}}(%esp), %eax -; X86-POPCNT-NEXT: popcntl %eax, %eax -; X86-POPCNT-NEXT: andl $1, %eax +; X86-POPCNT-NEXT: xorl %eax, %eax +; X86-POPCNT-NEXT: cmpb $0, {{[0-9]+}}(%esp) +; X86-POPCNT-NEXT: setnp %al ; X86-POPCNT-NEXT: retl ; ; X64-POPCNT-LABEL: parity_32_mask255: ; X64-POPCNT: # %bb.0: -; X64-POPCNT-NEXT: movzbl %dil, %eax -; X64-POPCNT-NEXT: popcntl %eax, %eax -; X64-POPCNT-NEXT: andl $1, %eax +; X64-POPCNT-NEXT: xorl %eax, %eax +; X64-POPCNT-NEXT: testb %dil, %dil +; X64-POPCNT-NEXT: setnp %al ; X64-POPCNT-NEXT: retq %a = and i32 %x, 255 %b = tail call i32 @llvm.ctpop.i32(i32 %a) @@ -597,17 +597,16 @@ ; ; X86-POPCNT-LABEL: parity_32_mask15: ; X86-POPCNT: # %bb.0: -; X86-POPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-POPCNT-NEXT: andl $15, %eax -; X86-POPCNT-NEXT: popcntl %eax, %eax -; X86-POPCNT-NEXT: andl $1, %eax +; X86-POPCNT-NEXT: xorl %eax, %eax +; X86-POPCNT-NEXT: testb $15, {{[0-9]+}}(%esp) +; X86-POPCNT-NEXT: setnp %al ; X86-POPCNT-NEXT: retl ; ; X64-POPCNT-LABEL: parity_32_mask15: ; X64-POPCNT: # %bb.0: -; X64-POPCNT-NEXT: andl $15, %edi -; X64-POPCNT-NEXT: popcntl %edi, %eax -; X64-POPCNT-NEXT: andl $1, %eax +; X64-POPCNT-NEXT: xorl %eax, %eax +; X64-POPCNT-NEXT: testb $15, %dil +; X64-POPCNT-NEXT: setnp %al ; X64-POPCNT-NEXT: retq %a = and i32 %x, 15 %b = tail call i32 @llvm.ctpop.i32(i32 %a) @@ -676,18 +675,17 @@ ; ; X86-POPCNT-LABEL: parity_64_zexti8: ; X86-POPCNT: # %bb.0: -; X86-POPCNT-NEXT: movzbl {{[0-9]+}}(%esp), %eax -; X86-POPCNT-NEXT: popcntl %eax, %eax -; X86-POPCNT-NEXT: andl $1, %eax +; X86-POPCNT-NEXT: xorl %eax, %eax +; X86-POPCNT-NEXT: cmpb $0, {{[0-9]+}}(%esp) +; X86-POPCNT-NEXT: setnp %al ; X86-POPCNT-NEXT: xorl %edx, %edx ; X86-POPCNT-NEXT: retl ; ; X64-POPCNT-LABEL: parity_64_zexti8: ; X64-POPCNT: # %bb.0: -; X64-POPCNT-NEXT: # kill: def $edi killed $edi def $rdi -; X64-POPCNT-NEXT: movzbl %dil, %eax -; X64-POPCNT-NEXT: popcntq %rax, %rax -; X64-POPCNT-NEXT: andl $1, %eax +; X64-POPCNT-NEXT: xorl %eax, %eax +; X64-POPCNT-NEXT: testb %dil, %dil +; X64-POPCNT-NEXT: setnp %al ; X64-POPCNT-NEXT: retq %a = zext i8 %x to i64 %b = tail call i64 @llvm.ctpop.i64(i64 %a) @@ -713,17 +711,17 @@ ; ; X86-POPCNT-LABEL: parity_64_mask255: ; X86-POPCNT: # %bb.0: -; X86-POPCNT-NEXT: movzbl {{[0-9]+}}(%esp), %eax -; X86-POPCNT-NEXT: popcntl %eax, %eax -; X86-POPCNT-NEXT: andl $1, %eax +; X86-POPCNT-NEXT: xorl %eax, %eax +; X86-POPCNT-NEXT: cmpb $0, {{[0-9]+}}(%esp) +; X86-POPCNT-NEXT: setnp %al ; X86-POPCNT-NEXT: xorl %edx, %edx ; X86-POPCNT-NEXT: retl ; ; X64-POPCNT-LABEL: parity_64_mask255: ; X64-POPCNT: # %bb.0: -; X64-POPCNT-NEXT: movzbl %dil, %eax -; X64-POPCNT-NEXT: popcntq %rax, %rax -; X64-POPCNT-NEXT: andl $1, %eax +; X64-POPCNT-NEXT: xorl %eax, %eax +; X64-POPCNT-NEXT: testb %dil, %dil +; X64-POPCNT-NEXT: setnp %al ; X64-POPCNT-NEXT: retq %a = and i64 %x, 255 %b = tail call i64 @llvm.ctpop.i64(i64 %a) @@ -749,18 +747,17 @@ ; ; X86-POPCNT-LABEL: parity_64_mask15: ; X86-POPCNT: # %bb.0: -; X86-POPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-POPCNT-NEXT: andl $15, %eax -; X86-POPCNT-NEXT: popcntl %eax, %eax -; X86-POPCNT-NEXT: andl $1, %eax +; X86-POPCNT-NEXT: xorl %eax, %eax +; X86-POPCNT-NEXT: testb $15, {{[0-9]+}}(%esp) +; X86-POPCNT-NEXT: setnp %al ; X86-POPCNT-NEXT: xorl %edx, %edx ; X86-POPCNT-NEXT: retl ; ; X64-POPCNT-LABEL: parity_64_mask15: ; X64-POPCNT: # %bb.0: -; X64-POPCNT-NEXT: andl $15, %edi -; X64-POPCNT-NEXT: popcntq %rdi, %rax -; X64-POPCNT-NEXT: andl $1, %eax +; X64-POPCNT-NEXT: xorl %eax, %eax +; X64-POPCNT-NEXT: testb $15, %dil +; X64-POPCNT-NEXT: setnp %al ; X64-POPCNT-NEXT: retq %a = and i64 %x, 15 %b = tail call i64 @llvm.ctpop.i64(i64 %a)