diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp index 01c4f8cdf4e..b0d017e0620 100644 --- a/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -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(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); } } diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp index a2d528b5f4e..fe91da1b6af 100644 --- a/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -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; diff --git a/test/Transforms/InstCombine/apint-shift.ll b/test/Transforms/InstCombine/apint-shift.ll index 6573b5bf4f4..55243a64918 100644 --- a/test/Transforms/InstCombine/apint-shift.ll +++ b/test/Transforms/InstCombine/apint-shift.ll @@ -168,13 +168,6 @@ define i11 @test23(i44 %A) { ret i11 %D } -define i17 @test24(i17 %X) { - %Y = and i17 %X, -5 ; [#uses=1] - %Z = shl i17 %Y, 9 ; [#uses=1] - %Q = ashr i17 %Z, 9 ; [#uses=1] - ret i17 %Q -} - define i37 @test25(i37 %tmp.2, i37 %AA) { %x = lshr i37 %AA, 17 ; [#uses=1] %tmp.3 = lshr i37 %tmp.2, 17 ; [#uses=1]