[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