From: Chris Lattner Date: Sun, 10 Jan 2010 02:39:31 +0000 (+0000) Subject: two changes: X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5324d802835a677888ff020174c9eab5e86d6b15;p=oota-llvm.git two changes: 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 --- diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp index 3ad786b6bdd..34937ab5031 100644 --- a/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -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(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(CI.use_back())) + return 0; + if (Instruction *I = commonCastTransforms(CI)) return I; diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index 490df8fab6e..de7f8c11f26 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -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 +}