[clang] Always honor fp-contract pragmas on PlayStation (PR #162549)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 8 16:28:07 PDT 2025
https://github.com/wjristow updated https://github.com/llvm/llvm-project/pull/162549
>From 123ddd98310228a8afd9a5f93b0a7b482df8e93e Mon Sep 17 00:00:00 2001
From: Warren Ristow <warren.ristow at sony.com>
Date: Wed, 8 Oct 2025 13:52:37 -0700
Subject: [PATCH] Always honor fp-contract pragmas on PlayStation
The pragma:
#pragma clang fp contract (off)
can be used to disable FMA, but when cross-statement FMA is enabled in
`fast` fp contract mode (via `-ffast-math`, for example), the effect of
that pragma is suppressed.
To have Clang honor that pragma in 'fast' fp contract mode in C/C++, an
additional switch:
-ffp-contract=fast-honor-pragmas
must be applied. On PlayStation, we want to always honor that pragma,
without requiring the additional switch to be specified. This commit
does that.
---
clang/lib/CodeGen/BackendUtil.cpp | 6 ++-
clang/test/CodeGen/X86/fma-fast-pragma.cpp | 53 ++++++++++++++++++++++
2 files changed, 58 insertions(+), 1 deletion(-)
create mode 100644 clang/test/CodeGen/X86/fma-fast-pragma.cpp
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 2d959827d6972..0840c7348c18b 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -406,7 +406,11 @@ static bool initTargetOptions(const CompilerInstance &CI,
Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
break;
case LangOptions::FPM_Fast:
- Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
+ // We always honor fp-contract pragmas for PlayStation.
+ if (CI.getASTContext().getTargetInfo().getTriple().isPS())
+ Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
+ else
+ Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
break;
}
diff --git a/clang/test/CodeGen/X86/fma-fast-pragma.cpp b/clang/test/CodeGen/X86/fma-fast-pragma.cpp
new file mode 100644
index 0000000000000..9d38e245b5f64
--- /dev/null
+++ b/clang/test/CodeGen/X86/fma-fast-pragma.cpp
@@ -0,0 +1,53 @@
+// REQUIRES: x86-registered-target
+
+// With the pragma in place, generic targets leave FMA enabled unless the
+// switch '-ffp-contract=fast-honor-pragmas' is used to disable it; whereas
+// for PlayStation, the pragma is always honored, so FMA is disabled even in
+// plain 'fast' mode:
+// RUN: %clang_cc1 -S -triple x86_64-unknown-unknown -target-feature +fma \
+// RUN: -O2 -ffp-contract=fast -o - %s | \
+// RUN: FileCheck --check-prefix=CHECK-YES-FMA %s
+// RUN: %clang_cc1 -S -triple x86_64-unknown-unknown -target-feature +fma \
+// RUN: -O2 -ffp-contract=fast-honor-pragmas -o - %s | \
+// RUN: FileCheck --check-prefix=CHECK-NO-FMA %s
+// RUN: %clang_cc1 -S -triple x86_64-unknown-unknown -target-feature +fma \
+// RUN: -O2 -ffp-contract=fast -ffp-contract=fast-honor-pragmas -o - %s | \
+// RUN: FileCheck --check-prefix=CHECK-NO-FMA %s
+// RUN: %clang_cc1 -S -triple x86_64-sie-ps5 -target-feature +fma \
+// RUN: -O2 -ffp-contract=fast -o - %s | \
+// RUN: FileCheck --check-prefix=CHECK-NO-FMA %s
+// RUN: %clang_cc1 -S -triple x86_64-sie-ps5 -target-feature +fma \
+// RUN: -O2 -ffp-contract=fast-honor-pragmas -o - %s | \
+// RUN: FileCheck --check-prefix=CHECK-NO-FMA %s
+//
+// With the pragma suppressed, FMA happens in 'fast' or 'fast-honor-pragmas'
+// modes (for generic targets and for PlayStation):
+// RUN: %clang_cc1 -S -DSUPPRESS_PRAGMA \
+// RUN: -triple x86_64-unknown-unknown -target-feature +fma \
+// RUN: -O2 -ffp-contract=fast -o - %s | \
+// RUN: FileCheck --check-prefix=CHECK-YES-FMA %s
+// RUN: %clang_cc1 -S -DSUPPRESS_PRAGMA \
+// RUN: -triple x86_64-unknown-unknown -target-feature +fma \
+// RUN: -O2 -ffp-contract=fast-honor-pragmas -o - %s | \
+// RUN: FileCheck --check-prefix=CHECK-YES-FMA %s
+// RUN: %clang_cc1 -S -DSUPPRESS_PRAGMA \
+// RUN: -triple x86_64-sie-ps5 -target-feature +fma \
+// RUN: -O2 -ffp-contract=fast -o - %s | \
+// RUN: FileCheck --check-prefix=CHECK-YES-FMA %s
+// RUN: %clang_cc1 -S -DSUPPRESS_PRAGMA \
+// RUN: -triple x86_64-sie-ps5 -target-feature +fma \
+// RUN: -O2 -ffp-contract=fast-honor-pragmas -o - %s | \
+// RUN: FileCheck --check-prefix=CHECK-YES-FMA %s
+//
+float compute(float a, float b, float c) {
+#if !defined(SUPPRESS_PRAGMA)
+#pragma clang fp contract (off)
+#endif
+ float product = a * b;
+ return product + c;
+}
+
+// CHECK-NO-FMA: vmulss
+// CHECK-NO-FMA-NEXT: vaddss
+
+// CHECK-YES-FMA: vfmadd213ss
More information about the cfe-commits
mailing list