[llvm-commits] [llvm] r83799 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/xor2.ll

Chris Lattner sabre at nondot.org
Sun Oct 11 15:22:13 PDT 2009


Author: lattner
Date: Sun Oct 11 17:22:13 2009
New Revision: 83799

URL: http://llvm.org/viewvc/llvm-project?rev=83799&view=rev
Log:
teach instcombine to simplify xor's harder, catching the
new testcase.

Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/xor2.ll

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=83799&r1=83798&r2=83799&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Oct 11 17:22:13 2009
@@ -1047,6 +1047,33 @@
     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<Instruction>(I->getOperand(0)))
+      if (LHSInst->getOpcode() == Instruction::And && LHSInst->hasOneUse() &&
+          isa<ConstantInt>(I->getOperand(1)) &&
+          isa<ConstantInt>(LHSInst->getOperand(1)) &&
+          (LHSKnownOne & RHSKnownOne & DemandedMask) != 0) {
+        ConstantInt *AndRHS = cast<ConstantInt>(LHSInst->getOperand(1));
+        ConstantInt *XorRHS = cast<ConstantInt>(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;

Modified: llvm/trunk/test/Transforms/InstCombine/xor2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/xor2.ll?rev=83799&r1=83798&r2=83799&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/xor2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/xor2.ll Sun Oct 11 17:22:13 2009
@@ -30,3 +30,14 @@
         %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
+}





More information about the llvm-commits mailing list