https://github.com/mikolaj-pirog created
https://github.com/llvm/llvm-project/pull/169859
As in title. These are 2 changes to how fp contract pragmas interact with each
other and the CLI options:
- Code like this, compiled under -ffp-contract=fast
```
//
float foo(float a, float b, float c, float d, float e) {
#pragma STDC FP_CONTRACT ON
float mul = c * d;
float add = mul + e;
return add;
}
```cpp
will now have 'contract' set on fp ops, i.e. `on` pragma won't overwrite `fast`
CLI option.
- Code like this:
```
float bar(float a, float b, float c, float d, float e) {
#pragma clang fp contract(fast)
#pragma clang fp contract(on)
float mul = c * d;
float add = mul + e;
return add;
}
```cpp
will now have 'contract' set as well -- `on` doesn't overwrite previous `fast`.
From cdbf16cbf245ba47f587b6203f604e81b170eab7 Mon Sep 17 00:00:00 2001
From: "Pirog, Mikolaj Maciej" <[email protected]>
Date: Tue, 30 Sep 2025 15:57:14 +0200
Subject: [PATCH 1/3] init
---
clang/lib/Sema/SemaAttr.cpp | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 8411a3da8322d..9b58fa9ffa118 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -1381,13 +1381,18 @@ void Sema::ActOnPragmaVisibility(const IdentifierInfo*
VisType,
void Sema::ActOnPragmaFPContract(SourceLocation Loc,
LangOptions::FPModeKind FPC) {
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
+ auto CurrentContractMode = NewFPFeatures.getFPContractModeOverride();
+ auto DefContractMode = getLangOpts().getDefaultFPContractMode();
+ llvm::outs() << "Cur mode from CLI:\t" <<
getLangOpts().getDefaultFPContractMode() << "\n" << "Cur override:\t" <<
CurrentContractMode << "\n";
switch (FPC) {
case LangOptions::FPM_On:
- NewFPFeatures.setAllowFPContractWithinStatement();
+ if (CurrentContractMode == LangOptions::FPM_Off && DefContractMode !=
LangOptions::FPM_Fast)
+ NewFPFeatures.setAllowFPContractWithinStatement();
break;
case LangOptions::FPM_Fast:
case LangOptions::FPM_FastHonorPragmas:
- NewFPFeatures.setAllowFPContractAcrossStatement();
+ if (CurrentContractMode == LangOptions::FPM_Off || CurrentContractMode ==
LangOptions::FPM_On)
+ NewFPFeatures.setAllowFPContractAcrossStatement();
break;
case LangOptions::FPM_Off:
NewFPFeatures.setDisallowFPContract();
From 0044a180a3163d6526580cf0d8c954b75a49e8f7 Mon Sep 17 00:00:00 2001
From: "Pirog, Mikolaj Maciej" <[email protected]>
Date: Thu, 27 Nov 2025 22:29:25 +0100
Subject: [PATCH 2/3] Further work
---
clang/lib/Sema/SemaAttr.cpp | 11 +++++-----
.../ffp-contract-fhp-pragma-override.cpp | 21 +++++++++++--------
.../test/CodeGen/fp-contract-fast-pragma.cpp | 19 +++++++++++++----
clang/test/CodeGen/fp-function-attrs.cpp | 2 +-
clang/test/CodeGenCUDA/fp-contract.cu | 12 +++++------
5 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 116e64199607d..8cbfe47332624 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -1381,18 +1381,17 @@ void Sema::ActOnPragmaVisibility(const IdentifierInfo*
VisType,
void Sema::ActOnPragmaFPContract(SourceLocation Loc,
LangOptions::FPModeKind FPC) {
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
- auto CurrentContractMode = NewFPFeatures.getFPContractModeOverride();
+ bool HasContractOverride = NewFPFeatures.hasFPContractModeOverride();
auto DefContractMode = getLangOpts().getDefaultFPContractMode();
- llvm::outs() << "Cur mode from CLI:\t" <<
getLangOpts().getDefaultFPContractMode() << "\n" << "Cur override:\t" <<
CurrentContractMode << "\n";
+
switch (FPC) {
case LangOptions::FPM_On:
- if (CurrentContractMode == LangOptions::FPM_Off && DefContractMode !=
LangOptions::FPM_Fast)
- NewFPFeatures.setAllowFPContractWithinStatement();
+ if ((HasContractOverride && NewFPFeatures.getFPContractModeOverride() ==
LangOptions::FPM_Off) || (!HasContractOverride && DefContractMode ==
LangOptions::FPM_Off))
+ NewFPFeatures.setAllowFPContractWithinStatement();
break;
case LangOptions::FPM_Fast:
case LangOptions::FPM_FastHonorPragmas:
- if (CurrentContractMode == LangOptions::FPM_Off || CurrentContractMode ==
LangOptions::FPM_On)
- NewFPFeatures.setAllowFPContractAcrossStatement();
+ NewFPFeatures.setAllowFPContractAcrossStatement();
break;
case LangOptions::FPM_Off:
NewFPFeatures.setDisallowFPContract();
diff --git a/clang/test/CodeGen/ffp-contract-fhp-pragma-override.cpp
b/clang/test/CodeGen/ffp-contract-fhp-pragma-override.cpp
index ff35c9204c79c..fe2d52fae5cf0 100644
--- a/clang/test/CodeGen/ffp-contract-fhp-pragma-override.cpp
+++ b/clang/test/CodeGen/ffp-contract-fhp-pragma-override.cpp
@@ -2,15 +2,16 @@
float fp_contract_on_1(float a, float b, float c) {
// CHECK-LABEL: fp_contract_on_1fff(
- // CHECK: call float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float
{{.*}})
+ // CHECK: fmul contract float
+ // CHECK: fadd contract float
#pragma STDC FP_CONTRACT ON
return a * b + c;
}
float fp_contract_on_2(float a, float b, float c) {
// CHECK-LABEL: fp_contract_on_2fff(
- // CHECK: fmul float
- // CHECK: fadd float
+ // CHECK: fmul contract float
+ // CHECK: fadd contract float
#pragma STDC FP_CONTRACT ON
float t = a * b;
return t + c;
@@ -52,15 +53,16 @@ float fp_contract_default_2(float a, float b, float c) {
float fp_contract_clang_on_1(float a, float b, float c) {
// CHECK-LABEL: fp_contract_clang_on_1fff(
- // CHECK: call float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float
{{.*}})
+ // CHECK: fmul contract float
+ // CHECK: fadd contract float
#pragma clang fp contract(on)
return a * b + c;
}
float fp_contract_clang_on_2(float a, float b, float c) {
// CHECK-LABEL: fp_contract_clang_on_2fff(
- // CHECK: fmul float
- // CHECK: fadd float
+ // CHECK: fmul contract float
+ // CHECK: fadd contract float
#pragma clang fp contract(on)
float t = a * b;
return t + c;
@@ -104,14 +106,15 @@ float fp_contract_clang_fast_2(float a, float b, float c)
{
float fp_contract_global_on_1(float a, float b, float c) {
// CHECK-LABEL: fp_contract_global_on_1fff(
- // CHECK: call float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float
{{.*}})
+ // CHECK: fmul contract float
+ // CHECK: fadd contract float
return a * b + c;
}
float fp_contract_global_on_2(float a, float b, float c) {
// CHECK-LABEL: fp_contract_global_on_2fff(
- // CHECK: fmul float
- // CHECK: fadd float
+ // CHECK: fmul contract float
+ // CHECK: fadd contract float
float t = a * b;
return t + c;
}
diff --git a/clang/test/CodeGen/fp-contract-fast-pragma.cpp
b/clang/test/CodeGen/fp-contract-fast-pragma.cpp
index 0bb01d6e17a1d..f0399dbdc9039 100644
--- a/clang/test/CodeGen/fp-contract-fast-pragma.cpp
+++ b/clang/test/CodeGen/fp-contract-fast-pragma.cpp
@@ -87,17 +87,28 @@ float fp_contract_6(float a, float b, float c) {
return a * b + c;
}
+// 'on' after 'fast' shouldn't disable 'fast'
+#pragma clang fp contract(fast)
+#pragma clang fp contract(on)
+float fp_contract_7(float a, float b, float c) {
+ // COMMON: _Z13fp_contract_7fff
+ // CHECK: %[[M:.+]] = fmul contract float %a, %b
+ // CHECK-NEXT: fadd contract float %[[M]], %c
+ // STRICT: %[[M:.+]] = tail call contract float
@llvm.experimental.constrained.fmul.f32(float %a, float %b, metadata
!"round.tonearest", metadata !"fpexcept.strict")
+ // STRICT-NEXT: tail call contract float
@llvm.experimental.constrained.fadd.f32(float %[[M]], float %c, metadata
!"round.tonearest", metadata !"fpexcept.strict")
+ return a * b + c;
+}
#pragma clang fp contract(fast)
-float fp_contract_7(float a) {
-// COMMON: _Z13fp_contract_7f
+float fp_contract_8(float a) {
+// COMMON: _Z13fp_contract_8f
// CHECK: tail call contract float @llvm.sqrt.f32(float %a)
// STRICT: tail call contract float
@llvm.experimental.constrained.sqrt.f32(float %a, metadata !"round.tonearest",
metadata !"fpexcept.strict")
return __builtin_sqrtf(a);
}
-float fp_contract_8(float a) {
-// COMMON: _Z13fp_contract_8f
+float fp_contract_9(float a) {
+// COMMON: _Z13fp_contract_9f
// CHECK: tail call float @llvm.sqrt.f32(float %a)
// STRICT: tail call float @llvm.experimental.constrained.sqrt.f32(float %a,
metadata !"round.tonearest", metadata !"fpexcept.strict")
#pragma clang fp contract(off)
diff --git a/clang/test/CodeGen/fp-function-attrs.cpp
b/clang/test/CodeGen/fp-function-attrs.cpp
index 3775bd5452d78..3b3122f492fc1 100644
--- a/clang/test/CodeGen/fp-function-attrs.cpp
+++ b/clang/test/CodeGen/fp-function-attrs.cpp
@@ -51,7 +51,7 @@ float test_contract_on_pragma(float a, float b, float c) {
// CHECK: define{{.*}} float @_Z23test_contract_on_pragmafff(float noundef
nofpclass(nan inf) %a, float noundef nofpclass(nan inf) %b, float noundef
nofpclass(nan inf) %c)
// CHECK: fmul fast float {{%.+}}, {{%.+}}
-// CHECK: fadd reassoc nnan ninf nsz arcp afn float {{%.+}}, {{%.+}}
+// CHECK: fadd fast float {{%.+}}, {{%.+}}
// CHECK: attributes [[FAST_ATTRS]] = { {{.*}}"no-infs-fp-math"="true"
{{.*}}"no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true"{{.*}} }
// CHECK: attributes [[PRECISE_ATTRS]] = { {{.*}}"no-infs-fp-math"="false"
{{.*}}"no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false"{{.*}} }
diff --git a/clang/test/CodeGenCUDA/fp-contract.cu
b/clang/test/CodeGenCUDA/fp-contract.cu
index d6c796a817cbf..b3fc8e30e8990 100644
--- a/clang/test/CodeGenCUDA/fp-contract.cu
+++ b/clang/test/CodeGenCUDA/fp-contract.cu
@@ -268,8 +268,7 @@ __host__ __device__ float func2(float a, float b, float c) {
// COMMON-LABEL: _Z5func3fff
// NV-OPT-FAST: fma.rn.f32
// NV-OPT-FAST-NEXT: st.param.b32
-// NV-OPT-FASTSTD: mul.rn.f32
-// NV-OPT-FASTSTD: add.rn.f32
+// NV-OPT-FASTSTD: fma.rn.f32
// NV-OPT-FASTSTD-NEXT: st.param.b32
// NV-OPT-ON: mul.rn.f32
// NV-OPT-ON: add.rn.f32
@@ -278,8 +277,8 @@ __host__ __device__ float func2(float a, float b, float c) {
// NV-OPT-OFF: add.rn.f32
// NV-OPT-OFF-NEXT: st.param.b32
-// AMD-OPT-FAST-IR: fmul float
-// AMD-OPT-FAST-IR: fadd float
+// AMD-OPT-FAST-IR: fmul contract float
+// AMD-OPT-FAST-IR: fadd contract float
// AMD-OPT-ON-IR: fmul float
// AMD-OPT-ON-IR: fadd float
// AMD-OPT-OFF-IR: fmul float
@@ -287,9 +286,8 @@ __host__ __device__ float func2(float a, float b, float c) {
// AMD-OPT-FAST: v_fmac_f32_e32
// AMD-OPT-FAST-NEXT: s_setpc_b64
-// AMD-OPT-FASTSTD: v_mul_f32_e32
-// AMD-OPT-FASTSTD-NEXT: v_add_f32_e32
-// AMD-OPT-FASTSTD-NEXT: s_setpc_b64
+// AMD-OPT-FASTSTD: v_fmac_f32_e32
+// AMD-OPT-FASTSTD: s_setpc_b64
// AMD-OPT-ON: v_mul_f32_e32
// AMD-OPT-ON-NEXT: v_add_f32_e32
// AMD-OPT-ON-NEXT: s_setpc_b64
From c4cb1d198a68965a2be2cadb27876536156047e1 Mon Sep 17 00:00:00 2001
From: "Pirog, Mikolaj Maciej" <[email protected]>
Date: Thu, 27 Nov 2025 22:29:40 +0100
Subject: [PATCH 3/3] Format
---
clang/lib/Sema/SemaAttr.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 8cbfe47332624..8a9a1e62770e1 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -1386,8 +1386,10 @@ void Sema::ActOnPragmaFPContract(SourceLocation Loc,
switch (FPC) {
case LangOptions::FPM_On:
- if ((HasContractOverride && NewFPFeatures.getFPContractModeOverride() ==
LangOptions::FPM_Off) || (!HasContractOverride && DefContractMode ==
LangOptions::FPM_Off))
- NewFPFeatures.setAllowFPContractWithinStatement();
+ if ((HasContractOverride &&
+ NewFPFeatures.getFPContractModeOverride() == LangOptions::FPM_Off) ||
+ (!HasContractOverride && DefContractMode == LangOptions::FPM_Off))
+ NewFPFeatures.setAllowFPContractWithinStatement();
break;
case LangOptions::FPM_Fast:
case LangOptions::FPM_FastHonorPragmas:
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits