diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -598,6 +598,9 @@ Floating Point Support in Clang ------------------------------- +- The driver option ``-menable-unsafe-fp-math`` has been removed. To enable + unsafe floating-point optimizations use ``-funsafe-math-optimizations`` or + ``-ffast-math`` instead. Internal API Changes -------------------- diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1596,10 +1596,6 @@ PosFlag, NegFlag>; -def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">, Flags<[CC1Option]>, - HelpText<"Allow unsafe floating-point math optimizations which may decrease precision">, - MarshallingInfoFlag>, - ImpliedByAnyOf<[cl_unsafe_math_optimizations.KeyPath, ffast_math.KeyPath]>; defm math_errno : BoolFOption<"math-errno", LangOpts<"MathErrno">, DefaultFalse, PosFlag, @@ -1879,7 +1875,10 @@ } // end -f[no-]sanitize* flags def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">, - Group; + Group, Flags<[CC1Option]>, + HelpText<"Allow unsafe floating-point math optimizations which may decrease precision">, + MarshallingInfoFlag>, + ImpliedByAnyOf<[cl_unsafe_math_optimizations.KeyPath, ffast_math.KeyPath]>; def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">, Group; def fassociative_math : Flag<["-"], "fassociative-math">, Group; @@ -1887,12 +1886,12 @@ defm reciprocal_math : BoolFOption<"reciprocal-math", LangOpts<"AllowRecip">, DefaultFalse, PosFlag, + [funsafe_math_optimizations.KeyPath]>, NegFlag>; defm approx_func : BoolFOption<"approx-func", LangOpts<"ApproxFunc">, DefaultFalse, PosFlag, + [funsafe_math_optimizations.KeyPath]>, NegFlag>; defm finite_math_only : BoolFOption<"finite-math-only", LangOpts<"FiniteMathOnly">, DefaultFalse, @@ -1901,7 +1900,7 @@ defm signed_zeros : BoolFOption<"signed-zeros", LangOpts<"NoSignedZero">, DefaultFalse, NegFlag, + [cl_no_signed_zeros.KeyPath, funsafe_math_optimizations.KeyPath]>, PosFlag>; def fhonor_nans : Flag<["-"], "fhonor-nans">, Group; def fno_honor_nans : Flag<["-"], "fno-honor-nans">, Group; @@ -5426,7 +5425,7 @@ MarshallingInfoFlag>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>; def mreassociate : Flag<["-"], "mreassociate">, HelpText<"Allow reassociation transformations for floating-point instructions">, - MarshallingInfoFlag>, ImpliedByAnyOf<[menable_unsafe_fp_math.KeyPath]>; + MarshallingInfoFlag>, ImpliedByAnyOf<[funsafe_math_optimizations.KeyPath]>; def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">, HelpText<"Use IEEE 754 quadruple-precision for long double">, MarshallingInfoFlag>; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1862,7 +1862,11 @@ FuncAttrs.addAttribute("no-nans-fp-math", "true"); if (LangOpts.ApproxFunc) FuncAttrs.addAttribute("approx-func-fp-math", "true"); - if (LangOpts.UnsafeFPMath) + if ((LangOpts.FastMath || + !LangOpts.FastMath && LangOpts.AllowFPReassoc && LangOpts.AllowRecip && + !LangOpts.FiniteMathOnly && LangOpts.NoSignedZero && + LangOpts.ApproxFunc) && + LangOpts.getDefaultFPContractMode() != LangOptions::FPModeKind::FPM_Off) FuncAttrs.addAttribute("unsafe-fp-math", "true"); if (CodeGenOpts.SoftFloat) FuncAttrs.addAttribute("use-soft-float", "true"); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3103,7 +3103,7 @@ if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros && ApproxFunc && !TrappingMath) - CmdArgs.push_back("-menable-unsafe-fp-math"); + CmdArgs.push_back("-funsafe-math-optimizations"); if (!SignedZeros) CmdArgs.push_back("-fno-signed-zeros"); diff --git a/clang/test/CodeGen/fp-options-to-fast-math-flags.c b/clang/test/CodeGen/fp-options-to-fast-math-flags.c --- a/clang/test/CodeGen/fp-options-to-fast-math-flags.c +++ b/clang/test/CodeGen/fp-options-to-fast-math-flags.c @@ -5,7 +5,7 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fno-signed-zeros -emit-llvm -o - %s | FileCheck -check-prefix CHECK-NO-SIGNED-ZEROS %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -mreassociate -emit-llvm -o - %s | FileCheck -check-prefix CHECK-REASSOC %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -freciprocal-math -emit-llvm -o - %s | FileCheck -check-prefix CHECK-RECIP %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -menable-unsafe-fp-math -emit-llvm -o - %s | FileCheck -check-prefix CHECK-UNSAFE %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -funsafe-math-optimizations -emit-llvm -o - %s | FileCheck -check-prefix CHECK-UNSAFE %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -ffast-math -emit-llvm -o - %s | FileCheck -check-prefix CHECK-FAST %s float fn(float); diff --git a/clang/test/CodeGen/func-attr.c b/clang/test/CodeGen/func-attr.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/func-attr.c @@ -0,0 +1,12 @@ +// RUN: %clang -c -ffast-math -emit-llvm -S -o - %s \ +// RUN: | FileCheck %s + +// RUN: %clang -c -funsafe-math-optimizations -emit-llvm -S -o - %s \ +// RUN: | FileCheck %s + +float foo(float a, float b) { + return a+b; +} + +// CHECK: define{{.*}} float @foo(float noundef %a, float noundef %b) [[FAST_ATTRS:#[0-9]+]] +// CHECK: attributes [[FAST_ATTRS]] = { {{.*}} "approx-func-fp-math"="true" {{.*}} "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" {{.*}} "unsafe-fp-math"="true" diff --git a/clang/test/CodeGen/libcalls.c b/clang/test/CodeGen/libcalls.c --- a/clang/test/CodeGen/libcalls.c +++ b/clang/test/CodeGen/libcalls.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -Wno-implicit-function-declaration -fmath-errno -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix CHECK-YES %s // RUN: %clang_cc1 -Wno-implicit-function-declaration -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix CHECK-NO %s -// RUN: %clang_cc1 -Wno-implicit-function-declaration -menable-unsafe-fp-math -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix CHECK-FAST %s +// RUN: %clang_cc1 -Wno-implicit-function-declaration -funsafe-math-optimizations -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix CHECK-FAST %s // CHECK-YES-LABEL: define{{.*}} void @test_sqrt // CHECK-NO-LABEL: define{{.*}} void @test_sqrt diff --git a/clang/test/CodeGenCUDA/propagate-metadata.cu b/clang/test/CodeGenCUDA/propagate-metadata.cu --- a/clang/test/CodeGenCUDA/propagate-metadata.cu +++ b/clang/test/CodeGenCUDA/propagate-metadata.cu @@ -22,7 +22,7 @@ // RUN: %clang_cc1 -x cuda %s -emit-llvm -mlink-builtin-bitcode %t.bc \ // RUN: -fdenormal-fp-math-f32=preserve-sign -o - \ -// RUN: -fcuda-is-device -menable-unsafe-fp-math -triple nvptx-unknown-unknown \ +// RUN: -fcuda-is-device -funsafe-math-optimizations -triple nvptx-unknown-unknown \ // RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=FAST // Wrap everything in extern "C" so we don't have to worry about name mangling diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -43,23 +43,23 @@ // EXTERNAL_I: "-isystem" "path" // RUN: %clang_cl /fp:fast /fp:except -### -- %s 2>&1 | FileCheck -check-prefix=fpexcept %s -// fpexcept-NOT: -menable-unsafe-fp-math +// fpexcept-NOT: -funsafe-math-optimizations // fpexcept: -ffp-exception-behavior=strict // RUN: %clang_cl /fp:fast /fp:except /fp:except- -### -- %s 2>&1 | FileCheck -check-prefix=fpexcept_ %s -// fpexcept_: -menable-unsafe-fp-math +// fpexcept_: -funsafe-math-optimizations // fpexcept_: -ffp-exception-behavior=ignore // RUN: %clang_cl /fp:precise /fp:fast -### -- %s 2>&1 | FileCheck -check-prefix=fpfast %s -// fpfast: -menable-unsafe-fp-math +// fpfast: -funsafe-math-optimizations // fpfast: -ffast-math // RUN: %clang_cl /fp:fast /fp:precise -### -- %s 2>&1 | FileCheck -check-prefix=fpprecise %s -// fpprecise-NOT: -menable-unsafe-fp-math +// fpprecise-NOT: -funsafe-math-optimizations // fpprecise-NOT: -ffast-math // RUN: %clang_cl /fp:fast /fp:strict -### -- %s 2>&1 | FileCheck -check-prefix=fpstrict %s -// fpstrict-NOT: -menable-unsafe-fp-math +// fpstrict-NOT: -funsafe-math-optimizations // fpstrict-NOT: -ffast-math // fpstrict: -ffp-contract=off diff --git a/clang/test/Driver/fast-math.c b/clang/test/Driver/fast-math.c --- a/clang/test/Driver/fast-math.c +++ b/clang/test/Driver/fast-math.c @@ -151,14 +151,14 @@ // RUN: -fno-signed-zeros -fno-trapping-math -fapprox-func -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-UNSAFE-MATH %s // CHECK-UNSAFE-MATH: "-cc1" -// CHECK-UNSAFE-MATH: "-menable-unsafe-fp-math" +// CHECK-UNSAFE-MATH: "-funsafe-math-optimizations" // CHECK-UNSAFE-MATH: "-mreassociate" // // RUN: %clang -### -fno-fast-math -fno-math-errno -fassociative-math -freciprocal-math \ // RUN: -fno-signed-zeros -fno-trapping-math -fapprox-func -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NO-FAST-MATH-UNSAFE-MATH %s // CHECK-NO-FAST-MATH-UNSAFE-MATH: "-cc1" -// CHECK-NO-FAST-MATH-UNSAFE-MATH: "-menable-unsafe-fp-math" +// CHECK-NO-FAST-MATH-UNSAFE-MATH: "-funsafe-math-optimizations" // CHECK-NO-FAST-MATH-UNSAFE-MATH: "-mreassociate" // The 2nd -fno-fast-math overrides -fassociative-math. @@ -167,7 +167,7 @@ // RUN: -fno-fast-math -fno-signed-zeros -fno-trapping-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-UNSAFE-MATH-NO-FAST-MATH %s // CHECK-UNSAFE-MATH-NO-FAST-MATH: "-cc1" -// CHECK-UNSAFE-MATH-NO-FAST-MATH-NOT: "-menable-unsafe-fp-math" +// CHECK-UNSAFE-MATH-NO-FAST-MATH-NOT: "-funsafe-math-optimizations" // CHECK-UNSAFE-MATH-NO-FAST-MATH-NOT: "-mreassociate" // // Check that various umbrella flags also enable these frontend options. @@ -280,7 +280,7 @@ // RUN: | FileCheck --check-prefix=CHECK-NO-UNSAFE-MATH %s // CHECK-NO-UNSAFE-MATH: "-cc1" -// CHECK-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math" +// CHECK-NO-UNSAFE-MATH-NOT: "-funsafe-math-optimizations" // CHECK-NO_UNSAFE-MATH-NOT: "-mreassociate" // CHECK-NO-UNSAFE-MATH: "-o" @@ -292,9 +292,9 @@ // RUN: | FileCheck --check-prefix=CHECK-REASSOC-NO-UNSAFE-MATH %s // CHECK-REASSOC-NO-UNSAFE-MATH: "-cc1" -// CHECK-REASSOC-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math" +// CHECK-REASSOC-NO_UNSAFE-MATH-NOT: "-funsafe-math-optimizations" // CHECK-REASSOC-NO_UNSAFE-MATH: "-mreassociate" -// CHECK-REASSOC-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math" +// CHECK-REASSOC-NO-UNSAFE-MATH-NOT: "-funsafe-math-optimizations" // CHECK-REASSOC-NO-UNSAFE-MATH: "-o" @@ -309,9 +309,9 @@ // RUN: | FileCheck --check-prefix=CHECK-NO-REASSOC-NO-UNSAFE-MATH %s // CHECK-NO-REASSOC-NO-UNSAFE-MATH: "-cc1" -// CHECK-NO-REASSOC-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math" +// CHECK-NO-REASSOC-NO_UNSAFE-MATH-NOT: "-funsafe-math-optimizations" // CHECK-NO-REASSOC-NO_UNSAFE-MATH-NOT: "-mreassociate" -// CHECK-NO-REASSOC-NO-UNSAFE-MATH-NOT: "-menable-unsafe-fp-math" +// CHECK-NO-REASSOC-NO_UNSAFE-MATH-NOT: "-funsafe-math-optimizations" // CHECK-NO-REASSOC-NO-UNSAFE-MATH: "-o" diff --git a/clang/test/Driver/fp-model.c b/clang/test/Driver/fp-model.c --- a/clang/test/Driver/fp-model.c +++ b/clang/test/Driver/fp-model.c @@ -86,7 +86,7 @@ // CHECK-FPM-FAST: "-cc1" // CHECK-FPM-FAST: "-menable-no-infs" // CHECK-FPM-FAST: "-menable-no-nans" -// CHECK-FPM-FAST: "-menable-unsafe-fp-math" +// CHECK-FPM-FAST: "-funsafe-math-optimizations" // CHECK-FPM-FAST: "-fno-signed-zeros" // CHECK-FPM-FAST: "-mreassociate" // CHECK-FPM-FAST: "-freciprocal-math" diff --git a/clang/test/Parser/fp-floatcontrol-syntax.cpp b/clang/test/Parser/fp-floatcontrol-syntax.cpp --- a/clang/test/Parser/fp-floatcontrol-syntax.cpp +++ b/clang/test/Parser/fp-floatcontrol-syntax.cpp @@ -42,7 +42,7 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -fdenormal-fp-math=preserve-sign,preserve-sign -fsyntax-only %s -DDEFAULT -verify // RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only %s -ffp-contract=fast -DPRECISE -verify // RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only %s -ffp-contract=off -frounding-math -ffp-exception-behavior=strict -DSTRICT -verify -// RUN: %clang_cc1 -triple x86_64-linux-gnu -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -ffp-contract=fast -ffast-math -ffinite-math-only -fsyntax-only %s -DFAST -verify +// RUN: %clang_cc1 -triple x86_64-linux-gnu -menable-no-infs -menable-no-nans -funsafe-math-optimizations -fno-signed-zeros -mreassociate -freciprocal-math -ffp-contract=fast -ffast-math -ffinite-math-only -fsyntax-only %s -DFAST -verify double a = 0.0; double b = 1.0; diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp --- a/clang/unittests/Frontend/CompilerInvocationTest.cpp +++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp @@ -705,7 +705,7 @@ // // * -cl-unsafe-math-optimizations // * -cl-mad-enable -// * -menable-unsafe-fp-math +// * -funsafe-math-optimizations // * -freciprocal-math TEST_F(CommandLineTest, ImpliedBoolOptionsNoFlagPresent) { @@ -723,7 +723,8 @@ ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-unsafe-math-optimizations")))); ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-mad-enable")))); - ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-menable-unsafe-fp-math")))); + ASSERT_THAT(GeneratedArgs, + Not(Contains(StrEq("-funsafe-math-optimizations")))); ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math")))); } @@ -745,13 +746,14 @@ ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-unsafe-math-optimizations"))); // Not generated - implied by the generated root flag. ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-mad-enable")))); - ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-menable-unsafe-fp-math")))); + ASSERT_THAT(GeneratedArgs, + Not(Contains(StrEq("-funsafe-math-optimizations")))); ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math")))); } TEST_F(CommandLineTest, ImpliedBoolOptionsAllFlagsPresent) { const char *Args[] = {"-cl-unsafe-math-optimizations", "-cl-mad-enable", - "-menable-unsafe-fp-math", "-freciprocal-math"}; + "-funsafe-math-optimizations", "-freciprocal-math"}; ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags)); ASSERT_TRUE(Invocation.getLangOpts()->CLUnsafeMath); @@ -765,12 +767,13 @@ ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-unsafe-math-optimizations"))); // Not generated - implied by their generated parent. ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-mad-enable")))); - ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-menable-unsafe-fp-math")))); + ASSERT_THAT(GeneratedArgs, + Not(Contains(StrEq("-funsafe-math-optimizations")))); ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math")))); } TEST_F(CommandLineTest, ImpliedBoolOptionsImpliedFlagsPresent) { - const char *Args[] = {"-cl-mad-enable", "-menable-unsafe-fp-math", + const char *Args[] = {"-cl-mad-enable", "-funsafe-math-optimizations", "-freciprocal-math"}; ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags)); @@ -785,13 +788,13 @@ Not(Contains(StrEq("-cl-unsafe-math-optimizations")))); // Generated - explicitly provided. ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-mad-enable"))); - ASSERT_THAT(GeneratedArgs, Contains(StrEq("-menable-unsafe-fp-math"))); + ASSERT_THAT(GeneratedArgs, Contains(StrEq("-funsafe-math-optimizations"))); // Not generated - implied by its generated parent. ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math")))); } TEST_F(CommandLineTest, PresentAndNotImpliedGenerated) { - const char *Args[] = {"-cl-mad-enable", "-menable-unsafe-fp-math"}; + const char *Args[] = {"-cl-mad-enable", "-funsafe-math-optimizations"}; ASSERT_TRUE(CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags)); @@ -799,7 +802,7 @@ // Present options that were not implied are generated. ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-mad-enable"))); - ASSERT_THAT(GeneratedArgs, Contains(StrEq("-menable-unsafe-fp-math"))); + ASSERT_THAT(GeneratedArgs, Contains(StrEq("-funsafe-math-optimizations"))); } // Diagnostic option.