4 new transformations:
authorChris Lattner <sabre@nondot.org>
Tue, 18 Feb 2003 19:57:07 +0000 (19:57 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 18 Feb 2003 19:57:07 +0000 (19:57 +0000)
  * X*C + X --> X * (C+1)
  * X + X*C --> X * (C+1)
  * X - X*C --> X * (1-C)
  * X*C - X --> X * (C-1)

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

lib/Transforms/Scalar/InstructionCombining.cpp

index 0c46a7b2233ede95b729a4155cc6d28ccfd2930a..f652e2bbc712e606eab6163ca57bd6e846369871 100644 (file)
@@ -146,6 +146,16 @@ static unsigned Log2(uint64_t Val) {
   return Count;
 }
 
+static inline Value *dyn_castFoldableMul(Value *V) {
+  if (V->use_size() == 1 && V->getType()->isInteger())
+    if (Instruction *I = dyn_cast<Instruction>(V))
+      if (I->getOpcode() == Instruction::Mul)
+        if (isa<Constant>(I->getOperand(1)))
+          return I->getOperand(0);
+  return 0;
+}
+
+
 Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
   bool Changed = SimplifyBinOp(I);
   Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
@@ -182,6 +192,22 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
     }
   }
 
+  // X*C + X --> X * (C+1)
+  if (dyn_castFoldableMul(LHS) == RHS) {
+    Constant *CP1 = *cast<Constant>(cast<Instruction>(LHS)->getOperand(1)) +
+                    *ConstantInt::get(I.getType(), 1);
+    assert(CP1 && "Couldn't constant fold C + 1?");
+    return BinaryOperator::create(Instruction::Mul, RHS, CP1);
+  }
+
+  // X + X*C --> X * (C+1)
+  if (dyn_castFoldableMul(RHS) == LHS) {
+    Constant *CP1 = *cast<Constant>(cast<Instruction>(RHS)->getOperand(1)) +
+                    *ConstantInt::get(I.getType(), 1);
+    assert(CP1 && "Couldn't constant fold C + 1?");
+    return BinaryOperator::create(Instruction::Mul, LHS, CP1);
+  }
+
   return Changed ? &I : 0;
 }
 
@@ -231,8 +257,24 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
         Instruction *NewNot = BinaryOperator::createNot(OtherOp, "B.not", &I);
         return BinaryOperator::create(Instruction::And, Op0, NewNot);
       }
+
+      // X - X*C --> X * (1-C)
+      if (dyn_castFoldableMul(Op1I) == Op0) {
+        Constant *CP1 = *ConstantInt::get(I.getType(), 1) -
+                        *cast<Constant>(cast<Instruction>(Op1)->getOperand(1));
+        assert(CP1 && "Couldn't constant fold 1-C?");
+        return BinaryOperator::create(Instruction::Mul, Op0, CP1);
+      }
     }
 
+  // X*C - X --> X * (C-1)
+  if (dyn_castFoldableMul(Op0) == Op1) {
+    Constant *CP1 = *cast<Constant>(cast<Instruction>(Op0)->getOperand(1)) -
+                    *ConstantInt::get(I.getType(), 1);
+    assert(CP1 && "Couldn't constant fold C - 1?");
+    return BinaryOperator::create(Instruction::Mul, Op1, CP1);
+  }
+
   return 0;
 }