change the preferred canonical form for a sign extension to be
authorChris Lattner <sabre@nondot.org>
Sun, 10 Jan 2010 07:08:30 +0000 (07:08 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 10 Jan 2010 07:08:30 +0000 (07:08 +0000)
lshr+ashr instead of trunc+sext.  We want to avoid type
conversions whenever possible, it is easier to codegen expressions
without truncates and extensions.

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

lib/Transforms/InstCombine/InstCombineCasts.cpp
lib/Transforms/InstCombine/InstCombineShifts.cpp
test/Transforms/InstCombine/apint-shift.ll

index 01c4f8cdf4e37ca95e0aba7b7e567198120f8a9c..b0d017e0620e6c152daffd8b1424a55dd9254785 100644 (file)
@@ -680,6 +680,8 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
   // 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
+    // TODO: Subsume this into EvaluateInDifferentType.
+    
     // 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);
@@ -707,7 +709,7 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
       APInt AndValue(APInt::getLowBitsSet(DstSize, MidSize));
       return BinaryOperator::CreateAnd(Trunc, 
                                        ConstantInt::get(Trunc->getType(),
-                                                               AndValue));
+                                                        AndValue));
     }
   }
 
@@ -927,6 +929,7 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
     // always do the transformation.
     if (NumCastsRemoved >= 2 ||
         NumBitsSExt > DestBitSize-SrcBitSize) {
+      
       // Okay, we can transform this!  Insert the new expression now.
       DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
             " to avoid sign extend: " << CI);
@@ -939,8 +942,10 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
           ComputeNumSignBits(Res) > DestBitSize - SrcBitSize)
         return ReplaceInstUsesWith(CI, Res);
       
-      // We need to emit a cast to truncate, then a cast to sext.
-      return new SExtInst(Builder->CreateTrunc(Res, Src->getType()), DestTy);
+      // We need to emit a shl + ashr to do the sign extend.
+      Value *ShAmt = ConstantInt::get(DestTy, DestBitSize-SrcBitSize);
+      return BinaryOperator::CreateAShr(Builder->CreateShl(Res, ShAmt, "sext"),
+                                        ShAmt);
     }
   }
 
index a2d528b5f4efe19464f825ff535ae931fe427610..fe91da1b6af4943bc90494b254079c9775acae40 100644 (file)
@@ -325,26 +325,6 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
         return BinaryOperator::CreateAnd(X,
                                         ConstantInt::get(I.getContext(), Mask));
       }
-      // We can simplify ((X << C) >>s C) into a trunc + sext.
-      // NOTE: we could do this for any C, but that would make 'unusual' integer
-      // types.  For now, just stick to ones well-supported by the code
-      // generators.
-      const Type *SExtType = 0;
-      switch (Ty->getBitWidth() - ShiftAmt1) {
-      case 1  :
-      case 8  :
-      case 16 :
-      case 32 :
-      case 64 :
-      case 128:
-        SExtType = IntegerType::get(I.getContext(),
-                                    Ty->getBitWidth() - ShiftAmt1);
-        break;
-      default: break;
-      }
-      if (SExtType)
-        return new SExtInst(Builder->CreateTrunc(X, SExtType, "sext"), Ty);
-      // Otherwise, we can't handle it yet.
     } else if (ShiftAmt1 < ShiftAmt2) {
       uint32_t ShiftDiff = ShiftAmt2-ShiftAmt1;
       
index 6573b5bf4f44f953631c4b8a31adc815d28c6420..55243a649183146378358c9b8a454e53f1363a71 100644 (file)
@@ -168,13 +168,6 @@ define i11 @test23(i44 %A) {
        ret i11 %D
 }
 
-define i17 @test24(i17 %X) {
-       %Y = and i17 %X, -5             ; <i17> [#uses=1]
-       %Z = shl i17 %Y, 9              ; <i17> [#uses=1]
-       %Q = ashr i17 %Z, 9             ; <i17> [#uses=1]
-       ret i17 %Q
-}
-
 define i37 @test25(i37 %tmp.2, i37 %AA) {
        %x = lshr i37 %AA, 17           ; <i37> [#uses=1]
        %tmp.3 = lshr i37 %tmp.2, 17            ; <i37> [#uses=1]