[llvm-commits] [llvm] r52440 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/sext-misc.ll

Chris Lattner sabre at nondot.org
Tue Jun 17 21:00:49 PDT 2008


Author: lattner
Date: Tue Jun 17 23:00:49 2008
New Revision: 52440

URL: http://llvm.org/viewvc/llvm-project?rev=52440&view=rev
Log:
make truncate/sext elimination capable of changing phi's.  This 
implements rdar://6013816 and the testcase in Transforms/InstCombine/sext-misc.ll.

Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/sext-misc.ll

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=52440&r1=52439&r2=52440&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Jun 17 23:00:49 2008
@@ -6838,6 +6838,16 @@
 ///
 /// This is a truncation operation if Ty is smaller than V->getType(), or an
 /// extension operation if Ty is larger.
+///
+/// If CastOpc is a truncation, then Ty will be a type smaller than V.  We
+/// should return true if trunc(V) can be computed by computing V in the smaller
+/// type.  If V is an instruction, then trunc(inst(x,y)) can be computed as
+/// inst(trunc(x),trunc(y)), which only makes sense if x and y can be
+/// efficiently truncated.
+///
+/// If CastOpc is a sext or zext, we are asking if the low bits of the value can
+/// bit computed in a larger type, which is then and'd or sext_in_reg'd to get
+/// the final result.
 bool InstCombiner::CanEvaluateInDifferentType(Value *V, const IntegerType *Ty,
                                               unsigned CastOpc,
                                               int &NumCastsRemoved) {
@@ -6858,7 +6868,7 @@
       // If the first operand is itself a cast, and is eliminable, do not count
       // this as an eliminable cast.  We would prefer to eliminate those two
       // casts first.
-      if (!isa<CastInst>(I->getOperand(0)))
+      if (!isa<CastInst>(I->getOperand(0)) && I->hasOneUse())
         ++NumCastsRemoved;
       return true;
     }
@@ -6923,8 +6933,17 @@
     // of casts in the input.
     if (I->getOpcode() == CastOpc)
       return true;
-    
     break;
+      
+  case Instruction::PHI: {
+    // We can change a phi if we can change all operands.
+    PHINode *PN = cast<PHINode>(I);
+    for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+      if (!CanEvaluateInDifferentType(PN->getIncomingValue(i), Ty, CastOpc,
+                                      NumCastsRemoved))
+        return false;
+    return true;
+  }
   default:
     // TODO: Can handle more cases here.
     break;
@@ -6957,7 +6976,7 @@
     Value *LHS = EvaluateInDifferentType(I->getOperand(0), Ty, isSigned);
     Value *RHS = EvaluateInDifferentType(I->getOperand(1), Ty, isSigned);
     Res = BinaryOperator::Create((Instruction::BinaryOps)I->getOpcode(),
-                                 LHS, RHS, I->getName());
+                                 LHS, RHS);
     break;
   }    
   case Instruction::Trunc:
@@ -6969,16 +6988,27 @@
     if (I->getOperand(0)->getType() == Ty)
       return I->getOperand(0);
     
-    // Otherwise, must be the same type of case, so just reinsert a new one.
+    // Otherwise, must be the same type of cast, so just reinsert a new one.
     Res = CastInst::Create(cast<CastInst>(I)->getOpcode(), I->getOperand(0),
-                           Ty, I->getName());
+                           Ty);
     break;
+  case Instruction::PHI: {
+    PHINode *OPN = cast<PHINode>(I);
+    PHINode *NPN = PHINode::Create(Ty);
+    for (unsigned i = 0, e = OPN->getNumIncomingValues(); i != e; ++i) {
+      Value *V =EvaluateInDifferentType(OPN->getIncomingValue(i), Ty, isSigned);
+      NPN->addIncoming(V, OPN->getIncomingBlock(i));
+    }
+    Res = NPN;
+    break;
+  }
   default: 
     // TODO: Can handle more cases here.
     assert(0 && "Unreachable!");
     break;
   }
   
+  Res->takeName(I);
   return InsertNewInstBefore(Res, *I);
 }
 

Modified: llvm/trunk/test/Transforms/InstCombine/sext-misc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sext-misc.ll?rev=52440&r1=52439&r2=52440&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/sext-misc.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/sext-misc.ll Tue Jun 17 23:00:49 2008
@@ -1,6 +1,4 @@
 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep sext
-; RUN: llvm-as < %s | llc -march=x86-64 | not grep movslq
-; RUN: llvm-as < %s | llc -march=x86 | not grep sar
 
 declare i32 @llvm.ctpop.i32(i32)
 declare i32 @llvm.ctlz.i32(i32)
@@ -50,3 +48,18 @@
   %n = sext i16 %s to i32
   ret i32 %n
 }
+
+; rdar://6013816
+define i16 @test(i16 %t, i1 %cond) nounwind {
+entry:
+	br i1 %cond, label %T, label %F
+T:
+	%t2 = sext i16 %t to i32
+	br label %F
+
+F:
+	%V = phi i32 [%t2, %T], [42, %entry]
+	%W = trunc i32 %V to i16
+	ret i16 %W
+}
+





More information about the llvm-commits mailing list