From a1693a2ed3f62c35739ca4e78517c5dbd6c7c45e Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 6 Aug 2017 23:11:49 +0000 Subject: [PATCH] [InstCombine] Support (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) for vector splats. llvm-svn: 310233 --- .../lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 18 ++++++++++-------- llvm/test/Transforms/InstCombine/add.ll | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index a2666f4..d7d460b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -126,14 +126,6 @@ Instruction *InstCombiner::OptAndOp(BinaryOperator *Op, switch (Op->getOpcode()) { default: break; - case Instruction::Xor: - if (Op->hasOneUse()) { - // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) - Value *And = Builder.CreateAnd(X, AndRHS); - And->takeName(Op); - return BinaryOperator::CreateXor(And, Together); - } - break; case Instruction::Or: if (Op->hasOneUse()){ ConstantInt *TogetherCI = dyn_cast(Together); @@ -1280,6 +1272,15 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { return new ZExtInst(IsZero, I.getType()); } + const APInt *XorC; + if (match(Op0, m_OneUse(m_Xor(m_Value(X), m_APInt(XorC))))) { + // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) + Constant *NewC = ConstantInt::get(I.getType(), *C & *XorC); + Value *And = Builder.CreateAnd(X, Op1); + And->takeName(Op0); + return BinaryOperator::CreateXor(And, NewC); + } + // If the mask is only needed on one incoming arm, push the 'and' op up. if (match(Op0, m_OneUse(m_Xor(m_Value(X), m_Value(Y)))) || match(Op0, m_OneUse(m_Or(m_Value(X), m_Value(Y))))) { @@ -1298,6 +1299,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { return BinaryOperator::Create(BinOp, NewLHS, Y); } } + } if (ConstantInt *AndRHS = dyn_cast(Op1)) { diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll index 9cc2ae4..7502152 100644 --- a/llvm/test/Transforms/InstCombine/add.ll +++ b/llvm/test/Transforms/InstCombine/add.ll @@ -39,8 +39,8 @@ define i32 @flip_and_mask(i32 %x) { define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) { ; CHECK-LABEL: @flip_and_mask_splat( -; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> %x, -; CHECK-NEXT: [[INC:%.*]] = and <2 x i8> [[TMP1]], +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> %x, +; CHECK-NEXT: [[INC:%.*]] = xor <2 x i8> [[TMP1]], ; CHECK-NEXT: ret <2 x i8> [[INC]] ; %shl = shl <2 x i8> %x, -- 2.7.4