[llvm] Inliner: Handle nofpclass return attributes (PR #179776)

via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 4 12:48:48 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

Follow along with how range is handled.

---
Full diff: https://github.com/llvm/llvm-project/pull/179776.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Utils/InlineFunction.cpp (+10) 
- (added) llvm/test/Transforms/Inline/ret_attr_nofpclass.ll (+59) 


``````````diff
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index aa902f687d8aa..3230b306f17d1 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1543,6 +1543,8 @@ static AttrBuilder IdentifyValidPoisonGeneratingAttributes(CallBase &CB) {
     Valid.addAlignmentAttr(CB.getRetAlign());
   if (std::optional<ConstantRange> Range = CB.getRange())
     Valid.addRangeAttr(*Range);
+  if (CB.hasRetAttr(Attribute::NoFPClass))
+    Valid.addNoFPClassAttr(CB.getRetNoFPClass());
   return Valid;
 }
 
@@ -1648,6 +1650,14 @@ static void AddReturnAttributes(CallBase &CB, ValueToValueMapTy &VMap,
               CBRange.getRange().intersectWith(NewRange.getRange()));
         }
       }
+
+      Attribute CBNoFPClass = ValidPG.getAttribute(Attribute::NoFPClass);
+      if (CBNoFPClass.isValid() && AL.hasRetAttr(Attribute::NoFPClass)) {
+        ValidPG.addNoFPClassAttr(
+            CBNoFPClass.getNoFPClass() |
+            AL.getRetAttr(Attribute::NoFPClass).getNoFPClass());
+      }
+
       // Three checks.
       // If the callsite has `noundef`, then a poison due to violating the
       // return attribute will create UB anyways so we can always propagate.
diff --git a/llvm/test/Transforms/Inline/ret_attr_nofpclass.ll b/llvm/test/Transforms/Inline/ret_attr_nofpclass.ll
new file mode 100644
index 0000000000000..08364f98f6a71
--- /dev/null
+++ b/llvm/test/Transforms/Inline/ret_attr_nofpclass.ll
@@ -0,0 +1,59 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=inline %s | FileCheck %s
+; RUN: opt -S -passes='cgscc(inline)' %s | FileCheck %s
+; RUN: opt -S -passes='module-inline' %s | FileCheck %s
+
+declare float @val_f32()
+declare float @use.val(float) willreturn nounwind
+
+define float @callee() {
+; CHECK-LABEL: define float @callee() {
+; CHECK-NEXT:    [[R:%.*]] = call float @val_f32()
+; CHECK-NEXT:    ret float [[R]]
+;
+  %r = call float @val_f32()
+  ret float %r
+}
+
+define float @caller_okay_use_after_poison_anyways() {
+; CHECK-LABEL: define float @caller_okay_use_after_poison_anyways() {
+; CHECK-NEXT:    [[R_I:%.*]] = call nofpclass(nan) float @val_f32()
+; CHECK-NEXT:    call void @use.val(float [[R_I]])
+; CHECK-NEXT:    ret float [[R_I]]
+;
+  %r = call nofpclass(nan) float @callee()
+  call void @use.val(float %r)
+  ret float %r
+}
+
+define float @callee_nofpclass_inf_nan() {
+; CHECK-LABEL: define float @callee_nofpclass_inf_nan() {
+; CHECK-NEXT:    [[R:%.*]] = call nofpclass(nan inf) float @val_f32()
+; CHECK-NEXT:    ret float [[R]]
+;
+  %r = call nofpclass(nan inf) float @val_f32()
+  ret float %r
+}
+
+define float @caller_okay_intersect_nofpclass() {
+; CHECK-LABEL: define float @caller_okay_intersect_nofpclass() {
+; CHECK-NEXT:    [[R_I:%.*]] = call nofpclass(nan) float @val_f32()
+; CHECK-NEXT:    call void @use.val(float [[R_I]])
+; CHECK-NEXT:    ret float [[R_I]]
+;
+  %r = call nofpclass(nan) float @callee_nofpclass_inf_nan()
+  call void @use.val(float %r)
+  ret float %r
+}
+
+define float @caller_not_intersecting_nofpclass() {
+; CHECK-LABEL: define float @caller_not_intersecting_nofpclass() {
+; CHECK-NEXT:    [[R_I:%.*]] = call nofpclass(zero) float @val_f32()
+; CHECK-NEXT:    call void @use.val(float [[R_I]])
+; CHECK-NEXT:    ret float [[R_I]]
+;
+  %r = call nofpclass(zero) float @callee_nofpclass_inf_nan()
+  call void @use.val(float %r)
+  ret float %r
+}
+

``````````

</details>


https://github.com/llvm/llvm-project/pull/179776


More information about the llvm-commits mailing list