Implement new transforms:
authorChris Lattner <sabre@nondot.org>
Mon, 23 Jun 2003 21:59:52 +0000 (21:59 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 23 Jun 2003 21:59:52 +0000 (21:59 +0000)
  Replace (cast (sub A, B) to bool) -> (setne A, B)
  Replace (cast (add A, B) to bool) -> (setne A, -B)

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

lib/Transforms/Scalar/InstructionCombining.cpp

index a0a09e4b1daf0294927ad20d52571edfc0e6a63c..505313ba9c3e26b2ae2eb3ce9a08f992b7e54ec6 100644 (file)
@@ -898,15 +898,17 @@ static inline bool isEliminableCastOfCast(const CastInst &CI,
 // CastInst simplification
 //
 Instruction *InstCombiner::visitCastInst(CastInst &CI) {
+  Value *Src = CI.getOperand(0);
+
   // If the user is casting a value to the same type, eliminate this cast
   // instruction...
-  if (CI.getType() == CI.getOperand(0)->getType())
-    return ReplaceInstUsesWith(CI, CI.getOperand(0));
+  if (CI.getType() == Src->getType())
+    return ReplaceInstUsesWith(CI, Src);
 
   // If casting the result of another cast instruction, try to eliminate this
   // one!
   //
-  if (CastInst *CSrc = dyn_cast<CastInst>(CI.getOperand(0))) {
+  if (CastInst *CSrc = dyn_cast<CastInst>(Src)) {
     if (isEliminableCastOfCast(CI, CSrc)) {
       // This instruction now refers directly to the cast's src operand.  This
       // has a good chance of making CSrc dead.
@@ -933,7 +935,7 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
   // If casting the result of a getelementptr instruction with no offset, turn
   // this into a cast of the original pointer!
   //
-  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CI.getOperand(0))) {
+  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Src)) {
     bool AllZeroOperands = true;
     for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
       if (!isa<Constant>(GEP->getOperand(i)) ||
@@ -947,6 +949,33 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
     }
   }
 
+  // If this is a cast to bool (which is effectively a "!=0" test), then we can
+  // perform a few optimizations...
+  //
+  if (CI.getType() == Type::BoolTy) {
+    if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Src)) {
+      Value *Op0 = BO->getOperand(0), *Op1 = BO->getOperand(1);
+
+      // Replace (cast (sub A, B) to bool) with (setne A, B)
+      if (BO->getOpcode() == Instruction::Sub)
+        return new SetCondInst(Instruction::SetNE, Op0, Op1);
+
+      // Replace (cast (add A, B) to bool) with (setne A, -B) if B is
+      // efficiently invertible, or if the add has just this one use.
+      if (BO->getOpcode() == Instruction::Add)
+        if (Value *NegVal = dyn_castNegVal(Op1))
+          return new SetCondInst(Instruction::SetNE, Op0, NegVal);
+        else if (Value *NegVal = dyn_castNegVal(Op0))
+          return new SetCondInst(Instruction::SetNE, NegVal, Op1);
+        else if (BO->use_size() == 1) {
+          Instruction *Neg = BinaryOperator::createNeg(Op1, BO->getName());
+          BO->setName("");
+          InsertNewInstBefore(Neg, CI);
+          return new SetCondInst(Instruction::SetNE, Op0, Neg);
+        }
+    }
+  }
+
   return 0;
 }