be more aggressive about transforming add -> or when the operands have no
authorChris Lattner <sabre@nondot.org>
Mon, 19 May 2008 20:01:56 +0000 (20:01 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 19 May 2008 20:01:56 +0000 (20:01 +0000)
intersecting bits.  This triggers all over the place, for example in lencode,
with adds of stuff like:

%tmp580 = mul i32 %tmp579, 2
%tmp582 = and i32 %b8, 1
and

%tmp28 = shl i32 %abs.i, 1
%sign.0 = select i1 %tmp23, i32 1, i32 0
and
%tmp344 = shl i32 %tmp343, 2
%tmp346 = and i32 %tmp96, 3

etc.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51263 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/add2.ll

index 8c5e1369dedf1f7658154574587722f4e27e366d..3b341247688e5a3340daaa1ff10599025c891b04 100644 (file)
@@ -2503,6 +2503,25 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
   if (match(RHS, m_And(m_Value(), m_ConstantInt(C2))))
     if (Instruction *R = AssociativeOpt(I, AddMaskingAnd(C2)))
       return R;
+  
+  // A+B --> A|B iff A and B have no bits set in common.
+  if (const IntegerType *IT = dyn_cast<IntegerType>(I.getType())) {
+    APInt Mask = APInt::getAllOnesValue(IT->getBitWidth());
+    APInt LHSKnownOne(IT->getBitWidth(), 0);
+    APInt LHSKnownZero(IT->getBitWidth(), 0);
+    ComputeMaskedBits(LHS, Mask, LHSKnownZero, LHSKnownOne);
+    if (LHSKnownZero != 0) {
+      APInt RHSKnownOne(IT->getBitWidth(), 0);
+      APInt RHSKnownZero(IT->getBitWidth(), 0);
+      ComputeMaskedBits(RHS, Mask, RHSKnownZero, RHSKnownOne);
+      
+      // No bits in common -> bitwise or.
+      if ((LHSKnownZero|RHSKnownZero).isAllOnesValue()) {
+        cerr << "HACK\n" << *LHS << *RHS << "\n";
+        return BinaryOperator::CreateOr(LHS, RHS);
+      }
+    }
+  }
 
   // W*X + Y*Z --> W * (X+Z)  iff W == Y
   if (I.getType()->isIntOrIntVector()) {
index de1bbf41b0981dbed13aa7b63fd8345309797c27..161d56b40b572b07e203aa019568c6983ec6c3e4 100644 (file)
@@ -29,3 +29,18 @@ EntryBlock:
 
 declare i32 @callee(i32)
 
+
+define i32 @test3(i32 %A) {
+  %B = and i32 %A, 7
+  %C = and i32 %A, 32
+  %F = add i32 %B, %C
+  ret i32 %F
+}
+
+define i32 @test4(i32 %A) {
+  %B = and i32 %A, 128
+  %C = lshr i32 %A, 30
+  %F = add i32 %B, %C
+  ret i32 %F
+}
+