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 bbf0d1932a.
This commit is contained in:
Zahira Ammarguellat
2023-03-09 09:24:01 -05:00
parent 99b7c2bad3
commit 2f1264260b
7 changed files with 10 additions and 184 deletions

View File

@@ -193,11 +193,6 @@ class Preprocessor {
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 @@ public:
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 &&

View File

@@ -1637,35 +1637,14 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
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.

View File

@@ -207,11 +207,6 @@ void Preprocessor::Initialize(const TargetInfo &Target,
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() {

View File

@@ -565,13 +565,6 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
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 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
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 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
}
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());

View File

@@ -380,7 +380,7 @@ _Float16 f(_Float16 a, _Float16 b, _Float16 c, _Float16 d) {
//
// 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__;

View File

@@ -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__;
}

View File

@@ -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;
}