Skip to content

Commit

Permalink
[clang] Set correct FPOptions if attribute 'optnone' presents
Browse files Browse the repository at this point in the history
Attribute `optnone` must turn off all optimizations including fast-math
ones. Actually AST nodes in the 'optnone' function still had fast-math
flags. This change implements fixing FP options before function body is
parsed.
  • Loading branch information
spavloff committed Mar 18, 2024
1 parent 65ae09e commit 24c96a1
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 0 deletions.
11 changes: 11 additions & 0 deletions clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,8 @@ class FPOptions {
/// Return difference with the given option set.
FPOptionsOverride getChangesFrom(const FPOptions &Base) const;

void applyChanges(FPOptionsOverride FPO);

// We can define most of the accessors automatically:
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
TYPE get##NAME() const { \
Expand Down Expand Up @@ -923,6 +925,11 @@ class FPOptionsOverride {
setAllowFPContractAcrossStatement();
}

void setDisallowOptimizations() {
setFPPreciseEnabled(true);
setDisallowFPContract();
}

storage_type getAsOpaqueInt() const {
return (static_cast<storage_type>(Options.getAsOpaqueInt())
<< FPOptions::StorageBitSize) |
Expand Down Expand Up @@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const
return getChangesSlow(Base);
}

inline void FPOptions::applyChanges(FPOptionsOverride FPO) {
*this = FPO.applyOverrides(*this);
}

/// Describes the kind of translation unit being processed.
enum TranslationUnitKind {
/// The translation unit is a complete translation unit.
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -3222,6 +3222,7 @@ class Sema final {
Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D,
SkipBodyInfo *SkipBody = nullptr,
FnBodyKind BodyKind = FnBodyKind::Other);
void applyFunctionAttributesBeforeParsingBody(Decl *FD);

/// Determine whether we can delay parsing the body of a function or
/// function template until it is used, assuming we don't care about emitting
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2508,6 +2508,10 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
Sema::PragmaStackSentinelRAII
PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);

// Some function attributes (like OptimizeNoneAttr) affect FP options.
Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
Actions.applyFunctionAttributesBeforeParsingBody(Decl);

// Do not enter a scope for the brace, as the arguments are in the same scope
// (the function body) as the body itself. Instead, just read the statement
// list and put it into a CompoundStmt for safe keeping.
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15919,6 +15919,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
return D;
}

void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) {
if (FD->hasAttr<OptimizeNoneAttr>()) {
FPOptionsOverride FPO;
FPO.setDisallowOptimizations();
CurFPFeatures.applyChanges(FPO);
FpPragmaStack.CurrentValue =
CurFPFeatures.getChangesFrom(FPOptions(LangOpts));
}
}

/// Given the set of return statements within a function body,
/// compute the variables that are subject to the named return value
/// optimization.
Expand Down
11 changes: 11 additions & 0 deletions clang/test/AST/ast-dump-fpfeatures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,14 @@ float func_18(float x, float y) {
// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward
// CHECK: ReturnStmt
// CHECK: BinaryOperator {{.*}} ConstRoundingMode=downward

#pragma float_control(precise, off)
__attribute__((optnone))
float func_19(float x, float y) {
return x + y;
}

// CHECK-LABEL: FunctionDecl {{.*}} func_19 'float (float, float)'
// CHECK: CompoundStmt {{.*}} MathErrno=1
// CHECK: ReturnStmt
// CHECK: BinaryOperator {{.*}} 'float' '+' MathErrno=1

0 comments on commit 24c96a1

Please sign in to comment.