two changes:
authorChris Lattner <sabre@nondot.org>
Sun, 10 Jan 2010 02:39:31 +0000 (02:39 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 10 Jan 2010 02:39:31 +0000 (02:39 +0000)
1) don't try to optimize a sext or zext that is only used by a trunc, let
   the trunc get optimized first.  This avoids some pointless effort in
   some common cases since instcombine scans down a block in the first pass.
2) Change the cost model for zext elimination to consider an 'and' cheaper
   than a zext.  This allows us to do it more aggressively, and for the next
   patch to simplify the code quite a bit.

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

lib/Transforms/InstCombine/InstCombineCasts.cpp
test/Transforms/InstCombine/cast.ll

index 3ad786b6bdd8479f533edf292bd09148cd408fcd..34937ab5031a5a85622471ee8d3b9bb45de78e13 100644 (file)
@@ -695,6 +695,11 @@ static int CanEvaluateZExtd(Value *V, const Type *Ty,unsigned &NumCastsRemoved,
 }
 
 Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
+  // If this zero extend is only used by a truncate, let the truncate by
+  // eliminated before we try to optimize this zext.
+  if (CI.hasOneUse() && isa<TruncInst>(CI.use_back()))
+    return 0;
+  
   // If one of the common conversion will work, do it.
   if (Instruction *Result = commonCastTransforms(CI))
     return Result;
@@ -716,33 +721,25 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
     int BitsZExt = CanEvaluateZExtd(Src, DestTy, NumCastsRemoved, TD);
     if (BitsZExt == -1) return 0;
     
+    // Okay, we can transform this!  Insert the new expression now.
+    DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
+          " to avoid zero extend: " << CI);
+    Value *Res = EvaluateInDifferentType(Src, DestTy, false);
+    assert(Res->getType() == DestTy);
+    
+    // If the high bits are already filled with zeros, just replace this
+    // cast with the result.
     uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
     uint32_t DestBitSize = DestTy->getScalarSizeInBits();
-
-    // If this is a zero-extension, we need to do an AND to maintain the clear
-    // top-part of the computation.  If we know the result will be zero 
-    // extended enough already, we don't need the and.
-    if (NumCastsRemoved >= 1 ||
-        unsigned(BitsZExt) >= DestBitSize-SrcBitSize) {
-      
-      // Okay, we can transform this!  Insert the new expression now.
-      DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
-            " to avoid zero extend: " << CI);
-      Value *Res = EvaluateInDifferentType(Src, DestTy, false);
-      assert(Res->getType() == DestTy);
-      
-      // If the high bits are already filled with zeros, just replace this
-      // cast with the result.
-      if (unsigned(BitsZExt) >= DestBitSize-SrcBitSize ||
-          MaskedValueIsZero(Res, APInt::getHighBitsSet(DestBitSize,
-                                                       DestBitSize-SrcBitSize)))
-        return ReplaceInstUsesWith(CI, Res);
-      
-      // We need to emit an AND to clear the high bits.
-      Constant *C = ConstantInt::get(CI.getContext(), 
-                                 APInt::getLowBitsSet(DestBitSize, SrcBitSize));
-      return BinaryOperator::CreateAnd(Res, C);
-    }
+    if (unsigned(BitsZExt) >= DestBitSize-SrcBitSize ||
+        MaskedValueIsZero(Res, APInt::getHighBitsSet(DestBitSize,
+                                                     DestBitSize-SrcBitSize)))
+      return ReplaceInstUsesWith(CI, Res);
+    
+    // We need to emit an AND to clear the high bits.
+    Constant *C = ConstantInt::get(CI.getContext(), 
+                               APInt::getLowBitsSet(DestBitSize, SrcBitSize));
+    return BinaryOperator::CreateAnd(Res, C);
   }
 
   // If this is a TRUNC followed by a ZEXT then we are dealing with integral
@@ -951,6 +948,11 @@ static unsigned CanEvaluateSExtd(Value *V, const Type *Ty,
 }
 
 Instruction *InstCombiner::visitSExt(SExtInst &CI) {
+  // If this sign extend is only used by a truncate, let the truncate by
+  // eliminated before we try to optimize this zext.
+  if (CI.hasOneUse() && isa<TruncInst>(CI.use_back()))
+    return 0;
+  
   if (Instruction *I = commonCastTransforms(CI))
     return I;
   
index 490df8fab6e5ce2cd2f5e5b7219358893ff0a0fb..de7f8c11f26423953e68c24c001589eb91a19137 100644 (file)
@@ -430,4 +430,30 @@ define i64 @test46(i64 %A) {
 ; CHECK-NEXT: ret i64 %D
 }
 
+define i64 @test47(i8 %A) {
+ %B = sext i8 %A to i32
+ %C = or i32 %B, 42
+ %E = zext i32 %C to i64 
+ ret i64 %E
+; CHECK: @test47
+; CHECK-NEXT:   %B = sext i8 %A to i64
+; CHECK-NEXT: %C = or i64 %B, 42
+; CHECK-NEXT:  %E = and i64 %C, 4294967295
+; CHECK-NEXT:  ret i64 %E
+}
+
+define i64 @test48(i8 %A, i8 %a) {
+  %b = zext i8 %a to i32
+  %B = zext i8 %A to i32
+  %C = shl i32 %B, 8
+  %D = or i32 %C, %b
+  %E = zext i32 %D to i64
+  ret i64 %E
+; CHECK: @test48
+; CHECK-NEXT: %b = zext i8 %a to i64
+; CHECK-NEXT: %B = zext i8 %A to i64
+; CHECK-NEXT: %C = shl i64 %B, 8
+; CHECK-NEXT: %D = or i64 %C, %b
+; CHECK-NEXT: ret i64 %D
+}