Revert "Currently the control of the eval-method is mixed with fast-math."
Setting __FLT_EVAL_METHOD__ to -1 with fast-math will set
__GLIBC_FLT_EVAL_METHOD to 2 and long double ends up being used for
float_t and double_t. This creates some ABI breakage with various C libraries.
See details here: https://github.com/llvm/llvm-project/issues/60781
This reverts commit bbf0d1932a3c1be970ed8a580e51edf571b80fd5.
(cherry picked from commit 2f1264260b37e9bd79737181e459ae20e10c5fea)
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 0cb3769..3226268 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -193,11 +193,6 @@
LangOptions::FPEvalMethodKind CurrentFPEvalMethod =
LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
- // Keeps the value of the last evaluation method before a
- // `pragma float_control (precise,off) is applied.
- LangOptions::FPEvalMethodKind LastFPEvalMethod =
- LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
-
// The most recent pragma location where the floating point evaluation
// method was modified. This is used to determine whether the
// 'pragma clang fp eval_method' was used whithin the current scope.
@@ -2335,14 +2330,6 @@
return LastFPEvalPragmaLocation;
}
- LangOptions::FPEvalMethodKind getLastFPEvalMethod() const {
- return LastFPEvalMethod;
- }
-
- void setLastFPEvalMethod(LangOptions::FPEvalMethodKind Val) {
- LastFPEvalMethod = Val;
- }
-
void setCurrentFPEvalMethod(SourceLocation PragmaLoc,
LangOptions::FPEvalMethodKind Val) {
assert(Val != LangOptions::FEM_UnsetOnCommandLine &&
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index bbc271e..76d0d53 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1637,35 +1637,14 @@
Tok.setKind(tok::string_literal);
} else if (II == Ident__FLT_EVAL_METHOD__) {
// __FLT_EVAL_METHOD__ is set to the default value.
- if (getTUFPEvalMethod() ==
- LangOptions::FPEvalMethodKind::FEM_Indeterminable) {
- // This is possible if `AllowFPReassoc` or `AllowReciprocal` is enabled.
- // These modes can be triggered via the command line option `-ffast-math`
- // or via a `pragam float_control`.
- // __FLT_EVAL_METHOD__ expands to -1.
- // The `minus` operator is the next token we read from the stream.
- auto Toks = std::make_unique<Token[]>(1);
- OS << "-";
- Tok.setKind(tok::minus);
- // Push the token `1` to the stream.
- Token NumberToken;
- NumberToken.startToken();
- NumberToken.setKind(tok::numeric_constant);
- NumberToken.setLiteralData("1");
- NumberToken.setLength(1);
- Toks[0] = NumberToken;
- EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion*/ false,
- /*IsReinject*/ false);
- } else {
- OS << getTUFPEvalMethod();
- // __FLT_EVAL_METHOD__ expands to a simple numeric value.
- Tok.setKind(tok::numeric_constant);
- if (getLastFPEvalPragmaLocation().isValid()) {
- // The program is ill-formed. The value of __FLT_EVAL_METHOD__ is
- // altered by the pragma.
- Diag(Tok, diag::err_illegal_use_of_flt_eval_macro);
- Diag(getLastFPEvalPragmaLocation(), diag::note_pragma_entered_here);
- }
+ OS << getTUFPEvalMethod();
+ // __FLT_EVAL_METHOD__ expands to a simple numeric value.
+ Tok.setKind(tok::numeric_constant);
+ if (getLastFPEvalPragmaLocation().isValid()) {
+ // The program is ill-formed. The value of __FLT_EVAL_METHOD__ is altered
+ // by the pragma.
+ Diag(Tok, diag::err_illegal_use_of_flt_eval_macro);
+ Diag(getLastFPEvalPragmaLocation(), diag::note_pragma_entered_here);
}
} else if (II == Ident__COUNTER__) {
// __COUNTER__ expands to a simple numeric value.
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index d9a51b7..0d411ab 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -207,11 +207,6 @@
else
// Set initial value of __FLT_EVAL_METHOD__ from the command line.
setCurrentFPEvalMethod(SourceLocation(), getLangOpts().getFPEvalMethod());
- // When `-ffast-math` option is enabled, it triggers several driver math
- // options to be enabled. Among those, only one the following two modes
- // affect the eval-method: reciprocal or reassociate.
- if (getLangOpts().AllowFPReassoc || getLangOpts().AllowRecip)
- setCurrentFPEvalMethod(SourceLocation(), LangOptions::FEM_Indeterminable);
}
void Preprocessor::InitializeForModelFile() {
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 42f5827..3ea97f6 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -565,13 +565,6 @@
case PFC_Precise:
NewFPFeatures.setFPPreciseEnabled(true);
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
- if (PP.getCurrentFPEvalMethod() ==
- LangOptions::FPEvalMethodKind::FEM_Indeterminable &&
- PP.getLastFPEvalPragmaLocation().isValid())
- // A preceding `pragma float_control(precise,off)` has changed
- // the value of the evaluation method.
- // Set it back to its old value.
- PP.setCurrentFPEvalMethod(SourceLocation(), PP.getLastFPEvalMethod());
break;
case PFC_NoPrecise:
if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict)
@@ -581,10 +574,6 @@
else
NewFPFeatures.setFPPreciseEnabled(false);
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
- PP.setLastFPEvalMethod(PP.getCurrentFPEvalMethod());
- // `AllowFPReassoc` or `AllowReciprocal` option is enabled.
- PP.setCurrentFPEvalMethod(
- Loc, LangOptions::FPEvalMethodKind::FEM_Indeterminable);
break;
case PFC_Except:
if (!isPreciseFPEnabled())
@@ -608,12 +597,6 @@
}
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
NewFPFeatures = FpPragmaStack.CurrentValue;
- if (CurFPFeatures.getAllowFPReassociate() ||
- CurFPFeatures.getAllowReciprocal())
- // Since we are popping the pragma, we don't want to be passing
- // a location here.
- PP.setCurrentFPEvalMethod(SourceLocation(),
- CurFPFeatures.getFPEvalMethod());
break;
}
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
diff --git a/clang/test/CodeGen/X86/fexcess-precision.c b/clang/test/CodeGen/X86/fexcess-precision.c
index 3257068..68c2f76 100644
--- a/clang/test/CodeGen/X86/fexcess-precision.c
+++ b/clang/test/CodeGen/X86/fexcess-precision.c
@@ -380,7 +380,7 @@
//
// CHECK-UNSAFE-LABEL: @getFEM(
// CHECK-UNSAFE-NEXT: entry:
-// CHECK-UNSAFE-NEXT: ret i32 -1
+// CHECK-UNSAFE-NEXT: ret i32 0
//
int getFEM() {
return __FLT_EVAL_METHOD__;
diff --git a/clang/test/CodeGen/eval-method-fast-math.cpp b/clang/test/CodeGen/eval-method-fast-math.cpp
deleted file mode 100644
index 0b5b378..0000000
--- a/clang/test/CodeGen/eval-method-fast-math.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-// RUN: %clang_cc1 -fexperimental-strict-floating-point \
-// RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s \
-// RUN: | FileCheck %s -check-prefixes=CHECK
-
-// RUN: %clang_cc1 -triple i386--linux -emit-llvm -o - %s \
-// RUN: | FileCheck %s -check-prefixes=CHECK-EXT
-
-// RUN: %clang_cc1 -fexperimental-strict-floating-point \
-// RUN: -mreassociate -freciprocal-math -ffp-contract=fast \
-// RUN: -ffast-math -triple x86_64-linux-gnu \
-// RUN: -emit-llvm -o - %s \
-// RUN: | FileCheck %s -check-prefixes=CHECK-FAST
-
-// RUN: %clang_cc1 -triple i386--linux -mreassociate -freciprocal-math \
-// RUN: -ffp-contract=fast -ffast-math -emit-llvm -o - %s \
-// RUN: | FileCheck %s -check-prefixes=CHECK-FAST
-
-float a = 1.0f, b = 2.0f, c = 3.0f;
-#pragma float_control(precise, off)
-float res2 = a + b + c;
-int val3 = __FLT_EVAL_METHOD__;
-#pragma float_control(precise, on)
-float res3 = a + b + c;
-int val4 = __FLT_EVAL_METHOD__;
-
-// CHECK: @val3 = global i32 -1
-// CHECK: @val4 = global i32 0
-
-// CHECK-EXT: @val3 = global i32 -1
-// CHECK-EXT: @val4 = global i32 2
-
-// CHECK-FAST: @val3 = global i32 -1
-// CHECK-FAST: @val4 = global i32 -1
-
-float res;
-int add(float a, float b, float c) {
- // CHECK: fadd float
- // CHECK: load float, ptr
- // CHECK: fadd float
- // CHECK: store float
- // CHECK: ret i32 0
- res = a + b + c;
- return __FLT_EVAL_METHOD__;
-}
-
-int add_precise(float a, float b, float c) {
-#pragma float_control(precise, on)
- // CHECK: fadd float
- // CHECK: load float, ptr
- // CHECK: fadd float
- // CHECK: store float
- // CHECK: ret i32 0
- res = a + b + c;
- return __FLT_EVAL_METHOD__;
-}
-
-#pragma float_control(push)
-#pragma float_control(precise, on)
-int add_precise_1(float a, float b, float c) {
- // CHECK: fadd float
- // CHECK: load float, ptr
- // CHECK: fadd float
- // CHECK: store float
- // CHECK: ret i32 0
- res = a + b + c;
- return __FLT_EVAL_METHOD__;
-}
-#pragma float_control(pop)
-
-int add_not_precise(float a, float b, float c) {
- // Fast-math is enabled with this pragma.
-#pragma float_control(precise, off)
- // CHECK: fadd fast float
- // CHECK: load float, ptr
- // CHECK: fadd fast float
- // CHECK: float {{.*}}, ptr
- // CHECK: ret i32 -1
- res = a + b + c;
- return __FLT_EVAL_METHOD__;
-}
-
-#pragma float_control(push)
-// Fast-math is enabled with this pragma.
-#pragma float_control(precise, off)
-int add_not_precise_1(float a, float b, float c) {
- // CHECK: fadd fast float
- // CHECK: load float, ptr
- // CHECK: fadd fast float
- // CHECK: float {{.*}}, ptr
- // CHECK: ret i32 -1
- res = a + b + c;
- return __FLT_EVAL_METHOD__;
-}
-#pragma float_control(pop)
-
-int getFPEvalMethod() {
- // CHECK: ret i32 0
- return __FLT_EVAL_METHOD__;
-}
-
-float res1;
-int whatever(float a, float b, float c) {
-#pragma float_control(precise, off)
- // CHECK: load float, ptr
- // CHECK: fadd fast float
- // CHECK: store float {{.*}}, ptr
- // CHECK: store i32 -1
- // CHECK: store i32 0
- // CHECK: ret i32 -1
- res1 = a + b + c;
- int val1 = __FLT_EVAL_METHOD__;
- {
-#pragma float_control(precise, on)
- int val2 = __FLT_EVAL_METHOD__;
- }
- return __FLT_EVAL_METHOD__;
-}
diff --git a/clang/test/Preprocessor/flt_eval_macro.cpp b/clang/test/Preprocessor/flt_eval_macro.cpp
index 37c28f2..fa5d6fc 100644
--- a/clang/test/Preprocessor/flt_eval_macro.cpp
+++ b/clang/test/Preprocessor/flt_eval_macro.cpp
@@ -17,7 +17,7 @@
// RUN: %s -o - | FileCheck %s -strict-whitespace
// RUN: %clang_cc1 -E -dM -triple=x86_64-apple-macos13.0 -ffast-math \
-// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-MINUS-ONE -strict-whitespace
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK -strict-whitespace
// RUN: %clang_cc1 -E -dM -triple i386-pc-windows -target-cpu pentium4 %s -o - \
// RUN: | FileCheck %s -strict-whitespace
@@ -64,7 +64,6 @@
int foo() {
// CHECK: #define Name "One"
- // CHECK-MINUS-ONE: #define Name "MinusOne"
// EXT: #define Name "Three"
return Name;
}