[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner lattner at cs.uiuc.edu
Tue Jul 22 16:48:01 PDT 2003


Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.96 -> 1.97

---
Log message:

  - InstCombine (cast (xor A, B) to bool) ==> (setne A, B)
  - InstCombine (cast (and X, (1 << size(X)-1)) to bool) ==> x < 0


---
Diffs of the changes:

Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.96 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.97
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.96	Mon Jul 21 14:42:57 2003
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Tue Jul 22 16:46:59 2003
@@ -291,6 +291,13 @@
   return Changed ? &I : 0;
 }
 
+// isSignBit - Return true if the value represented by the constant only has the
+// highest order bit set.
+static bool isSignBit(ConstantInt *CI) {
+  unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
+  return (CI->getRawValue() & ~(-1LL << NumBits)) == (1ULL << (NumBits-1));
+}
+
 Instruction *InstCombiner::visitSub(BinaryOperator &I) {
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
@@ -959,13 +966,15 @@
     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)
+      switch (BO->getOpcode()) {
+      case Instruction::Sub:
+      case Instruction::Xor:
+        // Replace (cast ([sub|xor] A, B) to bool) with (setne A, B)
         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)
+      case Instruction::Add:
         if (Value *NegVal = dyn_castNegVal(Op1))
           return new SetCondInst(Instruction::SetNE, Op0, NegVal);
         else if (Value *NegVal = dyn_castNegVal(Op0))
@@ -976,6 +985,36 @@
           InsertNewInstBefore(Neg, CI);
           return new SetCondInst(Instruction::SetNE, Op0, Neg);
         }
+        break;
+
+      case Instruction::And:
+        // Replace (cast (and X, (1 << size(X)-1)) to bool) with x < 0,
+        // converting X to be a signed value as appropriate.  Don't worry about
+        // bool values, as they will be optimized other ways if they occur in
+        // this configuration.
+        if (ConstantInt *CInt = dyn_cast<ConstantInt>(Op1))
+          if (isSignBit(CInt)) {
+            // If 'X' is not signed, insert a cast now...
+            if (!CInt->getType()->isSigned()) {
+              const Type *DestTy;
+              switch (CInt->getType()->getPrimitiveID()) {
+              case Type::UByteTyID:  DestTy = Type::SByteTy; break;
+              case Type::UShortTyID: DestTy = Type::ShortTy; break;
+              case Type::UIntTyID:   DestTy = Type::IntTy;   break;
+              case Type::ULongTyID:  DestTy = Type::LongTy;  break;
+              default: assert(0 && "Invalid unsigned integer type!"); abort();
+              }
+              CastInst *NewCI = new CastInst(Op0, DestTy,
+                                             Op0->getName()+".signed");
+              InsertNewInstBefore(NewCI, CI);
+              Op0 = NewCI;
+            }
+            return new SetCondInst(Instruction::SetLT, Op0,
+                                   Constant::getNullValue(Op0->getType()));
+          }
+        break;
+      default: break;
+      }
     }
   }
 
@@ -1294,7 +1333,7 @@
 
   // Instcombine load (constant global) into the value loaded...
   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
-    if ((GV->isConstant()) && (!(GV->isExternal())))
+    if (GV->isConstant() && !GV->isExternal())
       return ReplaceInstUsesWith(LI, GV->getInitializer());
 
   // Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded...
@@ -1302,7 +1341,7 @@
     if (CE->getOpcode() == Instruction::GetElementPtr)
       if (ConstantPointerRef *G=dyn_cast<ConstantPointerRef>(CE->getOperand(0)))
         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getValue()))
-          if ((GV->isConstant()) && (!(GV->isExternal())))
+          if (GV->isConstant() && !GV->isExternal())
             if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
               return ReplaceInstUsesWith(LI, V);
   return 0;





More information about the llvm-commits mailing list