From: Craig Topper Date: Thu, 18 May 2017 20:27:32 +0000 (+0000) Subject: [InstSimplify] Make m_Not work for xor -1, X X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0c3c8c6175fcc49b854d434022574dacd5329789;p=llvm [InstSimplify] Make m_Not work for xor -1, X Currently m_Not only works the canonical xor X, -1 form that InstCombine produces. InstSimplify can't rely on this canonicalization. Differential Revision: https://reviews.llvm.org/D33331 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303379 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 6b2b22e82b9..072c6c5ece8 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -886,17 +886,21 @@ template struct not_match { 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(); } }; diff --git a/test/Transforms/InstSimplify/AndOrXor.ll b/test/Transforms/InstSimplify/AndOrXor.ll index 2d7eeae0fd0..a027c7e1828 100644 --- a/test/Transforms/InstSimplify/AndOrXor.ll +++ b/test/Transforms/InstSimplify/AndOrXor.ll @@ -865,3 +865,11 @@ define <2 x i8> @shl_undersized_mask_splat(<2 x i8> %x) { 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 +}