https://github.com/spavloff updated 
https://github.com/llvm/llvm-project/pull/85605

>From 5049e0209e240f0f8a3ccb6e248d55d1480b7bad Mon Sep 17 00:00:00 2001
From: Serge Pavlov <sepavl...@gmail.com>
Date: Mon, 18 Mar 2024 13:20:15 +0700
Subject: [PATCH 1/2] [clang] Set correct FPOptions if attribute 'optnone'
 presents

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.
---
 clang/include/clang/Basic/LangOptions.h | 11 +++++++++++
 clang/include/clang/Sema/Sema.h         |  1 +
 clang/lib/Parse/ParseStmt.cpp           |  4 ++++
 clang/lib/Sema/SemaDecl.cpp             | 10 ++++++++++
 clang/test/AST/ast-dump-fpfeatures.cpp  | 11 +++++++++++
 5 files changed, 37 insertions(+)

diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index 08fc706e3cbf74..19c60a8cb5e946 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -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 {                                                     
\
@@ -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) |
@@ -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.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 95ea5ebc7f1ac1..ccc2ded67589ec 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -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
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 76a3fa8f2627de..489ae9f167b95d 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -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.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5850cd0ab6b9aa..1f52f5e57e5376 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15919,6 +15919,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope 
*FnBodyScope, Decl *D,
   return D;
 }
 
+void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) {
+  if (FD && 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.
diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp 
b/clang/test/AST/ast-dump-fpfeatures.cpp
index da0011602a728e..5eda5528c07018 100644
--- a/clang/test/AST/ast-dump-fpfeatures.cpp
+++ b/clang/test/AST/ast-dump-fpfeatures.cpp
@@ -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' '+' 
ConstRoundingMode=downward MathErrno=1

>From 87c855dd05cb12a0d2b5e4329848c889a68498df Mon Sep 17 00:00:00 2001
From: Serge Pavlov <sepavl...@gmail.com>
Date: Wed, 20 Mar 2024 23:22:49 +0700
Subject: [PATCH 2/2] Support more cases of function body

---
 clang/lib/Parse/ParseStmt.cpp          |  4 ----
 clang/lib/Parse/Parser.cpp             |  4 ++++
 clang/test/AST/ast-dump-fpfeatures.cpp | 24 ++++++++++++++++++++++++
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 489ae9f167b95d..76a3fa8f2627de 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2508,10 +2508,6 @@ 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.
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index cc0e41ed221c4f..e4b8757c38f7f4 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1495,6 +1495,10 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator 
&D,
     return Actions.ActOnFinishFunctionBody(Res, nullptr, false);
   }
 
+  // Some function attributes (like OptimizeNoneAttr) affect FP options.
+  Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
+  Actions.applyFunctionAttributesBeforeParsingBody(Res);
+
   if (Tok.is(tok::kw_try))
     return ParseFunctionTryBlock(Res, BodyScope);
 
diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp 
b/clang/test/AST/ast-dump-fpfeatures.cpp
index 5eda5528c07018..e2a941d30b0cf9 100644
--- a/clang/test/AST/ast-dump-fpfeatures.cpp
+++ b/clang/test/AST/ast-dump-fpfeatures.cpp
@@ -189,6 +189,7 @@ float func_18(float x, float y) {
 // CHECK:             BinaryOperator {{.*}} ConstRoundingMode=downward
 
 #pragma float_control(precise, off)
+
 __attribute__((optnone))
 float func_19(float x, float y) {
   return x + y;
@@ -198,3 +199,26 @@ float func_19(float x, float y) {
 // CHECK:         CompoundStmt {{.*}} MathErrno=1
 // CHECK:           ReturnStmt
 // CHECK:             BinaryOperator {{.*}} 'float' '+' 
ConstRoundingMode=downward MathErrno=1
+
+__attribute__((optnone))
+float func_20(float x, float y) try {
+  return x + y;
+} catch (...) {
+  return 1.0;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_20 'float (float, float)'
+// CHECK:         CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1
+// CHECK:           ReturnStmt
+// CHECK:             BinaryOperator {{.*}} 'float' '+' 
ConstRoundingMode=downward MathErrno=1
+
+struct C21 {
+  C21(float x, float y);
+  float member;
+};
+
+__attribute__((optnone)) C21::C21(float x, float y) : member(x + y) {}
+
+// CHECK-LABEL: CXXConstructorDecl {{.*}} C21 'void (float, float)'
+// CHECK:         CXXCtorInitializer {{.*}} 'member' 'float'
+// CHECK:           BinaryOperator {{.*}} 'float' '+' 
ConstRoundingMode=downward MathErrno=1

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to