[llvm-commits] [llvm] r93127 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCasts.cpp test/Transforms/InstCombine/cast.ll

Chris Lattner sabre at nondot.org
Sun Jan 10 12:25:54 PST 2010


Author: lattner
Date: Sun Jan 10 14:25:54 2010
New Revision: 93127

URL: http://llvm.org/viewvc/llvm-project?rev=93127&view=rev
Log:
teach zext optimization how to deal with truncs that don't come from
the zext dest type.  This allows us to handle test52/53 in cast.ll,
and allows llvm-gcc to generate much better code for PR4216 in -m64
mode:

_test_bitfield:                                             ## @test_bitfield
	orl	$32962, %edi
	movl	%edi, %eax
	andl	$-25350, %eax
	ret

This also fixes a bug handling vector extends, ensuring that the
mask produced is a vector constant, not an integer constant.


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/trunk/test/Transforms/InstCombine/cast.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=93127&r1=93126&r2=93127&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Sun Jan 10 14:25:54 2010
@@ -192,7 +192,9 @@
       return I->getOperand(0);
     
     // 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);
+    // This also handles the case of zext(trunc(x)) -> zext(x).
+    Res = CastInst::CreateIntegerCast(I->getOperand(0), Ty,
+                                      Opc == Instruction::SExt);
     break;
   case Instruction::Select: {
     Value *True = EvaluateInDifferentType(I->getOperand(1), Ty, isSigned);
@@ -597,6 +599,10 @@
   
   unsigned Opc = I->getOpcode();
   switch (Opc) {
+  case Instruction::ZExt:  // zext(zext(x)) -> zext(x).
+  case Instruction::SExt:  // zext(sext(x)) -> sext(x).
+  case Instruction::Trunc: // zext(trunc(x)) -> trunc(x) or zext(x)
+    return true;
   case Instruction::And:
   case Instruction::Or:
   case Instruction::Xor:
@@ -608,9 +614,6 @@
            CanEvaluateZExtd(I->getOperand(1), Ty, TD);
       
   //case Instruction::LShr:
-  case Instruction::ZExt: // zext(zext(x)) -> zext(x).
-  case Instruction::SExt: // zext(sext(x)) -> sext(x).
-    return true;
       
   case Instruction::Select:
     return CanEvaluateZExtd(I->getOperand(1), Ty, TD) &&
@@ -671,7 +674,7 @@
       return ReplaceInstUsesWith(CI, Res);
     
     // We need to emit an AND to clear the high bits.
-    Constant *C = ConstantInt::get(CI.getContext(), 
+    Constant *C = ConstantInt::get(Res->getType(),
                                APInt::getLowBitsSet(DestBitSize, SrcBitSize));
     return BinaryOperator::CreateAnd(Res, C);
   }
@@ -810,23 +813,20 @@
   //case Instruction::LShr:  TODO
   //case Instruction::Trunc: TODO
       
-  case Instruction::SExt:
-  case Instruction::ZExt: {
-    // sext(sext(x)) -> sext(x)
-    // sext(zext(x)) -> zext(x)
+  case Instruction::SExt: // sext(sext(x)) -> sext(x)
+  case Instruction::ZExt: // sext(zext(x)) -> zext(x)
     return true;
-  }
   case Instruction::Select:
     return CanEvaluateSExtd(I->getOperand(1), Ty, TD) &&
            CanEvaluateSExtd(I->getOperand(2), Ty, TD);
+      
   case Instruction::PHI: {
     // We can change a phi if we can change all operands.  Note that we never
     // get into trouble with cyclic PHIs here because we only consider
     // instructions with a single use.
     PHINode *PN = cast<PHINode>(I);
-    for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+    for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
       if (!CanEvaluateSExtd(PN->getIncomingValue(i), Ty, TD)) return false;
-    }
     return true;
   }
   default:

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

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/cast.ll Sun Jan 10 14:25:54 2010
@@ -496,6 +496,30 @@
 ; CHECK-NEXT: %sext = shl i64 %E, 32
 ; CHECK-NEXT: %F = ashr i64 %sext, 32
 ; CHECK-NEXT: ret i64 %F
+}
 
+define i32 @test52(i64 %A) {
+  %B = trunc i64 %A to i16
+  %C = or i16 %B, -32574
+  %D = and i16 %C, -25350
+  %E = zext i16 %D to i32
+  ret i32 %E
+; CHECK: @test52
+; CHECK-NEXT: %B = trunc i64 %A to i32
+; CHECK-NEXT: %C = or i32 %B, 32962
+; CHECK-NEXT: %D = and i32 %C, 40186
+; CHECK-NEXT: ret i32 %D
 }
 
+define i64 @test53(i32 %A) {
+  %B = trunc i32 %A to i16
+  %C = or i16 %B, -32574
+  %D = and i16 %C, -25350
+  %E = zext i16 %D to i64
+  ret i64 %E
+; CHECK: @test53
+; CHECK-NEXT: %B = zext i32 %A to i64
+; CHECK-NEXT: %C = or i64 %B, 32962
+; CHECK-NEXT: %D = and i64 %C, 40186
+; CHECK-NEXT: ret i64 %D
+}





More information about the llvm-commits mailing list