Skip to content

Commit e9d5680

Browse files
committed
[Instcombine] Avoid widening trunc+sext to trunc+shl+ashr when not profitable
Skip the transform that replaces: %a = trunc i64 %x to i16 %b = sext i16 %a to i32 with %a = trunc i64 %x to i32 %b = shl i32 %a, 16 %c = ashr exact i32 %b, 16 when (pre-trunc) source type is wider than the final destination type. Modern architectures typically have efficient sign-extend instruction. It is preferable to preserve the sext for this case. Resolves #116019
1 parent cae73be commit e9d5680

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,17 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
15281528
}
15291529

15301530
// Try to extend the entire expression tree to the wide destination type.
1531-
if (shouldChangeType(SrcTy, DestTy) && canEvaluateSExtd(Src, DestTy)) {
1531+
bool shouldExtendExpression = true;
1532+
Value *X = nullptr;
1533+
// Do not extend expression in the trunc + sext pattern when destination type
1534+
// is narrower than original (pre-trunc) type: modern architectures typically
1535+
// provide efficient sign-extend instruction, so preserving the sext is
1536+
// preferable here.
1537+
if (match(Src, m_Trunc(m_Value(X))))
1538+
if (X->getType()->getScalarSizeInBits() > DestBitSize)
1539+
shouldExtendExpression = false;
1540+
if (shouldExtendExpression && shouldChangeType(SrcTy, DestTy) &&
1541+
canEvaluateSExtd(Src, DestTy)) {
15321542
// Okay, we can transform this! Insert the new expression now.
15331543
LLVM_DEBUG(
15341544
dbgs() << "ICE: EvaluateInDifferentType converting expression type"
@@ -1548,8 +1558,7 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
15481558
ShAmt);
15491559
}
15501560

1551-
Value *X;
1552-
if (match(Src, m_Trunc(m_Value(X)))) {
1561+
if (X) {
15531562
// If the input has more sign bits than bits truncated, then convert
15541563
// directly to final type.
15551564
unsigned XBitSize = X->getType()->getScalarSizeInBits();

llvm/test/Transforms/InstCombine/sext.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,17 @@ define i10 @test19(i10 %i) {
320320
ret i10 %d
321321
}
322322

323+
define i32 @test20(i64 %i) {
324+
; CHECK-LABEL: @test20(
325+
; CHECK-NEXT: [[A:%.*]] = trunc i64 [[I:%.*]] to i16
326+
; CHECK-NEXT: [[B:%.*]] = sext i16 [[A]] to i32
327+
; CHECK-NEXT: ret i32 [[B]]
328+
;
329+
%a = trunc i64 %i to i16
330+
%b = sext i16 %a to i32
331+
ret i32 %b
332+
}
333+
323334
define i32 @smear_set_bit(i32 %x) {
324335
; CHECK-LABEL: @smear_set_bit(
325336
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 24

0 commit comments

Comments
 (0)