https://github.com/wenju-he created https://github.com/llvm/llvm-project/pull/211768
b630323 dropped the cc1-level ImpliedByAnyOf<[cl_fast_relaxed_math]> on fast_math to let -fhonor-nans/-fhonor-infinities override -cl-fast-relaxed-math via the Driver. This broke our downstream test that talks to cc1/CompilerInvocation directly: a bare -cl-fast-relaxed-math no longer implied nnan/ninf/nofpclass, silently degrading to plain contract. Restore the cc1-level implication so -cl-fast-relaxed-math alone gives the full fast-math cascade again, and give -menable-no-nans/ -menable-no-infs real CC1Option negation flags (-mno-enable-no-nans/ -mno-enable-no-infs). The Driver now emits the negation flag when -fhonor-nans/-fhonor-infinities is combined with -cl-fast-relaxed-math, explicitly cancelling just the implied NaN or Inf assumption without suppressing the rest of the cascade. >From 152618ca703ffb290e7b0796af0f06431a9b013b Mon Sep 17 00:00:00 2001 From: Wenju He <[email protected]> Date: Fri, 24 Jul 2026 12:49:14 +0200 Subject: [PATCH] [clang][Driver] Restore -cl-fast-relaxed-math fast-math cascade at cc1 level b630323 dropped the cc1-level ImpliedByAnyOf<[cl_fast_relaxed_math]> on fast_math to let -fhonor-nans/-fhonor-infinities override -cl-fast-relaxed-math via the Driver. This broke our downstream test that talks to cc1/CompilerInvocation directly: a bare -cl-fast-relaxed-math no longer implied nnan/ninf/nofpclass, silently degrading to plain contract. Restore the cc1-level implication so -cl-fast-relaxed-math alone gives the full fast-math cascade again, and give -menable-no-nans/ -menable-no-infs real CC1Option negation flags (-mno-enable-no-nans/ -mno-enable-no-infs). The Driver now emits the negation flag when -fhonor-nans/-fhonor-infinities is combined with -cl-fast-relaxed-math, explicitly cancelling just the implied NaN or Inf assumption without suppressing the rest of the cascade. Co-Authored-By: Claude Sonnet 5 <[email protected]> --- clang/include/clang/Options/Options.td | 21 ++++++++++++++------- clang/lib/Driver/ToolChains/Clang.cpp | 12 ++++++++++++ clang/test/CodeGenOpenCL/relaxed-fpmath.cl | 10 ++++++++++ clang/test/Driver/opencl.cl | 10 +++++++--- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 41848b18f2e1b..82ba02e262b0c 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -2507,7 +2507,8 @@ def ffp_exception_behavior_EQ : Joined<["-"], "ffp-exception-behavior=">, Group< defm fast_math : BoolFOption<"fast-math", LangOpts<"FastMath">, Default<hlsl.KeyPath>, PosFlag<SetTrue, [], [ClangOption, CC1Option, FC1Option, FlangOption], - "Allow aggressive, lossy floating-point optimizations">, + "Allow aggressive, lossy floating-point optimizations", + [cl_fast_relaxed_math.KeyPath]>, NegFlag<SetFalse, [], [ClangOption, CC1Option, FC1Option, FlangOption]>>; defm math_errno : BoolFOption<"math-errno", LangOpts<"MathErrno">, DefaultFalse, @@ -8773,12 +8774,18 @@ let Visibility = [CC1Option, FC1Option] in { def mreassociate : Flag<["-"], "mreassociate">, HelpText<"Allow reassociation transformations for floating-point instructions">, MarshallingInfoFlag<LangOpts<"AllowFPReassoc">>, ImpliedByAnyOf<[funsafe_math_optimizations.KeyPath]>; -def menable_no_nans : Flag<["-"], "menable-no-nans">, - HelpText<"Allow optimization to assume there are no NaNs.">, - MarshallingInfoFlag<LangOpts<"NoHonorNaNs">>, ImpliedByAnyOf<[ffast_math.KeyPath]>; -def menable_no_infs : Flag<["-"], "menable-no-infs">, - HelpText<"Allow optimization to assume there are no infinities.">, - MarshallingInfoFlag<LangOpts<"NoHonorInfs">>, ImpliedByAnyOf<[ffast_math.KeyPath]>; +defm enable_no_nans : BoolMOption<"enable-no-nans", + LangOpts<"NoHonorNaNs">, DefaultFalse, + PosFlag<SetTrue, [], [CC1Option, FC1Option], + "Allow optimization to assume there are no NaNs.", + [ffast_math.KeyPath]>, + NegFlag<SetFalse, [], [CC1Option, FC1Option]>>; +defm enable_no_infs : BoolMOption<"enable-no-infs", + LangOpts<"NoHonorInfs">, DefaultFalse, + PosFlag<SetTrue, [], [CC1Option, FC1Option], + "Allow optimization to assume there are no infinities.", + [ffast_math.KeyPath]>, + NegFlag<SetFalse, [], [CC1Option, FC1Option]>>; def pic_level : Separate<["-"], "pic-level">, HelpText<"Value for __PIC__">, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 660e61d7c5de3..d27d019c88c71 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3386,11 +3386,23 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, A->claim(); } + // -cl-fast-relaxed-math implies -ffast-math at the cc1 level (so that + // callers talking to cc1 directly, e.g. via CompilerInvocation, get the + // full fast-math cascade from a bare -cl-fast-relaxed-math). When the + // Driver determines NaNs/Infs should still be honored (because + // -fhonor-nans/-fhonor-infinities overrode -cl-fast-relaxed-math), it must + // explicitly cancel that cc1-level implication. + bool NeedsHonorOverride = Args.hasArg(options::OPT_cl_fast_relaxed_math); + if (!HonorINFs) CmdArgs.push_back("-menable-no-infs"); + else if (NeedsHonorOverride) + CmdArgs.push_back("-mno-enable-no-infs"); if (!HonorNaNs) CmdArgs.push_back("-menable-no-nans"); + else if (NeedsHonorOverride) + CmdArgs.push_back("-mno-enable-no-nans"); if (ApproxFunc) CmdArgs.push_back("-fapprox-func"); diff --git a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl index e875a6c9d1ad8..44fc9513b5498 100644 --- a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl +++ b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl @@ -5,6 +5,14 @@ // RUN: %clang_cc1 %s -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD // RUN: %clang_cc1 %s -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED +// -cl-fast-relaxed-math alone implies -ffast-math at the cc1 level, so both +// -menable-no-nans and -menable-no-infs are implied. +// RUN: %clang_cc1 %s -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST +// A caller (e.g. a cc1-direct invocation) can cancel just one side of the +// implied fast-math NaN/Inf assumptions via the negation flags. +// RUN: %clang_cc1 %s -emit-llvm -cl-fast-relaxed-math -mno-enable-no-nans -o - | FileCheck %s -check-prefix=NONAN +// RUN: %clang_cc1 %s -emit-llvm -cl-fast-relaxed-math -mno-enable-no-infs -o - | FileCheck %s -check-prefix=NOINF + // Check the fp options are correct with PCH. // RUN: %clang_cc1 %s -DGEN_PCH=1 -finclude-default-header -triple spir-unknown-unknown -emit-pch -o %t.pch // RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -o - | FileCheck %s -check-prefix=NORMAL @@ -25,6 +33,8 @@ float spscalardiv(float a, float b) { // UNSAFE: fdiv reassoc nsz arcp contract afn float // MAD: fdiv float // NOSIGNED: fdiv nsz float + // NONAN: fdiv reassoc ninf nsz arcp contract afn float + // NOINF: fdiv reassoc nnan nsz arcp contract afn float return a / b; } // CHECK: attributes diff --git a/clang/test/Driver/opencl.cl b/clang/test/Driver/opencl.cl index 8024c27f69f69..3110fb3f0bd77 100644 --- a/clang/test/Driver/opencl.cl +++ b/clang/test/Driver/opencl.cl @@ -12,9 +12,9 @@ // RUN: %clang -S -### -cl-finite-math-only %s 2>&1 | FileCheck --check-prefix=CHECK-FINITE-MATH-ONLY %s // RUN: %clang -S -### -cl-kernel-arg-info %s 2>&1 | FileCheck --check-prefix=CHECK-KERNEL-ARG-INFO %s // RUN: %clang -S -### -cl-unsafe-math-optimizations %s 2>&1 | FileCheck --check-prefix=CHECK-UNSAFE-MATH-OPT %s -// RUN: %clang -S -### -cl-fast-relaxed-math %s 2>&1 | FileCheck --check-prefix=CHECK-FAST-RELAXED-MATH %s -// RUN: %clang -S -### -cl-fast-relaxed-math -fhonor-nans %s 2>&1 | FileCheck --check-prefixes=CHECK-FAST-RELAXED-MATH,NO-NNAN %s -// RUN: %clang -S -### -cl-fast-relaxed-math -fhonor-infinities %s 2>&1 | FileCheck --check-prefixes=CHECK-FAST-RELAXED-MATH,NO-NINF %s +// RUN: %clang -S -### -cl-fast-relaxed-math %s 2>&1 | FileCheck --check-prefixes=CHECK-FAST-RELAXED-MATH,NO-MNO-ENABLE %s +// RUN: %clang -S -### -cl-fast-relaxed-math -fhonor-nans %s 2>&1 | FileCheck --check-prefixes=CHECK-FAST-RELAXED-MATH,NO-NNAN,YES-NO-ENABLE-NNAN %s +// RUN: %clang -S -### -cl-fast-relaxed-math -fhonor-infinities %s 2>&1 | FileCheck --check-prefixes=CHECK-FAST-RELAXED-MATH,NO-NINF,YES-NO-ENABLE-NINF %s // RUN: %clang -S -### -cl-mad-enable %s 2>&1 | FileCheck --check-prefix=CHECK-MAD-ENABLE %s // RUN: %clang -S -### -cl-no-signed-zeros %s 2>&1 | FileCheck --check-prefix=CHECK-NO-SIGNED-ZEROS %s // RUN: %clang -S -### -cl-denorms-are-zero %s 2>&1 | FileCheck --check-prefix=CHECK-DENORMS-ARE-ZERO %s @@ -47,6 +47,10 @@ // CHECK-NO-SIGNED-ZEROS: "-cc1" {{.*}} "-cl-no-signed-zeros" // NO-NNAN-NOT: "menable-no-nans" // NO-NINF-NOT: "menable-no-infs" +// YES-NO-ENABLE-NNAN: "-mno-enable-no-nans" +// YES-NO-ENABLE-NINF: "-mno-enable-no-infs" +// NO-MNO-ENABLE-NOT: "-mno-enable-no-nans" +// NO-MNO-ENABLE-NOT: "-mno-enable-no-infs" // This is not forwarded // CHECK-DENORMS-ARE-ZERO-NOT: "-cl-denorms-are-zero" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
