[llvm-commits] CAST patch: #3: lib/Transforms (except instcombine)

Chris Lattner clattner at apple.com
Mon Nov 20 14:48:32 PST 2006


On Nov 18, 2006, at 11:24 AM, Reid Spencer wrote:

> Chris,
>
> Here's the CAST patch. This passes 100% of llvm/test and llvm-test.  
> The
> order of the files in the patch has been set up for logical review.  
> Some
> of this you've already seen, but its changed so much that those things
> should probably be reviewed again.


+++ lib/Transforms/ExprTypeConvert.cpp	18 Nov 2006 19:22:12 -0000
@@ -51,14 +51,26 @@ bool llvm::ExpressionConvertibleToType(V

    Instruction *I = dyn_cast<Instruction>(V);
    if (I == 0) return false;              // Otherwise, we can't  
convert!

    switch (I->getOpcode()) {
-  case Instruction::Cast:
+  case Instruction::Trunc:
+  case Instruction::ZExt:
+  case Instruction::SExt:
+  case Instruction::FPTrunc:
+  case Instruction::FPExt:
+  case Instruction::UIToFP:
+  case Instruction::SIToFP:
+  case Instruction::FPToUI:
+  case Instruction::FPToSI:
+  case Instruction::PtrToInt:
+  case Instruction::IntToPtr:
+  case Instruction::BitCast:
      // We can convert the expr if the cast destination type is  
losslessly
      // convertible to the requested type.
-    if (!Ty->isLosslesslyConvertibleTo(I->getType())) return false;
+    if (!Ty->isLosslesslyConvertibleTo(I->getType()))
+      return false;

      // We also do not allow conversion of a cast that casts from a  
ptr to array
      // of X to a *X.  For example: cast [4 x %List *] * %val to % 
List * *
      //
      if (const PointerType *SPT =

Many of these casts can't pass the isLosslesslyConvertibleTo  
predicate, don't include them.  This also happens in  
OperandConvertibleToType.  Note that isLosslesslyConvertibleTo would  
never accept int<->ptr before, these should just check bitcast.


@@ -226,13 +238,24 @@ Value *llvm::ConvertExpressionToType(Val
    ValueHandle IHandle(VMC, I);  // Prevent I from being removed!

    Constant *Dummy = Constant::getNullValue(Ty);

    switch (I->getOpcode()) {
-  case Instruction::Cast:
+  case Instruction::Trunc:
+  case Instruction::ZExt:
+  case Instruction::SExt:
+  case Instruction::FPTrunc:
+  case Instruction::FPExt:
+  case Instruction::UIToFP:
+  case Instruction::SIToFP:
+  case Instruction::FPToUI:
+  case Instruction::FPToSI:
+  case Instruction::PtrToInt:
+  case Instruction::IntToPtr:
+  case Instruction::BitCast:
      assert(VMC.NewCasts.count(ValueHandle(VMC, I)) == 0);
-    Res = new CastInst(I->getOperand(0), Ty, Name);
+    Res = CastInst::getCast(I->getOperand(0), Ty, Name);
      VMC.NewCasts.insert(ValueHandle(VMC, Res));
      break;

Likewise, since they can't be accepted above, they will never reach  
this.  Similar thing happens in ConvertOperandToType.



-    // Do not allow a 'cast ushort %V to uint' to have it's first  
operand be
+    // Do not allow a 'zext ushort %V to uint' to have it's first  
operand be
      // converted to a 'short' type.  Doing so changes the way sign  
promotion
      // happens, and breaks things.  Only allow the cast to take  
place if the
      // signedness doesn't change... or if the current cast is not a  
lossy
      // conversion.
      //
-    if (!I->getType()->isLosslesslyConvertibleTo(I->getOperand(0)- 
 >getType()) &&
-        I->getOperand(0)->getType()->isSigned() != Ty->isSigned())
+    if (!I->getType()->isLosslesslyConvertibleTo(V->getType()) &&
+        V->getType()->isSigned() != Ty->isSigned())
        return false;

      // We also do not allow conversion of a cast that casts from a  
ptr to array
      // of X to a *X.  For example: cast [4 x %List *] * %val to % 
List * *
      //

This if-check can be completely eliminated if you just handle bitcast.


--- lib/Transforms/LevelRaise.cpp	27 Aug 2006 22:42:51 -0000	1.111
+++ lib/Transforms/LevelRaise.cpp	18 Nov 2006 19:22:12 -0000
@@ -128,11 +119,11 @@ bool RPR::PeepholeOptimize(BasicBlock *B
        return true;
      }

      // Check to see if it's a cast of an instruction that does not  
depend on the
      // specific type of the operands to do it's job.
-    if (!isReinterpretingCast(CI)) {
+    if (CI->isNoopCast(TD.getIntPtrType())) {
        ValueTypeCache ConvertedTypes;

        // Check to see if we can convert the source of the cast to  
match the
        // destination type of the cast...
        //

Plz use isa<BitCast>.  There is no reason to make this code more  
general.


@@ -289,16 +294,17 @@ bool RPR::PeepholeOptimize(BasicBlock *B
      //
      if (CastInst *CI = dyn_cast<CastInst>(Pointer))
        if (Value *CastSrc = CI->getOperand(0)) // CSPT =  
CastSrcPointerType
          if (const PointerType *CSPT = dyn_cast<PointerType>(CastSrc- 
 >getType()))
            // convertible types?
-          if (Val->getType()->isLosslesslyConvertibleTo(CSPT- 
 >getElementType())) {
+          if (Val->getType()->isLosslesslyConvertibleTo(CSPT- 
 >getElementType()))
+          {
              PRINT_PEEPHOLE3("st-src-cast:in ", *Pointer, *Val, *SI);

              // Insert the new T cast instruction... stealing old  
T's name
              std::string Name(CI->getName()); CI->setName("");
-            CastInst *NCI = new CastInst(Val, CSPT->getElementType(),
+            CastInst *NCI = CastInst::getCast(Val, CSPT- 
 >getElementType(),
                                           Name, BI);

              // Replace the old store with a new one!
              ReplaceInstWithInst(BB->getInstList(), BI,
                                  SI = new StoreInst(NCI, CastSrc));


isa<BitCast>, please create a new bitcast instead of using getCast.


@@ -334,11 +340,12 @@ bool RPR::PeepholeOptimize(BasicBlock *B
              // Create the new load instruction... loading the pre- 
casted value
              LoadInst *NewLI = new LoadInst(CastSrc, LI->getName(),  
BI);

              // Insert the new T cast instruction... stealing old  
T's name
-            CastInst *NCI = new CastInst(NewLI, LI->getType(), CI- 
 >getName());
+            CastInst *NCI =
+              CastInst::getCast(NewLI, LI->getType(), CI->getName());
@@ -373,11 +380,11 @@ bool RPR::PeepholeOptimize(BasicBlock *B
        else
-        NewCast = new CastInst(CI->getCalledValue(), NewPFunTy,
+        NewCast = CastInst::getCast(CI->getCalledValue(), NewPFunTy,
                                 CI->getCalledValue()->getName() 
+"_c",CI);


These should create bitcast's explicitly.

===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/IPO/GlobalOpt.cpp,v
retrieving revision 1.71
diff -t -d -u -p -5 -r1.71 GlobalOpt.cpp
--- lib/Transforms/IPO/GlobalOpt.cpp	2 Nov 2006 20:25:50 -0000	1.71
+++ lib/Transforms/IPO/GlobalOpt.cpp	18 Nov 2006 19:22:13 -0000
@@ -328,12 +328,11 @@ static bool CleanupConstantGlobalUsers(V
        if (CE->getOpcode() == Instruction::GetElementPtr) {
          Constant *SubInit = 0;
          if (Init)
            SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
          Changed |= CleanupConstantGlobalUsers(CE, SubInit);
-      } else if (CE->getOpcode() == Instruction::Cast &&
-                 isa<PointerType>(CE->getType())) {
+      } else if (CE->isCast() && isa<PointerType>(CE->getType())) {
          // Pointer cast, delete any stores and memsets to the global.
          Changed |= CleanupConstantGlobalUsers(CE, 0);
        }

        if (CE->use_empty()) {

This only accepts bitcasts, please only check for bitcast.

@@ -1173,11 +1172,11 @@ static void ShrinkGlobalToBoolean(Global

        std::string Name = LI->getName(); LI->setName("");
        LoadInst *NLI = new LoadInst(NewGV, Name+".b", LI);
        Value *NSI;
        if (IsOneZero)
-        NSI = new CastInst(NLI, LI->getType(), Name, LI);
+        NSI = CastInst::getCast(NLI, LI->getType(), Name, LI);
        else
          NSI = new SelectInst(NLI, OtherVal, InitVal, Name, LI);

This cast is always a zext, please be explicit.


--- lib/Transforms/IPO/InlineSimple.cpp	2 Nov 2006 20:25:50 -0000	1.75
+++ lib/Transforms/IPO/InlineSimple.cpp	18 Nov 2006 19:22:13 -0000
@@ -141,16 +141,14 @@ void FunctionInfo::analyzeFunction(Funct
           II != E; ++II) {
        if (isa<DbgInfoIntrinsic>(II)) continue;  // Debug intrinsics  
don't count.

        // Noop casts don't count.
        if (const CastInst *CI = dyn_cast<CastInst>(II)) {
-        const Type *OpTy = CI->getOperand(0)->getType();
-        if (CI->getType()->isLosslesslyConvertibleTo(OpTy))
+        // FIXME: isNoopCast parameter should be TD->getIntPtrType()
+        // to make accurate decisions about Ptr->Int and Int->Ptr  
casts.
+        if (CI->isNoopCast(Type::ULongTy))
            continue;
-        if ((isa<PointerType>(CI->getType()) && OpTy->isInteger()) ||
-            (isa<PointerType>(OpTy) && CI->getType()->isInteger()))
-          continue;  // ptr <-> int is *probably* noop cast.

This is a heuristic check, please just use 'isa<BitCast> ||  
isa<IntToPtr> || isa<PtrToInt>' for simplicity.


--- lib/Transforms/Scalar/IndVarSimplify.cpp	21 Sep 2006 05:12:20  
-0000	1.95
+++ lib/Transforms/Scalar/IndVarSimplify.cpp	18 Nov 2006 19:22:15 -0000
@@ -521,13 +521,13 @@ void IndVarSimplify::runOnLoop(Loop *L)
      InsertedSizes[LargestType->getPrimitiveSize()] = true;
      for (unsigned i = 0, e = IndVars.size(); i != e; ++i)
        if (!InsertedSizes[IndVars[i].first->getType()- 
 >getPrimitiveSize()]) {
          PHINode *PN = IndVars[i].first;
          InsertedSizes[PN->getType()->getPrimitiveSize()] = true;
-        Instruction *New = new CastInst(IndVar,
-                                        PN->getType()- 
 >getUnsignedVersion(),
-                                        "indvar", InsertPt);
+        Instruction *New =
+          CastInst::getCast(IndVar, PN->getType()->getUnsignedVersion 
(),
+                               "indvar", InsertPt);
          Rewriter.addInsertedValue(New, SE->getSCEV(New));
        }
    }

These casts are always truncates.


--- lib/Transforms/Scalar/LoopStrengthReduce.cpp	17 Nov 2006 06:17:33  
-0000	1.94
+++ lib/Transforms/Scalar/LoopStrengthReduce.cpp	18 Nov 2006 19:22:20  
-0000
@@ -626,11 +626,11 @@ static bool isTargetConstant(const SCEVH
        return (V > -(1 << 16) && V < (1 << 16)-1);
    }

    if (SCEVUnknown *SU = dyn_cast<SCEVUnknown>(V))
      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(SU->getValue()))
-      if (CE->getOpcode() == Instruction::Cast) {
+      if (CE->isCast()) {
          Constant *Op0 = CE->getOperand(0);
          if (isa<GlobalValue>(Op0) &&
              TLI &&
              TLI->isLegalAddressImmediate(cast<GlobalValue>(Op0)))
            return true;

This should only be ptrtoint.


--- lib/Transforms/Scalar/ScalarReplAggregates.cpp	8 Nov 2006  
06:47:33 -0000	1.49
+++ lib/Transforms/Scalar/ScalarReplAggregates.cpp	18 Nov 2006  
19:22:21 -0000
@@ -649,13 +649,13 @@ void SROA::ConvertUsesToScalar(Value *Pt
                                       "tmp", SI);
          } else {
            // If SV is signed, convert it to unsigned, so that the  
next cast zero
            // extends the value.
            if (SV->getType()->isSigned())
-            SV = new CastInst(SV, SV->getType()->getUnsignedVersion(),
+            SV = CastInst::getCast(SV, SV->getType()- 
 >getUnsignedVersion(),
                                SV->getName(), SI);
-          SV = new CastInst(SV, Old->getType(), SV->getName(), SI);
+          SV = CastInst::getCast(SV, Old->getType(), SV->getName(),  
SI);
            if (Offset && Offset < TD.getTypeSize(SV->getType())*8)
              SV = new ShiftInst(Instruction::Shl, SV,
                                 ConstantInt::get(Type::UByteTy,  
Offset),
                                 SV->getName()+".adj", SI);
            // Mask out the bits we are about to insert from the old  
value.

These two casts should just be:

            // Always zero extend the value.
                      if (different size)
    	         SV = new ZExtInst(SV, Old->getType(), SV->getName(), SI);
		   else
			 SV = new BitCast(..)
            if (Offset && Offset < TD.getTypeSize(SV->getType())*8)
              SV = new ShiftInst(Instruction::Shl, SV,
                                 ConstantInt::get(Type::UByteTy,  
Offset),
                                 SV->getName()+".adj", SI);
            // Mask out the bits we are about to insert from the old  
value.


--- lib/Transforms/Utils/SimplifyCFG.cpp	8 Nov 2006 06:47:33 -0000	1.104
+++ lib/Transforms/Utils/SimplifyCFG.cpp	18 Nov 2006 19:22:22 -0000
@@ -424,11 +424,11 @@ static Value *GatherConstantSetNEs(Value
          return Inst->getOperand(0);
        } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst- 
 >getOperand(0))) {
          Values.push_back(C);
          return Inst->getOperand(1);
        }
-    } else if (Inst->getOpcode() == Instruction::Cast) {
+    } else if (Inst->isCast()) {
        // Cast of X to bool is really a comparison against zero.
        assert(Inst->getType() == Type::BoolTy && "Can only handle  
bool values!");
        Values.push_back(ConstantInt::get(Inst->getOperand(0)->getType 
(), 0));
        return Inst->getOperand(0);
      } else if (Inst->getOpcode() == Instruction::And) {


This is a serious bug.  Just remove this code entirely:

     } else if (Inst->getOpcode() == Instruction::Cast) {
       // Cast of X to bool is really a comparison against zero.
       assert(Inst->getType() == Type::BoolTy && "Can only handle  
bool values!");
       Values.push_back(ConstantInt::get(Inst->getOperand(0)->getType 
(), 0));
       return Inst->getOperand(0);

Comparisons against zero are now always setcc's.


-Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20061120/de33239a/attachment.html>


More information about the llvm-commits mailing list