From: Chris Lattner Date: Sun, 10 Jan 2010 07:40:50 +0000 (+0000) Subject: now that the cost model has changed, we can always consider X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=dde5ee5d37d05c326d33497e1dbd16f77191a1ae;p=oota-llvm.git now that the cost model has changed, we can always consider elimination of a sign extend to be a win, which simplifies the client of CanEvaluateSExtd, and allows us to eliminate more casts (examples taken from real code). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93109 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp index b0d017e0620..13f60716f2e 100644 --- a/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -919,34 +919,25 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) { if (NumBitsSExt == 0) return 0; + // Okay, we can transform this! Insert the new expression now. + DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type" + " to avoid sign extend: " << CI); + Value *Res = EvaluateInDifferentType(Src, DestTy, true); + assert(Res->getType() == DestTy); + uint32_t SrcBitSize = SrcTy->getScalarSizeInBits(); uint32_t DestBitSize = DestTy->getScalarSizeInBits(); + + // If the high bits are already filled with sign bit, just replace this + // cast with the result. + if (NumBitsSExt > DestBitSize - SrcBitSize || + ComputeNumSignBits(Res) > DestBitSize - SrcBitSize) + return ReplaceInstUsesWith(CI, Res); - // Because this is a sign extension, we can always transform it by inserting - // two new shifts (to do the extension). However, this is only profitable - // if we've eliminated two or more casts from the input. If we know the - // result will be sign-extended enough to not require these shifts, we can - // 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); - Value *Res = EvaluateInDifferentType(Src, DestTy, true); - assert(Res->getType() == DestTy); - - // If the high bits are already filled with sign bit, just replace this - // cast with the result. - if (NumBitsSExt > DestBitSize - SrcBitSize || - ComputeNumSignBits(Res) > DestBitSize - SrcBitSize) - return ReplaceInstUsesWith(CI, Res); - - // 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); - } + // 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); } // If the input is a shl/ashr pair of a same constant, then this is a sign diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index de7f8c11f26..4f0475ac59d 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -185,8 +185,8 @@ define i32 @test22(i32 %X) { %c2 = sext i8 %c1 to i32 ; [#uses=1] %RV = shl i32 %c2, 24 ; [#uses=1] ret i32 %RV -; CHECK: %RV = shl i32 %X, 24 -; CHECK: ret i32 %RV +; CHECK: shl i32 %X, 24 +; CHECK-NEXT: ret i32 } define i32 @test23(i32 %X) { @@ -457,3 +457,45 @@ define i64 @test48(i8 %A, i8 %a) { ; CHECK-NEXT: ret i64 %D } +define i64 @test49(i64 %A) { + %B = trunc i64 %A to i32 + %C = or i32 %B, 1 + %D = sext i32 %C to i64 + ret i64 %D +; CHECK: @test49 +; CHECK-NEXT: %C = shl i64 %A, 32 +; CHECK-NEXT: ashr i64 %C, 32 +; CHECK-NEXT: %D = or i64 {{.*}}, 1 +; CHECK-NEXT: ret i64 %D +} + +define i64 @test50(i64 %A) { + %a = lshr i64 %A, 2 + %B = trunc i64 %a to i32 + %D = add i32 %B, -1 + %E = sext i32 %D to i64 + ret i64 %E +; CHECK: @test50 +; CHECK-NEXT: shl i64 %A, 30 +; CHECK-NEXT: add i64 {{.*}}, -4294967296 +; CHECK-NEXT: %E = ashr i64 {{.*}}, 32 +; CHECK-NEXT: ret i64 %E +} + +define i64 @test51(i64 %A, i1 %cond) { + %B = trunc i64 %A to i32 + %C = and i32 %B, -2 + %D = or i32 %B, 1 + %E = select i1 %cond, i32 %C, i32 %D + %F = sext i32 %E to i64 + ret i64 %F +; CHECK: @test51 +; CHECK-NEXT: %C = and i64 %A, 4294967294 +; CHECK-NEXT: %D = or i64 %A, 1 +; CHECK-NEXT: %E = select i1 %cond, i64 %C, i64 %D +; CHECK-NEXT: %sext = shl i64 %E, 32 +; CHECK-NEXT: %F = ashr i64 %sext, 32 +; CHECK-NEXT: ret i64 %F + +} +