[llvm-commits] [llvm] r64809 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/zext.ll

Chris Lattner sabre at nondot.org
Tue Feb 17 12:47:23 PST 2009


Author: lattner
Date: Tue Feb 17 14:47:23 2009
New Revision: 64809

URL: http://llvm.org/viewvc/llvm-project?rev=64809&view=rev
Log:
commit a tweaked version of Daniel's patch for PR3599.  We now
eliminate all the extensions and all but the one required truncate
from the testcase, but the or/and/shift stuff still isn't zapped.

Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/zext.ll

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

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Feb 17 14:47:23 2009
@@ -8271,32 +8271,35 @@
 
   Value *Src = CI.getOperand(0);
 
-  // If this is a cast of a cast
-  if (CastInst *CSrc = dyn_cast<CastInst>(Src)) {   // A->B->C cast
-    // If this is a TRUNC followed by a ZEXT then we are dealing with integral
-    // types and if the sizes are just right we can convert this into a logical
-    // 'and' which will be much cheaper than the pair of casts.
-    if (isa<TruncInst>(CSrc)) {
-      // Get the sizes of the types involved
-      Value *A = CSrc->getOperand(0);
-      uint32_t SrcSize = A->getType()->getPrimitiveSizeInBits();
-      uint32_t MidSize = CSrc->getType()->getPrimitiveSizeInBits();
-      uint32_t DstSize = CI.getType()->getPrimitiveSizeInBits();
-      // If we're actually extending zero bits and the trunc is a no-op
-      if (MidSize < DstSize && SrcSize == DstSize) {
-        // Replace both of the casts with an And of the type mask.
-        APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize));
-        Constant *AndConst = ConstantInt::get(AndValue);
-        Instruction *And = 
-          BinaryOperator::CreateAnd(CSrc->getOperand(0), AndConst);
-        // Unfortunately, if the type changed, we need to cast it back.
-        if (And->getType() != CI.getType()) {
-          And->setName(CSrc->getName()+".mask");
-          InsertNewInstBefore(And, CI);
-          And = CastInst::CreateIntegerCast(And, CI.getType(), false/*ZExt*/);
-        }
-        return And;
-      }
+  // If this is a TRUNC followed by a ZEXT then we are dealing with integral
+  // types and if the sizes are just right we can convert this into a logical
+  // 'and' which will be much cheaper than the pair of casts.
+  if (TruncInst *CSrc = dyn_cast<TruncInst>(Src)) {   // A->B->C cast
+    // Get the sizes of the types involved.  We know that the intermediate type
+    // will be smaller than A or C, but don't know the relation between A and C.
+    Value *A = CSrc->getOperand(0);
+    unsigned SrcSize = A->getType()->getPrimitiveSizeInBits();
+    unsigned MidSize = CSrc->getType()->getPrimitiveSizeInBits();
+    unsigned DstSize = CI.getType()->getPrimitiveSizeInBits();
+    // If we're actually extending zero bits, then if
+    // SrcSize <  DstSize: zext(a & mask)
+    // SrcSize == DstSize: a & mask
+    // SrcSize  > DstSize: trunc(a) & mask
+    if (SrcSize < DstSize) {
+      APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize));
+      Constant *AndConst = ConstantInt::get(AndValue);
+      Instruction *And =
+        BinaryOperator::CreateAnd(A, AndConst, CSrc->getName()+".mask");
+      InsertNewInstBefore(And, CI);
+      return new ZExtInst(And, CI.getType());
+    } else if (SrcSize == DstSize) {
+      APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize));
+      return BinaryOperator::CreateAnd(A, ConstantInt::get(AndValue));
+    } else if (SrcSize > DstSize) {
+      Instruction *Trunc = new TruncInst(A, CI.getType(), "tmp");
+      InsertNewInstBefore(Trunc, CI);
+      APInt AndValue(APInt::getLowBitsSet(DstSize, MidSize));
+      return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(AndValue));
     }
   }
 

Modified: llvm/trunk/test/Transforms/InstCombine/zext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/zext.ll?rev=64809&r1=64808&r2=64809&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/zext.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/zext.ll Tue Feb 17 14:47:23 2009
@@ -8,3 +8,26 @@
         ret i64 %c2
 }
 
+; PR3599
+define i32 @test2(i64 %tmp) nounwind readnone {
+entry:
+	%tmp5 = trunc i64 %tmp to i8		; <i8> [#uses=1]
+	%tmp7 = lshr i64 %tmp, 8		; <i64> [#uses=1]
+	%tmp8 = trunc i64 %tmp7 to i8		; <i8> [#uses=1]
+	%tmp10 = lshr i64 %tmp, 16		; <i64> [#uses=1]
+	%tmp11 = trunc i64 %tmp10 to i8		; <i8> [#uses=1]
+	%tmp13 = lshr i64 %tmp, 24		; <i64> [#uses=1]
+	%tmp14 = trunc i64 %tmp13 to i8		; <i8> [#uses=1]
+	%tmp1 = zext i8 %tmp5 to i32		; <i32> [#uses=1]
+	%tmp2 = zext i8 %tmp8 to i32		; <i32> [#uses=1]
+	%tmp3 = shl i32 %tmp2, 8		; <i32> [#uses=1]
+	%tmp4 = zext i8 %tmp11 to i32		; <i32> [#uses=1]
+	%tmp6 = shl i32 %tmp4, 16		; <i32> [#uses=1]
+	%tmp9 = zext i8 %tmp14 to i32		; <i32> [#uses=1]
+	%tmp12 = shl i32 %tmp9, 24		; <i32> [#uses=1]
+	%tmp15 = or i32 %tmp12, %tmp1		; <i32> [#uses=1]
+	%tmp16 = or i32 %tmp15, %tmp6		; <i32> [#uses=1]
+	%tmp17 = or i32 %tmp16, %tmp3		; <i32> [#uses=1]
+	ret i32 %tmp17
+}
+





More information about the llvm-commits mailing list