From d08831499818771527e2da55eedd0bdfbdc37edb Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 11 Oct 2009 22:22:13 +0000 Subject: [PATCH] teach instcombine to simplify xor's harder, catching the new testcase. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83799 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 27 +++++++++++++++++++ test/Transforms/InstCombine/xor2.ll | 11 ++++++++ 2 files changed, 38 insertions(+) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 6d166664f8f..dcb65a8ed91 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1047,6 +1047,33 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, if (ShrinkDemandedConstant(I, 1, DemandedMask)) return I; + // If our LHS is an 'and' and if it has one use, and if any of the bits we + // are flipping are known to be set, then the xor is just resetting those + // bits to zero. We can just knock out bits from the 'and' and the 'xor', + // simplifying both of them. + if (Instruction *LHSInst = dyn_cast(I->getOperand(0))) + if (LHSInst->getOpcode() == Instruction::And && LHSInst->hasOneUse() && + isa(I->getOperand(1)) && + isa(LHSInst->getOperand(1)) && + (LHSKnownOne & RHSKnownOne & DemandedMask) != 0) { + ConstantInt *AndRHS = cast(LHSInst->getOperand(1)); + ConstantInt *XorRHS = cast(I->getOperand(1)); + APInt NewMask = ~(LHSKnownOne & RHSKnownOne & DemandedMask); + + Constant *AndC = + ConstantInt::get(I->getType(), NewMask & AndRHS->getValue()); + Instruction *NewAnd = + BinaryOperator::CreateAnd(I->getOperand(0), AndC, "tmp"); + InsertNewInstBefore(NewAnd, *I); + + Constant *XorC = + ConstantInt::get(I->getType(), NewMask & XorRHS->getValue()); + Instruction *NewXor = + BinaryOperator::CreateXor(NewAnd, XorC, "tmp"); + return InsertNewInstBefore(NewXor, *I); + } + + RHSKnownZero = KnownZeroOut; RHSKnownOne = KnownOneOut; break; diff --git a/test/Transforms/InstCombine/xor2.ll b/test/Transforms/InstCombine/xor2.ll index 94a464c8dcd..23a99158137 100644 --- a/test/Transforms/InstCombine/xor2.ll +++ b/test/Transforms/InstCombine/xor2.ll @@ -30,3 +30,14 @@ define i32 @test2(i32 %tmp1) { %ov110 = xor i32 %ov3, 153 ret i32 %ov110 } + +define i32 @test3(i32 %tmp1) { +; CHECK: @test3 +; CHECK-NEXT: or i32 %tmp1, 8 +; CHECK-NEXT: and i32 +; CHECK-NEXT: ret i32 + %ovm = or i32 %tmp1, 145 + %ov31 = and i32 %ovm, 177 + %ov110 = xor i32 %ov31, 153 + ret i32 %ov110 +}