[llvm] [FunctionAttrs] Don't infer noundef when return has nofpclass (PR #191822)
Shonie Caplan via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 03:27:22 PDT 2026
https://github.com/shoniecaplan updated https://github.com/llvm/llvm-project/pull/191822
>From 59656aa3fe3afc349dbb27cdc4f3991f2b9d83e5 Mon Sep 17 00:00:00 2001
From: Shonie Caplan <shonie at genki.com>
Date: Mon, 13 Apr 2026 22:58:19 +0900
Subject: [PATCH 1/3] [FunctionAttrs] Don't infer noundef when return has
nofpclass
- Fixes: #191338
nofpclass violations on a return produce poison.
Poison returns marked noundef are UB.
This turns off noundef inference when nofpclass attributes are present.
---
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 4 ++++
llvm/test/Transforms/FunctionAttrs/noundef.ll | 8 ++++++++
2 files changed, 12 insertions(+)
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index c5e20c766ad52..e25bf70a6259d 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -1742,6 +1742,10 @@ static void addNoUndefAttrs(const SCCNodeSet &SCCNodes,
!Attr.getRange().contains(
computeConstantRange(RetVal, /*ForSigned=*/false)))
return false;
+
+ Attribute NoFP = Attrs.getRetAttr(Attribute::NoFPClass);
+ if (NoFP.hasAttribute(Attribute::NoFPClass))
+ return false;
}
return true;
})) {
diff --git a/llvm/test/Transforms/FunctionAttrs/noundef.ll b/llvm/test/Transforms/FunctionAttrs/noundef.ll
index 4f53c08804621..4b1224fd318f4 100644
--- a/llvm/test/Transforms/FunctionAttrs/noundef.ll
+++ b/llvm/test/Transforms/FunctionAttrs/noundef.ll
@@ -214,3 +214,11 @@ define range(i8 0, 10) i8 @definitely_in_range(i8 noundef range(i8 0, 10) %v) {
;
ret i8 %v
}
+
+define nofpclass(nan) float @test_ret_nofpclass(float noundef %x) {
+; CHECK-LABEL: define nofpclass(nan) float @test_ret_nofpclass(
+; CHECK-SAME: float noundef returned [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: ret float [[X]]
+;
+ ret float %x
+}
>From 616a038b9fcd5b7b2e0366d835411bf032cd468b Mon Sep 17 00:00:00 2001
From: Shonie Caplan <shonie4caplan at gmail.com>
Date: Tue, 14 Apr 2026 15:25:05 +0900
Subject: [PATCH 2/3] [FunctionAttrs] Squash - Check nofpclass against computed
---
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 6 +++--
llvm/test/Transforms/FunctionAttrs/noundef.ll | 22 +++++++++++++++++--
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index e25bf70a6259d..7dc1ee46775c5 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -57,6 +57,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/KnownFPClass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -1743,8 +1744,9 @@ static void addNoUndefAttrs(const SCCNodeSet &SCCNodes,
computeConstantRange(RetVal, /*ForSigned=*/false)))
return false;
- Attribute NoFP = Attrs.getRetAttr(Attribute::NoFPClass);
- if (NoFP.hasAttribute(Attribute::NoFPClass))
+ FPClassTest AttrFPClass = Attrs.getRetNoFPClass();
+ KnownFPClass ComputedFPClass = computeKnownFPClass(RetVal, DL);
+ if (!ComputedFPClass.isKnownNever(AttrFPClass))
return false;
}
return true;
diff --git a/llvm/test/Transforms/FunctionAttrs/noundef.ll b/llvm/test/Transforms/FunctionAttrs/noundef.ll
index 4b1224fd318f4..75e5655f2a93e 100644
--- a/llvm/test/Transforms/FunctionAttrs/noundef.ll
+++ b/llvm/test/Transforms/FunctionAttrs/noundef.ll
@@ -215,10 +215,28 @@ define range(i8 0, 10) i8 @definitely_in_range(i8 noundef range(i8 0, 10) %v) {
ret i8 %v
}
-define nofpclass(nan) float @test_ret_nofpclass(float noundef %x) {
-; CHECK-LABEL: define nofpclass(nan) float @test_ret_nofpclass(
+define nofpclass(nan) float @maybe_nofpclass(float noundef %x) {
+; CHECK-LABEL: define nofpclass(nan) float @maybe_nofpclass(
; CHECK-SAME: float noundef returned [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret float [[X]]
;
ret float %x
}
+
+define nofpclass(nan) float @compute_not_nofpclass(float noundef nofpclass(nan) %x) {
+; CHECK-LABEL: define nofpclass(nan) float @compute_not_nofpclass(
+; CHECK-SAME: float noundef nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[Y:%.*]] = fmul float [[X]], 0x7FF8000000000000
+; CHECK-NEXT: ret float [[Y]]
+;
+ %y = fmul float %x, 0x7FF8000000000000
+ ret float %y
+}
+
+define nofpclass(nan) float @definitely_nofpclass(float noundef nofpclass(nan) %x) {
+; CHECK-LABEL: define noundef nofpclass(nan) float @definitely_nofpclass(
+; CHECK-SAME: float noundef returned nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: ret float [[X]]
+;
+ ret float %x
+}
>From 5abf6636be66e17a2f69a51ce5848988f6ec4d40 Mon Sep 17 00:00:00 2001
From: Shonie Caplan <94767648+shoniecaplan at users.noreply.github.com>
Date: Thu, 16 Apr 2026 19:27:12 +0900
Subject: [PATCH 3/3] Update llvm/lib/Transforms/IPO/FunctionAttrs.cpp
Co-authored-by: Yingwei Zheng <dtcxzyw at qq.com>
---
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 7dc1ee46775c5..0bbe2d6298811 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -1745,9 +1745,11 @@ static void addNoUndefAttrs(const SCCNodeSet &SCCNodes,
return false;
FPClassTest AttrFPClass = Attrs.getRetNoFPClass();
- KnownFPClass ComputedFPClass = computeKnownFPClass(RetVal, DL);
- if (!ComputedFPClass.isKnownNever(AttrFPClass))
- return false;
+ if (AttrFPClass != fcNone) {
+ KnownFPClass ComputedFPClass = computeKnownFPClass(RetVal, DL);
+ if (!ComputedFPClass.isKnownNever(AttrFPClass))
+ return false;
+ }
}
return true;
})) {
More information about the llvm-commits
mailing list