[llvm] [IR] Make semantics of strictfp consistent (PR #209465)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 05:53:45 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
Although the section on constrainedfp in the LangRef clearly states "All function definitions that use constrained floating point intrinsics must have the strictfp attribute", indicating that strictfp propagates from callee to caller, the general description of strictfp does not specify this. Refine its semantics and make it so, eliminating the inconsistency.
---
Patch is 25.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/209465.diff
8 Files Affected:
- (modified) llvm/docs/LangRef.md (+3-4)
- (modified) llvm/include/llvm/IR/Function.h (+3)
- (modified) llvm/lib/IR/Verifier.cpp (+5)
- (modified) llvm/test/Transforms/EarlyCSE/replace-calls-def-attrs.ll (+35-32)
- (modified) llvm/test/Transforms/InstCombine/erf.ll (+22-18)
- (modified) llvm/test/Transforms/InstCombine/fdim.ll (+4-3)
- (modified) llvm/test/Transforms/InstSimplify/disable_folding.ll (+8-6)
- (modified) llvm/test/Transforms/SimplifyCFG/X86/merge-compatible-invokes-of-landingpad.ll (+16-14)
``````````diff
diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index f7e3ca8db80e1..0c913a254854c 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -2794,7 +2794,9 @@ fn -> other_fn -> other_fn ; fn is norecurse
optimizations that require assumptions about the floating-point rounding
mode or that might alter the state of floating-point status flags that
might otherwise be set or cleared by calling this function. LLVM will
- not introduce any new floating-point instructions that may trap.
+ not introduce any new floating-point instructions that may trap. The
+ attribute propagates from callee to caller, and all function definitions
+ that contain strictfp calls must be marked strictfp.
(denormal_fpenv)=
@@ -26572,9 +26574,6 @@ point intrinsics must have the `strictfp` attribute either on the
calling instruction or on the declaration or definition of the function
being called.
-All function *definitions* that use constrained floating point intrinsics
-must have the `strictfp` attribute.
-
#### '`llvm.experimental.constrained.fadd`' Intrinsic
##### Syntax:
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index bd28f0d9902da..0238c9b352f5f 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -632,6 +632,9 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
addFnAttr(Attribute::NoRecurse);
}
+ /// Determine if the function has strict floating point sematics.
+ bool isStrictFP() const { return hasFnAttribute(Attribute::StrictFP); }
+
/// Determine if the function is required to make forward progress.
bool mustProgress() const {
return hasFnAttribute(Attribute::MustProgress) ||
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index fa0fe7a2e6092..2b4f0048cae4f 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3889,6 +3889,11 @@ void Verifier::visitCallBase(CallBase &Call) {
Check(!Attrs.hasFnAttr(Attribute::DenormalFPEnv),
"denormal_fpenv attribute may not apply to call sites", Call);
+ Check(!Attrs.hasFnAttr(Attribute::StrictFP) ||
+ Call.getFunction()->isStrictFP(),
+ "strictfp attribute must propagate from the call site to the caller",
+ Call);
+
// Verify call attributes.
verifyFunctionAttrs(FTy, Attrs, &Call, IsIntrinsic, Call.isInlineAsm());
diff --git a/llvm/test/Transforms/EarlyCSE/replace-calls-def-attrs.ll b/llvm/test/Transforms/EarlyCSE/replace-calls-def-attrs.ll
index 1dbffd962a638..b8854e3061dbf 100644
--- a/llvm/test/Transforms/EarlyCSE/replace-calls-def-attrs.ll
+++ b/llvm/test/Transforms/EarlyCSE/replace-calls-def-attrs.ll
@@ -13,7 +13,7 @@ declare i8 @buz.fp(float, float)
define i8 @same_parent_combine_diff_attrs(i8 %x, i8 %y) {
; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs(
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2:[0-9]+]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C1]], i8 [[C1]])
; CHECK-NEXT: ret i8 [[R]]
;
@@ -27,7 +27,7 @@ define i8 @same_parent_combine_diff_attrs(i8 %x, i8 %y) {
define i8 @same_parent_combine_diff_attrs_needs_intersect(i8 %x, i8 %y) {
; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_needs_intersect(
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]]
+; CHECK-NEXT: [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr [[C1]])
; CHECK-NEXT: ret i8 [[R]]
;
@@ -41,7 +41,7 @@ define i8 @same_parent_combine_diff_attrs_needs_intersect(i8 %x, i8 %y) {
define i8 @same_parent_combine_diff_attrs_fmf(float %x, float %y) {
; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fmf(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call nnan float @baz.fp(float [[X]], float noundef [[Y]]) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: [[C1:%.*]] = call nnan float @baz.fp(float [[X]], float noundef [[Y]]) #[[ATTR3:[0-9]+]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz.fp(float [[C1]], float [[C1]])
; CHECK-NEXT: ret i8 [[R]]
;
@@ -55,7 +55,7 @@ define i8 @same_parent_combine_diff_attrs_fmf(float %x, float %y) {
define i8 @same_parent_combine_diff_attrs_fmf2(float %x, float %y) {
; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fmf2(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call nnan float @baz.fp(float [[X]], float noundef [[Y]]) #[[ATTR1]]
+; CHECK-NEXT: [[C1:%.*]] = call nnan float @baz.fp(float [[X]], float noundef [[Y]]) #[[ATTR2]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz.fp(float [[C1]], float [[C1]])
; CHECK-NEXT: ret i8 [[R]]
;
@@ -69,7 +69,7 @@ define i8 @same_parent_combine_diff_attrs_fmf2(float %x, float %y) {
define i8 @same_parent_combine_diff_attrs_needs_intersect2(i8 %x, i8 %y) {
; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_needs_intersect2(
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2]]
+; CHECK-NEXT: [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR3]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr [[C1]])
; CHECK-NEXT: ret i8 [[R]]
;
@@ -83,7 +83,7 @@ define i8 @same_parent_combine_diff_attrs_needs_intersect2(i8 %x, i8 %y) {
define i8 @same_parent_combine_diff_attrs_really_needs_intersect(i8 %x, i8 %y) {
; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_really_needs_intersect(
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2]]
+; CHECK-NEXT: [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR3]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr noundef [[C1]])
; CHECK-NEXT: ret i8 [[R]]
;
@@ -112,7 +112,7 @@ define i8 @same_parent_combine_diff_attrs_fail_side_effects(i8 %x, i8 %y) {
define i8 @same_parent_combine_diff_attrs_quasi_side_effects2(i8 %x, i8 %y) {
; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_quasi_side_effects2(
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR1]]
+; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR2]]
; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]])
; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
; CHECK-NEXT: ret i8 [[R]]
@@ -127,10 +127,10 @@ define i8 @same_parent_combine_diff_attrs_quasi_side_effects2(i8 %x, i8 %y) {
define i8 @diff_parent_combine_diff_attrs(i1 %c, i8 %x, i8 %y) {
; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs(
; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]]
+; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2]]
; CHECK-NEXT: br i1 [[C]], label %[[T:.*]], label %[[F:.*]]
; CHECK: [[T]]:
-; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR2]]
+; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR3]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
; CHECK-NEXT: ret i8 [[R]]
; CHECK: [[F]]:
@@ -151,7 +151,7 @@ F:
define i8 @diff_parent_combine_diff_attrs_preserves_return_attrs(i1 %c, i8 %x, i8 %y) {
; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs_preserves_return_attrs(
; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call nonnull ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2]]
+; CHECK-NEXT: [[C1:%.*]] = call nonnull ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR3]]
; CHECK-NEXT: br i1 [[C]], label %[[T:.*]], label %[[F:.*]]
; CHECK: [[T]]:
; CHECK-NEXT: [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr noundef [[C1]])
@@ -172,8 +172,8 @@ F:
define i8 @same_parent_combine_diff_attrs_todo(i8 %x, i8 %y) {
; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_todo(
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]]
-; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR3:[0-9]+]]
+; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2]]
+; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR4:[0-9]+]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
; CHECK-NEXT: ret i8 [[R]]
;
@@ -184,11 +184,12 @@ define i8 @same_parent_combine_diff_attrs_todo(i8 %x, i8 %y) {
}
-define i8 @same_parent_combine_diff_attrs_fail(i8 %x, i8 %y) {
+define i8 @same_parent_combine_diff_attrs_fail(i8 %x, i8 %y) strictfp {
+; CHECK: Function Attrs: strictfp
; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fail(
-; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]]
-; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR4:[0-9]+]]
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2]]
+; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR5:[0-9]+]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
; CHECK-NEXT: ret i8 [[R]]
;
@@ -202,10 +203,10 @@ define i8 @same_parent_combine_diff_attrs_fail(i8 %x, i8 %y) {
define i8 @diff_parent_combine_diff_attrs_todo(i1 %c, i8 %x, i8 %y) {
; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs_todo(
; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]]
+; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2]]
; CHECK-NEXT: br i1 [[C]], label %[[T:.*]], label %[[F:.*]]
; CHECK: [[T]]:
-; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR5:[0-9]+]]
+; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR6:[0-9]+]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
; CHECK-NEXT: ret i8 [[R]]
; CHECK: [[F]]:
@@ -223,13 +224,14 @@ F:
ret i8 %r2
}
-define i8 @diff_parent_combine_diff_attrs_fail(i1 %c, i8 %x, i8 %y) {
+define i8 @diff_parent_combine_diff_attrs_fail(i1 %c, i8 %x, i8 %y) strictfp {
+; CHECK: Function Attrs: strictfp
; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs_fail(
-; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]]
+; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR2]]
; CHECK-NEXT: br i1 [[C]], label %[[T:.*]], label %[[F:.*]]
; CHECK: [[T]]:
-; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR4]]
+; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR5]]
; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
; CHECK-NEXT: ret i8 [[R]]
; CHECK: [[F]]:
@@ -247,10 +249,11 @@ F:
ret i8 %r2
}
-define i32 @commutative_intrinsic_intersection_failure(i32 %arg, i32 %arg1) {
+define i32 @commutative_intrinsic_intersection_failure(i32 %arg, i32 %arg1) strictfp {
+; CHECK: Function Attrs: strictfp
; CHECK-LABEL: define i32 @commutative_intrinsic_intersection_failure(
-; CHECK-SAME: i32 [[ARG:%.*]], i32 [[ARG1:%.*]]) {
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @llvm.smin.i32(i32 [[ARG]], i32 [[ARG1]]) #[[ATTR6:[0-9]+]]
+; CHECK-SAME: i32 [[ARG:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @llvm.smin.i32(i32 [[ARG]], i32 [[ARG1]]) #[[ATTR0]]
; CHECK-NEXT: [[CALL2:%.*]] = call i32 @llvm.smin.i32(i32 [[ARG1]], i32 [[ARG]])
; CHECK-NEXT: [[OR:%.*]] = or i32 [[CALL2]], [[CALL]]
; CHECK-NEXT: ret i32 [[OR]]
@@ -262,11 +265,11 @@ define i32 @commutative_intrinsic_intersection_failure(i32 %arg, i32 %arg1) {
}
;.
-; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
-; CHECK: attributes #[[ATTR1]] = { memory(none) }
-; CHECK: attributes #[[ATTR2]] = { memory(read) }
-; CHECK: attributes #[[ATTR3]] = { alwaysinline memory(none) }
-; CHECK: attributes #[[ATTR4]] = { strictfp memory(none) }
-; CHECK: attributes #[[ATTR5]] = { noinline optnone memory(none) }
-; CHECK: attributes #[[ATTR6]] = { strictfp }
+; CHECK: attributes #[[ATTR0]] = { strictfp }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+; CHECK: attributes #[[ATTR2]] = { memory(none) }
+; CHECK: attributes #[[ATTR3]] = { memory(read) }
+; CHECK: attributes #[[ATTR4]] = { alwaysinline memory(none) }
+; CHECK: attributes #[[ATTR5]] = { strictfp memory(none) }
+; CHECK: attributes #[[ATTR6]] = { noinline optnone memory(none) }
;.
diff --git a/llvm/test/Transforms/InstCombine/erf.ll b/llvm/test/Transforms/InstCombine/erf.ll
index 9f83acabb6fb7..57015fb490a7e 100644
--- a/llvm/test/Transforms/InstCombine/erf.ll
+++ b/llvm/test/Transforms/InstCombine/erf.ll
@@ -75,7 +75,7 @@ define double @erf_inf() {
define float @erff_inf_memory_none() {
; CHECK-LABEL: define float @erff_inf_memory_none() {
-; CHECK-NEXT: [[R:%.*]] = call float @erff(float +inf) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: [[R:%.*]] = call float @erff(float +inf) #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret float [[R]]
;
%r = call float @erff(float 0x7FF0000000000000) readnone
@@ -84,7 +84,7 @@ define float @erff_inf_memory_none() {
define double @erf_inf_memory_none() {
; CHECK-LABEL: define double @erf_inf_memory_none() {
-; CHECK-NEXT: [[R:%.*]] = call double @erf(double +inf) #[[ATTR1]]
+; CHECK-NEXT: [[R:%.*]] = call double @erf(double +inf) #[[ATTR2]]
; CHECK-NEXT: ret double [[R]]
;
%r = call double @erf(double 0x7FF0000000000000) readnone
@@ -111,7 +111,7 @@ define double @erf_neg_inf() {
define float @erff_neg_inf_memory_none() {
; CHECK-LABEL: define float @erff_neg_inf_memory_none() {
-; CHECK-NEXT: [[R:%.*]] = call float @erff(float -inf) #[[ATTR1]]
+; CHECK-NEXT: [[R:%.*]] = call float @erff(float -inf) #[[ATTR2]]
; CHECK-NEXT: ret float [[R]]
;
%r = call float @erff(float 0xFFF0000000000000) readnone
@@ -120,7 +120,7 @@ define float @erff_neg_inf_memory_none() {
define double @erf_neg_inf_memory_none() {
; CHECK-LABEL: define double @erf_neg_inf_memory_none() {
-; CHECK-NEXT: [[R:%.*]] = call double @erf(double -inf) #[[ATTR1]]
+; CHECK-NEXT: [[R:%.*]] = call double @erf(double -inf) #[[ATTR2]]
; CHECK-NEXT: ret double [[R]]
;
%r = call double @erf(double 0xFFF0000000000000) readnone
@@ -147,7 +147,7 @@ define double @erf_nan() {
define float @erff_nan_memory_none() {
; CHECK-LABEL: define float @erff_nan_memory_none() {
-; CHECK-NEXT: [[R:%.*]] = call float @erff(float +qnan) #[[ATTR1]]
+; CHECK-NEXT: [[R:%.*]] = call float @erff(float +qnan) #[[ATTR2]]
; CHECK-NEXT: ret float [[R]]
;
%r = call float @erff(float 0x7FF8000000000000) readnone
@@ -156,7 +156,7 @@ define float @erff_nan_memory_none() {
define double @erf_nan_memory_none() {
; CHECK-LABEL: define double @erf_nan_memory_none() {
-; CHECK-NEXT: [[R:%.*]] = call double @erf(double +qnan) #[[ATTR1]]
+; CHECK-NEXT: [[R:%.*]] = call double @erf(double +qnan) #[[ATTR2]]
; CHECK-NEXT: ret double [[R]]
;
%r = call double @erf(double 0x7FF8000000000000) readnone
@@ -181,36 +181,40 @@ define double @erf_poison() {
ret double %r
}
-define float @erff_const_strictfp() {
-; CHECK-LABEL: define float @erff_const_strictfp() {
-; CHECK-NEXT: [[R:%.*]] = call float @erff(float 5.000000e-01) #[[ATTR2:[0-9]+]]
+define float @erff_const_strictfp() strictfp {
+; CHECK-LABEL: define float @erff_const_strictfp(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[R:%.*]] = call float @erff(float 5.000000e-01) #[[ATTR0]]
; CHECK-NEXT: ret float [[R]]
;
%r = call float @erff(float 5.000000e-01) strictfp
ret float %r
}
-define double @erf_const_strictfp() {
-; CHECK-LABEL: define double @erf_const_strictfp() {
-; CHECK-NEXT: [[R:%.*]] = call double @erf(double -5.000000e-01) #[[ATTR2]]
+define double @erf_const_strictfp() strictfp {
+; CHECK-LABEL: define double @erf_const_strictfp(
+; CHECK-SAME: ) #[[ATTR0]] {
+; CHECK-NEXT: [[R:%.*]] = call double @erf(double -5.000000e-01) #[[ATTR0]]
; CHECK-NEXT: ret double [[R]]
;
%r = call double @erf(double -5.000000e-01) strictfp
ret double %r
}
-define float @erff_nan_strictfp() {
-; CHECK-LABEL: define float @erff_nan_strictfp() {
-; CHECK-NEXT: [[R:%.*]] = call float @erff(float +qnan) #[[ATTR2]]
+define float @erff_nan_strictfp() strictfp {
+; CHECK-LABEL: define float @erff_nan_strictfp(
+; CHECK-SAME: ) #[[ATTR0]] {
+; CHECK-NEXT: [[R:%.*]] = call float @erff(float +qnan) #[[ATTR0]]
; CHECK-NEXT: ret float [[R]]
;
%r = call float @erff(float 0x7FF8000000000000) strictfp
ret float %r
}
-define double @erf_nan_strictfp() {
-; CHECK-LABEL: define double @erf_nan_strictfp() {
-; CHECK-NEXT: [[R:%.*]] = call double @erf(double +qnan) #[[ATTR2]]
+define double @erf_nan_strictfp() strictfp {
+; CHECK-LABEL: define double @erf_nan_strictfp(
+; CHECK-SAME: ) #[[ATTR0]] {
+; CHECK-NEXT: [[R:%.*]] = call double @erf(double +qnan) #[[ATTR0]]
; CHECK-NEXT: ret double [[R]]
;
%r = call double @erf(double 0x7FF8000000000000) strictfp
diff --git a/llvm/test/Transforms/InstCombine/fdim.ll b/llvm/test/Transforms/InstCombine/fdim.ll
index edbdaedc975c0..f167a842642db 100644
--- a/llvm/test/Transforms/InstCombine/fdim.ll
+++ b/llvm/test/Transforms/InstCombine/fdim.ll
@@ -99,9 +99,10 @@ define double @fdim_nzero() {
ret double %dim
}
-define double @fdim_strictfp() {
-; CHECK-LABEL: define double @fdim_strictfp() {
-; CHECK-NEXT: [[DIM:%.*]] = call double @fdim(double 1.000000e+01, double 8.000000e+00) #[[ATTR1:[0-9]+]]
+define double @fdim_strictfp() strictfp {
+; CHECK-LABEL: define double @fdim_strictfp(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[DIM:%.*]] = call double @fdim(double 1.000000e+01, double 8.000000e+00) #[[ATTR0]]
; CHECK-NEXT: ret double [[DIM]]
;
%dim = call double @fdim(double 10.0, double 8.0) strictfp
diff --git a/llvm/test/Transforms/InstSimplify/disable_folding.ll b/llvm/test/Transforms/InstSimplify/disable_folding.ll
index 69892012629bc..02ec4877e51d9 100644
--- a/llvm/test/Transforms/InstSimplify/disable_folding.ll
+++ b/llvm/test/Transforms/InstSimplify/disable_folding.ll
@@ -31,9 +31,10 @@ define float @test_llvm_sin() {
}
; Should not be folded, even when -disable-fp-call-folding is not set, as it is marked as strictfp.
-define float @test_fmax_ftz_nan_f_strictfp() {
-; CHECK-LABEL: define float @test_fmax_ftz_nan_f_strictfp() {
-; CHECK-NEXT: [[RES:%.*]] = call float @llvm.nvvm.fmax.ftz.nan.f(float 1.250000e+00, float -2.000000e+00) #[[ATTR1:[0-9]+]]
+define float @test_fmax_ftz_nan_f_strictfp() #1 {
+; CHECK-LABEL: define float @test_fmax_ftz_nan_f_strictfp(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[RES:%.*]] = call float @llvm.nvvm.fmax.ftz.nan.f(float 1.250000e+00, float -2.000000e+00) #[[ATTR0]]
; CHECK-NEXT: ret float [[RES]]
;
%res = call float @llvm.nvvm.fmax.ftz.nan.f(float 1.25, float -2.0) #1
@@ -42,9 +43,10 @@ define float @test_fmax_ftz_nan_f_strictfp() {
; Check that strictfp disables folding for LLVM math intrinsics like sin.f32
; even when -disable-fp-call-folding is not set.
-define float @test_llvm_sin_strictfp() {
-; CHECK-LABEL: define float @test_llvm_sin_strictfp() {
-; CHECK-NEXT: [[RES:%.*]] = call float @llvm.sin.f32(float 5.000000e-01) #[[ATTR1]]
+define float @test_llvm_sin_strictfp() #1 {
+; CHECK-LABEL: define float @test_llvm_sin_strictfp(
+; CHECK-SAME: ) #[[ATTR0]] {
+; CHECK-NEXT: ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/209465
More information about the llvm-commits
mailing list