Index: llvm/trunk/include/llvm/IR/PatternMatch.h =================================================================== --- llvm/trunk/include/llvm/IR/PatternMatch.h +++ llvm/trunk/include/llvm/IR/PatternMatch.h @@ -886,17 +886,21 @@ template bool match(OpTy *V) { if (auto *O = dyn_cast(V)) - if (O->getOpcode() == Instruction::Xor) - return matchIfNot(O->getOperand(0), O->getOperand(1)); + if (O->getOpcode() == Instruction::Xor) { + if (isAllOnes(O->getOperand(1))) + return L.match(O->getOperand(0)); + if (isAllOnes(O->getOperand(0))) + return L.match(O->getOperand(1)); + } return false; } private: - bool matchIfNot(Value *LHS, Value *RHS) { - return (isa(RHS) || isa(RHS) || + bool isAllOnes(Value *V) { + return (isa(V) || isa(V) || // FIXME: Remove CV. - isa(RHS)) && - cast(RHS)->isAllOnesValue() && L.match(LHS); + isa(V)) && + cast(V)->isAllOnesValue(); } }; Index: llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll =================================================================== --- llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll +++ llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll @@ -865,3 +865,11 @@ ret <2 x i8> %mask } +define i32 @reversed_not(i32 %a) { +; CHECK-LABEL: @reversed_not( +; CHECK-NEXT: ret i32 -1 +; + %nega = xor i32 -1, %a + %or = or i32 %a, %nega + ret i32 %or +}