[llvm] [Instcombine] Avoid widening trunc+sext to trunc+shl+ashr when not profitable (PR #160483)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 24 03:11:09 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Wenju He (wenju-he)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/160483.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp (+12-3)
- (modified) llvm/test/Transforms/InstCombine/sext.ll (+11)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 9ca8194b44f8f..ea029e47730bf 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1528,7 +1528,17 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
}
// Try to extend the entire expression tree to the wide destination type.
- if (shouldChangeType(SrcTy, DestTy) && canEvaluateSExtd(Src, DestTy)) {
+ bool shouldExtendExpression = true;
+ Value *X = nullptr;
+ // Do not extend expression in the trunc + sext pattern when destination type
+ // is narrower than original (pre-trunc) type: modern architectures typically
+ // provide efficient sign-extend instruction, so preserving the sext is
+ // preferable here.
+ if (match(Src, m_Trunc(m_Value(X))))
+ if (X->getType()->getScalarSizeInBits() > DestBitSize)
+ shouldExtendExpression = false;
+ if (shouldExtendExpression && shouldChangeType(SrcTy, DestTy) &&
+ canEvaluateSExtd(Src, DestTy)) {
// Okay, we can transform this! Insert the new expression now.
LLVM_DEBUG(
dbgs() << "ICE: EvaluateInDifferentType converting expression type"
@@ -1548,8 +1558,7 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) {
ShAmt);
}
- Value *X;
- if (match(Src, m_Trunc(m_Value(X)))) {
+ if (X) {
// If the input has more sign bits than bits truncated, then convert
// directly to final type.
unsigned XBitSize = X->getType()->getScalarSizeInBits();
diff --git a/llvm/test/Transforms/InstCombine/sext.ll b/llvm/test/Transforms/InstCombine/sext.ll
index c72614d526036..92748034f52ab 100644
--- a/llvm/test/Transforms/InstCombine/sext.ll
+++ b/llvm/test/Transforms/InstCombine/sext.ll
@@ -320,6 +320,17 @@ define i10 @test19(i10 %i) {
ret i10 %d
}
+define i32 @test20(i64 %i) {
+; CHECK-LABEL: @test20(
+; CHECK-NEXT: [[A:%.*]] = trunc i64 [[I:%.*]] to i16
+; CHECK-NEXT: [[B:%.*]] = sext i16 [[A]] to i32
+; CHECK-NEXT: ret i32 [[B]]
+;
+ %a = trunc i64 %i to i16
+ %b = sext i16 %a to i32
+ ret i32 %b
+}
+
define i32 @smear_set_bit(i32 %x) {
; CHECK-LABEL: @smear_set_bit(
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 24
``````````
</details>
https://github.com/llvm/llvm-project/pull/160483
More information about the llvm-commits
mailing list