Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1280,6 +1280,11 @@ if (match(Op1, m_Or(m_Not(m_Specific(Op0)), m_Value(A))) || match(Op1, m_Or(m_Value(A), m_Not(m_Specific(Op0))))) return BinaryOperator::CreateAnd(A, Op0); + +// (A^B) & ((~(A)^B) -> 0 + if(match(Op0,m_Xor(m_Value(A),m_Value(B))) + && match(Op1,m_Xor(m_Not(m_Specific(A)),m_Specific(B)))) + return BinaryOperator::CreateAnd(A, Builder->CreateNot(A)); } if (ICmpInst *RHS = dyn_cast(Op1)) Index: test/Transforms/InstCombine/or-xor.ll =================================================================== --- test/Transforms/InstCombine/or-xor.ll +++ test/Transforms/InstCombine/or-xor.ll @@ -92,3 +92,13 @@ ; CHECK-NEXT: %z = or i32 %y.not, %x ; CHECK-NEXT: ret i32 %z } + +define i32 @test10(i32%x,i32%y){ +;CHECK-LABEL: @test10( +;CHECK-NEXT: ret i32 0 +%xor = xor i32%x,%y +%nega = xor i32%x,-1 +%xor1 = xor i32%nega,%y +%and = and i32%xor,%xor1 +ret i32 %and +}