[llvm] [DAG] canCreateUndefOrPoison - ISD::FCEIL/FFLOOR/FTRUNC/FRINT/FNEARBYINT/FROUND/FROUNDEVEN can never create poison/undef (PR #196543)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Fri May 8 09:03:18 PDT 2026


https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/196543

>From 994d48e0ae215044cef6ac3d0cbfdfd2e80ea0af Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Fri, 8 May 2026 15:11:39 +0100
Subject: [PATCH 1/2] [DAG] canCreateUndefOrPoison -
 ISD::FCEIL/FFLOOR/FTRUNC/FRINT/FNEARBYINT/FROUND/FROUNDEVEN can never create
 poison/undef

---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  7 +++
 llvm/test/CodeGen/X86/freeze-unary.ll         | 63 +++++--------------
 2 files changed, 22 insertions(+), 48 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 15fc74b6cc7c9..0b7d8b7946f99 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5900,6 +5900,13 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::BUILD_PAIR:
   case ISD::SPLAT_VECTOR:
   case ISD::FABS:
+  case ISD::FCEIL:
+  case ISD::FFLOOR:
+  case ISD::FTRUNC:
+  case ISD::FRINT:
+  case ISD::FNEARBYINT:
+  case ISD::FROUND:
+  case ISD::FROUNDEVEN:
     return false;
 
   case ISD::ABS:
diff --git a/llvm/test/CodeGen/X86/freeze-unary.ll b/llvm/test/CodeGen/X86/freeze-unary.ll
index a2c8be0d91e4a..e29db28415318 100644
--- a/llvm/test/CodeGen/X86/freeze-unary.ll
+++ b/llvm/test/CodeGen/X86/freeze-unary.ll
@@ -465,21 +465,16 @@ define <16 x i8> @freeze_parity_vec(<16 x i8> %a0) nounwind {
 define float @ftrunc_freeze_fnearbyint(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_fnearbyint:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    pushl %eax
 ; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-NEXT:    movss %xmm0, (%esp)
 ; X86-NEXT:    calll nearbyintf
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
-; X86-NEXT:    calll truncf
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: ftrunc_freeze_fnearbyint:
 ; X64:       # %bb.0:
 ; X64-NEXT:    roundss $12, %xmm0, %xmm0
-; X64-NEXT:    roundss $11, %xmm0, %xmm0
 ; X64-NEXT:    retq
   %f0 = call float @llvm.nearbyint.f32(float %a0)
   %fr = freeze float %f0
@@ -490,15 +485,13 @@ define float @ftrunc_freeze_fnearbyint(float %a0) nounwind {
 define float @ftrunc_freeze_fround(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_fround:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    pushl %eax
 ; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-NEXT:    movss %xmm0, (%esp)
 ; X86-NEXT:    calll roundf
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
+; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll truncf
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: ftrunc_freeze_fround:
@@ -509,7 +502,6 @@ define float @ftrunc_freeze_fround(float %a0) nounwind {
 ; X64-NEXT:    addss %xmm0, %xmm1
 ; X64-NEXT:    xorps %xmm0, %xmm0
 ; X64-NEXT:    roundss $11, %xmm1, %xmm0
-; X64-NEXT:    roundss $11, %xmm0, %xmm0
 ; X64-NEXT:    retq
   %f0 = call float @llvm.round.f32(float %a0)
   %fr = freeze float %f0
@@ -520,21 +512,16 @@ define float @ftrunc_freeze_fround(float %a0) nounwind {
 define float @ftrunc_freeze_froundeven(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_froundeven:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    pushl %eax
 ; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-NEXT:    movss %xmm0, (%esp)
 ; X86-NEXT:    calll roundevenf
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
-; X86-NEXT:    calll truncf
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: ftrunc_freeze_froundeven:
 ; X64:       # %bb.0:
 ; X64-NEXT:    roundss $8, %xmm0, %xmm0
-; X64-NEXT:    roundss $11, %xmm0, %xmm0
 ; X64-NEXT:    retq
   %f0 = call float @llvm.roundeven.f32(float %a0)
   %fr = freeze float %f0
@@ -545,21 +532,16 @@ define float @ftrunc_freeze_froundeven(float %a0) nounwind {
 define float @ftrunc_freeze_frint(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_frint:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    pushl %eax
 ; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-NEXT:    movss %xmm0, (%esp)
 ; X86-NEXT:    calll rintf
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
-; X86-NEXT:    calll truncf
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: ftrunc_freeze_frint:
 ; X64:       # %bb.0:
 ; X64-NEXT:    roundss $4, %xmm0, %xmm0
-; X64-NEXT:    roundss $11, %xmm0, %xmm0
 ; X64-NEXT:    retq
   %f0 = call float @llvm.rint.f32(float %a0)
   %fr = freeze float %f0
@@ -570,21 +552,16 @@ define float @ftrunc_freeze_frint(float %a0) nounwind {
 define float @ftrunc_freeze_ftrunc(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_ftrunc:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
-; X86-NEXT:    calll truncf
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl %eax
 ; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-NEXT:    movss %xmm0, (%esp)
 ; X86-NEXT:    calll truncf
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: ftrunc_freeze_ftrunc:
 ; X64:       # %bb.0:
 ; X64-NEXT:    roundss $11, %xmm0, %xmm0
-; X64-NEXT:    roundss $11, %xmm0, %xmm0
 ; X64-NEXT:    retq
   %f0 = call float @llvm.trunc.f32(float %a0)
   %fr = freeze float %f0
@@ -595,21 +572,16 @@ define float @ftrunc_freeze_ftrunc(float %a0) nounwind {
 define float @ftrunc_freeze_ffloor(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_ffloor:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    pushl %eax
 ; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-NEXT:    movss %xmm0, (%esp)
 ; X86-NEXT:    calll floorf
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
-; X86-NEXT:    calll truncf
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: ftrunc_freeze_ffloor:
 ; X64:       # %bb.0:
 ; X64-NEXT:    roundss $9, %xmm0, %xmm0
-; X64-NEXT:    roundss $11, %xmm0, %xmm0
 ; X64-NEXT:    retq
   %f0 = call float @llvm.floor.f32(float %a0)
   %fr = freeze float %f0
@@ -620,21 +592,16 @@ define float @ftrunc_freeze_ffloor(float %a0) nounwind {
 define float @ftrunc_freeze_fceil(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_fceil:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    pushl %eax
 ; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-NEXT:    movss %xmm0, (%esp)
 ; X86-NEXT:    calll ceilf
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
-; X86-NEXT:    calll truncf
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: ftrunc_freeze_fceil:
 ; X64:       # %bb.0:
 ; X64-NEXT:    roundss $10, %xmm0, %xmm0
-; X64-NEXT:    roundss $11, %xmm0, %xmm0
 ; X64-NEXT:    retq
   %f0 = call float @llvm.ceil.f32(float %a0)
   %fr = freeze float %f0

>From b9802fd8b1b9fda561855eb978bbdde5c7d285e2 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Fri, 8 May 2026 15:17:17 +0100
Subject: [PATCH 2/2] Add missing fold support for ftrunc(fround(x)) ->
 fround(x)

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 1 +
 llvm/test/CodeGen/X86/freeze-unary.ll         | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 15577af91ff03..5a467a5a5ba53 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -20316,6 +20316,7 @@ SDValue DAGCombiner::visitFTRUNC(SDNode *N) {
   case ISD::FRINT:
   case ISD::FTRUNC:
   case ISD::FNEARBYINT:
+  case ISD::FROUND:
   case ISD::FROUNDEVEN:
   case ISD::FFLOOR:
   case ISD::FCEIL:
diff --git a/llvm/test/CodeGen/X86/freeze-unary.ll b/llvm/test/CodeGen/X86/freeze-unary.ll
index e29db28415318..03b003f52ffd6 100644
--- a/llvm/test/CodeGen/X86/freeze-unary.ll
+++ b/llvm/test/CodeGen/X86/freeze-unary.ll
@@ -489,8 +489,6 @@ define float @ftrunc_freeze_fround(float %a0) nounwind {
 ; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-NEXT:    movss %xmm0, (%esp)
 ; X86-NEXT:    calll roundf
-; X86-NEXT:    fstps (%esp)
-; X86-NEXT:    calll truncf
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;



More information about the llvm-commits mailing list