[llvm-branch-commits] [llvm] [InstCombine] Fold fpto[su]i of llvm.trunc (PR #231414)
Harrison Hao via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Oct 13 02:05:46 PDT 2026
https://github.com/harrisonGPU updated https://github.com/llvm/llvm-project/pull/231414
>From 05a6200b74a09d535e3d0f0d716d38e0eaf1484e Mon Sep 17 00:00:00 2001
From: Harrison Hao <tsworld1314 at gmail.com>
Date: Tue, 13 Oct 2026 16:13:30 +0800
Subject: [PATCH 1/2] [InstCombine] Fold fpto[su]i of llvm.trunc
fptoui and fptosi already round toward zero, so a preceding llvm.trunc
is redundant and the conversion can take the untruncated value. NaN,
infinity, and out of range inputs produce poison in both forms.
```llvm
%t = call float @llvm.trunc.f32(float %x)
%r = fptosi float %t to i32
-->
%r = fptosi float %x to i32
```
The trunc may have other users; only the conversion operand is replaced.
---
.../Transforms/InstCombine/InstCombineCasts.cpp | 5 +++++
llvm/test/Transforms/InstCombine/fpcast.ll | 16 ++++++----------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index c217b59be9ea0..9c0c9cbc82f63 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -2592,6 +2592,11 @@ static Instruction *foldFPtoI(Instruction &FI, InstCombiner &IC) {
if (FPClass.isKnownNever(Mask))
return IC.replaceInstUsesWith(FI, ConstantInt::getNullValue(FI.getType()));
+ // fpto{u/s}i (trunc X) --> fpto{u/s}i X
+ Value *Src = nullptr;
+ if (match(FI.getOperand(0), m_Intrinsic<Intrinsic::trunc>(m_Value(Src))))
+ return IC.replaceOperand(FI, 0, Src);
+
// fpto{u/s}i (fdiv ({u/s}itofp X to F), C_fp) --> {u/s}div X, C
//
// F has precision p (significand bits incl. hidden bit); C_fp is the exact FP
diff --git a/llvm/test/Transforms/InstCombine/fpcast.ll b/llvm/test/Transforms/InstCombine/fpcast.ll
index 715c7eceb9da8..4e6eb207e97d1 100644
--- a/llvm/test/Transforms/InstCombine/fpcast.ll
+++ b/llvm/test/Transforms/InstCombine/fpcast.ll
@@ -798,8 +798,7 @@ define <4 x i32> @neg_fptoui_sat_fptrunc(<4 x double> %a) {
define i32 @fptoui_trunc(float %x) {
; CHECK-LABEL: @fptoui_trunc(
-; CHECK-NEXT: [[T:%.*]] = call float @llvm.trunc.f32(float [[X:%.*]])
-; CHECK-NEXT: [[R:%.*]] = fptoui float [[T]] to i32
+; CHECK-NEXT: [[R:%.*]] = fptoui float [[T:%.*]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%t = call float @llvm.trunc.f32(float %x)
@@ -809,8 +808,7 @@ define i32 @fptoui_trunc(float %x) {
define i32 @fptosi_trunc(float %x) {
; CHECK-LABEL: @fptosi_trunc(
-; CHECK-NEXT: [[T:%.*]] = call float @llvm.trunc.f32(float [[X:%.*]])
-; CHECK-NEXT: [[R:%.*]] = fptosi float [[T]] to i32
+; CHECK-NEXT: [[R:%.*]] = fptosi float [[T:%.*]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%t = call float @llvm.trunc.f32(float %x)
@@ -820,8 +818,7 @@ define i32 @fptosi_trunc(float %x) {
define <2 x i64> @fptoui_trunc_vec(<2 x double> %x) {
; CHECK-LABEL: @fptoui_trunc_vec(
-; CHECK-NEXT: [[T:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[X:%.*]])
-; CHECK-NEXT: [[R:%.*]] = fptoui <2 x double> [[T]] to <2 x i64>
+; CHECK-NEXT: [[R:%.*]] = fptoui <2 x double> [[T:%.*]] to <2 x i64>
; CHECK-NEXT: ret <2 x i64> [[R]]
;
%t = call <2 x double> @llvm.trunc.v2f64(<2 x double> %x)
@@ -831,8 +828,7 @@ define <2 x i64> @fptoui_trunc_vec(<2 x double> %x) {
define <2 x i64> @fptosi_trunc_vec(<2 x double> %x) {
; CHECK-LABEL: @fptosi_trunc_vec(
-; CHECK-NEXT: [[T:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[X:%.*]])
-; CHECK-NEXT: [[R:%.*]] = fptosi <2 x double> [[T]] to <2 x i64>
+; CHECK-NEXT: [[R:%.*]] = fptosi <2 x double> [[T:%.*]] to <2 x i64>
; CHECK-NEXT: ret <2 x i64> [[R]]
;
%t = call <2 x double> @llvm.trunc.v2f64(<2 x double> %x)
@@ -844,7 +840,7 @@ define i32 @fptoui_trunc_multi_use(float %x) {
; CHECK-LABEL: @fptoui_trunc_multi_use(
; CHECK-NEXT: [[T:%.*]] = call float @llvm.trunc.f32(float [[X:%.*]])
; CHECK-NEXT: call void @use(float [[T]])
-; CHECK-NEXT: [[R:%.*]] = fptoui float [[T]] to i32
+; CHECK-NEXT: [[R:%.*]] = fptoui float [[X]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%t = call float @llvm.trunc.f32(float %x)
@@ -857,7 +853,7 @@ define i32 @fptosi_trunc_multi_use(float %x) {
; CHECK-LABEL: @fptosi_trunc_multi_use(
; CHECK-NEXT: [[T:%.*]] = call float @llvm.trunc.f32(float [[X:%.*]])
; CHECK-NEXT: call void @use(float [[T]])
-; CHECK-NEXT: [[R:%.*]] = fptosi float [[T]] to i32
+; CHECK-NEXT: [[R:%.*]] = fptosi float [[X]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%t = call float @llvm.trunc.f32(float %x)
>From 23f13314e9a5bd02afc74358a56fb83a9decb2c0 Mon Sep 17 00:00:00 2001
From: Harrison Hao <tsworld1314 at gmail.com>
Date: Tue, 13 Oct 2026 17:00:37 +0800
Subject: [PATCH 2/2] Update for comments
---
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 2 +-
llvm/test/Transforms/InstCombine/fpcast.ll | 6 ++----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 9c0c9cbc82f63..775ff358f00bb 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -2593,7 +2593,7 @@ static Instruction *foldFPtoI(Instruction &FI, InstCombiner &IC) {
return IC.replaceInstUsesWith(FI, ConstantInt::getNullValue(FI.getType()));
// fpto{u/s}i (trunc X) --> fpto{u/s}i X
- Value *Src = nullptr;
+ Value *Src;
if (match(FI.getOperand(0), m_Intrinsic<Intrinsic::trunc>(m_Value(Src))))
return IC.replaceOperand(FI, 0, Src);
diff --git a/llvm/test/Transforms/InstCombine/fpcast.ll b/llvm/test/Transforms/InstCombine/fpcast.ll
index 4e6eb207e97d1..b47bc1c5f648c 100644
--- a/llvm/test/Transforms/InstCombine/fpcast.ll
+++ b/llvm/test/Transforms/InstCombine/fpcast.ll
@@ -864,8 +864,7 @@ define i32 @fptosi_trunc_multi_use(float %x) {
define i32 @fptoui_trunc_fmf(float %x) {
; CHECK-LABEL: @fptoui_trunc_fmf(
-; CHECK-NEXT: [[T:%.*]] = call nnan ninf nsz float @llvm.trunc.f32(float [[X:%.*]])
-; CHECK-NEXT: [[R:%.*]] = fptoui float [[T]] to i32
+; CHECK-NEXT: [[R:%.*]] = fptoui float [[T:%.*]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%t = call nnan ninf nsz float @llvm.trunc.f32(float %x)
@@ -875,8 +874,7 @@ define i32 @fptoui_trunc_fmf(float %x) {
define i32 @fptosi_trunc_fmf(float %x) {
; CHECK-LABEL: @fptosi_trunc_fmf(
-; CHECK-NEXT: [[T:%.*]] = call nnan ninf nsz float @llvm.trunc.f32(float [[X:%.*]])
-; CHECK-NEXT: [[R:%.*]] = fptosi float [[T]] to i32
+; CHECK-NEXT: [[R:%.*]] = fptosi float [[T:%.*]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%t = call nnan ninf nsz float @llvm.trunc.f32(float %x)
More information about the llvm-branch-commits
mailing list