diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5054,6 +5054,10 @@ SDValue Other) { if (SDValue NotOperand = getBitwiseNotOperand(Not, Mask, /* AllowUndefs */ true)) { + if (NotOperand->getOpcode() == ISD::ZERO_EXTEND || + NotOperand->getOpcode() == ISD::TRUNCATE) + NotOperand = NotOperand->getOperand(0); + if (Other == NotOperand) return true; if (Other->getOpcode() == ISD::AND) @@ -5062,6 +5066,13 @@ } return false; }; + + if (A->getOpcode() == ISD::ZERO_EXTEND || A->getOpcode() == ISD::TRUNCATE) + A = A->getOperand(0); + + if (B->getOpcode() == ISD::ZERO_EXTEND || B->getOpcode() == ISD::TRUNCATE) + B = B->getOperand(0); + if (A->getOpcode() == ISD::AND) return MatchNoCommonBitsPattern(A->getOperand(0), A->getOperand(1), B) || MatchNoCommonBitsPattern(A->getOperand(1), A->getOperand(0), B); diff --git a/llvm/test/CodeGen/X86/add-and-not.ll b/llvm/test/CodeGen/X86/add-and-not.ll --- a/llvm/test/CodeGen/X86/add-and-not.ll +++ b/llvm/test/CodeGen/X86/add-and-not.ll @@ -311,13 +311,9 @@ define i64 @add_and_xor_const_ext_trunc(i64 %x) { ; X86-LABEL: add_and_xor_const_ext_trunc: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx -; X86-NEXT: movl %ecx, %eax -; X86-NEXT: notl %eax -; X86-NEXT: andl $1, %eax -; X86-NEXT: addl %ecx, %eax -; X86-NEXT: adcl $0, %edx +; X86-NEXT: orl $1, %eax ; X86-NEXT: retl ; ; X64-LABEL: add_and_xor_const_ext_trunc: @@ -325,7 +321,7 @@ ; X64-NEXT: movl %edi, %eax ; X64-NEXT: notl %eax ; X64-NEXT: andl $1, %eax -; X64-NEXT: addq %rdi, %rax +; X64-NEXT: orq %rdi, %rax ; X64-NEXT: retq %t = trunc i64 %x to i32 %xor = xor i32 %t, -1