Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4540,10 +4540,25 @@ } // FIXME: unify with llvm::haveNoCommonBitsSet. -// FIXME: could also handle masked merge pattern (X & ~M) op (Y & M) bool SelectionDAG::haveNoCommonBitsSet(SDValue A, SDValue B) const { assert(A.getValueType() == B.getValueType() && "Values must have the same type"); + // Match masked merge pattern (X & ~M) op (Y & M) + if (A->getOpcode() == ISD::AND && B->getOpcode() == ISD::AND) { + auto MatchNoCommonBitsPattern = [&](SDValue A, SDValue B) { + if (isBitwiseNot(A, true)) { + SDValue NotOperand = A->getOperand(0); + return (NotOperand == B->getOperand(0) || + NotOperand == B->getOperand(1)); + } + return false; + }; + if (MatchNoCommonBitsPattern(A->getOperand(0), B) || + MatchNoCommonBitsPattern(A->getOperand(1), B) || + MatchNoCommonBitsPattern(B->getOperand(0), A) || + MatchNoCommonBitsPattern(B->getOperand(1), A)) + return true; + } return KnownBits::haveNoCommonBitsSet(computeKnownBits(A), computeKnownBits(B)); } Index: llvm/test/CodeGen/X86/or-lea.ll =================================================================== --- llvm/test/CodeGen/X86/or-lea.ll +++ llvm/test/CodeGen/X86/or-lea.ll @@ -136,12 +136,12 @@ define i32 @or_and_and_rhs_neg_i32(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: or_and_and_rhs_neg_i32: ; CHECK: # %bb.0: # %entry +; CHECK-NEXT: # kill: def $edx killed $edx def $rdx ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi ; CHECK-NEXT: andl %esi, %edx ; CHECK-NEXT: notl %esi ; CHECK-NEXT: andl %edi, %esi -; CHECK-NEXT: orl %edx, %esi -; CHECK-NEXT: leal 1(%rsi), %eax +; CHECK-NEXT: leal 1(%rdx,%rsi), %eax ; CHECK-NEXT: retq entry: %and1 = and i32 %z, %y @@ -155,12 +155,12 @@ define i32 @or_and_and_lhs_neg_i32(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: or_and_and_lhs_neg_i32: ; CHECK: # %bb.0: # %entry +; CHECK-NEXT: # kill: def $edx killed $edx def $rdx ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi ; CHECK-NEXT: andl %esi, %edx ; CHECK-NEXT: notl %esi ; CHECK-NEXT: andl %edi, %esi -; CHECK-NEXT: orl %edx, %esi -; CHECK-NEXT: leal 1(%rsi), %eax +; CHECK-NEXT: leal 1(%rdx,%rsi), %eax ; CHECK-NEXT: retq entry: %and1 = and i32 %z, %y @@ -175,11 +175,11 @@ ; CHECK-LABEL: or_and_rhs_neg_and_i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi +; CHECK-NEXT: # kill: def $edi killed $edi def $rdi ; CHECK-NEXT: andl %esi, %edi ; CHECK-NEXT: notl %esi ; CHECK-NEXT: andl %edx, %esi -; CHECK-NEXT: orl %edi, %esi -; CHECK-NEXT: leal 1(%rsi), %eax +; CHECK-NEXT: leal 1(%rsi,%rdi), %eax ; CHECK-NEXT: retq entry: %xor = xor i32 %y, -1 @@ -194,11 +194,11 @@ ; CHECK-LABEL: or_and_lhs_neg_and_i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi +; CHECK-NEXT: # kill: def $edi killed $edi def $rdi ; CHECK-NEXT: andl %esi, %edi ; CHECK-NEXT: notl %esi ; CHECK-NEXT: andl %edx, %esi -; CHECK-NEXT: orl %edi, %esi -; CHECK-NEXT: leal 1(%rsi), %eax +; CHECK-NEXT: leal 1(%rsi,%rdi), %eax ; CHECK-NEXT: retq entry: %xor = xor i32 %y, -1 @@ -215,8 +215,7 @@ ; CHECK-NEXT: andq %rsi, %rdx ; CHECK-NEXT: notq %rsi ; CHECK-NEXT: andq %rdi, %rsi -; CHECK-NEXT: orq %rdx, %rsi -; CHECK-NEXT: leaq 1(%rsi), %rax +; CHECK-NEXT: leaq 1(%rdx,%rsi), %rax ; CHECK-NEXT: retq entry: %and1 = and i64 %z, %y @@ -233,8 +232,7 @@ ; CHECK-NEXT: andq %rsi, %rdx ; CHECK-NEXT: notq %rsi ; CHECK-NEXT: andq %rdi, %rsi -; CHECK-NEXT: orq %rdx, %rsi -; CHECK-NEXT: leaq 1(%rsi), %rax +; CHECK-NEXT: leaq 1(%rdx,%rsi), %rax ; CHECK-NEXT: retq entry: %and1 = and i64 %z, %y @@ -251,8 +249,7 @@ ; CHECK-NEXT: andq %rsi, %rdi ; CHECK-NEXT: notq %rsi ; CHECK-NEXT: andq %rdx, %rsi -; CHECK-NEXT: orq %rdi, %rsi -; CHECK-NEXT: leaq 1(%rsi), %rax +; CHECK-NEXT: leaq 1(%rsi,%rdi), %rax ; CHECK-NEXT: retq entry: %xor = xor i64 %y, -1 @@ -269,8 +266,7 @@ ; CHECK-NEXT: andq %rsi, %rdi ; CHECK-NEXT: notq %rsi ; CHECK-NEXT: andq %rdx, %rsi -; CHECK-NEXT: orq %rdi, %rsi -; CHECK-NEXT: leaq 1(%rsi), %rax +; CHECK-NEXT: leaq 1(%rsi,%rdi), %rax ; CHECK-NEXT: retq entry: %xor = xor i64 %y, -1