[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-04-25 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Hi @dyung.

The observed difference is due to the FP contraction turned off if optnone is 
specified. In O0 this optimization is still applied. As a result, the function 
with optnone contains separate fadd and fmul, while without this attribute the 
function contains combined operatin fmuladd.

This optimization is turned off in `FPOption.setDisallowOptimizations` 
(introduced by this patch) by the call `setDisallowFPContract()`. If it is 
removed, I think, the output would be identical.

https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Implementation of '#pragma STDC FENV_ROUND' (PR #89617)

2024-04-25 Thread Serge Pavlov via cfe-commits

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

>From 0fc5c57264ecf51f8b9fe8303520a51cb1fee40e Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Thu, 14 Apr 2022 18:00:14 +0700
Subject: [PATCH 1/2] Implementation of '#pragma STDC FENV_ROUND'

This pragma is introduced by forthcoming C2x standard and can be used to
set particular rounding mode without need to call 'fesetmode' or accessing
control mode registers directly. Previously this pragma was implemented in
clang partially, only for the purpose of using in constant expressions and
making tests.

This change implements the pragma according to the standard draft. It sets
up dynamic rounding mode in the compound statement where the pragma acts.
This is inevitable for targets that set rounding mode by changing some
control register. Targets that support static rounding mode encoded in
instructions can have more efficient implementation, it is not
implemented in this change.

The implementation uses intrinsic functions 'get_rounding' and
'set_rounding' to save/restore dynamic rounding mode. In some cases
using functions that operate entire set of control modes or even FP
environment may give more efficient implementation. This optimization is
not a part of this change.
---
 clang/include/clang/AST/Stmt.h|   9 +
 .../clang/Basic/DiagnosticParseKinds.td   |   3 -
 clang/include/clang/Basic/LangOptions.h   |   6 +
 clang/lib/CodeGen/CGStmt.cpp  |  56 ++
 clang/lib/CodeGen/CodeGenFunction.h   |   3 +
 clang/lib/Parse/ParsePragma.cpp   |   3 -
 clang/test/CodeGen/complex-strictfp.c |  60 ---
 clang/test/CodeGen/math-errno.c   |   6 +-
 clang/test/CodeGen/pragma-fenv_access.c   |  45 -
 clang/test/CodeGen/pragma-fenv_round.c| 160 ++
 clang/test/Parser/pragma-fenv_round.c |   1 -
 11 files changed, 315 insertions(+), 37 deletions(-)
 create mode 100644 clang/test/CodeGen/pragma-fenv_round.c

diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 9cd7a364cd3f1d..6eceecd93e59c2 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1658,6 +1658,15 @@ class CompoundStmt final
 return *getTrailingObjects();
   }
 
+  /// Get FPOptions inside this statement. They may differ from the outer
+  /// options due to pragmas.
+  /// \param CurFPOptions FPOptions outside this statement.
+  FPOptions getNewFPOptions(FPOptions CurFPOptions) const {
+return hasStoredFPFeatures()
+   ? getStoredFPFeatures().applyOverrides(CurFPOptions)
+   : CurFPOptions;
+  }
+
   using body_iterator = Stmt **;
   using body_range = llvm::iterator_range;
 
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 38174cf3549f14..329af794405998 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1257,9 +1257,6 @@ def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in 
STDC namespace">,
 // The C standard 7.6.1p2 says "The [FENV_ACCESS] pragma shall occur either
 // outside external declarations or preceding all explicit declarations and
 // statements inside a compound statement.
-def warn_stdc_fenv_round_not_supported :
-   Warning<"pragma STDC FENV_ROUND is not supported">,
-   InGroup;
 def warn_stdc_unknown_rounding_mode : Warning<
   "invalid or unsupported rounding mode in '#pragma STDC FENV_ROUND' - 
ignored">,
   InGroup;
diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index ae4715921d1665..28164f564e907d 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -839,6 +839,12 @@ class FPOptions {
getAllowFEnvAccess();
   }
 
+  /// Checks if the rounding mode is unknown at compile-time.
+  bool isRoundingModeDynamic() const {
+return (getConstRoundingMode() == RoundingMode::Dynamic) &&
+   (getAllowFEnvAccess() || getRoundingMath());
+  }
+
   RoundingMode getRoundingMode() const {
 RoundingMode RM = getConstRoundingMode();
 if (RM == RoundingMode::Dynamic) {
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 576fe2f7a2d46f..4fbc906afaeed5 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -486,6 +486,56 @@ bool CodeGenFunction::EmitSimpleStmt(const Stmt *S,
   return true;
 }
 
+namespace {
+/// Cleanup action that restores floating-point control modes upon leaving
+/// a scope.
+struct FPControlModesCleanup final : EHScopeStack::Cleanup {
+  llvm::Value *PreviousModes;
+  FPControlModesCleanup(llvm::Value *M) : PreviousModes(M) {}
+  void Emit(CodeGenFunction , Flags flags) override {
+CGF.Builder.CreateIntrinsic(llvm::Intrinsic::set_rounding, {},
+{PreviousModes});
+  }
+};
+} // 

[clang] Implementation of '#pragma STDC FENV_ROUND' (PR #89617)

2024-04-23 Thread Serge Pavlov via cfe-commits

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

>From 0fc5c57264ecf51f8b9fe8303520a51cb1fee40e Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Thu, 14 Apr 2022 18:00:14 +0700
Subject: [PATCH] Implementation of '#pragma STDC FENV_ROUND'

This pragma is introduced by forthcoming C2x standard and can be used to
set particular rounding mode without need to call 'fesetmode' or accessing
control mode registers directly. Previously this pragma was implemented in
clang partially, only for the purpose of using in constant expressions and
making tests.

This change implements the pragma according to the standard draft. It sets
up dynamic rounding mode in the compound statement where the pragma acts.
This is inevitable for targets that set rounding mode by changing some
control register. Targets that support static rounding mode encoded in
instructions can have more efficient implementation, it is not
implemented in this change.

The implementation uses intrinsic functions 'get_rounding' and
'set_rounding' to save/restore dynamic rounding mode. In some cases
using functions that operate entire set of control modes or even FP
environment may give more efficient implementation. This optimization is
not a part of this change.
---
 clang/include/clang/AST/Stmt.h|   9 +
 .../clang/Basic/DiagnosticParseKinds.td   |   3 -
 clang/include/clang/Basic/LangOptions.h   |   6 +
 clang/lib/CodeGen/CGStmt.cpp  |  56 ++
 clang/lib/CodeGen/CodeGenFunction.h   |   3 +
 clang/lib/Parse/ParsePragma.cpp   |   3 -
 clang/test/CodeGen/complex-strictfp.c |  60 ---
 clang/test/CodeGen/math-errno.c   |   6 +-
 clang/test/CodeGen/pragma-fenv_access.c   |  45 -
 clang/test/CodeGen/pragma-fenv_round.c| 160 ++
 clang/test/Parser/pragma-fenv_round.c |   1 -
 11 files changed, 315 insertions(+), 37 deletions(-)
 create mode 100644 clang/test/CodeGen/pragma-fenv_round.c

diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 9cd7a364cd3f1d..6eceecd93e59c2 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1658,6 +1658,15 @@ class CompoundStmt final
 return *getTrailingObjects();
   }
 
+  /// Get FPOptions inside this statement. They may differ from the outer
+  /// options due to pragmas.
+  /// \param CurFPOptions FPOptions outside this statement.
+  FPOptions getNewFPOptions(FPOptions CurFPOptions) const {
+return hasStoredFPFeatures()
+   ? getStoredFPFeatures().applyOverrides(CurFPOptions)
+   : CurFPOptions;
+  }
+
   using body_iterator = Stmt **;
   using body_range = llvm::iterator_range;
 
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 38174cf3549f14..329af794405998 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1257,9 +1257,6 @@ def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in 
STDC namespace">,
 // The C standard 7.6.1p2 says "The [FENV_ACCESS] pragma shall occur either
 // outside external declarations or preceding all explicit declarations and
 // statements inside a compound statement.
-def warn_stdc_fenv_round_not_supported :
-   Warning<"pragma STDC FENV_ROUND is not supported">,
-   InGroup;
 def warn_stdc_unknown_rounding_mode : Warning<
   "invalid or unsupported rounding mode in '#pragma STDC FENV_ROUND' - 
ignored">,
   InGroup;
diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index ae4715921d1665..28164f564e907d 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -839,6 +839,12 @@ class FPOptions {
getAllowFEnvAccess();
   }
 
+  /// Checks if the rounding mode is unknown at compile-time.
+  bool isRoundingModeDynamic() const {
+return (getConstRoundingMode() == RoundingMode::Dynamic) &&
+   (getAllowFEnvAccess() || getRoundingMath());
+  }
+
   RoundingMode getRoundingMode() const {
 RoundingMode RM = getConstRoundingMode();
 if (RM == RoundingMode::Dynamic) {
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 576fe2f7a2d46f..4fbc906afaeed5 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -486,6 +486,56 @@ bool CodeGenFunction::EmitSimpleStmt(const Stmt *S,
   return true;
 }
 
+namespace {
+/// Cleanup action that restores floating-point control modes upon leaving
+/// a scope.
+struct FPControlModesCleanup final : EHScopeStack::Cleanup {
+  llvm::Value *PreviousModes;
+  FPControlModesCleanup(llvm::Value *M) : PreviousModes(M) {}
+  void Emit(CodeGenFunction , Flags flags) override {
+CGF.Builder.CreateIntrinsic(llvm::Intrinsic::set_rounding, {},
+{PreviousModes});
+  }
+};
+} // 

[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-04-23 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Thanks!

> Is there any existing bookkeeping we no longer need to do if we're going to 
> have this RAII object in scope during function parsing?

It seems handling fast-math is the only case that prevented using this RAII 
object.

https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-04-23 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff closed 
https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Implementation of '#pragma STDC FENV_ROUND' (PR #89617)

2024-04-22 Thread Serge Pavlov via cfe-commits

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

>From fc7aab600c25b39b2df039c0cbcf517719736311 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Thu, 14 Apr 2022 18:00:14 +0700
Subject: [PATCH] Implementation of '#pragma STDC FENV_ROUND'

This pragma is introduced by forthcoming C2x standard and can be used to
set particular rounding mode without need to call 'fesetmode' or accessing
control mode registers directly. Previously this pragma was implemented in
clang partially, only for the purpose of using in constant expressions and
making tests.

This change implements the pragma according to the standard draft. It sets
up dynamic rounding mode in the compound statement where the pragma acts.
This is inevitable for targets that set rounding mode by changing some
control register. Targets that support static rounding mode encoded in
instructions can have more efficient implementation, it is not
implemented in this change.

The implementation uses intrinsic functions 'get_rounding' and
'set_rounding' to save/restore dynamic rounding mode. In some cases
using functions that operate entire set of control modes or even FP
environment may give more efficient implementation. This optimization is
not a part of this change.
---
 clang/include/clang/AST/Stmt.h|   9 +
 .../clang/Basic/DiagnosticParseKinds.td   |   3 -
 clang/include/clang/Basic/LangOptions.h   |   6 +
 clang/lib/CodeGen/CGStmt.cpp  |  56 ++
 clang/lib/CodeGen/CodeGenFunction.h   |   3 +
 clang/lib/Parse/ParsePragma.cpp   |   3 -
 clang/test/CodeGen/complex-strictfp.c |  60 ---
 clang/test/CodeGen/math-errno.c   |   2 +-
 clang/test/CodeGen/pragma-fenv_access.c   |  45 -
 clang/test/CodeGen/pragma-fenv_round.c| 160 ++
 clang/test/Parser/pragma-fenv_round.c |   1 -
 11 files changed, 313 insertions(+), 35 deletions(-)
 create mode 100644 clang/test/CodeGen/pragma-fenv_round.c

diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 1b9c9231047717..0ee9c13df75e41 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1663,6 +1663,15 @@ class CompoundStmt final
 return *getTrailingObjects();
   }
 
+  /// Get FPOptions inside this statement. They may differ from the outer
+  /// options due to pragmas.
+  /// \param CurFPOptions FPOptions outside this statement.
+  FPOptions getNewFPOptions(FPOptions CurFPOptions) const {
+return hasStoredFPFeatures()
+   ? getStoredFPFeatures().applyOverrides(CurFPOptions)
+   : CurFPOptions;
+  }
+
   using body_iterator = Stmt **;
   using body_range = llvm::iterator_range;
 
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index bb9ca2a50cc06c..cbda8975717d2e 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1255,9 +1255,6 @@ def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in 
STDC namespace">,
 // The C standard 7.6.1p2 says "The [FENV_ACCESS] pragma shall occur either
 // outside external declarations or preceding all explicit declarations and
 // statements inside a compound statement.
-def warn_stdc_fenv_round_not_supported :
-   Warning<"pragma STDC FENV_ROUND is not supported">,
-   InGroup;
 def warn_stdc_unknown_rounding_mode : Warning<
   "invalid or unsupported rounding mode in '#pragma STDC FENV_ROUND' - 
ignored">,
   InGroup;
diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index 24b109e32cdd3e..ae8c7b2ead8ee2 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -834,6 +834,12 @@ class FPOptions {
getAllowFEnvAccess();
   }
 
+  /// Checks if the rounding mode is unknown at compile-time.
+  bool isRoundingModeDynamic() const {
+return (getConstRoundingMode() == RoundingMode::Dynamic) &&
+   (getAllowFEnvAccess() || getRoundingMath());
+  }
+
   RoundingMode getRoundingMode() const {
 RoundingMode RM = getConstRoundingMode();
 if (RM == RoundingMode::Dynamic) {
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 576fe2f7a2d46f..4fbc906afaeed5 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -486,6 +486,56 @@ bool CodeGenFunction::EmitSimpleStmt(const Stmt *S,
   return true;
 }
 
+namespace {
+/// Cleanup action that restores floating-point control modes upon leaving
+/// a scope.
+struct FPControlModesCleanup final : EHScopeStack::Cleanup {
+  llvm::Value *PreviousModes;
+  FPControlModesCleanup(llvm::Value *M) : PreviousModes(M) {}
+  void Emit(CodeGenFunction , Flags flags) override {
+CGF.Builder.CreateIntrinsic(llvm::Intrinsic::set_rounding, {},
+{PreviousModes});
+  }
+};
+} // 

[clang] Implementation of '#pragma STDC FENV_ROUND' (PR #89617)

2024-04-22 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff created 
https://github.com/llvm/llvm-project/pull/89617

This pragma is introduced by forthcoming C2x standard and can be used to set 
particular rounding mode without need to call 'fesetmode' or accessing control 
mode registers directly. Previously this pragma was implemented in clang 
partially, only for the purpose of using in constant expressions and making 
tests.

This change implements the pragma according to the standard draft. It sets up 
dynamic rounding mode in the compound statement where the pragma acts. This is 
inevitable for targets that set rounding mode by changing some control 
register. Targets that support static rounding mode encoded in instructions can 
have more efficient implementation, it is not implemented in this change.

The implementation uses intrinsic functions 'get_rounding' and 'set_rounding' 
to save/restore dynamic rounding mode. In some cases using functions that 
operate entire set of control modes or even FP environment may give more 
efficient implementation. This optimization is not a part of this change.

>From 58adf3643828272d071fd49195cfcf0b2164eb70 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Thu, 14 Apr 2022 18:00:14 +0700
Subject: [PATCH] Implementation of '#pragma STDC FENV_ROUND'

This pragma is introduced by forthcoming C2x standard and can be used to
set particular rounding mode without need to call 'fesetmode' or accessing
control mode registers directly. Previously this pragma was implemented in
clang partially, only for the purpose of using in constant expressions and
making tests.

This change implements the pragma according to the standard draft. It sets
up dynamic rounding mode in the compound statement where the pragma acts.
This is inevitable for targets that set rounding mode by changing some
control register. Targets that support static rounding mode encoded in
instructions can have more efficient implementation, it is not
implemented in this change.

The implementation uses intrinsic functions 'get_rounding' and
'set_rounding' to save/restore dynamic rounding mode. In some cases
using functions that operate entire set of control modes or even FP
environment may give more efficient implementation. This optimization is
not a part of this change.
---
 clang/include/clang/AST/Stmt.h|   9 +
 .../clang/Basic/DiagnosticParseKinds.td   |   3 -
 clang/include/clang/Basic/LangOptions.h   |   6 +
 clang/lib/CodeGen/CGStmt.cpp  |  56 ++
 clang/lib/CodeGen/CodeGenFunction.h   |   3 +
 clang/lib/Parse/ParsePragma.cpp   |   3 -
 clang/test/CodeGen/complex-strictfp.c |  60 ---
 clang/test/CodeGen/math-errno.c   |   2 +-
 clang/test/CodeGen/pragma-fenv_access.c   |  45 -
 clang/test/CodeGen/pragma-fenv_round.c| 160 ++
 clang/test/Parser/pragma-fenv_round.c |   1 -
 11 files changed, 313 insertions(+), 35 deletions(-)
 create mode 100644 clang/test/CodeGen/pragma-fenv_round.c

diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 1b9c9231047717..0ee9c13df75e41 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1663,6 +1663,15 @@ class CompoundStmt final
 return *getTrailingObjects();
   }
 
+  /// Get FPOptions inside this statement. They may differ from the outer
+  /// options due to pragmas.
+  /// \param CurFPOptions FPOptions outside this statement.
+  FPOptions getNewFPOptions(FPOptions CurFPOptions) const {
+return hasStoredFPFeatures()
+   ? getStoredFPFeatures().applyOverrides(CurFPOptions)
+   : CurFPOptions;
+  }
+
   using body_iterator = Stmt **;
   using body_range = llvm::iterator_range;
 
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index bb9ca2a50cc06c..cbda8975717d2e 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1255,9 +1255,6 @@ def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in 
STDC namespace">,
 // The C standard 7.6.1p2 says "The [FENV_ACCESS] pragma shall occur either
 // outside external declarations or preceding all explicit declarations and
 // statements inside a compound statement.
-def warn_stdc_fenv_round_not_supported :
-   Warning<"pragma STDC FENV_ROUND is not supported">,
-   InGroup;
 def warn_stdc_unknown_rounding_mode : Warning<
   "invalid or unsupported rounding mode in '#pragma STDC FENV_ROUND' - 
ignored">,
   InGroup;
diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index 24b109e32cdd3e..2ec642e25ddcc6 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -834,6 +834,12 @@ class FPOptions {
getAllowFEnvAccess();
   }
 
+  /// Checks if the rounding mode is unknown at compile-time.
+  bool 

[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-04-22 Thread Serge Pavlov via cfe-commits

spavloff wrote:

A little about the significance of this fix. To implement pragma FENV_ROUND, we 
need to apply the FP options stored in the instance of CompoundStmt to the 
builder object, so that it uses the specified rounding mode. It can be done 
using the class CGFPOptionsRAII. However in this case a couple of issues rise, 
both related to fast-math. This patch is intended to fix one of them an is a 
prerequisite for pragma FENV_ROUND implementation.

https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-04-15 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Ping.

https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-04-15 Thread Serge Pavlov via cfe-commits

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

>From 07e171e0566ab584299a57c210106bb8220c6261 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 18 Mar 2024 13:20:15 +0700
Subject: [PATCH 1/4] [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 24b109e32cdd3e..f7d304d7ad9a7d 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -873,6 +873,8 @@ class FPOptions {
   /// Return difference with the given option set.
   FPOptionsOverride getChangesFrom(const FPOptions ) const;
 
+  void applyChanges(FPOptionsOverride FPO);
+
   // We can define most of the accessors automatically:
 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)
\
   TYPE get##NAME() const { 
\
@@ -954,6 +956,11 @@ class FPOptionsOverride {
   setAllowFPContractAcrossStatement();
   }
 
+  void setDisallowOptimizations() {
+setFPPreciseEnabled(true);
+setDisallowFPContract();
+  }
+
   storage_type getAsOpaqueInt() const {
 return (static_cast(Options.getAsOpaqueInt())
 << FPOptions::StorageBitSize) |
@@ -1010,6 +1017,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const 
FPOptions ) 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 c6e0332c3176b3..f14a27b4d694ed 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3072,6 +3072,7 @@ class Sema final : public SemaBase {
   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 ) {
   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 8b3b9d020db572..f5fc1de8db5574 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15910,6 +15910,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope 
*FnBodyScope, Decl *D,
   return D;
 }
 
+void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) {
+  if (FD && FD->hasAttr()) {
+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 

[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-24 Thread Serge Pavlov via cfe-commits

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 
Date: Mon, 18 Mar 2024 13:20:15 +0700
Subject: [PATCH 1/4] [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 ) 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(Options.getAsOpaqueInt())
 << FPOptions::StorageBitSize) |
@@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const 
FPOptions ) 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 ) {
   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()) {
+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;
+}
+
+// 

[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-20 Thread Serge Pavlov via cfe-commits

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 
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 ) 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(Options.getAsOpaqueInt())
 << FPOptions::StorageBitSize) |
@@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const 
FPOptions ) 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 ) {
   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()) {
+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;
+}
+
+// 

[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-20 Thread Serge Pavlov via cfe-commits

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 
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 ) 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(Options.getAsOpaqueInt())
 << FPOptions::StorageBitSize) |
@@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const 
FPOptions ) 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 ) {
   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()) {
+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;
+}
+
+// 

[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-19 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff ready_for_review 
https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-19 Thread Serge Pavlov via cfe-commits

spavloff wrote:

> optnone is a very strange attribute; it's a directive to the compiler with no 
> clear semantics.

`fast-math` also does not have clear semantics. It is however used to express 
user's expectations that some assumptions are valid. `optnone` could also be 
treated from similar viewpoint. It is very convenient for a user to have a "big 
switch" that would turn off "all" things that can complicate code generation. 
Which transformations are optimizations that should be turned off by optnone - 
it depends on user expectations. Fast-math options are definitely in this list, 
- they are unsafe transformations aimed at performance.

> And presumably they don't actually want to disable all optimization of their 
> function anyway; they just want to turn off fast math.

They can use `#pragma float_control(precise, on)`. However `optnone`, according 
to the documentation, is also a legitimate way to turn off fast math.

> I have uploaded your patch and compared the attributes generated from your 
> patch and the little test case from 
> https://github.com/llvm/llvm-project/issues/62098. The attributes generated 
> are different. Therefore, the expected optimizations from this patch are 
> going to be different than what we currently have. I think that's a problem.

Exactly. User specifies attribute `optnone` but the functions has attribute 
"no-infs-fp-math"="true", which is unsafe optimization. Even if this function 
is not transformed in IR pipeline, the attribute can cause CodeGen to emit code 
as if fast-math is in effect. Such behavior contradicts the meaning of 
`optnone` described in documenttion.

https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-18 Thread Serge Pavlov via cfe-commits

spavloff wrote:

> Hmm. Is there some sort of optimization in IRGen that we need to suppress 
> here, or is it something in LLVM code gen? Presumably normal LLVM 
> optimization passes all just skip `optnone` functions.

The issue https://github.com/llvm/llvm-project/issues/62098 demonstrates such 
case. Anyway, It is not good to have bogus attributes in AST.

> Mostly I'm wondering how far we're expected to go with `optnone`.

It impedes implementation of pragma FENV_ROUND. The pragma requires setting FP 
options inside CompoundStmt and it interacts with the fictious attributes. This 
is the reason of this patch.



https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-18 Thread Serge Pavlov via cfe-commits

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 
Date: Mon, 18 Mar 2024 13:20:15 +0700
Subject: [PATCH] [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 ) 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(Options.getAsOpaqueInt())
 << FPOptions::StorageBitSize) |
@@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const 
FPOptions ) 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 ) {
   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()) {
+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;
+}
+
+// 

[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-18 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff converted_to_draft 
https://github.com/llvm/llvm-project/pull/85605
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Set correct FPOptions if attribute 'optnone' presents (PR #85605)

2024-03-18 Thread Serge Pavlov via cfe-commits

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

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.

>From 24c96a1f43b8d2e0977331c92aec1c14ccc504a2 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 18 Mar 2024 13:20:15 +0700
Subject: [PATCH] [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 ) 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(Options.getAsOpaqueInt())
 << FPOptions::StorageBitSize) |
@@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const 
FPOptions ) 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 ) {
   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..59c327515dba70 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->hasAttr()) {
+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..f6e9d3637417e6 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: 

[clang-tools-extra] [llvm] [clang] [GlobalISel][ARM] Legalze set_fpenv and get_fpenv (PR #79852)

2024-02-03 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff closed 
https://github.com/llvm/llvm-project/pull/79852
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [clang] [GlobalISel][ARM] Legalze set_fpenv and get_fpenv (PR #79852)

2024-02-03 Thread Serge Pavlov via cfe-commits

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

>From b0cd3a40ecaac9ca49c7a0e697ecdbe2b6c899e2 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 29 Jan 2024 21:09:40 +0700
Subject: [PATCH 1/2] [GlobalISel][ARM] Legalze set_fpenv and get_fpenv

Implement handling of get/set floating point environment for ARM in
Global Instruction Selector. Lowering of these intrinsics to operations
on FPSCR was previously inplemented in DAG selector, in GlobalISel it
is reused.
---
 llvm/lib/Target/ARM/ARMLegalizerInfo.cpp|  8 +++
 llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp |  8 +++
 llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll   | 78 +
 3 files changed, 94 insertions(+)
 create mode 100644 llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll

diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp 
b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
index abea0fef5cdc5..7bf44abf3fa8f 100644
--- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
@@ -193,6 +193,11 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget ) 
{
 .legalForCartesianProduct({s32}, {s32, s64});
 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
 .legalForCartesianProduct({s32, s64}, {s32});
+
+getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV})
+  .legalFor({s32});
+getActionDefinitionsBuilder(G_RESET_FPENV)
+  .legalIf([=](const LegalityQuery ) { return true; });
   } else {
 getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
 .libcallFor({s32, s64});
@@ -219,6 +224,9 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget ) {
 .libcallForCartesianProduct({s32}, {s32, s64});
 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
 .libcallForCartesianProduct({s32, s64}, {s32});
+
+getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV})
+.libcall();
   }
 
   // Just expand whatever loads and stores are left.
diff --git a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp 
b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
index 746a8715df0a6..5d4ae9a7648e6 100644
--- a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
@@ -469,6 +469,14 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr 
) const {
 OperandsMapping = getOperandsMapping(OperandBanks);
 break;
   }
+  case G_GET_FPENV:
+  case G_SET_FPENV:
+OperandsMapping =
+getOperandsMapping({::ValueMappings[ARM::GPR3OpsIdx], nullptr});
+break;
+  case G_RESET_FPENV:
+OperandsMapping = getOperandsMapping({nullptr});
+break;
   default:
 return getInvalidInstructionMapping();
   }
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll 
b/llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll
new file mode 100644
index 0..3d18a65bd4345
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll
@@ -0,0 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 4
+; RUN: llc -mtriple=arm-eabi -mattr=+vfp2 -global-isel=1 
--verify-machineinstrs %s -o - | FileCheck %s
+
+declare i32 @llvm.get.fpenv.i32()
+declare void @llvm.set.fpenv.i32(i32)
+declare void @llvm.reset.fpenv()
+
+define i32 @func_get_fpenv() {
+; CHECK-LABEL: func_get_fpenv:
+; CHECK:   @ %bb.0: @ %entry
+; CHECK-NEXT:vmrs r0, fpscr
+; CHECK-NEXT:mov pc, lr
+entry:
+  %fpenv = call i32 @llvm.get.fpenv.i32()
+  ret i32 %fpenv
+}
+
+define i32 @func_get_fpenv_soft() #0 {
+; CHECK-LABEL: func_get_fpenv_soft:
+; CHECK:   @ %bb.0: @ %entry
+; CHECK-NEXT:.save {r4, lr}
+; CHECK-NEXT:push {r4, lr}
+; CHECK-NEXT:.pad #8
+; CHECK-NEXT:sub sp, sp, #8
+; CHECK-NEXT:add r4, sp, #4
+; CHECK-NEXT:mov r0, r4
+; CHECK-NEXT:bl fegetenv
+; CHECK-NEXT:ldr r0, [r4]
+; CHECK-NEXT:add sp, sp, #8
+; CHECK-NEXT:pop {r4, lr}
+; CHECK-NEXT:mov pc, lr
+entry:
+  %fpenv = call i32 @llvm.get.fpenv.i32()
+  ret i32 %fpenv
+}
+
+define void @func_set_fpenv(i32 %fpenv) {
+; CHECK-LABEL: func_set_fpenv:
+; CHECK:   @ %bb.0: @ %entry
+; CHECK-NEXT:vmsr fpscr, r0
+; CHECK-NEXT:mov pc, lr
+entry:
+  call void @llvm.set.fpenv.i32(i32 %fpenv)
+  ret void
+}
+
+define void @func_set_fpenv_soft(i32 %fpenv) #0 {
+; CHECK-LABEL: func_set_fpenv_soft:
+; CHECK:   @ %bb.0: @ %entry
+; CHECK-NEXT:.save {r11, lr}
+; CHECK-NEXT:push {r11, lr}
+; CHECK-NEXT:.pad #8
+; CHECK-NEXT:sub sp, sp, #8
+; CHECK-NEXT:add r1, sp, #4
+; CHECK-NEXT:str r0, [r1]
+; CHECK-NEXT:mov r0, r1
+; CHECK-NEXT:bl fesetenv
+; CHECK-NEXT:add sp, sp, #8
+; CHECK-NEXT:pop {r11, lr}
+; CHECK-NEXT:mov pc, lr
+entry:
+  call void @llvm.set.fpenv.i32(i32 %fpenv)
+  ret void
+}
+
+define void @func_reset() {
+; CHECK-LABEL: func_reset:
+; CHECK:   @ %bb.0: @ %entry
+; CHECK-NEXT:mov r0, #0
+; CHECK-NEXT:vmsr fpscr, r0
+; CHECK-NEXT:mov pc, lr
+entry:
+  call void @llvm.reset.fpenv()
+  

[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-30 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff closed 
https://github.com/llvm/llvm-project/pull/73770
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-30 Thread Serge Pavlov via cfe-commits


@@ -4623,10 +4623,12 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
+llvm::RoundingMode RM =
+E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();

spavloff wrote:

Yes, it should. Thank you!

https://github.com/llvm/llvm-project/pull/73770
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-30 Thread Serge Pavlov via cfe-commits

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

>From 48ed25acfa5765af607efce2309605b96a09d477 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 29 Nov 2023 00:53:54 +0700
Subject: [PATCH 1/2] [clang] Use current rounding mode for float inc/dec

Increment and decrement are equivalent to adding or subtracting 1. For
the floating-point values these operations depend on the current
rounding mode. Teach constant evaluator to perform ++ and -- according
to the current floating-point environment.
---
 clang/lib/AST/ExprConstant.cpp   |  6 --
 clang/test/SemaCXX/rounding-math.cpp | 21 +
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 16697e5f076a8f8..e0abe832c47a9f1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4623,10 +4623,12 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
+llvm::RoundingMode RM =
+E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
 if (AccessKind == AK_Increment)
-  Value.add(One, APFloat::rmNearestTiesToEven);
+  Value.add(One, RM);
 else
-  Value.subtract(One, APFloat::rmNearestTiesToEven);
+  Value.subtract(One, RM);
 return true;
   }
   bool foundPointer(APValue , QualType SubobjType) {
diff --git a/clang/test/SemaCXX/rounding-math.cpp 
b/clang/test/SemaCXX/rounding-math.cpp
index 73f9f10e6d59417..e7ead05041b560d 100644
--- a/clang/test/SemaCXX/rounding-math.cpp
+++ b/clang/test/SemaCXX/rounding-math.cpp
@@ -77,3 +77,24 @@ struct S1d {
   int f;
 };
 static_assert(sizeof(S1d) == sizeof(int), "");
+
+constexpr float incr_down(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+
+// 0x1.0p23 = 8388608.0, inc(8388608.0) = 8388609.0
+static_assert(incr_down(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round down -> 
16777216.0
+static_assert(incr_down(0x1.0p24F) == 0x1.0p24F, "");
+
+#pragma STDC FENV_ROUND FE_UPWARD
+constexpr float incr_up(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+static_assert(incr_up(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round up -> 
16777218.0
+static_assert(incr_up(0x1.0p24F) == 0x1.02p24F, "");

>From 6b558d3737366891ba1afeec91f7d9796b9e8b42 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Thu, 30 Nov 2023 13:25:38 +0700
Subject: [PATCH 2/2] Use getActiveRoundingMode

---
 clang/lib/AST/ExprConstant.cpp | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index e0abe832c47a9f1..2aafe5bd5289fc2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4623,13 +4623,13 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
-llvm::RoundingMode RM =
-E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
+llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
+APFloat::opStatus St;
 if (AccessKind == AK_Increment)
-  Value.add(One, RM);
+  St = Value.add(One, RM);
 else
-  Value.subtract(One, RM);
-return true;
+  St = Value.subtract(One, RM);
+return checkFloatingPointResult(Info, E, St);
   }
   bool foundPointer(APValue , QualType SubobjType) {
 if (!checkConst(SubobjType))

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


[clang] [clang] Use current rounding mode for float inc/dec (PR #73770)

2023-11-29 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff created 
https://github.com/llvm/llvm-project/pull/73770

Increment and decrement are equivalent to adding or subtracting 1. For the 
floating-point values these operations depend on the current rounding mode. 
Teach constant evaluator to perform ++ and -- according to the current 
floating-point environment.

>From 48ed25acfa5765af607efce2309605b96a09d477 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 29 Nov 2023 00:53:54 +0700
Subject: [PATCH] [clang] Use current rounding mode for float inc/dec

Increment and decrement are equivalent to adding or subtracting 1. For
the floating-point values these operations depend on the current
rounding mode. Teach constant evaluator to perform ++ and -- according
to the current floating-point environment.
---
 clang/lib/AST/ExprConstant.cpp   |  6 --
 clang/test/SemaCXX/rounding-math.cpp | 21 +
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 16697e5f076a8f8..e0abe832c47a9f1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4623,10 +4623,12 @@ struct IncDecSubobjectHandler {
 if (Old) *Old = APValue(Value);
 
 APFloat One(Value.getSemantics(), 1);
+llvm::RoundingMode RM =
+E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
 if (AccessKind == AK_Increment)
-  Value.add(One, APFloat::rmNearestTiesToEven);
+  Value.add(One, RM);
 else
-  Value.subtract(One, APFloat::rmNearestTiesToEven);
+  Value.subtract(One, RM);
 return true;
   }
   bool foundPointer(APValue , QualType SubobjType) {
diff --git a/clang/test/SemaCXX/rounding-math.cpp 
b/clang/test/SemaCXX/rounding-math.cpp
index 73f9f10e6d59417..e7ead05041b560d 100644
--- a/clang/test/SemaCXX/rounding-math.cpp
+++ b/clang/test/SemaCXX/rounding-math.cpp
@@ -77,3 +77,24 @@ struct S1d {
   int f;
 };
 static_assert(sizeof(S1d) == sizeof(int), "");
+
+constexpr float incr_down(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+
+// 0x1.0p23 = 8388608.0, inc(8388608.0) = 8388609.0
+static_assert(incr_down(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round down -> 
16777216.0
+static_assert(incr_down(0x1.0p24F) == 0x1.0p24F, "");
+
+#pragma STDC FENV_ROUND FE_UPWARD
+constexpr float incr_up(float k) {
+  float x = k;
+  ++x;
+  return x;
+}
+static_assert(incr_up(0x1.0p23F) == 0x1.02p23F, "");
+// 0x1.0p24 = 16777216.0, inc(16777216.0) = 16777217.0 -> round up -> 
16777218.0
+static_assert(incr_up(0x1.0p24F) == 0x1.02p24F, "");

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


[clang] [llvm] [clang-tools-extra] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-28 Thread Serge Pavlov via cfe-commits

spavloff wrote:

LGTM.

https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang-tools-extra] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff edited 
https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang-tools-extra] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits


@@ -8900,6 +8900,83 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
   return FP;
 }
 
+SDValue PPCTargetLowering::LowerSET_ROUNDING(SDValue Op,
+ SelectionDAG ) const {
+  SDLoc Dl(Op);
+  MachineFunction  = DAG.getMachineFunction();
+  EVT PtrVT = getPointerTy(MF.getDataLayout());
+  SDValue Chain = Op.getOperand(0);
+
+  // If requested mode is constant, just use simpler mtfsb.
+  if (auto *CVal = dyn_cast(Op.getOperand(1))) {
+uint64_t Mode = CVal->getZExtValue();
+if (Mode >= 4)
+  llvm_unreachable("Unsupported rounding mode!");
+unsigned InternalRnd = Mode ^ (~(Mode >> 1) & 1);
+SDNode *SetHi = DAG.getMachineNode(
+(InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
+{DAG.getConstant(30, Dl, MVT::i32, true), Chain});
+SDNode *SetLo = DAG.getMachineNode(
+(InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
+{DAG.getConstant(31, Dl, MVT::i32, true), SDValue(SetHi, 0)});
+return SDValue(SetLo, 0);
+  }
+
+  // Use x ^ (~(x >> 1) & 1) to transform LLVM rounding mode to Power format.
+  SDValue One = DAG.getConstant(1, Dl, MVT::i32);
+  SDValue SrcFlag = DAG.getNode(ISD::AND, Dl, MVT::i32, Op.getOperand(1),
+DAG.getConstant(3, Dl, MVT::i32));
+  SDValue DstFlag = DAG.getNode(
+  ISD::XOR, Dl, MVT::i32, SrcFlag,
+  DAG.getNode(ISD::AND, Dl, MVT::i32,
+  DAG.getNOT(Dl,
+ DAG.getNode(ISD::SRL, Dl, MVT::i32, SrcFlag, One),
+ MVT::i32),
+  One));
+  SDValue MFFS = DAG.getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
+  Chain = MFFS.getValue(1);
+  SDValue NewFPSCR;
+  if (isTypeLegal(MVT::i64)) {
+// Set the last two bits (rounding mode) of bitcasted FPSCR.
+NewFPSCR = DAG.getNode(
+ISD::OR, Dl, MVT::i64,
+DAG.getNode(ISD::AND, Dl, MVT::i64,
+DAG.getNode(ISD::BITCAST, Dl, MVT::i64, MFFS),
+DAG.getNOT(Dl, DAG.getConstant(3, Dl, MVT::i64), 
MVT::i64)),
+DAG.getNode(ISD::ZERO_EXTEND, Dl, MVT::i64, DstFlag));

spavloff wrote:

Is there guarantee that the upper bits (63-2) of `DestFlag` are zeros? 

https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits


@@ -8900,6 +8900,83 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
   return FP;
 }
 
+SDValue PPCTargetLowering::LowerSET_ROUNDING(SDValue Op,
+ SelectionDAG ) const {
+  SDLoc Dl(Op);
+  MachineFunction  = DAG.getMachineFunction();
+  EVT PtrVT = getPointerTy(MF.getDataLayout());
+  SDValue Chain = Op.getOperand(0);
+
+  // If requested mode is constant, just use simpler mtfsb.
+  if (auto *CVal = dyn_cast(Op.getOperand(1))) {
+uint64_t Mode = CVal->getZExtValue();
+if (Mode >= 4)
+  llvm_unreachable("Unsupported rounding mode!");

spavloff wrote:

Would using `assert` be more appropriate?

https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff commented:

The patch looks good but I am not familiar with PPC instructions enough. Could 
you please run the runtime tests from here: 
https://github.com/llvm/llvm-test-suite/tree/main/MultiSource/UnitTests/Float/rounding?
 You just need to build application from two files: `clang rounding.c 
rounding-dynamic.c`.

https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [PowerPC] Implement llvm.set.rounding intrinsic (PR #67302)

2023-11-23 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff edited 
https://github.com/llvm/llvm-project/pull/67302
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] fix test PR69717.cpp (PR #72134)

2023-11-13 Thread Serge Pavlov via cfe-commits

spavloff wrote:

@antmox Thank you for fixing that!
LGTM.
Could you please commit the patch when tests pass?

https://github.com/llvm/llvm-project/pull/72134
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Added commit: 
https://github.com/llvm/llvm-project/commit/93ae26331592f41bf2b1d10b048743d80c468385
 to run the test on x86 only.


https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 93ae263 - [clang] Run test on x86 only

2023-11-13 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-11-13T19:20:34+07:00
New Revision: 93ae26331592f41bf2b1d10b048743d80c468385

URL: 
https://github.com/llvm/llvm-project/commit/93ae26331592f41bf2b1d10b048743d80c468385
DIFF: 
https://github.com/llvm/llvm-project/commit/93ae26331592f41bf2b1d10b048743d80c468385.diff

LOG: [clang] Run test on x86 only

The test Sema/PR69717.cpp fails on platforms that do not support
pragma float_control. So run this test on x86 only.

Added: 


Modified: 
clang/test/Sema/PR69717.cpp

Removed: 




diff  --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
index 3207092b948ae86..42a87bd1ac1ec8d 100644
--- a/clang/test/Sema/PR69717.cpp
+++ b/clang/test/Sema/PR69717.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -verify -fsyntax-only %s
+// REQUIRES: x86-registered-target
 // expected-no-diagnostics
 
 // Testcase for https://github.com/llvm/llvm-project/issues/69717



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


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff closed 
https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits


@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema ) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema )
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}

spavloff wrote:

Added explicit stack reset.

https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

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

>From e1623db8f86a8584d17729f000a455f5672adad4 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 30 Oct 2023 14:38:50 +0700
Subject: [PATCH 1/3] [clang] Do not clear FP pragma stack when instantiating
 functions

When instantiation function, a call to Sema::resetFPOption was used to
set the FP options associated with AST node. However this function also
cleared FP pragma stack. It is incorrect, as template instantiation
takes place on AST representation and semantic information like the FP
pragma stack should not influence it. Tt was a reason for miscompilation
in some cases.

To make the Sema interface more convenient, `resetFPOptions` does not
clear FP pragma stack anymore. Instead, it is cleared in
`FpPragmaStackSaveRAII`, which is used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717
(Problems with float_control pragma stack in Clang 17.x).
---
 clang/include/clang/Sema/Sema.h |  5 +++--
 clang/test/Sema/PR69717.cpp | 17 +
 2 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/PR69717.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f69f366c1750918..f146a162c1b8644 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema ) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema )
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:
@@ -722,7 +724,6 @@ class Sema final {
 
   void resetFPOptions(FPOptions FPO) {
 CurFPFeatures = FPO;
-FpPragmaStack.Stack.clear();
 FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
   }
 
diff --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
new file mode 100644
index 000..3207092b948ae86
--- /dev/null
+++ b/clang/test/Sema/PR69717.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// Testcase for https://github.com/llvm/llvm-project/issues/69717
+
+#pragma float_control(precise, on, push)
+
+template
+constexpr T multi(T x, T y) {
+  return x * y;
+}
+
+int multi_i(int x, int y) {
+  return multi(x, y);
+}
+
+#pragma float_control(pop)

>From f6af73145fdf37a08a493a1a16775bbc60090fe0 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:02:40 +0700
Subject: [PATCH 2/3] Explicitly clear FpPragmaStack

---
 clang/include/clang/Sema/Sema.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f146a162c1b8644..995d6ea1f9e8810 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,9 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema )
-: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
+  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+  S.FpPragmaStack.Stack.clear();
+}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:

>From 517ee9663646e0ee4f12be4d2b5f24e91a8f0e83 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:12:49 +0700
Subject: [PATCH 3/3] Fix clang-format errors

---
 clang/include/clang/Sema/Sema.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 995d6ea1f9e8810..38377f01a10086f 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,7 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema )
-  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {
   S.FpPragmaStack.Stack.clear();
 }
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }

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


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

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

>From 7882ea746ecf8721356fc6afbd7798b8db4e185d Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 30 Oct 2023 14:38:50 +0700
Subject: [PATCH 1/3] [clang] Do not clear FP pragma stack when instantiating
 functions

When instantiation function, a call to Sema::resetFPOption was used to
set the FP options associated with AST node. However this function also
cleared FP pragma stack. It is incorrect, as template instantiation
takes place on AST representation and semantic information like the FP
pragma stack should not influence it. Tt was a reason for miscompilation
in some cases.

To make the Sema interface more convenient, `resetFPOptions` does not
clear FP pragma stack anymore. Instead, it is cleared in
`FpPragmaStackSaveRAII`, which is used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717
(Problems with float_control pragma stack in Clang 17.x).
---
 clang/include/clang/Sema/Sema.h |  5 +++--
 clang/test/Sema/PR69717.cpp | 17 +
 2 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/PR69717.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e9752345ffd173..1e8892d1a550453 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema ) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema )
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:
@@ -722,7 +724,6 @@ class Sema final {
 
   void resetFPOptions(FPOptions FPO) {
 CurFPFeatures = FPO;
-FpPragmaStack.Stack.clear();
 FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
   }
 
diff --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
new file mode 100644
index 000..3207092b948ae86
--- /dev/null
+++ b/clang/test/Sema/PR69717.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// Testcase for https://github.com/llvm/llvm-project/issues/69717
+
+#pragma float_control(precise, on, push)
+
+template
+constexpr T multi(T x, T y) {
+  return x * y;
+}
+
+int multi_i(int x, int y) {
+  return multi(x, y);
+}
+
+#pragma float_control(pop)

>From 44b096810d88da1d1331be12802c68cdf8e1785b Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:02:40 +0700
Subject: [PATCH 2/3] Explicitly clear FpPragmaStack

---
 clang/include/clang/Sema/Sema.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e8892d1a550453..1d61dc7ff0aa26d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,9 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema )
-: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
+  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+  S.FpPragmaStack.Stack.clear();
+}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:

>From 244e967fb48c0b3b75682a6a32c1afd148c8c203 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:12:49 +0700
Subject: [PATCH 3/3] Fix clang-format errors

---
 clang/include/clang/Sema/Sema.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1d61dc7ff0aa26d..d88c20e5170a661 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,7 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema )
-  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {
   S.FpPragmaStack.Stack.clear();
 }
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }

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


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-13 Thread Serge Pavlov via cfe-commits

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

>From 7882ea746ecf8721356fc6afbd7798b8db4e185d Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 30 Oct 2023 14:38:50 +0700
Subject: [PATCH 1/2] [clang] Do not clear FP pragma stack when instantiating
 functions

When instantiation function, a call to Sema::resetFPOption was used to
set the FP options associated with AST node. However this function also
cleared FP pragma stack. It is incorrect, as template instantiation
takes place on AST representation and semantic information like the FP
pragma stack should not influence it. Tt was a reason for miscompilation
in some cases.

To make the Sema interface more convenient, `resetFPOptions` does not
clear FP pragma stack anymore. Instead, it is cleared in
`FpPragmaStackSaveRAII`, which is used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717
(Problems with float_control pragma stack in Clang 17.x).
---
 clang/include/clang/Sema/Sema.h |  5 +++--
 clang/test/Sema/PR69717.cpp | 17 +
 2 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/PR69717.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e9752345ffd173..1e8892d1a550453 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema ) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema )
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:
@@ -722,7 +724,6 @@ class Sema final {
 
   void resetFPOptions(FPOptions FPO) {
 CurFPFeatures = FPO;
-FpPragmaStack.Stack.clear();
 FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
   }
 
diff --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
new file mode 100644
index 000..3207092b948ae86
--- /dev/null
+++ b/clang/test/Sema/PR69717.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// Testcase for https://github.com/llvm/llvm-project/issues/69717
+
+#pragma float_control(precise, on, push)
+
+template
+constexpr T multi(T x, T y) {
+  return x * y;
+}
+
+int multi_i(int x, int y) {
+  return multi(x, y);
+}
+
+#pragma float_control(pop)

>From 44b096810d88da1d1331be12802c68cdf8e1785b Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 13 Nov 2023 15:02:40 +0700
Subject: [PATCH 2/2] Explicitly clear FpPragmaStack

---
 clang/include/clang/Sema/Sema.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e8892d1a550453..1d61dc7ff0aa26d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -714,7 +714,9 @@ class Sema final {
   class FpPragmaStackSaveRAII {
   public:
 FpPragmaStackSaveRAII(Sema )
-: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
+  : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+  S.FpPragmaStack.Stack.clear();
+}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:

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


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-11-09 Thread Serge Pavlov via cfe-commits

spavloff wrote:

`pragma pack` uses pragma stack and it is allowed in any place: 
https://godbolt.org/z/f8fP1vn63 . If such pragma presents in the late-parsed 
template, and push-pop operations in it are not balanced, the late parse of 
such function can break the pragma stack and next templates can be parsed 
incorrectly. It is not a FP pragma, but it demonstrates that the compiler must 
provide some Sema state isolation for late parsed templates.

For floating-point pragmas the stack could be cleared once, before the late 
parsing takes place. However it is complicated by the fact that the pragma 
stack set in precompiled header must be available in the unit that uses the 
header. Another complication is implicit assumption in some places that the 
default FP options are defined by LangOpts. It is not true, in some cases 
target may modify the default state (i386 is an example).

This fix is not optimal. The problems mentioned above are solvable and they 
should be fixed. However to have a quick solution for the initial PR the fix 
probably could be used.


https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-31 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff closed 
https://github.com/llvm/llvm-project/pull/69041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-31 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Thanks!

https://github.com/llvm/llvm-project/pull/69041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-10-31 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Late parsing (in contrast to template instantiation) is sensitive to the pragma 
stack because the late parsed text may contain pragmas. If, for example, the 
parsed text contains unbalanced pus/pop pragmas, it is detected if the pragma 
stack is empty, but can be missed if there is an unfinished pragma.

https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-10-30 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Actually the pragma stack is not saved during template instantiation. It is 
saved during late template parsing using class `FpPragmaStackSaveRAII`. For 
template instantiation the dependency on the stack can be considered as an 
error, because all information about FP options should be taken from AST.

That was the reason for this issue - the pragma stack was cleared because 
`resetFPOptions` was introduced for late parsing. If instantiation was made 
during parsing, it spoiled the pragma stack.

https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-10-30 Thread Serge Pavlov via cfe-commits

spavloff wrote:

> To be clear, we're still ensuring the current pragma state during 
> instantiation is what it was when the template is parsed, we're just not 
> incorrectly dropping all of the saved pragma state when we're doing it?

Yes, the pragma is used at parse stage to set correct FP options is AST nodes. 
During template instantiation the function `resetFPOptions` is used to set the 
required FP options in Sema, because in some cases (ImplicitCast) the options 
are taken from Sema and not AST node. As a result the new AST nodes get FP 
otions as they are specified in the template pattern.

The issue with `resetFPOptions` was that it also reset pragma stack. It is OK 
for late template parse, or for the functions that are instantiated at the end 
of translation unit, but not for templates that are instantiated immediately, 
like consexpr functions.

https://github.com/llvm/llvm-project/pull/70646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-30 Thread Serge Pavlov via cfe-commits

spavloff wrote:

Ping.

https://github.com/llvm/llvm-project/pull/69041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Do not clear FP pragma stack when instantiating functions (PR #70646)

2023-10-30 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff created 
https://github.com/llvm/llvm-project/pull/70646

When instantiation function, a call to Sema::resetFPOption was used to set the 
FP options associated with AST node. However this function also cleared FP 
pragma stack, and it is incorrect. Template instantiation takes place on AST 
representation and semantic information like the FP pragma stack should not 
affect it. This was a reason for miscompilation in some cases.

To make the Sema interface more consistent, now `resetFPOptions` does not clear 
FP pragma stack anymore. It is cleared in `FpPragmaStackSaveRAII`, which is 
used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717 
(Problems with float_control pragma stack in Clang 17.x).

>From 7882ea746ecf8721356fc6afbd7798b8db4e185d Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Mon, 30 Oct 2023 14:38:50 +0700
Subject: [PATCH] [clang] Do not clear FP pragma stack when instantiating
 functions

When instantiation function, a call to Sema::resetFPOption was used to
set the FP options associated with AST node. However this function also
cleared FP pragma stack. It is incorrect, as template instantiation
takes place on AST representation and semantic information like the FP
pragma stack should not influence it. Tt was a reason for miscompilation
in some cases.

To make the Sema interface more convenient, `resetFPOptions` does not
clear FP pragma stack anymore. Instead, it is cleared in
`FpPragmaStackSaveRAII`, which is used in parsing only.

This change must fix https://github.com/llvm/llvm-project/issues/69717
(Problems with float_control pragma stack in Clang 17.x).
---
 clang/include/clang/Sema/Sema.h |  5 +++--
 clang/test/Sema/PR69717.cpp | 17 +
 2 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/PR69717.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e9752345ffd173..1e8892d1a550453 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,9 +710,11 @@ class Sema final {
 return result;
   }
 
+  // Saves the current floating-point pragma stack and clear it in this Sema.
   class FpPragmaStackSaveRAII {
   public:
-FpPragmaStackSaveRAII(Sema ) : S(S), SavedStack(S.FpPragmaStack) {}
+FpPragmaStackSaveRAII(Sema )
+: S(S), SavedStack(std::move(S.FpPragmaStack)) {}
 ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
 
   private:
@@ -722,7 +724,6 @@ class Sema final {
 
   void resetFPOptions(FPOptions FPO) {
 CurFPFeatures = FPO;
-FpPragmaStack.Stack.clear();
 FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
   }
 
diff --git a/clang/test/Sema/PR69717.cpp b/clang/test/Sema/PR69717.cpp
new file mode 100644
index 000..3207092b948ae86
--- /dev/null
+++ b/clang/test/Sema/PR69717.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// Testcase for https://github.com/llvm/llvm-project/issues/69717
+
+#pragma float_control(precise, on, push)
+
+template
+constexpr T multi(T x, T y) {
+  return x * y;
+}
+
+int multi_i(int x, int y) {
+  return multi(x, y);
+}
+
+#pragma float_control(pop)

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


[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-16 Thread Serge Pavlov via cfe-commits

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

>From 1374e323198d7188e688845eb951df4148a1dfd8 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 11 Oct 2023 14:27:26 +0700
Subject: [PATCH 1/5] [clang] Additional FP classification functions

C language standard defined library functions `iszero`, `issignaling`
and `issubnormal`, which did not have counterparts among clang
builtin functions. This change adds new functions:

__builtin_iszero
__builtin_issubnormal
__builtin_issignaling

They provide builtin implementation for the missing standard functions.
---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Basic/Builtins.def |  3 +++
 clang/lib/CodeGen/CGBuiltin.cpp| 24 
 clang/test/CodeGen/builtins.c  | 15 +++
 4 files changed, 44 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d918967e7f0b02..2453804cd7735be 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -621,6 +621,8 @@ Floating Point Support in Clang
 - Add ``__builtin_exp10``, ``__builtin_exp10f``,
   ``__builtin_exp10f16``, ``__builtin_exp10l`` and
   ``__builtin_exp10f128`` builtins.
+- Add ``__builtin_iszero``, ``__builtin_issignaling`` and
+  ``__builtin_issubnormal``.
 
 AST Matchers
 
diff --git a/clang/include/clang/Basic/Builtins.def 
b/clang/include/clang/Basic/Builtins.def
index 6ea8484606cfd5d..ebcb5b45e5bdc23 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -494,6 +494,9 @@ BUILTIN(__builtin_isinf,  "i.", "FnctE")
 BUILTIN(__builtin_isinf_sign, "i.", "FnctE")
 BUILTIN(__builtin_isnan,  "i.", "FnctE")
 BUILTIN(__builtin_isnormal,   "i.", "FnctE")
+BUILTIN(__builtin_issubnormal,"i.", "FnctE")
+BUILTIN(__builtin_iszero, "i.", "FnctE")
+BUILTIN(__builtin_issignaling,"i.", "FnctE")
 BUILTIN(__builtin_isfpclass,  "i.", "nctE")
 
 // FP signbit builtins
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8cb7943df9a7822..5d3946a84b6c34a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3287,6 +3287,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issignaling: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcSNan),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isinf: {
 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
 Value *V = EmitScalarExpr(E->getArg(0));
@@ -3321,6 +3329,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issubnormal: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, 
FPClassTest::fcSubnormal),
+   ConvertType(E->getType(;
+  }
+
+  case Builtin::BI__builtin_iszero: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcZero),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isfpclass: {
 Expr::EvalResult Result;
 if (!E->getArg(1)->EvaluateAsInt(Result, CGM.getContext()))
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 1b1b2cd6413a344..ce1182b724dcc21 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -64,6 +64,9 @@ int main(void) {
   P(isinf_sign, (1.));
   P(isnan, (1.));
   P(isfinite, (1.));
+  P(iszero, (1.));
+  P(issubnormal, (1.));
+  P(issignaling, (1.));
   P(isfpclass, (1., 1));
 
   // Bitwise & Numeric Functions
@@ -270,6 +273,18 @@ void test_float_builtins(__fp16 *H, float F, double D, 
long double LD) {
   // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 264)
   // CHECK: zext i1 [[TMP]] to i32
 
+  res = __builtin_issubnormal(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 144)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_iszero(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 96)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_issignaling(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 1)
+  // CHECK: zext i1 [[TMP]] to i32
+
   res = __builtin_flt_rounds();
   // CHECK: call i32 @llvm.get.rounding(
 }

>From 

[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-15 Thread Serge Pavlov via cfe-commits

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

>From 1374e323198d7188e688845eb951df4148a1dfd8 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 11 Oct 2023 14:27:26 +0700
Subject: [PATCH 1/5] [clang] Additional FP classification functions

C language standard defined library functions `iszero`, `issignaling`
and `issubnormal`, which did not have counterparts among clang
builtin functions. This change adds new functions:

__builtin_iszero
__builtin_issubnormal
__builtin_issignaling

They provide builtin implementation for the missing standard functions.
---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Basic/Builtins.def |  3 +++
 clang/lib/CodeGen/CGBuiltin.cpp| 24 
 clang/test/CodeGen/builtins.c  | 15 +++
 4 files changed, 44 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d918967e7f0b02..2453804cd7735be 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -621,6 +621,8 @@ Floating Point Support in Clang
 - Add ``__builtin_exp10``, ``__builtin_exp10f``,
   ``__builtin_exp10f16``, ``__builtin_exp10l`` and
   ``__builtin_exp10f128`` builtins.
+- Add ``__builtin_iszero``, ``__builtin_issignaling`` and
+  ``__builtin_issubnormal``.
 
 AST Matchers
 
diff --git a/clang/include/clang/Basic/Builtins.def 
b/clang/include/clang/Basic/Builtins.def
index 6ea8484606cfd5d..ebcb5b45e5bdc23 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -494,6 +494,9 @@ BUILTIN(__builtin_isinf,  "i.", "FnctE")
 BUILTIN(__builtin_isinf_sign, "i.", "FnctE")
 BUILTIN(__builtin_isnan,  "i.", "FnctE")
 BUILTIN(__builtin_isnormal,   "i.", "FnctE")
+BUILTIN(__builtin_issubnormal,"i.", "FnctE")
+BUILTIN(__builtin_iszero, "i.", "FnctE")
+BUILTIN(__builtin_issignaling,"i.", "FnctE")
 BUILTIN(__builtin_isfpclass,  "i.", "nctE")
 
 // FP signbit builtins
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8cb7943df9a7822..5d3946a84b6c34a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3287,6 +3287,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issignaling: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcSNan),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isinf: {
 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
 Value *V = EmitScalarExpr(E->getArg(0));
@@ -3321,6 +3329,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issubnormal: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, 
FPClassTest::fcSubnormal),
+   ConvertType(E->getType(;
+  }
+
+  case Builtin::BI__builtin_iszero: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcZero),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isfpclass: {
 Expr::EvalResult Result;
 if (!E->getArg(1)->EvaluateAsInt(Result, CGM.getContext()))
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 1b1b2cd6413a344..ce1182b724dcc21 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -64,6 +64,9 @@ int main(void) {
   P(isinf_sign, (1.));
   P(isnan, (1.));
   P(isfinite, (1.));
+  P(iszero, (1.));
+  P(issubnormal, (1.));
+  P(issignaling, (1.));
   P(isfpclass, (1., 1));
 
   // Bitwise & Numeric Functions
@@ -270,6 +273,18 @@ void test_float_builtins(__fp16 *H, float F, double D, 
long double LD) {
   // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 264)
   // CHECK: zext i1 [[TMP]] to i32
 
+  res = __builtin_issubnormal(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 144)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_iszero(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 96)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_issignaling(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 1)
+  // CHECK: zext i1 [[TMP]] to i32
+
   res = __builtin_flt_rounds();
   // CHECK: call i32 @llvm.get.rounding(
 }

>From 

[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-15 Thread Serge Pavlov via cfe-commits

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

>From 1374e323198d7188e688845eb951df4148a1dfd8 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 11 Oct 2023 14:27:26 +0700
Subject: [PATCH 1/4] [clang] Additional FP classification functions

C language standard defined library functions `iszero`, `issignaling`
and `issubnormal`, which did not have counterparts among clang
builtin functions. This change adds new functions:

__builtin_iszero
__builtin_issubnormal
__builtin_issignaling

They provide builtin implementation for the missing standard functions.
---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Basic/Builtins.def |  3 +++
 clang/lib/CodeGen/CGBuiltin.cpp| 24 
 clang/test/CodeGen/builtins.c  | 15 +++
 4 files changed, 44 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d918967e7f0b02..2453804cd7735be 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -621,6 +621,8 @@ Floating Point Support in Clang
 - Add ``__builtin_exp10``, ``__builtin_exp10f``,
   ``__builtin_exp10f16``, ``__builtin_exp10l`` and
   ``__builtin_exp10f128`` builtins.
+- Add ``__builtin_iszero``, ``__builtin_issignaling`` and
+  ``__builtin_issubnormal``.
 
 AST Matchers
 
diff --git a/clang/include/clang/Basic/Builtins.def 
b/clang/include/clang/Basic/Builtins.def
index 6ea8484606cfd5d..ebcb5b45e5bdc23 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -494,6 +494,9 @@ BUILTIN(__builtin_isinf,  "i.", "FnctE")
 BUILTIN(__builtin_isinf_sign, "i.", "FnctE")
 BUILTIN(__builtin_isnan,  "i.", "FnctE")
 BUILTIN(__builtin_isnormal,   "i.", "FnctE")
+BUILTIN(__builtin_issubnormal,"i.", "FnctE")
+BUILTIN(__builtin_iszero, "i.", "FnctE")
+BUILTIN(__builtin_issignaling,"i.", "FnctE")
 BUILTIN(__builtin_isfpclass,  "i.", "nctE")
 
 // FP signbit builtins
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8cb7943df9a7822..5d3946a84b6c34a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3287,6 +3287,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issignaling: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcSNan),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isinf: {
 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
 Value *V = EmitScalarExpr(E->getArg(0));
@@ -3321,6 +3329,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issubnormal: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, 
FPClassTest::fcSubnormal),
+   ConvertType(E->getType(;
+  }
+
+  case Builtin::BI__builtin_iszero: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcZero),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isfpclass: {
 Expr::EvalResult Result;
 if (!E->getArg(1)->EvaluateAsInt(Result, CGM.getContext()))
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 1b1b2cd6413a344..ce1182b724dcc21 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -64,6 +64,9 @@ int main(void) {
   P(isinf_sign, (1.));
   P(isnan, (1.));
   P(isfinite, (1.));
+  P(iszero, (1.));
+  P(issubnormal, (1.));
+  P(issignaling, (1.));
   P(isfpclass, (1., 1));
 
   // Bitwise & Numeric Functions
@@ -270,6 +273,18 @@ void test_float_builtins(__fp16 *H, float F, double D, 
long double LD) {
   // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 264)
   // CHECK: zext i1 [[TMP]] to i32
 
+  res = __builtin_issubnormal(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 144)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_iszero(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 96)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_issignaling(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 1)
+  // CHECK: zext i1 [[TMP]] to i32
+
   res = __builtin_flt_rounds();
   // CHECK: call i32 @llvm.get.rounding(
 }

>From 

[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-15 Thread Serge Pavlov via cfe-commits

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

>From 1374e323198d7188e688845eb951df4148a1dfd8 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 11 Oct 2023 14:27:26 +0700
Subject: [PATCH 1/3] [clang] Additional FP classification functions

C language standard defined library functions `iszero`, `issignaling`
and `issubnormal`, which did not have counterparts among clang
builtin functions. This change adds new functions:

__builtin_iszero
__builtin_issubnormal
__builtin_issignaling

They provide builtin implementation for the missing standard functions.
---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Basic/Builtins.def |  3 +++
 clang/lib/CodeGen/CGBuiltin.cpp| 24 
 clang/test/CodeGen/builtins.c  | 15 +++
 4 files changed, 44 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d918967e7f0b02..2453804cd7735be 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -621,6 +621,8 @@ Floating Point Support in Clang
 - Add ``__builtin_exp10``, ``__builtin_exp10f``,
   ``__builtin_exp10f16``, ``__builtin_exp10l`` and
   ``__builtin_exp10f128`` builtins.
+- Add ``__builtin_iszero``, ``__builtin_issignaling`` and
+  ``__builtin_issubnormal``.
 
 AST Matchers
 
diff --git a/clang/include/clang/Basic/Builtins.def 
b/clang/include/clang/Basic/Builtins.def
index 6ea8484606cfd5d..ebcb5b45e5bdc23 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -494,6 +494,9 @@ BUILTIN(__builtin_isinf,  "i.", "FnctE")
 BUILTIN(__builtin_isinf_sign, "i.", "FnctE")
 BUILTIN(__builtin_isnan,  "i.", "FnctE")
 BUILTIN(__builtin_isnormal,   "i.", "FnctE")
+BUILTIN(__builtin_issubnormal,"i.", "FnctE")
+BUILTIN(__builtin_iszero, "i.", "FnctE")
+BUILTIN(__builtin_issignaling,"i.", "FnctE")
 BUILTIN(__builtin_isfpclass,  "i.", "nctE")
 
 // FP signbit builtins
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8cb7943df9a7822..5d3946a84b6c34a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3287,6 +3287,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issignaling: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcSNan),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isinf: {
 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
 Value *V = EmitScalarExpr(E->getArg(0));
@@ -3321,6 +3329,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issubnormal: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, 
FPClassTest::fcSubnormal),
+   ConvertType(E->getType(;
+  }
+
+  case Builtin::BI__builtin_iszero: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcZero),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isfpclass: {
 Expr::EvalResult Result;
 if (!E->getArg(1)->EvaluateAsInt(Result, CGM.getContext()))
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 1b1b2cd6413a344..ce1182b724dcc21 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -64,6 +64,9 @@ int main(void) {
   P(isinf_sign, (1.));
   P(isnan, (1.));
   P(isfinite, (1.));
+  P(iszero, (1.));
+  P(issubnormal, (1.));
+  P(issignaling, (1.));
   P(isfpclass, (1., 1));
 
   // Bitwise & Numeric Functions
@@ -270,6 +273,18 @@ void test_float_builtins(__fp16 *H, float F, double D, 
long double LD) {
   // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 264)
   // CHECK: zext i1 [[TMP]] to i32
 
+  res = __builtin_issubnormal(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 144)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_iszero(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 96)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_issignaling(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 1)
+  // CHECK: zext i1 [[TMP]] to i32
+
   res = __builtin_flt_rounds();
   // CHECK: call i32 @llvm.get.rounding(
 }

>From 

[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-15 Thread Serge Pavlov via cfe-commits


@@ -494,6 +494,9 @@ BUILTIN(__builtin_isinf,  "i.", "FnctE")
 BUILTIN(__builtin_isinf_sign, "i.", "FnctE")
 BUILTIN(__builtin_isnan,  "i.", "FnctE")
 BUILTIN(__builtin_isnormal,   "i.", "FnctE")
+BUILTIN(__builtin_issubnormal,"i.", "FnctE")
+BUILTIN(__builtin_iszero, "i.", "FnctE")
+BUILTIN(__builtin_issignaling,"i.", "FnctE")

spavloff wrote:

Yes, this is a copy-past error. Thanks for the catch.

https://github.com/llvm/llvm-project/pull/69041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-15 Thread Serge Pavlov via cfe-commits

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

>From 1374e323198d7188e688845eb951df4148a1dfd8 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 11 Oct 2023 14:27:26 +0700
Subject: [PATCH 1/2] [clang] Additional FP classification functions

C language standard defined library functions `iszero`, `issignaling`
and `issubnormal`, which did not have counterparts among clang
builtin functions. This change adds new functions:

__builtin_iszero
__builtin_issubnormal
__builtin_issignaling

They provide builtin implementation for the missing standard functions.
---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Basic/Builtins.def |  3 +++
 clang/lib/CodeGen/CGBuiltin.cpp| 24 
 clang/test/CodeGen/builtins.c  | 15 +++
 4 files changed, 44 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d918967e7f0b02..2453804cd7735be 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -621,6 +621,8 @@ Floating Point Support in Clang
 - Add ``__builtin_exp10``, ``__builtin_exp10f``,
   ``__builtin_exp10f16``, ``__builtin_exp10l`` and
   ``__builtin_exp10f128`` builtins.
+- Add ``__builtin_iszero``, ``__builtin_issignaling`` and
+  ``__builtin_issubnormal``.
 
 AST Matchers
 
diff --git a/clang/include/clang/Basic/Builtins.def 
b/clang/include/clang/Basic/Builtins.def
index 6ea8484606cfd5d..ebcb5b45e5bdc23 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -494,6 +494,9 @@ BUILTIN(__builtin_isinf,  "i.", "FnctE")
 BUILTIN(__builtin_isinf_sign, "i.", "FnctE")
 BUILTIN(__builtin_isnan,  "i.", "FnctE")
 BUILTIN(__builtin_isnormal,   "i.", "FnctE")
+BUILTIN(__builtin_issubnormal,"i.", "FnctE")
+BUILTIN(__builtin_iszero, "i.", "FnctE")
+BUILTIN(__builtin_issignaling,"i.", "FnctE")
 BUILTIN(__builtin_isfpclass,  "i.", "nctE")
 
 // FP signbit builtins
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8cb7943df9a7822..5d3946a84b6c34a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3287,6 +3287,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issignaling: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcSNan),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isinf: {
 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
 Value *V = EmitScalarExpr(E->getArg(0));
@@ -3321,6 +3329,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issubnormal: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, 
FPClassTest::fcSubnormal),
+   ConvertType(E->getType(;
+  }
+
+  case Builtin::BI__builtin_iszero: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcZero),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isfpclass: {
 Expr::EvalResult Result;
 if (!E->getArg(1)->EvaluateAsInt(Result, CGM.getContext()))
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 1b1b2cd6413a344..ce1182b724dcc21 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -64,6 +64,9 @@ int main(void) {
   P(isinf_sign, (1.));
   P(isnan, (1.));
   P(isfinite, (1.));
+  P(iszero, (1.));
+  P(issubnormal, (1.));
+  P(issignaling, (1.));
   P(isfpclass, (1., 1));
 
   // Bitwise & Numeric Functions
@@ -270,6 +273,18 @@ void test_float_builtins(__fp16 *H, float F, double D, 
long double LD) {
   // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 264)
   // CHECK: zext i1 [[TMP]] to i32
 
+  res = __builtin_issubnormal(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 144)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_iszero(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 96)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_issignaling(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 1)
+  // CHECK: zext i1 [[TMP]] to i32
+
   res = __builtin_flt_rounds();
   // CHECK: call i32 @llvm.get.rounding(
 }

>From 

[clang] [clang] Additional FP classification functions (PR #69041)

2023-10-13 Thread Serge Pavlov via cfe-commits

https://github.com/spavloff created 
https://github.com/llvm/llvm-project/pull/69041

C language standard defined library functions `iszero`, `issignaling` and 
`issubnormal`, which did not have counterparts among clang builtin functions. 
This change adds new functions:

__builtin_iszero
__builtin_issubnormal
__builtin_issignaling

They provide builtin implementation for the missing standard functions.

>From 1374e323198d7188e688845eb951df4148a1dfd8 Mon Sep 17 00:00:00 2001
From: Serge Pavlov 
Date: Wed, 11 Oct 2023 14:27:26 +0700
Subject: [PATCH] [clang] Additional FP classification functions

C language standard defined library functions `iszero`, `issignaling`
and `issubnormal`, which did not have counterparts among clang
builtin functions. This change adds new functions:

__builtin_iszero
__builtin_issubnormal
__builtin_issignaling

They provide builtin implementation for the missing standard functions.
---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Basic/Builtins.def |  3 +++
 clang/lib/CodeGen/CGBuiltin.cpp| 24 
 clang/test/CodeGen/builtins.c  | 15 +++
 4 files changed, 44 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d918967e7f0b02..2453804cd7735be 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -621,6 +621,8 @@ Floating Point Support in Clang
 - Add ``__builtin_exp10``, ``__builtin_exp10f``,
   ``__builtin_exp10f16``, ``__builtin_exp10l`` and
   ``__builtin_exp10f128`` builtins.
+- Add ``__builtin_iszero``, ``__builtin_issignaling`` and
+  ``__builtin_issubnormal``.
 
 AST Matchers
 
diff --git a/clang/include/clang/Basic/Builtins.def 
b/clang/include/clang/Basic/Builtins.def
index 6ea8484606cfd5d..ebcb5b45e5bdc23 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -494,6 +494,9 @@ BUILTIN(__builtin_isinf,  "i.", "FnctE")
 BUILTIN(__builtin_isinf_sign, "i.", "FnctE")
 BUILTIN(__builtin_isnan,  "i.", "FnctE")
 BUILTIN(__builtin_isnormal,   "i.", "FnctE")
+BUILTIN(__builtin_issubnormal,"i.", "FnctE")
+BUILTIN(__builtin_iszero, "i.", "FnctE")
+BUILTIN(__builtin_issignaling,"i.", "FnctE")
 BUILTIN(__builtin_isfpclass,  "i.", "nctE")
 
 // FP signbit builtins
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8cb7943df9a7822..5d3946a84b6c34a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3287,6 +3287,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issignaling: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcSNan),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isinf: {
 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
 Value *V = EmitScalarExpr(E->getArg(0));
@@ -3321,6 +3329,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
ConvertType(E->getType(;
   }
 
+  case Builtin::BI__builtin_issubnormal: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, 
FPClassTest::fcSubnormal),
+   ConvertType(E->getType(;
+  }
+
+  case Builtin::BI__builtin_iszero: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcZero),
+   ConvertType(E->getType(;
+  }
+
   case Builtin::BI__builtin_isfpclass: {
 Expr::EvalResult Result;
 if (!E->getArg(1)->EvaluateAsInt(Result, CGM.getContext()))
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 1b1b2cd6413a344..ce1182b724dcc21 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -64,6 +64,9 @@ int main(void) {
   P(isinf_sign, (1.));
   P(isnan, (1.));
   P(isfinite, (1.));
+  P(iszero, (1.));
+  P(issubnormal, (1.));
+  P(issignaling, (1.));
   P(isfpclass, (1., 1));
 
   // Bitwise & Numeric Functions
@@ -270,6 +273,18 @@ void test_float_builtins(__fp16 *H, float F, double D, 
long double LD) {
   // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 264)
   // CHECK: zext i1 [[TMP]] to i32
 
+  res = __builtin_issubnormal(F);
+  // CHECK: [[TMP:%.*]] = call i1 @llvm.is.fpclass.f32(float {{.*}}, i32 144)
+  // CHECK: zext i1 [[TMP]] to i32
+
+  res = __builtin_iszero(F);
+  // CHECK: [[TMP:%.*]] = call i1 

[clang] 9fd57e4 - [clang] Support vectors in __builtin_isfpclass

2023-09-01 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-09-02T11:52:43+07:00
New Revision: 9fd57e4d48881b0f395621bd4a7aa8ec54dc6729

URL: 
https://github.com/llvm/llvm-project/commit/9fd57e4d48881b0f395621bd4a7aa8ec54dc6729
DIFF: 
https://github.com/llvm/llvm-project/commit/9fd57e4d48881b0f395621bd4a7aa8ec54dc6729.diff

LOG: [clang] Support vectors in __builtin_isfpclass

Builtin function `__builtin_isfpclass` now can be called for a vector
of floating-point values. In this case it is applied to the vector
elementwise and produces vector of integer values.

Differential Revision: https://reviews.llvm.org/D153339

Added: 


Modified: 
clang/docs/LanguageExtensions.rst
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaChecking.cpp
clang/test/CodeGen/isfpclass.c

Removed: 




diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index e739ecf3b9df4a..3d2e8aae4421ca 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3516,18 +3516,15 @@ Floating point builtins
 ``__builtin_isfpclass``
 ---
 
-``__builtin_isfpclass`` is used to test if the specified floating-point value
-falls into one of the specified floating-point classes.
+``__builtin_isfpclass`` is used to test if the specified floating-point values
+fall into one of the specified floating-point classes.
 
 **Syntax**:
 
 .. code-block:: c++
 
 int __builtin_isfpclass(fp_type expr, int mask)
-
-``fp_type`` is a floating-point type supported by the target. ``mask`` is an
-integer constant expression, where each bit represents floating-point class to
-test. The function returns boolean value.
+int_vector __builtin_isfpclass(fp_vector expr, int mask)
 
 **Example of use**:
 
@@ -3543,8 +3540,9 @@ test. The function returns boolean value.
 The ``__builtin_isfpclass()`` builtin is a generalization of functions 
``isnan``,
 ``isinf``, ``isfinite`` and some others defined by the C standard. It tests if
 the floating-point value, specified by the first argument, falls into any of 
data
-classes, specified by the second argument. The later is a bitmask, in which 
each
-data class is represented by a bit using the encoding:
+classes, specified by the second argument. The latter is an integer constant
+bitmask expression, in which each data class is represented by a bit
+using the encoding:
 
 == === ==
 Mask value Data class  Macro
@@ -3572,6 +3570,14 @@ the standard classification functions, for example, 
``__builtin_isfpclass(x, 3)`
 is identical to ``isnan``,``__builtin_isfpclass(x, 504)`` - to ``isfinite``
 and so on.
 
+If the first argument is a vector, the function is equivalent to the set of
+scalar calls of ``__builtin_isfpclass`` applied to the input elementwise.
+
+The result of ``__builtin_isfpclass`` is a boolean value, if the first argument
+is a scalar, or an integer vector with the same element count as the first
+argument. The element type in this vector has the same bit length as the
+element of the the first argument type.
+
 This function never raises floating-point exceptions and does not canonicalize
 its input. The floating-point argument is not promoted, its data class is
 determined based on its representation in its actual semantic type.

diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 895cd43ed1e815..51a04735bfd665 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -345,6 +345,7 @@ Floating Point Support in Clang
 - Add ``__builtin_elementwise_pow`` builtin for floating point types only.
 - Add ``__builtin_elementwise_bitreverse`` builtin for integer types only.
 - Add ``__builtin_elementwise_sqrt`` builtin for floating point types only.
+- ``__builtin_isfpclass`` builtin now supports vector types.
 
 AST Matchers
 

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index c78a6b9c510767..3932d9cd07d986 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -8404,14 +8404,15 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr 
*TheCall) {
 
 /// SemaBuiltinSemaBuiltinFPClassification - Handle functions like
 /// __builtin_isnan and friends.  This is declared to take (...), so we have
-/// to check everything. We expect the last argument to be a floating point
-/// value.
+/// to check everything.
 bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
   if (checkArgCount(*this, TheCall, NumArgs))
 return true;
 
+  bool IsFPClass = NumArgs == 2;
+
   // Find out position of floating-point argument.
-  unsigned FPArgNo = (NumArgs == 2) ? 0 : NumArgs - 1;
+  unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
 
   // We can count on all parameters preceding the floating-point just being 
int.
   // Try all of those.
@@ -8442,18 +8443,37 @@ bool 

[clang] 8859c64 - [clang][test] Make check pattern shorter

2023-08-30 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-08-30T13:08:48+07:00
New Revision: 8859c644ede4898f90f77dcad2286de08a9ba62e

URL: 
https://github.com/llvm/llvm-project/commit/8859c644ede4898f90f77dcad2286de08a9ba62e
DIFF: 
https://github.com/llvm/llvm-project/commit/8859c644ede4898f90f77dcad2286de08a9ba62e.diff

LOG: [clang][test] Make check pattern shorter

A check pattern in clang/test/SemaCXX/template-64605.cpp contains template
specialization kind (the text "implicit_instantiation"). It does not need to
be checked and can be safely removed.

Presence of this text in the check pattern prevents from backporting some
commits to the release branch: 
https://github.com/llvm/llvm-project/issues/64605.
It has only recently been printed and the relevant commit is not present in
the release/17.x branch.

Added: 


Modified: 
clang/test/SemaCXX/template-64605.cpp

Removed: 




diff  --git a/clang/test/SemaCXX/template-64605.cpp 
b/clang/test/SemaCXX/template-64605.cpp
index 99ccbfdc27f1c8..9d7f8d41001711 100644
--- a/clang/test/SemaCXX/template-64605.cpp
+++ b/clang/test/SemaCXX/template-64605.cpp
@@ -16,7 +16,7 @@ int f() { return b_64605(); }
 // CHECK:  ImplicitCastExpr {{.*}} 'float'  
RoundingMath=1 AllowFEnvAccess=1
 // CHECK-NEXT: IntegerLiteral {{.*}} 4294967295
 
-// CHECK:  FunctionDecl {{.*}} b_64605 'int ()' implicit_instantiation
+// CHECK:  FunctionDecl {{.*}} b_64605 'int ()'
 // CHECK-NEXT: TemplateArgument type 'void'
 
 // CHECK:  ImplicitCastExpr {{.*}} 'float'  
RoundingMath=1 AllowFEnvAccess=1



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


[clang] 73e5a70 - [clang] Run test for concrete target

2023-08-21 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-08-21T13:23:06+07:00
New Revision: 73e5a70e676850b79f196e01e2194a2485041584

URL: 
https://github.com/llvm/llvm-project/commit/73e5a70e676850b79f196e01e2194a2485041584
DIFF: 
https://github.com/llvm/llvm-project/commit/73e5a70e676850b79f196e01e2194a2485041584.diff

LOG: [clang] Run test for concrete target

The test clang/test/SemaCXX/template-64605.cpp uses pragma FENV_ACCESS,
which is not supported on all targets. Restrict it to x86_64 only.

Added: 


Modified: 
clang/test/SemaCXX/template-64605.cpp

Removed: 




diff  --git a/clang/test/SemaCXX/template-64605.cpp 
b/clang/test/SemaCXX/template-64605.cpp
index b13acbf2ae566b..99ccbfdc27f1c8 100644
--- a/clang/test/SemaCXX/template-64605.cpp
+++ b/clang/test/SemaCXX/template-64605.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -ast-dump -ast-dump-filter=b_64605 %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ast-dump -ast-dump-filter=b_64605 
%s | FileCheck %s
 
 // https://github.com/llvm/llvm-project/issues/64605
 



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


[clang] 0baf85c - [clang] Set FP options in Sema when instantiating CompoundStmt

2023-08-20 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-08-21T12:36:41+07:00
New Revision: 0baf85c331090fbe2d2b42214ed0664d55feb0b5

URL: 
https://github.com/llvm/llvm-project/commit/0baf85c331090fbe2d2b42214ed0664d55feb0b5
DIFF: 
https://github.com/llvm/llvm-project/commit/0baf85c331090fbe2d2b42214ed0664d55feb0b5.diff

LOG: [clang] Set FP options in Sema when instantiating CompoundStmt

When an expression is instantiated, TreeTransform skips ImplicitCastExpr
nodes, assuming they are recreated when the instantiated expression is
built. It breaks functions that use non-default floating-point options,
because they are kept in these ImplicitCastExprs. In this case the
recreated ImplicitCastExpr takes FP options from the current Sema state
and not from AST node.

To fix this issue the FP options in Sema object are set when a compound
statement is cloned in TreeTransform.

This change fixes https://github.com/llvm/llvm-project/issues/64605
([Regression 16 -> 17] Template instantiation ignores FENV_ACCESS being
ON for both definition and instantiation).

Differential Revision: https://reviews.llvm.org/D158158

Added: 
clang/test/SemaCXX/template-64605.cpp

Modified: 
clang/lib/Sema/TreeTransform.h

Removed: 




diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 1f41bbb189df26..769811c2772c6f 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -7491,6 +7491,10 @@ StmtResult
 TreeTransform::TransformCompoundStmt(CompoundStmt *S,
   bool IsStmtExpr) {
   Sema::CompoundScopeRAII CompoundScope(getSema());
+  Sema::FPFeaturesStateRAII FPSave(getSema());
+  if (S->hasStoredFPFeatures())
+getSema().resetFPOptions(
+S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
 
   const Stmt *ExprResult = S->getStmtExprResult();
   bool SubStmtInvalid = false;

diff  --git a/clang/test/SemaCXX/template-64605.cpp 
b/clang/test/SemaCXX/template-64605.cpp
new file mode 100644
index 00..b13acbf2ae566b
--- /dev/null
+++ b/clang/test/SemaCXX/template-64605.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -ast-dump -ast-dump-filter=b_64605 %s | FileCheck %s
+
+// https://github.com/llvm/llvm-project/issues/64605
+
+#pragma STDC FENV_ACCESS ON
+template 
+int b_64605() {
+  int x;
+  if ((float)0x != (float)0x1) {
+x = 1;
+  }
+  return x;
+}
+int f() { return b_64605(); }
+
+// CHECK:  ImplicitCastExpr {{.*}} 'float'  
RoundingMath=1 AllowFEnvAccess=1
+// CHECK-NEXT: IntegerLiteral {{.*}} 4294967295
+
+// CHECK:  FunctionDecl {{.*}} b_64605 'int ()' implicit_instantiation
+// CHECK-NEXT: TemplateArgument type 'void'
+
+// CHECK:  ImplicitCastExpr {{.*}} 'float'  
RoundingMath=1 AllowFEnvAccess=1
+// CHECK-NEXT: IntegerLiteral {{.*}} 4294967295



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


[clang] cc006ac - [clang] Fix delayed template parsing

2023-07-17 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-07-17T14:51:34+07:00
New Revision: cc006acdd6d7280a85c63fe375a4c9d1738e3fcd

URL: 
https://github.com/llvm/llvm-project/commit/cc006acdd6d7280a85c63fe375a4c9d1738e3fcd
DIFF: 
https://github.com/llvm/llvm-project/commit/cc006acdd6d7280a85c63fe375a4c9d1738e3fcd.diff

LOG: [clang] Fix delayed template parsing

Commit 98390ccb80569e8fbb20e6c996b4b8cff87fbec6 fixed late template
instantiation by clearing FP pragma stack before instantiation. This
solution was based on the assumptions:

- FP pragma stack is not used anymore and it is safe to clear it,
- Default FP options are determined by command line options.

Both the assumptions are wrong. When compilation produces precompiled
header file, state of the stack is serialized and then restored when the
precompiled header is used. Delayed template parsing occurs at the end
of translation unit but before serialization, so clearing FP pragma
stack effects serialized representation. When the precompiled file is
loaded, some conditions can be broken and clang crashed, it was
described in https://github.com/llvm/llvm-project/issues/63704. The
crash was observed only in few cases, on most buildbots it was absent.

The violation of expected conditions was caused by violation of the
second assumption. FPEvalMethod can be modified by target, so it is not
possible to deduce it from LangOptions only. So default FP state read
from precompiled header was different from the state in the initialized
Sema, and this was the crash reason.

Only two targets do such modification of default FP options, these are
i386 and AIX. so the problem was hard to reproduce.

Delayed template parsing should occur with empty pragma stack, so it
must be cleared before the instantiation, but the stack now is saved
and restored after the instantiation is done.

This change should fix https://github.com/llvm/llvm-project/issues/63704.

Differential Revision: https://reviews.llvm.org/D155380

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseTemplate.cpp
clang/test/PCH/late-parsed-instantiations.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index dbc071bf5cd838..2ffe3783c2f3e7 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,6 +710,16 @@ class Sema final {
 return result;
   }
 
+  class FpPragmaStackSaveRAII {
+  public:
+FpPragmaStackSaveRAII(Sema ) : S(S), SavedStack(S.FpPragmaStack) {}
+~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
+
+  private:
+Sema 
+PragmaStack SavedStack;
+  };
+
   void resetFPOptions(FPOptions FPO) {
 CurFPFeatures = FPO;
 FpPragmaStack.Stack.clear();

diff  --git a/clang/lib/Parse/ParseTemplate.cpp 
b/clang/lib/Parse/ParseTemplate.cpp
index 776c66b436472e..fc661d21b63a27 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1744,6 +1744,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate 
) {
 
   // Parsing should occur with empty FP pragma stack and FP options used in the
   // point of the template definition.
+  Sema::FpPragmaStackSaveRAII SavedStack(Actions);
   Actions.resetFPOptions(LPT.FPO);
 
   assert(!LPT.Toks.empty() && "Empty body!");

diff  --git a/clang/test/PCH/late-parsed-instantiations.cpp 
b/clang/test/PCH/late-parsed-instantiations.cpp
index e70147dcee6166..9ae6b56a09befa 100644
--- a/clang/test/PCH/late-parsed-instantiations.cpp
+++ b/clang/test/PCH/late-parsed-instantiations.cpp
@@ -4,7 +4,9 @@
 // RUN: %clang_cc1 -fdelayed-template-parsing -std=c++14 -emit-pch 
-fpch-instantiate-templates %s -o %t.pch -verify
 // RUN: %clang_cc1 -fdelayed-template-parsing -std=c++14 -include-pch %t.pch 
%s -verify
 
-// XFAIL: target={{.*}}-aix{{.*}}
+// Run this test for i686 as this is the target that modifies default FP 
options.
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fdelayed-template-parsing 
-std=c++14 -emit-pch -fpch-instantiate-templates %s -o %t.pch -verify
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fdelayed-template-parsing 
-std=c++14 -include-pch %t.pch %s -verify
 
 #ifndef HEADER_INCLUDED
 



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


[clang] fde5924 - [clang] Reset FP options before template instantiation

2023-07-12 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-07-13T11:49:00+07:00
New Revision: fde5924dcc69fe814085482df259b8cfee236f2c

URL: 
https://github.com/llvm/llvm-project/commit/fde5924dcc69fe814085482df259b8cfee236f2c
DIFF: 
https://github.com/llvm/llvm-project/commit/fde5924dcc69fe814085482df259b8cfee236f2c.diff

LOG: [clang] Reset FP options before template instantiation

AST nodes that may depend on FP options keep them as a difference
relative to the options outside the AST node. At the moment of
instantiation the FP options may be different from the default values,
defined by command-line option. In such case FP attributes would have
unexpected values. For example, the code:

template  void func_01(int last, C) {
  func_01(last, int());
}
void func_02() { func_01(0, 1); }
#pragma STDC FENV_ACCESS ON

caused compiler crash, because template instantiation takes place at the
end of translation unit, where pragma STDC FENV_ACCESS is in effect. As
a result, code in the template instantiation would use constrained
intrinsics while the function does not have StrictFP attribute.

To solve this problem, FP attributes in Sema must be set to default
values, defined by command line options.

This change resolves https://github.com/llvm/llvm-project/issues/63542.

Differential Revision: https://reviews.llvm.org/D154359

Added: 


Modified: 
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/test/CodeGen/fp-template.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 492fe8ba1b143c..9e5f85b0f9166b 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5087,6 +5087,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation 
PointOfInstantiation,
 // PushDeclContext because we don't have a scope.
 Sema::ContextRAII savedContext(*this, Function);
 
+FPFeaturesStateRAII SavedFPFeatures(*this);
+CurFPFeatures = FPOptions(getLangOpts());
+FpPragmaStack.CurrentValue = FPOptionsOverride();
+
 if (addInstantiatedParametersToScope(Function, PatternDecl, Scope,
  TemplateArgs))
   return;

diff  --git a/clang/test/CodeGen/fp-template.cpp 
b/clang/test/CodeGen/fp-template.cpp
index e0ea8e4d12ad34..a945b23fff1095 100644
--- a/clang/test/CodeGen/fp-template.cpp
+++ b/clang/test/CodeGen/fp-template.cpp
@@ -45,10 +45,24 @@ float func_03(float x, float y) {
 // CHECK:   call float @llvm.experimental.constrained.fsub.f32({{.*}}, 
metadata !"round.upward", metadata !"fpexcept.ignore")
 
 
-// This pragma sets non-default rounding mode before delayed parsing occurs. It
-// is used to check that the parsing uses FP options defined by command line
-// options or by pragma before the template definition but not by this pragma.
-#pragma STDC FENV_ROUND FE_TOWARDZERO
+#pragma STDC FENV_ROUND FE_TONEAREST
+
+namespace PR63542 {
+  template  float stable_sort(float x, Compare) {
+float result = x + x;
+stable_sort(x, int());
+return result;
+  }
+  float linkage_wrap() { return stable_sort(0.0, 1); }
+}
 
+// CHECK-LABEL: define {{.*}} float @_ZN7PR6354211stable_sortIiEEffT_(
+// CHECK: fadd float
+
+// These pragmas set non-default FP environment before delayed parsing occurs.
+// It is used to check that the parsing uses FP options defined by command line
+// options or by pragma before the template definition but not by these 
pragmas.
+#pragma STDC FENV_ROUND FE_TOWARDZERO
+#pragma STDC FENV_ACCESS ON
 
 // CHECK: attributes #[[ATTR01]] = { {{.*}}strictfp



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


[clang] 7d6c2e1 - [clang] Use llvm.is_fpclass to implement FP classification functions

2023-07-11 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-07-11T21:34:53+07:00
New Revision: 7d6c2e18114de9900d1b012cf9c219803b183f63

URL: 
https://github.com/llvm/llvm-project/commit/7d6c2e18114de9900d1b012cf9c219803b183f63
DIFF: 
https://github.com/llvm/llvm-project/commit/7d6c2e18114de9900d1b012cf9c219803b183f63.diff

LOG: [clang] Use llvm.is_fpclass to implement FP classification functions

Builtin floating-point number classification functions:

- __builtin_isnan,
- __builtin_isinf,
- __builtin_finite, and
- __builtin_isnormal

now are implemented using `llvm.is_fpclass`.

This change makes the target callback `TargetCodeGenInfo::testFPKind`
unneeded. It is preserved in this change and should be removed later.

Differential Revision: https://reviews.llvm.org/D112932

Added: 


Modified: 
clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/X86/strictfp_builtins.c
clang/test/CodeGen/aarch64-strictfp-builtins.c
clang/test/CodeGen/builtin_float.c
clang/test/CodeGen/builtin_float_strictfp.c
clang/test/CodeGen/builtins.c
clang/test/CodeGen/isfpclass.c
clang/test/CodeGen/strictfp_builtins.c
clang/test/Headers/__clang_hip_math.hip
clang/test/Headers/hip-header.hip
clang/test/Headers/openmp_device_math_isnan.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 088fb46faee5d8..1fbf29abcaae54 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -31,6 +31,7 @@
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
+#include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Analysis/ValueTracking.h"
@@ -2239,6 +2240,17 @@ static unsigned mutateLongDoubleBuiltin(unsigned 
BuiltinID) {
   }
 }
 
+static Value *tryUseTestFPKind(CodeGenFunction , unsigned BuiltinID,
+   Value *V) {
+  if (CGF.Builder.getIsFPConstrained() &&
+  CGF.Builder.getDefaultConstrainedExcept() != fp::ebIgnore) {
+if (Value *Result =
+CGF.getTargetHooks().testFPKind(V, BuiltinID, CGF.Builder, 
CGF.CGM))
+  return Result;
+  }
+  return nullptr;
+}
+
 RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned 
BuiltinID,
 const CallExpr *E,
 ReturnValueSlot ReturnValue) {
@@ -3122,37 +3134,49 @@ RValue CodeGenFunction::EmitBuiltinExpr(const 
GlobalDecl GD, unsigned BuiltinID,
 // ZExt bool to int type.
 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType(;
   }
+
   case Builtin::BI__builtin_isnan: {
 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
 Value *V = EmitScalarExpr(E->getArg(0));
-llvm::Type *Ty = V->getType();
-const llvm::fltSemantics  = Ty->getFltSemantics();
-if (!Builder.getIsFPConstrained() ||
-Builder.getDefaultConstrainedExcept() == fp::ebIgnore ||
-!Ty->isIEEE()) {
-  V = Builder.CreateFCmpUNO(V, V, "cmp");
-  return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType(;
-}
+if (Value *Result = tryUseTestFPKind(*this, BuiltinID, V))
+  return RValue::get(Result);
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcNan),
+   ConvertType(E->getType(;
+  }
 
-if (Value *Result = getTargetHooks().testFPKind(V, BuiltinID, Builder, 
CGM))
+  case Builtin::BI__builtin_isinf: {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
+Value *V = EmitScalarExpr(E->getArg(0));
+if (Value *Result = tryUseTestFPKind(*this, BuiltinID, V))
   return RValue::get(Result);
+return RValue::get(
+Builder.CreateZExt(Builder.createIsFPClass(V, FPClassTest::fcInf),
+   ConvertType(E->getType(;
+  }
 
-// NaN has all exp bits set and a non zero significand. Therefore:
-// isnan(V) == ((exp mask - (abs(V) & exp mask)) < 0)
-unsigned bitsize = Ty->getScalarSizeInBits();
-llvm::IntegerType *IntTy = Builder.getIntNTy(bitsize);
-Value *IntV = Builder.CreateBitCast(V, IntTy);
-APInt AndMask = APInt::getSignedMaxValue(bitsize);
-Value *AbsV =
-Builder.CreateAnd(IntV, llvm::ConstantInt::get(IntTy, AndMask));
-APInt ExpMask = APFloat::getInf(Semantics).bitcastToAPInt();
-Value *Sub =
-Builder.CreateSub(llvm::ConstantInt::get(IntTy, ExpMask), AbsV);
-// V = sign bit (Sub) <=> V = (Sub < 0)
-V = Builder.CreateLShr(Sub, llvm::ConstantInt::get(IntTy, bitsize - 1));
-if (bitsize > 32)
-  V = Builder.CreateTrunc(V, ConvertType(E->getType()));
-return RValue::get(V);
+  case Builtin::BIfinite:
+  case Builtin::BI__finite:
+  case Builtin::BIfinitef:
+  case Builtin::BI__finitef:
+  case Builtin::BIfinitel:
+ 

[clang] d4a5673 - [AIX][clang][tests] XFail PCH/late-parsed-instantiations.cpp

2023-07-06 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-07-06T14:06:30+07:00
New Revision: d4a5673addd69aa2a299d9de4db8d17373be

URL: 
https://github.com/llvm/llvm-project/commit/d4a5673addd69aa2a299d9de4db8d17373be
DIFF: 
https://github.com/llvm/llvm-project/commit/d4a5673addd69aa2a299d9de4db8d17373be.diff

LOG: [AIX][clang][tests] XFail PCH/late-parsed-instantiations.cpp

The issue: https://github.com/llvm/llvm-project/issues/63704

Added: 


Modified: 
clang/test/PCH/late-parsed-instantiations.cpp

Removed: 




diff  --git a/clang/test/PCH/late-parsed-instantiations.cpp 
b/clang/test/PCH/late-parsed-instantiations.cpp
index 7a787810a87f90..e70147dcee6166 100644
--- a/clang/test/PCH/late-parsed-instantiations.cpp
+++ b/clang/test/PCH/late-parsed-instantiations.cpp
@@ -4,6 +4,8 @@
 // RUN: %clang_cc1 -fdelayed-template-parsing -std=c++14 -emit-pch 
-fpch-instantiate-templates %s -o %t.pch -verify
 // RUN: %clang_cc1 -fdelayed-template-parsing -std=c++14 -include-pch %t.pch 
%s -verify
 
+// XFAIL: target={{.*}}-aix{{.*}}
+
 #ifndef HEADER_INCLUDED
 
 #define HEADER_INCLUDED



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


[clang] 2e90370 - [Clang] Reset FP options before function instantiations

2023-07-05 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-07-05T16:34:19+07:00
New Revision: 2e903709de003dc6ae980197f4a0850a158dd9b8

URL: 
https://github.com/llvm/llvm-project/commit/2e903709de003dc6ae980197f4a0850a158dd9b8
DIFF: 
https://github.com/llvm/llvm-project/commit/2e903709de003dc6ae980197f4a0850a158dd9b8.diff

LOG: [Clang] Reset FP options before function instantiations

This is recommit of 98390ccb80569e8fbb20e6c996b4b8cff87fbec6, reverted
in 82a3969d710f5fb7a2ee4c9afadb648653923fef, because it caused
https://github.com/llvm/llvm-project/issues/63542. Although the problem
described in the issue is independent of the reverted patch, fail of
PCH/late-parsed-instantiations.cpp indeed obseved on PowerPC and is
likely to be caused by wrong serialization of `LateParsedTemplate`
objects. In this patch the serialization is fixed.

Original commit message is below.

Previously function template instantiations occurred with FP options
that were in effect at the end of translation unit. It was a problem
for late template parsing as these FP options were used as attributes of
AST nodes and may result in crash. To fix it FP options are set to the
state of the point of template definition.

Differential Revision: https://reviews.llvm.org/D143241

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseTemplate.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/CodeGen/fp-template.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index eed23e5ba99c89..aa4fc8947cbe7d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,6 +710,12 @@ class Sema final {
 return result;
   }
 
+  void resetFPOptions(FPOptions FPO) {
+CurFPFeatures = FPO;
+FpPragmaStack.Stack.clear();
+FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
+  }
+
   // RAII object to push / pop sentinel slots for all MS #pragma stacks.
   // Actions should be performed only if we enter / exit a C++ method body.
   class PragmaStackSentinelRAII {
@@ -14028,6 +14034,8 @@ struct LateParsedTemplate {
   CachedTokens Toks;
   /// The template function declaration to be late parsed.
   Decl *D;
+  /// Floating-point options in the point of definition.
+  FPOptions FPO;
 };
 
 template <>

diff  --git a/clang/lib/Parse/ParseTemplate.cpp 
b/clang/lib/Parse/ParseTemplate.cpp
index d2e8a81ad521a9..776c66b436472e 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1742,6 +1742,10 @@ void 
Parser::ParseLateTemplatedFuncDef(LateParsedTemplate ) {
   Actions.PushDeclContext(Actions.getCurScope(), DC);
   }
 
+  // Parsing should occur with empty FP pragma stack and FP options used in the
+  // point of the template definition.
+  Actions.resetFPOptions(LPT.FPO);
+
   assert(!LPT.Toks.empty() && "Empty body!");
 
   // Append the current token at the end of the new token stream so that it

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 7ef99b4bfcaf54..a1f0f5732b2b77 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -11377,6 +11377,7 @@ void Sema::MarkAsLateParsedTemplate(FunctionDecl *FD, 
Decl *FnD,
   // Take tokens to avoid allocations
   LPT->Toks.swap(Toks);
   LPT->D = FnD;
+  LPT->FPO = getCurFPFeatures();
   LateParsedTemplateMap.insert(std::make_pair(FD, std::move(LPT)));
 
   FD->setLateTemplateParsed(true);

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 78f718533bd55c..b989ff2a9c95c4 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -8606,6 +8606,7 @@ void ASTReader::ReadLateParsedTemplates(
 
   auto LT = std::make_unique();
   LT->D = GetLocalDecl(*FMod, LateParsed[Idx++]);
+  LT->FPO = FPOptions::getFromOpaqueInt(LateParsed[Idx++]);
 
   ModuleFile *F = getOwningModuleFile(LT->D);
   assert(F && "No module");

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index e2dec17f7cae77..f4389ecd7629a1 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4278,6 +4278,7 @@ void ASTWriter::WriteLateParsedTemplates(Sema ) {
 LateParsedTemplate  = *LPTMapEntry.second;
 AddDeclRef(FD, Record);
 AddDeclRef(LPT.D, Record);
+Record.push_back(LPT.FPO.getAsOpaqueInt());
 Record.push_back(LPT.Toks.size());
 
 for (const auto  : LPT.Toks) {

diff  --git a/clang/test/CodeGen/fp-template.cpp 
b/clang/test/CodeGen/fp-template.cpp
index 9e0fc0555e3365..e0ea8e4d12ad34 100644
--- a/clang/test/CodeGen/fp-template.cpp
+++ b/clang/test/CodeGen/fp-template.cpp
@@ -15,4 +15,40 @@ float func_01(float x, float y) {
 // CHECK-SAME:  (float 

[clang] 82a3969 - Revert "[Clang] Reset FP options before function instantiations"

2023-06-28 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-06-29T02:07:41+07:00
New Revision: 82a3969d710f5fb7a2ee4c9afadb648653923fef

URL: 
https://github.com/llvm/llvm-project/commit/82a3969d710f5fb7a2ee4c9afadb648653923fef
DIFF: 
https://github.com/llvm/llvm-project/commit/82a3969d710f5fb7a2ee4c9afadb648653923fef.diff

LOG: Revert "[Clang] Reset FP options before function instantiations"

This reverts commit 98390ccb80569e8fbb20e6c996b4b8cff87fbec6.
It caused issue #63542.

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseTemplate.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/test/CodeGen/fp-template.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 35bd3e253f668..55d1dcf6ee0c2 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,12 +710,6 @@ class Sema final {
 return result;
   }
 
-  void resetFPOptions(FPOptions FPO) {
-CurFPFeatures = FPO;
-FpPragmaStack.Stack.clear();
-FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
-  }
-
   // RAII object to push / pop sentinel slots for all MS #pragma stacks.
   // Actions should be performed only if we enter / exit a C++ method body.
   class PragmaStackSentinelRAII {
@@ -14007,8 +14001,6 @@ struct LateParsedTemplate {
   CachedTokens Toks;
   /// The template function declaration to be late parsed.
   Decl *D;
-  /// Floating-point options in the point of definition.
-  FPOptions FPO;
 };
 
 template <>

diff  --git a/clang/lib/Parse/ParseTemplate.cpp 
b/clang/lib/Parse/ParseTemplate.cpp
index 776c66b436472..d2e8a81ad521a 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1742,10 +1742,6 @@ void 
Parser::ParseLateTemplatedFuncDef(LateParsedTemplate ) {
   Actions.PushDeclContext(Actions.getCurScope(), DC);
   }
 
-  // Parsing should occur with empty FP pragma stack and FP options used in the
-  // point of the template definition.
-  Actions.resetFPOptions(LPT.FPO);
-
   assert(!LPT.Toks.empty() && "Empty body!");
 
   // Append the current token at the end of the new token stream so that it

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index cb94edf67af59..063ddb418c431 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -11342,7 +11342,6 @@ void Sema::MarkAsLateParsedTemplate(FunctionDecl *FD, 
Decl *FnD,
   // Take tokens to avoid allocations
   LPT->Toks.swap(Toks);
   LPT->D = FnD;
-  LPT->FPO = getCurFPFeatures();
   LateParsedTemplateMap.insert(std::make_pair(FD, std::move(LPT)));
 
   FD->setLateTemplateParsed(true);

diff  --git a/clang/test/CodeGen/fp-template.cpp 
b/clang/test/CodeGen/fp-template.cpp
index e0ea8e4d12ad3..9e0fc0555e336 100644
--- a/clang/test/CodeGen/fp-template.cpp
+++ b/clang/test/CodeGen/fp-template.cpp
@@ -15,40 +15,4 @@ float func_01(float x, float y) {
 // CHECK-SAME:  (float noundef %{{.*}}, float noundef %{{.*}}) 
#[[ATTR01:[0-9]+]]{{.*}} {
 // CHECK:   call float @llvm.experimental.constrained.fadd.f32
 
-
-template 
-Ty templ_02(Ty x, Ty y) {
-  return x + y;
-}
-
-#pragma STDC FENV_ROUND FE_UPWARD
-
-template 
-Ty templ_03(Ty x, Ty y) {
-  return x - y;
-}
-
-#pragma STDC FENV_ROUND FE_TONEAREST
-
-float func_02(float x, float y) {
-  return templ_02(x, y);
-}
-
-// CHECK-LABEL: define {{.*}} float @_Z8templ_02IfET_S0_S0_
-// CHECK:   %add = fadd float %0, %1
-
-float func_03(float x, float y) {
-  return templ_03(x, y);
-}
-
-// CHECK-LABEL: define {{.*}} float @_Z8templ_03IfET_S0_S0_
-// CHECK:   call float @llvm.experimental.constrained.fsub.f32({{.*}}, 
metadata !"round.upward", metadata !"fpexcept.ignore")
-
-
-// This pragma sets non-default rounding mode before delayed parsing occurs. It
-// is used to check that the parsing uses FP options defined by command line
-// options or by pragma before the template definition but not by this pragma.
-#pragma STDC FENV_ROUND FE_TOWARDZERO
-
-
 // CHECK: attributes #[[ATTR01]] = { {{.*}}strictfp



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


[clang] 98390cc - [Clang] Reset FP options before function instantiations

2023-06-28 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-06-28T20:11:54+07:00
New Revision: 98390ccb80569e8fbb20e6c996b4b8cff87fbec6

URL: 
https://github.com/llvm/llvm-project/commit/98390ccb80569e8fbb20e6c996b4b8cff87fbec6
DIFF: 
https://github.com/llvm/llvm-project/commit/98390ccb80569e8fbb20e6c996b4b8cff87fbec6.diff

LOG: [Clang] Reset FP options before function instantiations

Previously function template instantiations occurred with FP options
that were in effect at the end of translation unit. It was a problem
for late template parsing as these FP options were used as attributes of
AST nodes and may result in crash. To fix it FP options are set to the
state of the point of template definition.

Differential Revision: https://reviews.llvm.org/D143241

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseTemplate.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/test/CodeGen/fp-template.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 55d1dcf6ee0c26..35bd3e253f668c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -710,6 +710,12 @@ class Sema final {
 return result;
   }
 
+  void resetFPOptions(FPOptions FPO) {
+CurFPFeatures = FPO;
+FpPragmaStack.Stack.clear();
+FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
+  }
+
   // RAII object to push / pop sentinel slots for all MS #pragma stacks.
   // Actions should be performed only if we enter / exit a C++ method body.
   class PragmaStackSentinelRAII {
@@ -14001,6 +14007,8 @@ struct LateParsedTemplate {
   CachedTokens Toks;
   /// The template function declaration to be late parsed.
   Decl *D;
+  /// Floating-point options in the point of definition.
+  FPOptions FPO;
 };
 
 template <>

diff  --git a/clang/lib/Parse/ParseTemplate.cpp 
b/clang/lib/Parse/ParseTemplate.cpp
index d2e8a81ad521a9..776c66b436472e 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1742,6 +1742,10 @@ void 
Parser::ParseLateTemplatedFuncDef(LateParsedTemplate ) {
   Actions.PushDeclContext(Actions.getCurScope(), DC);
   }
 
+  // Parsing should occur with empty FP pragma stack and FP options used in the
+  // point of the template definition.
+  Actions.resetFPOptions(LPT.FPO);
+
   assert(!LPT.Toks.empty() && "Empty body!");
 
   // Append the current token at the end of the new token stream so that it

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 063ddb418c4314..cb94edf67af594 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -11342,6 +11342,7 @@ void Sema::MarkAsLateParsedTemplate(FunctionDecl *FD, 
Decl *FnD,
   // Take tokens to avoid allocations
   LPT->Toks.swap(Toks);
   LPT->D = FnD;
+  LPT->FPO = getCurFPFeatures();
   LateParsedTemplateMap.insert(std::make_pair(FD, std::move(LPT)));
 
   FD->setLateTemplateParsed(true);

diff  --git a/clang/test/CodeGen/fp-template.cpp 
b/clang/test/CodeGen/fp-template.cpp
index 9e0fc0555e3365..e0ea8e4d12ad34 100644
--- a/clang/test/CodeGen/fp-template.cpp
+++ b/clang/test/CodeGen/fp-template.cpp
@@ -15,4 +15,40 @@ float func_01(float x, float y) {
 // CHECK-SAME:  (float noundef %{{.*}}, float noundef %{{.*}}) 
#[[ATTR01:[0-9]+]]{{.*}} {
 // CHECK:   call float @llvm.experimental.constrained.fadd.f32
 
+
+template 
+Ty templ_02(Ty x, Ty y) {
+  return x + y;
+}
+
+#pragma STDC FENV_ROUND FE_UPWARD
+
+template 
+Ty templ_03(Ty x, Ty y) {
+  return x - y;
+}
+
+#pragma STDC FENV_ROUND FE_TONEAREST
+
+float func_02(float x, float y) {
+  return templ_02(x, y);
+}
+
+// CHECK-LABEL: define {{.*}} float @_Z8templ_02IfET_S0_S0_
+// CHECK:   %add = fadd float %0, %1
+
+float func_03(float x, float y) {
+  return templ_03(x, y);
+}
+
+// CHECK-LABEL: define {{.*}} float @_Z8templ_03IfET_S0_S0_
+// CHECK:   call float @llvm.experimental.constrained.fsub.f32({{.*}}, 
metadata !"round.upward", metadata !"fpexcept.ignore")
+
+
+// This pragma sets non-default rounding mode before delayed parsing occurs. It
+// is used to check that the parsing uses FP options defined by command line
+// options or by pragma before the template definition but not by this pragma.
+#pragma STDC FENV_ROUND FE_TOWARDZERO
+
+
 // CHECK: attributes #[[ATTR01]] = { {{.*}}strictfp



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


[clang] 112fa9a - [Doc] Fix table layout

2023-06-18 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-06-18T23:46:08+07:00
New Revision: 112fa9aa7042861ba101828d87e8d6b629121eae

URL: 
https://github.com/llvm/llvm-project/commit/112fa9aa7042861ba101828d87e8d6b629121eae
DIFF: 
https://github.com/llvm/llvm-project/commit/112fa9aa7042861ba101828d87e8d6b629121eae.diff

LOG: [Doc] Fix table layout

Added: 


Modified: 
clang/docs/LanguageExtensions.rst

Removed: 




diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 4bcb05d202234..9944cb28f0487 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3535,6 +3535,7 @@ Mask value Data class  Macro
 0x0080 Positive subnormal  __FPCLASS_POSSUBNORMAL
 0x0100 Positive normal __FPCLASS_POSNORMAL
 0x0200 Positive infinity   __FPCLASS_POSINF
+== === ==
 
 For convenience preprocessor defines macros for these values. The function
 returns 1 if ``expr`` falls into one of the specified data classes, 0 
otherwise.



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


[clang] 7dd387d - [clang] Add __builtin_isfpclass

2023-06-18 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-06-18T22:53:32+07:00
New Revision: 7dd387d2971d7759cadfffeb2082439f6c7ddd49

URL: 
https://github.com/llvm/llvm-project/commit/7dd387d2971d7759cadfffeb2082439f6c7ddd49
DIFF: 
https://github.com/llvm/llvm-project/commit/7dd387d2971d7759cadfffeb2082439f6c7ddd49.diff

LOG: [clang] Add __builtin_isfpclass

A new builtin function __builtin_isfpclass is added. It is called as:

__builtin_isfpclass(, )

and returns an integer value, which is non-zero if the floating point
argument falls into one of the classes specified by the second argument,
and zero otherwise. The set of classes is an integer value, where each
value class is represented by a bit. There are ten data classes, as
defined by the IEEE-754 standard, they are represented by bits:

0x0001 (__FPCLASS_SNAN) - Signaling NaN
0x0002 (__FPCLASS_QNAN) - Quiet NaN
0x0004 (__FPCLASS_NEGINF)   - Negative infinity
0x0008 (__FPCLASS_NEGNORMAL)- Negative normal
0x0010 (__FPCLASS_NEGSUBNORMAL) - Negative subnormal
0x0020 (__FPCLASS_NEGZERO)  - Negative zero
0x0040 (__FPCLASS_POSZERO)  - Positive zero
0x0080 (__FPCLASS_POSSUBNORMAL) - Positive subnormal
0x0100 (__FPCLASS_POSNORMAL)- Positive normal
0x0200 (__FPCLASS_POSINF)   - Positive infinity

They have corresponding builtin macros to facilitate using the builtin
function:

if (__builtin_isfpclass(x, __FPCLASS_NEGZERO | __FPCLASS_POSZERO) {
  // x is any zero.
}

The data class encoding is identical to that used in llvm.is.fpclass
function.

Differential Revision: https://reviews.llvm.org/D152351

Added: 
clang/test/CodeGen/isfpclass.c

Modified: 
clang/docs/LanguageExtensions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/Builtins.def
clang/lib/AST/ExprConstant.cpp
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/Frontend/InitPreprocessor.cpp
clang/lib/Sema/SemaChecking.cpp
clang/test/CodeGen/builtins.c
clang/test/Preprocessor/init-aarch64.c
clang/test/Preprocessor/init.c
clang/test/Sema/builtins.c
clang/test/Sema/constant-builtins-2.c
llvm/include/llvm/IR/IRBuilder.h
llvm/lib/IR/IRBuilder.cpp

Removed: 




diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index f37db774a0f7b..4bcb05d202234 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3489,6 +3489,68 @@ Query for this feature with 
``__has_builtin(__builtin_add_overflow)``, etc.
 Floating point builtins
 ---
 
+``__builtin_isfpclass``
+---
+
+``__builtin_isfpclass`` is used to test if the specified floating-point value
+falls into one of the specified floating-point classes.
+
+**Syntax**:
+
+.. code-block:: c++
+
+int __builtin_isfpclass(fp_type expr, int mask)
+
+``fp_type`` is a floating-point type supported by the target. ``mask`` is an
+integer constant expression, where each bit represents floating-point class to
+test. The function returns boolean value.
+
+**Example of use**:
+
+.. code-block:: c++
+
+  if (__builtin_isfpclass(x, 448)) {
+ // `x` is positive finite value
+...
+  }
+
+**Description**:
+
+The ``__builtin_isfpclass()`` builtin is a generalization of functions 
``isnan``,
+``isinf``, ``isfinite`` and some others defined by the C standard. It tests if
+the floating-point value, specified by the first argument, falls into any of 
data
+classes, specified by the second argument. The later is a bitmask, in which 
each
+data class is represented by a bit using the encoding:
+
+== === ==
+Mask value Data class  Macro
+== === ==
+0x0001 Signaling NaN   __FPCLASS_SNAN
+0x0002 Quiet NaN   __FPCLASS_QNAN
+0x0004 Negative infinity   __FPCLASS_NEGINF
+0x0008 Negative normal __FPCLASS_NEGNORMAL
+0x0010 Negative subnormal  __FPCLASS_NEGSUBNORMAL
+0x0020 Negative zero   __FPCLASS_NEGZERO
+0x0040 Positive zero   __FPCLASS_POSZERO
+0x0080 Positive subnormal  __FPCLASS_POSSUBNORMAL
+0x0100 Positive normal __FPCLASS_POSNORMAL
+0x0200 Positive infinity   __FPCLASS_POSINF
+
+For convenience preprocessor defines macros for these values. The function
+returns 1 if ``expr`` falls into one of the specified data classes, 0 
otherwise.
+
+In the example above the mask value 448 (0x1C0) contains the bits selecting
+positive zero, positive subnormal and positive normal classes.
+``__builtin_isfpclass(x, 448)`` would return true only if ``x`` if of any of
+these data classes. Using suitable mask value, the function can implement any 
of
+the standard classification functions, for example, ``__builtin_isfpclass(x, 
3)``
+is identical to ``isnan``,``__builtin_isfpclass(x, 504)`` - to 

[clang] 5cc91f9 - [Clang] Copy strictfp attribute from pattern to instantiation

2023-02-26 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-02-27T11:19:20+07:00
New Revision: 5cc91f977eaa0b0947ff1cf2a52ea6bc4479081d

URL: 
https://github.com/llvm/llvm-project/commit/5cc91f977eaa0b0947ff1cf2a52ea6bc4479081d
DIFF: 
https://github.com/llvm/llvm-project/commit/5cc91f977eaa0b0947ff1cf2a52ea6bc4479081d.diff

LOG: [Clang] Copy strictfp attribute from pattern to instantiation

If a template function contained a pragma that made it strictfp, code
generation for such function crashed, because the instantiation did not
have strictfp attribute. As a solution this attribute is copied from the
template to instantiation.

Differential Revision: https://reviews.llvm.org/D143919

Added: 
clang/test/CodeGen/fp-template.cpp

Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0c6a3887e415..434b22cdba8c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10052,6 +10052,7 @@ class Sema final {
 const Decl *Pattern, Decl *Inst,
 LateInstantiatedAttrVec *LateAttrs = nullptr,
 LocalInstantiationScope *OuterMostScope = nullptr);
+  void updateAttrsForLateParsedTemplate(const Decl *Pattern, Decl *Inst);
 
   void
   InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList ,

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 7a0da8d08333..bf82ffb52a26 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -834,6 +834,22 @@ void Sema::InstantiateAttrs(const 
MultiLevelTemplateArgumentList ,
   }
 }
 
+/// Update instantiation attributes after template was late parsed.
+///
+/// Some attributes are evaluated based on the body of template. If it is
+/// late parsed, such attributes cannot be evaluated when declaration is
+/// instantiated. This function is used to update instantiation attributes when
+/// template definition is ready.
+void Sema::updateAttrsForLateParsedTemplate(const Decl *Pattern, Decl *Inst) {
+  for (const auto *Attr : Pattern->attrs()) {
+if (auto *A = dyn_cast(Attr)) {
+  if (!Inst->hasAttr())
+Inst->addAttr(A->clone(getASTContext()));
+  continue;
+}
+  }
+}
+
 /// In the MS ABI, we need to instantiate default arguments of dllexported
 /// default constructors along with the constructor definition. This allows IR
 /// gen to emit a constructor closure which calls the default constructor with
@@ -4916,6 +4932,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation 
PointOfInstantiation,
"missing LateParsedTemplate");
 LateTemplateParser(OpaqueParser, *LPTIter->second);
 Pattern = PatternDecl->getBody(PatternDecl);
+updateAttrsForLateParsedTemplate(PatternDecl, Function);
   }
 
   // Note, we should never try to instantiate a deleted function template.

diff  --git a/clang/test/CodeGen/fp-template.cpp 
b/clang/test/CodeGen/fp-template.cpp
new file mode 100644
index ..9e0fc0555e33
--- /dev/null
+++ b/clang/test/CodeGen/fp-template.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm 
-fdelayed-template-parsing -o - %s | FileCheck %s
+
+template 
+T templ_01(T x, T y) {
+#pragma STDC FENV_ACCESS ON
+  return x + y;
+}
+
+float func_01(float x, float y) {
+  return templ_01(x, y);
+}
+
+// CHECK-LABEL: define {{.*}} @_Z8templ_01IfET_S0_S0_
+// CHECK-SAME:  (float noundef %{{.*}}, float noundef %{{.*}}) 
#[[ATTR01:[0-9]+]]{{.*}} {
+// CHECK:   call float @llvm.experimental.constrained.fadd.f32
+
+// CHECK: attributes #[[ATTR01]] = { {{.*}}strictfp



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


[clang] d595b59 - [FPEnv] Fix complex operations in strictfp mode

2023-01-24 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-01-24T16:40:11+07:00
New Revision: d595b59d5c9c8e56c3b3d142912ee16a02071690

URL: 
https://github.com/llvm/llvm-project/commit/d595b59d5c9c8e56c3b3d142912ee16a02071690
DIFF: 
https://github.com/llvm/llvm-project/commit/d595b59d5c9c8e56c3b3d142912ee16a02071690.diff

LOG: [FPEnv] Fix complex operations in strictfp mode

Operations on floating-point complex data had incorrect FP attributes
in strictfp mode, because IRBuilder object was not synchronized with AST
node attributes.

Differential Revision: https://reviews.llvm.org/D141765

Added: 


Modified: 
clang/lib/CodeGen/CGExprComplex.cpp
clang/test/CodeGen/complex-strictfp.c

Removed: 




diff  --git a/clang/lib/CodeGen/CGExprComplex.cpp 
b/clang/lib/CodeGen/CGExprComplex.cpp
index e65e925a11d48..7a14a418c7b65 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -252,6 +252,7 @@ class ComplexExprEmitter
 ComplexPairTy LHS;
 ComplexPairTy RHS;
 QualType Ty;  // Computation Type.
+FPOptions FPFeatures;
   };
 
   BinOpInfo EmitBinOps(const BinaryOperator *E,
@@ -643,6 +644,7 @@ ComplexPairTy ComplexExprEmitter::EmitBinAdd(const 
BinOpInfo ) {
   llvm::Value *ResR, *ResI;
 
   if (Op.LHS.first->getType()->isFloatingPointTy()) {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
 ResR = Builder.CreateFAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
 if (Op.LHS.second && Op.RHS.second)
   ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i");
@@ -661,6 +663,7 @@ ComplexPairTy ComplexExprEmitter::EmitBinAdd(const 
BinOpInfo ) {
 ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo ) {
   llvm::Value *ResR, *ResI;
   if (Op.LHS.first->getType()->isFloatingPointTy()) {
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
 ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r");
 if (Op.LHS.second && Op.RHS.second)
   ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i");
@@ -753,6 +756,7 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const 
BinOpInfo ) {
 // FIXME: C11 also provides for imaginary types which would allow folding
 // still more of this within the type system.
 
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
 if (Op.LHS.second && Op.RHS.second) {
   // If both operands are complex, emit the core math directly, and then
   // test for NaNs. If we find NaNs in the result, we delegate to a libcall
@@ -854,6 +858,7 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const 
BinOpInfo ) {
 //
 // FIXME: We would be able to avoid the libcall in many places if we
 // supported imaginary types in addition to complex types.
+CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
 if (RHSi && !CGF.getLangOpts().FastMath) {
   BinOpInfo LibCallOp = Op;
   // If LHS was a real, supply a null imaginary part.
@@ -1025,6 +1030,7 @@ ComplexExprEmitter::EmitBinOps(const BinaryOperator *E,
 Ops.Ty = PromotionType;
   else
 Ops.Ty = E->getType();
+  Ops.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
   return Ops;
 }
 
@@ -1039,8 +1045,9 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
   if (const AtomicType *AT = LHSTy->getAs())
 LHSTy = AT->getValueType();
 
-  CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
   BinOpInfo OpInfo;
+  OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
+  CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
 
   // Load the RHS and LHS operands.
   // __block variables need to have the rhs evaluated first, plus this should

diff  --git a/clang/test/CodeGen/complex-strictfp.c 
b/clang/test/CodeGen/complex-strictfp.c
index 0bffed4ff331d..b0c84d5eebe72 100644
--- a/clang/test/CodeGen/complex-strictfp.c
+++ b/clang/test/CodeGen/complex-strictfp.c
@@ -1,12 +1,12 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown 
-ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown 
-ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck 
--implicit-check-not=fpexcept.maytrap --implicit-check-not=round.tonearest %s
 
 
 // Test that the constrained intrinsics are picking up the exception
 // metadata from the AST instead of the global default from the command line.
 // Include rounding metadata in the testing.
-// FIXME: All cases of "fpexcept.maytrap" in this test are wrong.
-// FIXME: All cases of "round.tonearest" in this test are wrong.
+// Any cases of "fpexcept.maytrap" in this test are clang bugs.
+// Any cases of "round.tonearest" in this test are clang bugs.
 
 #pragma float_control(except, on)
 #pragma STDC FENV_ROUND FE_UPWARD
@@ -15,7 +15,7 @@ _Complex double g1, g2;
 _Complex 

[clang] 65cf77d - [clang] Use FP options from AST for emitting code for casts

2023-01-20 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2023-01-20T20:47:43+07:00
New Revision: 65cf77d218cf8b6aee2dbe252f55120311c8

URL: 
https://github.com/llvm/llvm-project/commit/65cf77d218cf8b6aee2dbe252f55120311c8
DIFF: 
https://github.com/llvm/llvm-project/commit/65cf77d218cf8b6aee2dbe252f55120311c8.diff

LOG: [clang] Use FP options from AST for emitting code for casts

Differential Revision: https://reviews.llvm.org/D142001

Added: 


Modified: 
clang/lib/CodeGen/CGExprScalar.cpp
clang/test/CodeGen/X86/avx512dq-builtins-constrained.c
clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c

Removed: 




diff  --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index 6b265afa5a057..a0dcb978b1ac1 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2021,6 +2021,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
   Expr *E = CE->getSubExpr();
   QualType DestTy = CE->getType();
   CastKind Kind = CE->getCastKind();
+  CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
 
   // These cases are generally not written to ignore the result of
   // evaluating their sub-expressions, so we clear this now.

diff  --git a/clang/test/CodeGen/X86/avx512dq-builtins-constrained.c 
b/clang/test/CodeGen/X86/avx512dq-builtins-constrained.c
index 907e190fe370a..fc7c3361c9b76 100644
--- a/clang/test/CodeGen/X86/avx512dq-builtins-constrained.c
+++ b/clang/test/CodeGen/X86/avx512dq-builtins-constrained.c
@@ -1,10 +1,11 @@
 // REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-apple-darwin -target-feature +avx512dq -emit-llvm -o - -Wall 
-Werror | FileCheck %s --check-prefix=UNCONSTRAINED --check-prefix=COMMON 
--check-prefix=COMMONIR
-// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-apple-darwin -target-feature +avx512dq 
-ffp-exception-behavior=maytrap -DSTRICT=1 -emit-llvm -o - -Wall -Werror | 
FileCheck %s --check-prefix=CONSTRAINED --check-prefix=COMMON 
--check-prefix=COMMONIR
+// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-apple-darwin -target-feature +avx512dq 
-ffp-exception-behavior=maytrap -DSTRICT=1 -emit-llvm -o - -Wall -Werror | 
FileCheck %s --check-prefix=CONSTRAINED --check-prefix=COMMON 
--check-prefix=COMMONIR --implicit-check-not=fpexcept.maytrap
 // RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-apple-darwin -target-feature +avx512dq -S -o - -Wall -Werror | 
FileCheck %s --check-prefix=CHECK-ASM --check-prefix=COMMON
-// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-apple-darwin -target-feature +avx512dq 
-ffp-exception-behavior=maytrap -DSTRICT=1 -S -o - -Wall -Werror | FileCheck %s 
--check-prefix=CHECK-ASM --check-prefix=COMMON
+// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-apple-darwin -target-feature +avx512dq 
-ffp-exception-behavior=maytrap -DSTRICT=1 -S -o - -Wall -Werror | FileCheck %s 
--check-prefix=CHECK-ASM --check-prefix=COMMON 
--implicit-check-not=fpexcept.maytrap
+
+// Any cases of "fpexcept.maytrap" in this test are clang bugs.
 
-// FIXME: Every instance of "fpexcept.maytrap" is wrong.
 #ifdef STRICT
 // Test that the constrained intrinsics are picking up the exception
 // metadata from the AST instead of the global default from the command line.
@@ -18,7 +19,7 @@
 __m512d test_mm512_cvtepi64_pd(__m512i __A) {
   // COMMON-LABEL: test_mm512_cvtepi64_pd
   // UNCONSTRAINED: sitofp <8 x i64> %{{.*}} to <8 x double>
-  // CONSTRAINED: call <8 x double> 
@llvm.experimental.constrained.sitofp.v8f64.v8i64(<8 x i64> %{{.*}}, metadata 
!"round.tonearest", metadata !"fpexcept.maytrap")
+  // CONSTRAINED: call <8 x double> 
@llvm.experimental.constrained.sitofp.v8f64.v8i64(<8 x i64> %{{.*}}, metadata 
!"round.tonearest", metadata !"fpexcept.strict")
   // CHECK-ASM: vcvtqq2pd
   return _mm512_cvtepi64_pd(__A);
 }
@@ -26,7 +27,7 @@ __m512d test_mm512_cvtepi64_pd(__m512i __A) {
 __m512d test_mm512_mask_cvtepi64_pd(__m512d __W, __mmask8 __U, __m512i __A) {
   // COMMON-LABEL: test_mm512_mask_cvtepi64_pd
   // UNCONSTRAINED: sitofp <8 x i64> %{{.*}} to <8 x double>
-  // CONSTRAINED: call <8 x double> 
@llvm.experimental.constrained.sitofp.v8f64.v8i64(<8 x i64> %{{.*}}, metadata 
!"round.tonearest", metadata !"fpexcept.maytrap")
+  // CONSTRAINED: call <8 x double> 
@llvm.experimental.constrained.sitofp.v8f64.v8i64(<8 x i64> %{{.*}}, metadata 
!"round.tonearest", metadata !"fpexcept.strict")
   // COMMONIR: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> 
%{{.*}}
   // CHECK-ASM: vcvtqq2pd
   return _mm512_mask_cvtepi64_pd(__W, __U, __A);
@@ -35,7 +36,7 @@ __m512d test_mm512_mask_cvtepi64_pd(__m512d __W, __mmask8 
__U, __m512i __A) {
 __m512d test_mm512_maskz_cvtepi64_pd(__mmask8 

[clang] 1ddd586 - [clang] Missed rounding mode use in constant evaluation

2022-11-16 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-11-17T12:05:28+07:00
New Revision: 1ddd5863088b56f8614fb5a17abd2968c05790c3

URL: 
https://github.com/llvm/llvm-project/commit/1ddd5863088b56f8614fb5a17abd2968c05790c3
DIFF: 
https://github.com/llvm/llvm-project/commit/1ddd5863088b56f8614fb5a17abd2968c05790c3.diff

LOG: [clang] Missed rounding mode use in constant evaluation

Integer-to-float conversion was handled in constant evaluator with
default rounding mode. This change fixes the behavior and the conversion
is made using rounding mode stored in ImplicitCastExpr node.

Differential Revision: https://reviews.llvm.org/D137719

Added: 


Modified: 
clang/lib/AST/ExprConstant.cpp
clang/test/AST/const-fpfeatures.c

Removed: 




diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index e17df5da5cb2d..ecf072e070835 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2648,14 +2648,9 @@ static bool HandleIntToFloatCast(EvalInfo , const 
Expr *E,
  QualType SrcType, const APSInt ,
  QualType DestType, APFloat ) {
   Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
-  APFloat::opStatus St = Result.convertFromAPInt(Value, Value.isSigned(),
-   APFloat::rmNearestTiesToEven);
-  if (!Info.InConstantContext && St != llvm::APFloatBase::opOK &&
-  FPO.isFPConstrained()) {
-Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
-return false;
-  }
-  return true;
+  llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
+  APFloat::opStatus St = Result.convertFromAPInt(Value, Value.isSigned(), RM);
+  return checkFloatingPointResult(Info, E, St);
 }
 
 static bool truncateBitfieldValue(EvalInfo , const Expr *E,

diff  --git a/clang/test/AST/const-fpfeatures.c 
b/clang/test/AST/const-fpfeatures.c
index c29afe680..6600ea27405d9 100644
--- a/clang/test/AST/const-fpfeatures.c
+++ b/clang/test/AST/const-fpfeatures.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fexperimental-strict-floating-point -S -emit-llvm -triple 
i386-linux -Wno-unknown-pragmas %s -o - | FileCheck %s
+// RUN: %clang_cc1 -S -emit-llvm -triple i386-linux -Wno-unknown-pragmas %s -o 
- | FileCheck %s
 
 // nextUp(1.F) == 0x1.02p0F
 
@@ -13,6 +13,9 @@ float F3u = 0x1.01p0;
 // CHECK: @F2u = {{.*}} float 0x3FF02000
 // CHECK: @F3u = {{.*}} float 0x3FF02000
 
+float FI1u = 0xU;
+// CHECK: @FI1u = {{.*}} float 0x41F0
+
 float _Complex C1u = C0;
 // CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 
0x3FF02000 }
 
@@ -27,5 +30,8 @@ float F3d = 0x1.01p0;
 // CHECK: @F2d = {{.*}} float 1.00e+00
 // CHECK: @F3d = {{.*}} float 1.00e+00
 
+float FI1d = 0xU;
+// CHECK: @FI1d = {{.*}} float 0x41EFE000
+
 float _Complex C1d = C0;
 // CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 
1.00e+00 }



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


[clang] 1f67dc8 - [Driver] Enable nested configuration files

2022-11-15 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-11-16T13:32:27+07:00
New Revision: 1f67dc8b7c225290d1b3eb93d90e2c9861aeefc0

URL: 
https://github.com/llvm/llvm-project/commit/1f67dc8b7c225290d1b3eb93d90e2c9861aeefc0
DIFF: 
https://github.com/llvm/llvm-project/commit/1f67dc8b7c225290d1b3eb93d90e2c9861aeefc0.diff

LOG: [Driver] Enable nested configuration files

Users may partition parameters specified by configuration file and put
different groups into separate files. These files are inserted into the
main file using constructs `@file`. Relative file names in it are
resolved relative to the including configuration file and this is not
convenient in some cases. A configuration file, which resides in system
directory, may need to include a file with user-defined parameters and
still provide default definitions if such file is absent.

To solve such problems, the option `--config=` is allowed inside
configuration files. Like `@file` it results in insertion of
command-line arguments but the algorithm of file search is different and
allows overriding system definitions with user ones.

Differential Revision: https://reviews.llvm.org/D136354

Added: 


Modified: 
clang/docs/UsersManual.rst
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/lib/Driver/Driver.cpp
clang/test/Driver/Inputs/config-6.cfg
clang/test/Driver/config-file-errs.c
clang/test/Driver/config-file.c
clang/unittests/Driver/ToolChainTest.cpp
llvm/lib/Support/CommandLine.cpp

Removed: 




diff  --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 9b03db9e0f742..69dcd495d689c 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -985,7 +985,10 @@ configuration file:
 Files included by ``@file`` directives in configuration files are resolved
 relative to the including file. For example, if a configuration file
 ``~/.llvm/target.cfg`` contains the directive ``@os/linux.opts``, the file
-``linux.opts`` is searched for in the directory ``~/.llvm/os``.
+``linux.opts`` is searched for in the directory ``~/.llvm/os``. Another way to
+include a file content is using the command line option ``--config=``. It works
+similarly but the included file is searched for using the rules for 
configuration
+files.
 
 To generate paths relative to the configuration file, the  token 
may
 be used. This will expand to the absolute path of the directory containing the

diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 551ebf1c9bc2e..119ad57466b65 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -225,8 +225,6 @@ def note_drv_config_file_searched_in : Note<
   "was searched for in the directory: %0">;
 def err_drv_cannot_read_config_file : Error<
   "cannot read configuration file '%0': %1">;
-def err_drv_nested_config_file: Error<
-  "option '--config' is not allowed inside configuration file">;
 def err_drv_arg_requires_bitcode_input: Error<
   "option '%0' requires input to be LLVM bitcode">;
 

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index fd9d5c21e67c9..c63160e55ea30 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -970,11 +970,6 @@ bool Driver::readConfigFile(StringRef FileName,
   if (ContainErrors)
 return true;
 
-  if (NewOptions->hasArg(options::OPT_config)) {
-Diag(diag::err_drv_nested_config_file);
-return true;
-  }
-
   // Claim all arguments that come from a configuration file so that the driver
   // does not warn on any that is unused.
   for (Arg *A : *NewOptions)

diff  --git a/clang/test/Driver/Inputs/config-6.cfg 
b/clang/test/Driver/Inputs/config-6.cfg
index 24d93cf8eca61..e54ec0c629709 100644
--- a/clang/test/Driver/Inputs/config-6.cfg
+++ b/clang/test/Driver/Inputs/config-6.cfg
@@ -1 +1 @@
---config config-5
+--config=config-4.cfg

diff  --git a/clang/test/Driver/config-file-errs.c 
b/clang/test/Driver/config-file-errs.c
index 85b3443a7e530..96b49b2acf8ab 100644
--- a/clang/test/Driver/config-file-errs.c
+++ b/clang/test/Driver/config-file-errs.c
@@ -4,12 +4,6 @@
 // CHECK-MISSING-FILE: argument to '--config' is missing (expected 1 value)
 
 
-//--- '--config' must not be found in config files.
-//
-// RUN: not %clang --config %S/Inputs/config-6.cfg 2>&1 | FileCheck %s 
-check-prefix CHECK-NESTED
-// CHECK-NESTED: option '--config' is not allowed inside configuration file
-
-
 //--- Argument of '--config' must be existing file, if it is specified by path.
 //
 // RUN: not %clang --config somewhere/nonexistent-config-file 2>&1 | FileCheck 
%s -check-prefix CHECK-NONEXISTENT

diff  --git a/clang/test/Driver/config-file.c b/clang/test/Driver/config-file.c
index 9c8d5be575f3c..9df830ca4c753 100644
--- a/clang/test/Driver/config-file.c
+++ b/clang/test/Driver/config-file.c
@@ -44,9 

[clang] c14df22 - [Driver] Do not run test on AIX

2022-11-04 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-11-04T18:32:26+07:00
New Revision: c14df228ff3ca73e3c5c00c495216bba56665fd5

URL: 
https://github.com/llvm/llvm-project/commit/c14df228ff3ca73e3c5c00c495216bba56665fd5
DIFF: 
https://github.com/llvm/llvm-project/commit/c14df228ff3ca73e3c5c00c495216bba56665fd5.diff

LOG: [Driver] Do not run test on AIX

Differential Revision: https://reviews.llvm.org/D136090

Added: 


Modified: 
clang/test/Driver/response-file-errs.c

Removed: 




diff  --git a/clang/test/Driver/response-file-errs.c 
b/clang/test/Driver/response-file-errs.c
index c0e02a984b9af..64eb3208a836c 100644
--- a/clang/test/Driver/response-file-errs.c
+++ b/clang/test/Driver/response-file-errs.c
@@ -1,3 +1,6 @@
+// AIX reacts on opening directory 
diff erently than other systems.
+// UNSUPPORTED: aix
+
 // If response file does not exist, '@file; directive remains unexpanded in
 // command line.
 //



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


[clang] fdab9f1 - [Clang] Check for response file existence prior to check for recursion

2022-11-03 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-11-03T14:49:58+07:00
New Revision: fdab9f1203eea48a7b8e4c55c7ceafc54653797c

URL: 
https://github.com/llvm/llvm-project/commit/fdab9f1203eea48a7b8e4c55c7ceafc54653797c
DIFF: 
https://github.com/llvm/llvm-project/commit/fdab9f1203eea48a7b8e4c55c7ceafc54653797c.diff

LOG: [Clang] Check for response file existence prior to check for recursion

As now errors in file operation are handled, check for file existence
must be done prior to check for recursion, otherwise reported errors are
misleading.

Differential Revision: https://reviews.llvm.org/D136090

Added: 
clang/test/Driver/Inputs/inc-inexistent.rsp
clang/test/Driver/response-file-errs.c

Modified: 
clang/tools/driver/driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
llvm/lib/Support/CommandLine.cpp

Removed: 




diff  --git a/clang/test/Driver/Inputs/inc-inexistent.rsp 
b/clang/test/Driver/Inputs/inc-inexistent.rsp
new file mode 100644
index 0..c9ecfdf88ddd0
--- /dev/null
+++ b/clang/test/Driver/Inputs/inc-inexistent.rsp
@@ -0,0 +1 @@
+@inexistent.txt

diff  --git a/clang/test/Driver/response-file-errs.c 
b/clang/test/Driver/response-file-errs.c
new file mode 100644
index 0..c0e02a984b9af
--- /dev/null
+++ b/clang/test/Driver/response-file-errs.c
@@ -0,0 +1,15 @@
+// If response file does not exist, '@file; directive remains unexpanded in
+// command line.
+//
+// RUN: %clang @%S/Inputs/inexistent.rsp -### 2>&1 | FileCheck 
--check-prefix=INEXISTENT %s
+// INEXISTENT: @{{.*}}Inputs/inexistent.rsp
+
+// As the above case but '@file' is in response file.
+//
+// RUN: %clang @%S/Inputs/inc-inexistent.rsp -### 2>&1 | FileCheck 
--check-prefix=INEXISTENT2 %s
+// INEXISTENT2: @{{.*}}inexistent.txt
+
+// If file in `@file` is a directory, it is an error.
+//
+// RUN: not %clang @%S/Inputs -### 2>&1 | FileCheck --check-prefix=DIRECTORY %s
+// DIRECTORY: cannot not open file '{{.*}}Inputs': {{[Ii]}}s a directory

diff  --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 2cc3b48609cb3..4b1a246d99430 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -378,7 +378,7 @@ int clang_main(int Argc, char **Argv) {
   llvm::cl::ExpansionContext ECtx(A, Tokenizer);
   ECtx.setMarkEOLs(MarkEOLs);
   if (llvm::Error Err = ECtx.expandResponseFiles(Args)) {
-llvm::errs() << Err << '\n';
+llvm::errs() << toString(std::move(Err)) << '\n';
 return 1;
   }
 

diff  --git a/clang/unittests/Driver/ToolChainTest.cpp 
b/clang/unittests/Driver/ToolChainTest.cpp
index b143cd6329455..b45bab06d64b8 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -596,9 +596,10 @@ TEST(ToolChainTest, ConfigInexistentInclude) {
 ASSERT_TRUE(C);
 ASSERT_TRUE(C->containsError());
 EXPECT_EQ(1U, DiagConsumer->Errors.size());
-EXPECT_STREQ("cannot read configuration file '" USERCONFIG
- "': cannot not open file '" UNEXISTENT "'",
- DiagConsumer->Errors[0].c_str());
+EXPECT_STRCASEEQ("cannot read configuration file '" USERCONFIG
+ "': cannot not open file '" UNEXISTENT
+ "': no such file or directory",
+ DiagConsumer->Errors[0].c_str());
   }
 
 #undef USERCONFIG

diff  --git a/llvm/lib/Support/CommandLine.cpp 
b/llvm/lib/Support/CommandLine.cpp
index 136b813b1f6c8..fbaacbbbcf8a0 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -1158,9 +1158,11 @@ Error ExpansionContext::expandResponseFile(
   assert(sys::path::is_absolute(FName));
   llvm::ErrorOr> MemBufOrErr =
   FS->getBufferForFile(FName);
-  if (!MemBufOrErr)
-return llvm::createStringError(
-MemBufOrErr.getError(), Twine("cannot not open file '") + FName + "'");
+  if (!MemBufOrErr) {
+std::error_code EC = MemBufOrErr.getError();
+return llvm::createStringError(EC, Twine("cannot not open file '") + FName 
+
+   "': " + EC.message());
+  }
   MemoryBuffer  = *MemBufOrErr.get();
   StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize());
 
@@ -1262,7 +1264,7 @@ Error ExpansionContext::expandResponseFiles(
 if (auto CWD = FS->getCurrentWorkingDirectory()) {
   CurrDir = *CWD;
 } else {
-  return make_error(
+  return createStringError(
   CWD.getError(), Twine("cannot get absolute path for: ") + FName);
 }
   } else {
@@ -1271,49 +1273,48 @@ Error ExpansionContext::expandResponseFiles(
   llvm::sys::path::append(CurrDir, FName);
   FName = CurrDir.c_str();
 }
+
+ErrorOr Res = FS->status(FName);
+if (!Res || !Res->exists()) {
+  std::error_code EC = Res.getError();
+  if (!InConfigFile) {
+// If the specified file does not exist, leave '@file' unexpanded, as
+

[clang] fd3d7a9 - Handle errors in expansion of response files

2022-10-31 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-10-31T15:36:41+07:00
New Revision: fd3d7a9f8cbb5ad81fb96d92d5f7b1d51a4d4127

URL: 
https://github.com/llvm/llvm-project/commit/fd3d7a9f8cbb5ad81fb96d92d5f7b1d51a4d4127
DIFF: 
https://github.com/llvm/llvm-project/commit/fd3d7a9f8cbb5ad81fb96d92d5f7b1d51a4d4127.diff

LOG: Handle errors in expansion of response files

Previously an error raised during an expansion of response files (including
configuration files) was ignored and only the fact of its presence was
reported to the user with generic error messages. This made it difficult to
analyze problems. For example, if a configuration file tried to read an
inexistent file, the error message said that 'configuration file cannot
be found', which is wrong and misleading.

This change enhances handling errors in the expansion so that users
could get more informative error messages.

Differential Revision: https://reviews.llvm.org/D136090

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/lib/Driver/Driver.cpp
clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
clang/test/Driver/config-file-errs.c
clang/tools/driver/driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
flang/tools/flang-driver/driver.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index b09e124206213..e477d93ba067f 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -214,14 +214,14 @@ def err_drv_malformed_sanitizer_coverage_ignorelist : 
Error<
   "malformed sanitizer coverage ignorelist: '%0'">;
 def err_drv_duplicate_config : Error<
   "no more than one option '--config' is allowed">;
-def err_drv_config_file_not_exist : Error<
-  "configuration file '%0' does not exist">;
+def err_drv_cannot_open_config_file : Error<
+  "configuration file '%0' cannot be opened: %1">;
 def err_drv_config_file_not_found : Error<
   "configuration file '%0' cannot be found">;
 def note_drv_config_file_searched_in : Note<
   "was searched for in the directory: %0">;
 def err_drv_cannot_read_config_file : Error<
-  "cannot read configuration file '%0'">;
+  "cannot read configuration file '%0': %1">;
 def err_drv_nested_config_file: Error<
   "option '--config' is not allowed inside configuration file">;
 def err_drv_arg_requires_bitcode_input: Error<

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 26729f1d03ea8..80e6ec76d16f7 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -940,10 +940,24 @@ static void appendOneArg(InputArgList , const Arg 
*Opt,
 
 bool Driver::readConfigFile(StringRef FileName,
 llvm::cl::ExpansionContext ) {
+  // Try opening the given file.
+  auto Status = getVFS().status(FileName);
+  if (!Status) {
+Diag(diag::err_drv_cannot_open_config_file)
+<< FileName << Status.getError().message();
+return true;
+  }
+  if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
+Diag(diag::err_drv_cannot_open_config_file)
+<< FileName << "not a regular file";
+return true;
+  }
+
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
-Diag(diag::err_drv_cannot_read_config_file) << FileName;
+  if (llvm::Error Err = ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
+Diag(diag::err_drv_cannot_read_config_file)
+<< FileName << toString(std::move(Err));
 return true;
   }
 
@@ -1025,12 +1039,9 @@ bool Driver::loadConfigFiles() {
   if (llvm::sys::path::has_parent_path(CfgFileName)) {
 CfgFilePath.assign(CfgFileName);
 if (llvm::sys::path::is_relative(CfgFilePath)) {
-  if (getVFS().makeAbsolute(CfgFilePath))
-return true;
-  auto Status = getVFS().status(CfgFilePath);
-  if (!Status ||
-  Status->getType() != llvm::sys::fs::file_type::regular_file) {
-Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
+  if (getVFS().makeAbsolute(CfgFilePath)) {
+Diag(diag::err_drv_cannot_open_config_file)
+<< CfgFilePath << "cannot get absolute path";
 return true;
   }
 }

diff  --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp 
b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
index c4b3abc1a0a45..88d20ba3957d2 100644
--- a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
+++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -61,9 +61,11 @@ class ExpandResponseFilesDatabase : public 
CompilationDatabase {
 continue;
   

[clang] c1728a4 - Revert "Handle errors in expansion of response files"

2022-10-29 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-10-30T02:03:12+07:00
New Revision: c1728a40aae31abc0a5d4d07f6f6a6773d803f2c

URL: 
https://github.com/llvm/llvm-project/commit/c1728a40aae31abc0a5d4d07f6f6a6773d803f2c
DIFF: 
https://github.com/llvm/llvm-project/commit/c1728a40aae31abc0a5d4d07f6f6a6773d803f2c.diff

LOG: Revert "Handle errors in expansion of response files"

This reverts commit 17eb198de934eced784e16ec15e020a574ba07e1.
Reverted for investigation, because ClangDriverTests failed on some builders.

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/lib/Driver/Driver.cpp
clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
clang/test/Driver/config-file-errs.c
clang/tools/driver/driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
flang/tools/flang-driver/driver.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index e477d93ba067f..b09e124206213 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -214,14 +214,14 @@ def err_drv_malformed_sanitizer_coverage_ignorelist : 
Error<
   "malformed sanitizer coverage ignorelist: '%0'">;
 def err_drv_duplicate_config : Error<
   "no more than one option '--config' is allowed">;
-def err_drv_cannot_open_config_file : Error<
-  "configuration file '%0' cannot be opened: %1">;
+def err_drv_config_file_not_exist : Error<
+  "configuration file '%0' does not exist">;
 def err_drv_config_file_not_found : Error<
   "configuration file '%0' cannot be found">;
 def note_drv_config_file_searched_in : Note<
   "was searched for in the directory: %0">;
 def err_drv_cannot_read_config_file : Error<
-  "cannot read configuration file '%0': %1">;
+  "cannot read configuration file '%0'">;
 def err_drv_nested_config_file: Error<
   "option '--config' is not allowed inside configuration file">;
 def err_drv_arg_requires_bitcode_input: Error<

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 80e6ec76d16f7..26729f1d03ea8 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -940,24 +940,10 @@ static void appendOneArg(InputArgList , const Arg 
*Opt,
 
 bool Driver::readConfigFile(StringRef FileName,
 llvm::cl::ExpansionContext ) {
-  // Try opening the given file.
-  auto Status = getVFS().status(FileName);
-  if (!Status) {
-Diag(diag::err_drv_cannot_open_config_file)
-<< FileName << Status.getError().message();
-return true;
-  }
-  if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
-Diag(diag::err_drv_cannot_open_config_file)
-<< FileName << "not a regular file";
-return true;
-  }
-
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (llvm::Error Err = ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
-Diag(diag::err_drv_cannot_read_config_file)
-<< FileName << toString(std::move(Err));
+  if (!ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
+Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }
 
@@ -1039,9 +1025,12 @@ bool Driver::loadConfigFiles() {
   if (llvm::sys::path::has_parent_path(CfgFileName)) {
 CfgFilePath.assign(CfgFileName);
 if (llvm::sys::path::is_relative(CfgFilePath)) {
-  if (getVFS().makeAbsolute(CfgFilePath)) {
-Diag(diag::err_drv_cannot_open_config_file)
-<< CfgFilePath << "cannot get absolute path";
+  if (getVFS().makeAbsolute(CfgFilePath))
+return true;
+  auto Status = getVFS().status(CfgFilePath);
+  if (!Status ||
+  Status->getType() != llvm::sys::fs::file_type::regular_file) {
+Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
 return true;
   }
 }

diff  --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp 
b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
index 88d20ba3957d2..c4b3abc1a0a45 100644
--- a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
+++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -61,11 +61,9 @@ class ExpandResponseFilesDatabase : public 
CompilationDatabase {
 continue;
   llvm::BumpPtrAllocator Alloc;
   llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
-  llvm::Error Err = ECtx.setVFS(FS.get())
-.setCurrentDir(Cmd.Directory)
-.expandResponseFiles(Argv);
-  if (Err)
-llvm::errs() << Err;
+  ECtx.setVFS(FS.get())
+  .setCurrentDir(Cmd.Directory)
+  .expandResponseFiles(Argv);
   // Don't assign directly, 

[clang] 17eb198 - Handle errors in expansion of response files

2022-10-29 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-10-29T22:01:47+07:00
New Revision: 17eb198de934eced784e16ec15e020a574ba07e1

URL: 
https://github.com/llvm/llvm-project/commit/17eb198de934eced784e16ec15e020a574ba07e1
DIFF: 
https://github.com/llvm/llvm-project/commit/17eb198de934eced784e16ec15e020a574ba07e1.diff

LOG: Handle errors in expansion of response files

Previously an error raised during an expansion of response files (including
configuration files) was ignored and only the fact of its presence was
reported to the user with generic error messages. This made it difficult to
analyze problems. For example, if a configuration file tried to read an
inexistent file, the error message said that 'configuration file cannot
be found', which is wrong and misleading.

This change enhances handling errors in the expansion so that users
could get more informative error messages.

Differential Revision: https://reviews.llvm.org/D136090

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/lib/Driver/Driver.cpp
clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
clang/test/Driver/config-file-errs.c
clang/tools/driver/driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
flang/tools/flang-driver/driver.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index b09e124206213..e477d93ba067f 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -214,14 +214,14 @@ def err_drv_malformed_sanitizer_coverage_ignorelist : 
Error<
   "malformed sanitizer coverage ignorelist: '%0'">;
 def err_drv_duplicate_config : Error<
   "no more than one option '--config' is allowed">;
-def err_drv_config_file_not_exist : Error<
-  "configuration file '%0' does not exist">;
+def err_drv_cannot_open_config_file : Error<
+  "configuration file '%0' cannot be opened: %1">;
 def err_drv_config_file_not_found : Error<
   "configuration file '%0' cannot be found">;
 def note_drv_config_file_searched_in : Note<
   "was searched for in the directory: %0">;
 def err_drv_cannot_read_config_file : Error<
-  "cannot read configuration file '%0'">;
+  "cannot read configuration file '%0': %1">;
 def err_drv_nested_config_file: Error<
   "option '--config' is not allowed inside configuration file">;
 def err_drv_arg_requires_bitcode_input: Error<

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 26729f1d03ea8..80e6ec76d16f7 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -940,10 +940,24 @@ static void appendOneArg(InputArgList , const Arg 
*Opt,
 
 bool Driver::readConfigFile(StringRef FileName,
 llvm::cl::ExpansionContext ) {
+  // Try opening the given file.
+  auto Status = getVFS().status(FileName);
+  if (!Status) {
+Diag(diag::err_drv_cannot_open_config_file)
+<< FileName << Status.getError().message();
+return true;
+  }
+  if (Status->getType() != llvm::sys::fs::file_type::regular_file) {
+Diag(diag::err_drv_cannot_open_config_file)
+<< FileName << "not a regular file";
+return true;
+  }
+
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
-Diag(diag::err_drv_cannot_read_config_file) << FileName;
+  if (llvm::Error Err = ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
+Diag(diag::err_drv_cannot_read_config_file)
+<< FileName << toString(std::move(Err));
 return true;
   }
 
@@ -1025,12 +1039,9 @@ bool Driver::loadConfigFiles() {
   if (llvm::sys::path::has_parent_path(CfgFileName)) {
 CfgFilePath.assign(CfgFileName);
 if (llvm::sys::path::is_relative(CfgFilePath)) {
-  if (getVFS().makeAbsolute(CfgFilePath))
-return true;
-  auto Status = getVFS().status(CfgFilePath);
-  if (!Status ||
-  Status->getType() != llvm::sys::fs::file_type::regular_file) {
-Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
+  if (getVFS().makeAbsolute(CfgFilePath)) {
+Diag(diag::err_drv_cannot_open_config_file)
+<< CfgFilePath << "cannot get absolute path";
 return true;
   }
 }

diff  --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp 
b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
index c4b3abc1a0a45..88d20ba3957d2 100644
--- a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
+++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -61,9 +61,11 @@ class ExpandResponseFilesDatabase : public 
CompilationDatabase {
 continue;
   

[clang] 0dec5e1 - Keep configuration file search directories in ExpansionContext. NFC

2022-10-19 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-10-19T17:20:14+07:00
New Revision: 0dec5e164f9d289b6e576655c7cf21a3dd0389f8

URL: 
https://github.com/llvm/llvm-project/commit/0dec5e164f9d289b6e576655c7cf21a3dd0389f8
DIFF: 
https://github.com/llvm/llvm-project/commit/0dec5e164f9d289b6e576655c7cf21a3dd0389f8.diff

LOG: Keep configuration file search directories in ExpansionContext. NFC

Class ExpansionContext encapsulates options for search and expansion of
response files, including configuration files. With this change the
directories which are searched for configuration files are also stored
in ExpansionContext.

Differential Revision: https://reviews.llvm.org/D135439

Added: 


Modified: 
clang/include/clang/Driver/Driver.h
clang/lib/Driver/Driver.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp

Removed: 




diff  --git a/clang/include/clang/Driver/Driver.h 
b/clang/include/clang/Driver/Driver.h
index fe2b4bd629fae..6eb168e56510d 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -36,6 +36,9 @@ class Triple;
 namespace vfs {
 class FileSystem;
 }
+namespace cl {
+class ExpansionContext;
+}
 } // namespace llvm
 
 namespace clang {
@@ -677,13 +680,14 @@ class Driver {
   /// executable filename).
   ///
   /// \returns true if error occurred.
-  bool loadDefaultConfigFiles(ArrayRef CfgFileSearchDirs);
+  bool loadDefaultConfigFiles(llvm::cl::ExpansionContext );
 
   /// Read options from the specified file.
   ///
   /// \param [in] FileName File to read.
+  /// \param [in] Search and expansion options.
   /// \returns true, if error occurred while reading.
-  bool readConfigFile(StringRef FileName);
+  bool readConfigFile(StringRef FileName, llvm::cl::ExpansionContext );
 
   /// Set the driver mode (cl, gcc, etc) from the value of the `--driver-mode`
   /// option.

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 45530f5d68e6c..26729f1d03ea8 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -922,35 +922,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation 
,
   //
 }
 
-/// Looks the given directories for the specified file.
-///
-/// \param[out] FilePath File path, if the file was found.
-/// \param[in]  Dirs Directories used for the search.
-/// \param[in]  FileName Name of the file to search for.
-/// \return True if file was found.
-///
-/// Looks for file specified by FileName sequentially in directories specified
-/// by Dirs.
-///
-static bool searchForFile(SmallVectorImpl ,
-  ArrayRef Dirs, StringRef FileName,
-  llvm::vfs::FileSystem ) {
-  SmallString<128> WPath;
-  for (const StringRef  : Dirs) {
-if (Dir.empty())
-  continue;
-WPath.clear();
-llvm::sys::path::append(WPath, Dir, FileName);
-llvm::sys::path::native(WPath);
-auto Status = FS.status(WPath);
-if (Status && Status->getType() == llvm::sys::fs::file_type::regular_file) 
{
-  FilePath = std::move(WPath);
-  return true;
-}
-  }
-  return false;
-}
-
 static void appendOneArg(InputArgList , const Arg *Opt,
  const Arg *BaseArg) {
   // The args for config files or /clang: flags belong to 
diff erent InputArgList
@@ -967,11 +938,10 @@ static void appendOneArg(InputArgList , const Arg 
*Opt,
   Args.append(Copy);
 }
 
-bool Driver::readConfigFile(StringRef FileName) {
+bool Driver::readConfigFile(StringRef FileName,
+llvm::cl::ExpansionContext ) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  llvm::cl::ExpansionContext ExpCtx(Alloc, llvm::cl::tokenizeConfigFile);
-  ExpCtx.setVFS(());
   if (!ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
@@ -1012,6 +982,10 @@ bool Driver::readConfigFile(StringRef FileName) {
 }
 
 bool Driver::loadConfigFiles() {
+  llvm::cl::ExpansionContext ExpCtx(Saver.getAllocator(),
+llvm::cl::tokenizeConfigFile);
+  ExpCtx.setVFS(());
+
   // Process options that change search path for config files.
   if (CLOptions) {
 if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
@@ -1036,19 +1010,20 @@ bool Driver::loadConfigFiles() {
 
   // Prepare list of directories where config file is searched for.
   StringRef CfgFileSearchDirs[] = {UserConfigDir, SystemConfigDir, Dir};
+  ExpCtx.setSearchDirs(CfgFileSearchDirs);
 
   // First try to load configuration from the default files, return on error.
-  if (loadDefaultConfigFiles(CfgFileSearchDirs))
+  if (loadDefaultConfigFiles(ExpCtx))
 return true;
 
   // Then load configuration files specified explicitly.
-  llvm::SmallString<128> CfgFilePath;
+  SmallString<128> CfgFilePath;
   if (CLOptions) {
 for (auto CfgFileName : 

[clang] b934be2 - [Support] Class for response file expansion (NFC)

2022-09-29 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-09-29T19:15:01+07:00
New Revision: b934be2c059a99351d08069bb80155e49f047b6e

URL: 
https://github.com/llvm/llvm-project/commit/b934be2c059a99351d08069bb80155e49f047b6e
DIFF: 
https://github.com/llvm/llvm-project/commit/b934be2c059a99351d08069bb80155e49f047b6e.diff

LOG: [Support] Class for response file expansion (NFC)

Functions that implement expansion of response and config files depend
on many options, which are passes as arguments. Extending the expansion
requires new options, it in turn causes changing calls in various places
making them even more bulky.

This change introduces a class ExpansionContext, which represents set of
options that control the expansion. Its methods implements expansion of
responce files including config files. It makes extending the expansion
easier.

No functional changes.

Differential Revision: https://reviews.llvm.org/D132379

Added: 


Modified: 
clang/lib/Driver/Driver.cpp
clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
clang/tools/driver/driver.cpp
flang/tools/flang-driver/driver.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/include/llvm/Support/StringSaver.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp

Removed: 




diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index a40a992ac0877..f2ae25df5825e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -956,7 +956,9 @@ static void appendOneArg(InputArgList , const Arg *Opt,
 bool Driver::readConfigFile(StringRef FileName) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
+  llvm::cl::ExpansionContext ExpCtx(Alloc, llvm::cl::tokenizeConfigFile);
+  ExpCtx.setVFS(());
+  if (!ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }

diff  --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp 
b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
index 75d0d50d851f9..c4b3abc1a0a45 100644
--- a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
+++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -60,9 +60,10 @@ class ExpandResponseFilesDatabase : public 
CompilationDatabase {
   if (!SeenRSPFile)
 continue;
   llvm::BumpPtrAllocator Alloc;
-  llvm::StringSaver Saver(Alloc);
-  llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, 
false,
-llvm::StringRef(Cmd.Directory), *FS);
+  llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
+  ECtx.setVFS(FS.get())
+  .setCurrentDir(Cmd.Directory)
+  .expandResponseFiles(Argv);
   // Don't assign directly, Argv aliases CommandLine.
   std::vector ExpandedArgv(Argv.begin(), Argv.end());
   Cmd.CommandLine = std::move(ExpandedArgv);

diff  --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 34335a599a008..11eba44fcf22e 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -308,9 +308,8 @@ static int ExecuteCC1Tool(SmallVectorImpl 
) {
   llvm::cl::ResetAllOptionOccurrences();
 
   llvm::BumpPtrAllocator A;
-  llvm::StringSaver Saver(A);
-  llvm::cl::ExpandResponseFiles(Saver, ::cl::TokenizeGNUCommandLine, ArgV,
-/*MarkEOLs=*/false);
+  llvm::cl::ExpansionContext ECtx(A, llvm::cl::TokenizeGNUCommandLine);
+  ECtx.expandResponseFiles(ArgV);
   StringRef Tool = ArgV[1];
   void *GetExecutablePathVP = (void *)(intptr_t)GetExecutablePath;
   if (Tool == "-cc1")
@@ -373,7 +372,8 @@ int clang_main(int Argc, char **Argv) {
 
   if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).startswith("-cc1"))
 MarkEOLs = false;
-  llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Args, MarkEOLs);
+  llvm::cl::ExpansionContext ECtx(A, Tokenizer);
+  ECtx.setMarkEOLs(MarkEOLs).expandResponseFiles(Args);
 
   // Handle -cc1 integrated tools, even if -cc1 was expanded from a response
   // file.

diff  --git a/flang/tools/flang-driver/driver.cpp 
b/flang/tools/flang-driver/driver.cpp
index 1fee09d1df853..3ab6fc6205011 100644
--- a/flang/tools/flang-driver/driver.cpp
+++ b/flang/tools/flang-driver/driver.cpp
@@ -76,7 +76,8 @@ static void ExpandResponseFiles(
 llvm::StringSaver , llvm::SmallVectorImpl ) {
   // We're defaulting to the GNU syntax, since we don't have a CL mode.
   llvm::cl::TokenizerCallback tokenizer = ::cl::TokenizeGNUCommandLine;
-  llvm::cl::ExpandResponseFiles(saver, tokenizer, args, /* MarkEOLs=*/false);
+  llvm::cl::ExpansionContext ExpCtx(saver.getAllocator(), tokenizer);
+  ExpCtx.expandResponseFiles(args);
 }
 
 int main(int argc, const char **argv) {

diff  --git a/llvm/include/llvm/Support/CommandLine.h 

[clang] 5ddde5f - Revert "[Support] Class for response file expansion (NFC)"

2022-09-28 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-09-28T13:33:28+07:00
New Revision: 5ddde5f80ab69cc69f64f6fd0114fc7992a29c61

URL: 
https://github.com/llvm/llvm-project/commit/5ddde5f80ab69cc69f64f6fd0114fc7992a29c61
DIFF: 
https://github.com/llvm/llvm-project/commit/5ddde5f80ab69cc69f64f6fd0114fc7992a29c61.diff

LOG: Revert "[Support] Class for response file expansion (NFC)"

This reverts commit 6e491c48d6b9cadcc5b77f730dd83a1448197329.
There are missed changes in flang.

Added: 


Modified: 
clang/lib/Driver/Driver.cpp
clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
clang/tools/driver/driver.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/include/llvm/Support/StringSaver.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp

Removed: 




diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index f2ae25df5825..a40a992ac087 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -956,9 +956,7 @@ static void appendOneArg(InputArgList , const Arg *Opt,
 bool Driver::readConfigFile(StringRef FileName) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  llvm::cl::ExpansionContext ExpCtx(Alloc, llvm::cl::tokenizeConfigFile);
-  ExpCtx.setVFS(());
-  if (!ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
+  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }

diff  --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp 
b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
index c4b3abc1a0a4..75d0d50d851f 100644
--- a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
+++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -60,10 +60,9 @@ class ExpandResponseFilesDatabase : public 
CompilationDatabase {
   if (!SeenRSPFile)
 continue;
   llvm::BumpPtrAllocator Alloc;
-  llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
-  ECtx.setVFS(FS.get())
-  .setCurrentDir(Cmd.Directory)
-  .expandResponseFiles(Argv);
+  llvm::StringSaver Saver(Alloc);
+  llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, 
false,
+llvm::StringRef(Cmd.Directory), *FS);
   // Don't assign directly, Argv aliases CommandLine.
   std::vector ExpandedArgv(Argv.begin(), Argv.end());
   Cmd.CommandLine = std::move(ExpandedArgv);

diff  --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 11eba44fcf22..34335a599a00 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -308,8 +308,9 @@ static int ExecuteCC1Tool(SmallVectorImpl 
) {
   llvm::cl::ResetAllOptionOccurrences();
 
   llvm::BumpPtrAllocator A;
-  llvm::cl::ExpansionContext ECtx(A, llvm::cl::TokenizeGNUCommandLine);
-  ECtx.expandResponseFiles(ArgV);
+  llvm::StringSaver Saver(A);
+  llvm::cl::ExpandResponseFiles(Saver, ::cl::TokenizeGNUCommandLine, ArgV,
+/*MarkEOLs=*/false);
   StringRef Tool = ArgV[1];
   void *GetExecutablePathVP = (void *)(intptr_t)GetExecutablePath;
   if (Tool == "-cc1")
@@ -372,8 +373,7 @@ int clang_main(int Argc, char **Argv) {
 
   if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).startswith("-cc1"))
 MarkEOLs = false;
-  llvm::cl::ExpansionContext ECtx(A, Tokenizer);
-  ECtx.setMarkEOLs(MarkEOLs).expandResponseFiles(Args);
+  llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Args, MarkEOLs);
 
   // Handle -cc1 integrated tools, even if -cc1 was expanded from a response
   // file.

diff  --git a/llvm/include/llvm/Support/CommandLine.h 
b/llvm/include/llvm/Support/CommandLine.h
index 15deb8a0b027..58ded2ceee9d 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -31,7 +31,6 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/StringSaver.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 #include 
@@ -2066,88 +2065,56 @@ void tokenizeConfigFile(StringRef Source, StringSaver 
,
 SmallVectorImpl ,
 bool MarkEOLs = false);
 
-/// Contains options that control response file expansion.
-class ExpansionContext {
-  /// Provides persistent storage for parsed strings.
-  StringSaver Saver;
-
-  /// Tokenization strategy. Typically Unix or Windows.
-  TokenizerCallback Tokenizer;
-
-  /// File system used for all file access when running the expansion.
-  vfs::FileSystem *FS;
-
-  /// Path used to resolve relative rsp files. If empty, the file system
-  /// current directory is used instead.
-  StringRef CurrentDir;
-
-  /// True if names of nested response files must be resolved relative to
-  /// including file.
-  bool RelativeNames = false;
-

[clang] 6e491c4 - [Support] Class for response file expansion (NFC)

2022-09-27 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-09-28T11:47:59+07:00
New Revision: 6e491c48d6b9cadcc5b77f730dd83a1448197329

URL: 
https://github.com/llvm/llvm-project/commit/6e491c48d6b9cadcc5b77f730dd83a1448197329
DIFF: 
https://github.com/llvm/llvm-project/commit/6e491c48d6b9cadcc5b77f730dd83a1448197329.diff

LOG: [Support] Class for response file expansion (NFC)

Functions that implement expansion of response and config files depend
on many options, which are passes as arguments. Extending the expansion
requires new options, it in turn causes changing calls in various places
making them even more bulky.

This change introduces a class ExpansionContext, which represents set of
options that control the expansion. Its methods implements expansion of
responce files including config files. It makes extending the expansion
easier.

No functional changes.

Differential Revision: https://reviews.llvm.org/D132379

Added: 


Modified: 
clang/lib/Driver/Driver.cpp
clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
clang/tools/driver/driver.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/include/llvm/Support/StringSaver.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp

Removed: 




diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index a40a992ac0877..f2ae25df5825e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -956,7 +956,9 @@ static void appendOneArg(InputArgList , const Arg *Opt,
 bool Driver::readConfigFile(StringRef FileName) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
+  llvm::cl::ExpansionContext ExpCtx(Alloc, llvm::cl::tokenizeConfigFile);
+  ExpCtx.setVFS(());
+  if (!ExpCtx.readConfigFile(FileName, NewCfgArgs)) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }

diff  --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp 
b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
index 75d0d50d851f9..c4b3abc1a0a45 100644
--- a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
+++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -60,9 +60,10 @@ class ExpandResponseFilesDatabase : public 
CompilationDatabase {
   if (!SeenRSPFile)
 continue;
   llvm::BumpPtrAllocator Alloc;
-  llvm::StringSaver Saver(Alloc);
-  llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, 
false,
-llvm::StringRef(Cmd.Directory), *FS);
+  llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
+  ECtx.setVFS(FS.get())
+  .setCurrentDir(Cmd.Directory)
+  .expandResponseFiles(Argv);
   // Don't assign directly, Argv aliases CommandLine.
   std::vector ExpandedArgv(Argv.begin(), Argv.end());
   Cmd.CommandLine = std::move(ExpandedArgv);

diff  --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 34335a599a008..11eba44fcf22e 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -308,9 +308,8 @@ static int ExecuteCC1Tool(SmallVectorImpl 
) {
   llvm::cl::ResetAllOptionOccurrences();
 
   llvm::BumpPtrAllocator A;
-  llvm::StringSaver Saver(A);
-  llvm::cl::ExpandResponseFiles(Saver, ::cl::TokenizeGNUCommandLine, ArgV,
-/*MarkEOLs=*/false);
+  llvm::cl::ExpansionContext ECtx(A, llvm::cl::TokenizeGNUCommandLine);
+  ECtx.expandResponseFiles(ArgV);
   StringRef Tool = ArgV[1];
   void *GetExecutablePathVP = (void *)(intptr_t)GetExecutablePath;
   if (Tool == "-cc1")
@@ -373,7 +372,8 @@ int clang_main(int Argc, char **Argv) {
 
   if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).startswith("-cc1"))
 MarkEOLs = false;
-  llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Args, MarkEOLs);
+  llvm::cl::ExpansionContext ECtx(A, Tokenizer);
+  ECtx.setMarkEOLs(MarkEOLs).expandResponseFiles(Args);
 
   // Handle -cc1 integrated tools, even if -cc1 was expanded from a response
   // file.

diff  --git a/llvm/include/llvm/Support/CommandLine.h 
b/llvm/include/llvm/Support/CommandLine.h
index 58ded2ceee9d9..15deb8a0b027a 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -31,6 +31,7 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/StringSaver.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 #include 
@@ -2065,56 +2066,88 @@ void tokenizeConfigFile(StringRef Source, StringSaver 
,
 SmallVectorImpl ,
 bool MarkEOLs = false);
 
-/// Reads command line options from the given configuration file.
-///
-/// \param [in] CfgFileName Path to configuration file.
-/// \param [in] Saver  Objects that saves 

[clang] 7b9fae0 - [Clang] Use virtual FS in processing config files

2022-09-09 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-09-09T18:24:45+07:00
New Revision: 7b9fae05b4d0d3184ffc340e90d06a75e3cba2de

URL: 
https://github.com/llvm/llvm-project/commit/7b9fae05b4d0d3184ffc340e90d06a75e3cba2de
DIFF: 
https://github.com/llvm/llvm-project/commit/7b9fae05b4d0d3184ffc340e90d06a75e3cba2de.diff

LOG: [Clang] Use virtual FS in processing config files

Clang has support of virtual file system for the purpose of testing, but
treatment of config files did not use it. This change enables VFS in it
as well.

Differential Revision: https://reviews.llvm.org/D132867

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Driver/Driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 155eababa81e6..4804856bc8f5c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -93,6 +93,8 @@ Bug Fixes
   `Issue 57516 `_
 - Fix ``__builtin_assume_aligned`` crash when the 1st arg is array type. This 
fixes
   `Issue 57169 `_
+- Clang configuration files are now read through the virtual file system
+  rather than the physical one, if these are 
diff erent.
 
 
 Improvements to Clang's diagnostics

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index ca8e0e5240e1d..217236f459a50 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -911,7 +911,8 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation 
,
 /// by Dirs.
 ///
 static bool searchForFile(SmallVectorImpl ,
-  ArrayRef Dirs, StringRef FileName) {
+  ArrayRef Dirs, StringRef FileName,
+  llvm::vfs::FileSystem ) {
   SmallString<128> WPath;
   for (const StringRef  : Dirs) {
 if (Dir.empty())
@@ -919,7 +920,8 @@ static bool searchForFile(SmallVectorImpl ,
 WPath.clear();
 llvm::sys::path::append(WPath, Dir, FileName);
 llvm::sys::path::native(WPath);
-if (llvm::sys::fs::is_regular_file(WPath)) {
+auto Status = FS.status(WPath);
+if (Status && Status->getType() == llvm::sys::fs::file_type::regular_file) 
{
   FilePath = std::move(WPath);
   return true;
 }
@@ -930,7 +932,7 @@ static bool searchForFile(SmallVectorImpl ,
 bool Driver::readConfigFile(StringRef FileName) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
+  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }
@@ -970,7 +972,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
-  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
 SystemConfigDir.clear();
   else
 SystemConfigDir = static_cast(CfgDir);
@@ -979,7 +981,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
-  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
 UserConfigDir.clear();
   else
 UserConfigDir = static_cast(CfgDir);
@@ -1004,13 +1006,16 @@ bool Driver::loadConfigFile() {
   // If argument contains directory separator, treat it as a path to
   // configuration file.
   if (llvm::sys::path::has_parent_path(CfgFileName)) {
-SmallString<128> CfgFilePath;
-if (llvm::sys::path::is_relative(CfgFileName))
-  llvm::sys::fs::current_path(CfgFilePath);
-llvm::sys::path::append(CfgFilePath, CfgFileName);
-if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
-  Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
-  return true;
+SmallString<128> CfgFilePath(CfgFileName);
+if (llvm::sys::path::is_relative(CfgFilePath)) {
+  if (getVFS().makeAbsolute(CfgFilePath))
+return true;
+  auto Status = getVFS().status(CfgFilePath);
+  if (!Status ||
+  Status->getType() != llvm::sys::fs::file_type::regular_file) {
+Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
+return true;
+  }
 }
 return readConfigFile(CfgFilePath);
   }
@@ -1069,17 +1074,19 @@ bool Driver::loadConfigFile() {
   // Try to find config file. First try file with corrected architecture.
   llvm::SmallString<128> 

[clang] 55e1441 - Revert "[Clang] Use virtual FS in processing config files"

2022-09-09 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-09-09T16:43:15+07:00
New Revision: 55e1441f7b5d01a37fc46eb1711f03ee69845316

URL: 
https://github.com/llvm/llvm-project/commit/55e1441f7b5d01a37fc46eb1711f03ee69845316
DIFF: 
https://github.com/llvm/llvm-project/commit/55e1441f7b5d01a37fc46eb1711f03ee69845316.diff

LOG: Revert "[Clang] Use virtual FS in processing config files"

This reverts commit 9424497e43aff088e014d65fd952ec557e28e6cf.
Some buildbots failed, reverted for investigation.

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Driver/Driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4804856bc8f5c..155eababa81e6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -93,8 +93,6 @@ Bug Fixes
   `Issue 57516 `_
 - Fix ``__builtin_assume_aligned`` crash when the 1st arg is array type. This 
fixes
   `Issue 57169 `_
-- Clang configuration files are now read through the virtual file system
-  rather than the physical one, if these are 
diff erent.
 
 
 Improvements to Clang's diagnostics

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 217236f459a50..ca8e0e5240e1d 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -911,8 +911,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation 
,
 /// by Dirs.
 ///
 static bool searchForFile(SmallVectorImpl ,
-  ArrayRef Dirs, StringRef FileName,
-  llvm::vfs::FileSystem ) {
+  ArrayRef Dirs, StringRef FileName) {
   SmallString<128> WPath;
   for (const StringRef  : Dirs) {
 if (Dir.empty())
@@ -920,8 +919,7 @@ static bool searchForFile(SmallVectorImpl ,
 WPath.clear();
 llvm::sys::path::append(WPath, Dir, FileName);
 llvm::sys::path::native(WPath);
-auto Status = FS.status(WPath);
-if (Status && Status->getType() == llvm::sys::fs::file_type::regular_file) 
{
+if (llvm::sys::fs::is_regular_file(WPath)) {
   FilePath = std::move(WPath);
   return true;
 }
@@ -932,7 +930,7 @@ static bool searchForFile(SmallVectorImpl ,
 bool Driver::readConfigFile(StringRef FileName) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
+  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }
@@ -972,7 +970,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
-  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
+  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
 SystemConfigDir.clear();
   else
 SystemConfigDir = static_cast(CfgDir);
@@ -981,7 +979,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
-  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
+  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
 UserConfigDir.clear();
   else
 UserConfigDir = static_cast(CfgDir);
@@ -1006,16 +1004,13 @@ bool Driver::loadConfigFile() {
   // If argument contains directory separator, treat it as a path to
   // configuration file.
   if (llvm::sys::path::has_parent_path(CfgFileName)) {
-SmallString<128> CfgFilePath(CfgFileName);
-if (llvm::sys::path::is_relative(CfgFilePath)) {
-  if (getVFS().makeAbsolute(CfgFilePath))
-return true;
-  auto Status = getVFS().status(CfgFilePath);
-  if (!Status ||
-  Status->getType() != llvm::sys::fs::file_type::regular_file) {
-Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
-return true;
-  }
+SmallString<128> CfgFilePath;
+if (llvm::sys::path::is_relative(CfgFileName))
+  llvm::sys::fs::current_path(CfgFilePath);
+llvm::sys::path::append(CfgFilePath, CfgFileName);
+if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
+  Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
+  return true;
 }
 return readConfigFile(CfgFilePath);
   }
@@ -1074,19 +1069,17 @@ bool Driver::loadConfigFile() {
   // Try to find config file. First try file with corrected architecture.
   llvm::SmallString<128> CfgFilePath;
   if (!FixedConfigFile.empty()) {
-if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile,
-

[clang] 9424497 - [Clang] Use virtual FS in processing config files

2022-09-09 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-09-09T16:28:51+07:00
New Revision: 9424497e43aff088e014d65fd952ec557e28e6cf

URL: 
https://github.com/llvm/llvm-project/commit/9424497e43aff088e014d65fd952ec557e28e6cf
DIFF: 
https://github.com/llvm/llvm-project/commit/9424497e43aff088e014d65fd952ec557e28e6cf.diff

LOG: [Clang] Use virtual FS in processing config files

Clang has support of virtual file system for the purpose of testing, but
treatment of config files did not use it. This change enables VFS in it
as well.

Differential Revision: https://reviews.llvm.org/D132867

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Driver/Driver.cpp
clang/unittests/Driver/ToolChainTest.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 155eababa81e6..4804856bc8f5c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -93,6 +93,8 @@ Bug Fixes
   `Issue 57516 `_
 - Fix ``__builtin_assume_aligned`` crash when the 1st arg is array type. This 
fixes
   `Issue 57169 `_
+- Clang configuration files are now read through the virtual file system
+  rather than the physical one, if these are 
diff erent.
 
 
 Improvements to Clang's diagnostics

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index ca8e0e5240e1d..217236f459a50 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -911,7 +911,8 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation 
,
 /// by Dirs.
 ///
 static bool searchForFile(SmallVectorImpl ,
-  ArrayRef Dirs, StringRef FileName) {
+  ArrayRef Dirs, StringRef FileName,
+  llvm::vfs::FileSystem ) {
   SmallString<128> WPath;
   for (const StringRef  : Dirs) {
 if (Dir.empty())
@@ -919,7 +920,8 @@ static bool searchForFile(SmallVectorImpl ,
 WPath.clear();
 llvm::sys::path::append(WPath, Dir, FileName);
 llvm::sys::path::native(WPath);
-if (llvm::sys::fs::is_regular_file(WPath)) {
+auto Status = FS.status(WPath);
+if (Status && Status->getType() == llvm::sys::fs::file_type::regular_file) 
{
   FilePath = std::move(WPath);
   return true;
 }
@@ -930,7 +932,7 @@ static bool searchForFile(SmallVectorImpl ,
 bool Driver::readConfigFile(StringRef FileName) {
   // Try reading the given file.
   SmallVector NewCfgArgs;
-  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
+  if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs, getVFS())) {
 Diag(diag::err_drv_cannot_read_config_file) << FileName;
 return true;
   }
@@ -970,7 +972,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
-  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
 SystemConfigDir.clear();
   else
 SystemConfigDir = static_cast(CfgDir);
@@ -979,7 +981,7 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
-  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+  if (CfgDir.empty() || getVFS().makeAbsolute(CfgDir))
 UserConfigDir.clear();
   else
 UserConfigDir = static_cast(CfgDir);
@@ -1004,13 +1006,16 @@ bool Driver::loadConfigFile() {
   // If argument contains directory separator, treat it as a path to
   // configuration file.
   if (llvm::sys::path::has_parent_path(CfgFileName)) {
-SmallString<128> CfgFilePath;
-if (llvm::sys::path::is_relative(CfgFileName))
-  llvm::sys::fs::current_path(CfgFilePath);
-llvm::sys::path::append(CfgFilePath, CfgFileName);
-if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
-  Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
-  return true;
+SmallString<128> CfgFilePath(CfgFileName);
+if (llvm::sys::path::is_relative(CfgFilePath)) {
+  if (getVFS().makeAbsolute(CfgFilePath))
+return true;
+  auto Status = getVFS().status(CfgFilePath);
+  if (!Status ||
+  Status->getType() != llvm::sys::fs::file_type::regular_file) {
+Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
+return true;
+  }
 }
 return readConfigFile(CfgFilePath);
   }
@@ -1069,17 +1074,19 @@ bool Driver::loadConfigFile() {
   // Try to find config file. First try file with corrected architecture.
   llvm::SmallString<128> CfgFilePath;
   if (!FixedConfigFile.empty()) {
-   

[clang] 956f8c0 - [Driver] Override default location of config files

2022-08-17 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-08-17T18:52:53+07:00
New Revision: 956f8c0e1028edd65f68c4b386224d4ccb58c5b6

URL: 
https://github.com/llvm/llvm-project/commit/956f8c0e1028edd65f68c4b386224d4ccb58c5b6
DIFF: 
https://github.com/llvm/llvm-project/commit/956f8c0e1028edd65f68c4b386224d4ccb58c5b6.diff

LOG: [Driver] Override default location of config files

If directory for config files was specified in project configuration
using parameters CLANG_CONFIG_FILE_SYSTEM_DIR or CLANG_CONFIG_FILE_USER_DIR,
it was not overriden by command-line option `--config-system-dir=` or
`--config-user-dir=` that specified empty path.

This change corrects the behavior. It fixes the issue
https://github.com/llvm/llvm-project/issues/56836 ([clang] [test]
test/Driver/config-file-errs.c fails if CLANG_CONFIG_FILE_SYSTEM_DIR is
specified).

Added: 


Modified: 
clang/lib/Driver/Driver.cpp

Removed: 




diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 5b43a86d20581..59ddc89269d95 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -970,23 +970,19 @@ bool Driver::loadConfigFile() {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
-  if (!CfgDir.empty()) {
-if (llvm::sys::fs::make_absolute(CfgDir).value() != 0)
-  SystemConfigDir.clear();
-else
-  SystemConfigDir = static_cast(CfgDir);
-  }
+  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+SystemConfigDir.clear();
+  else
+SystemConfigDir = static_cast(CfgDir);
 }
 if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
   SmallString<128> CfgDir;
   CfgDir.append(
   CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
-  if (!CfgDir.empty()) {
-if (llvm::sys::fs::make_absolute(CfgDir).value() != 0)
-  UserConfigDir.clear();
-else
-  UserConfigDir = static_cast(CfgDir);
-  }
+  if (CfgDir.empty() || llvm::sys::fs::make_absolute(CfgDir))
+UserConfigDir.clear();
+  else
+UserConfigDir = static_cast(CfgDir);
 }
   }
 



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


[clang] 2bb7c54 - [Clang] Remove unused parameter. NFC

2022-08-01 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-08-01T14:53:13+07:00
New Revision: 2bb7c54621f31a957302a4deb3d25b752acb07bd

URL: 
https://github.com/llvm/llvm-project/commit/2bb7c54621f31a957302a4deb3d25b752acb07bd
DIFF: 
https://github.com/llvm/llvm-project/commit/2bb7c54621f31a957302a4deb3d25b752acb07bd.diff

LOG: [Clang] Remove unused parameter. NFC

BinaryOperator::getFPFeatures get parameter, which is not used. Similar
methods of other AST nodes do not have any parameter.

Added: 


Modified: 
clang/include/clang/AST/Expr.h
clang/lib/AST/ASTImporter.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/TreeTransform.h

Removed: 




diff  --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 1f3d524691ed6..1fc6dc90b6c7c 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4009,7 +4009,7 @@ class BinaryOperator : public Expr {
   }
 
   // This is used in ASTImporter
-  FPOptionsOverride getFPFeatures(const LangOptions ) const {
+  FPOptionsOverride getFPFeatures() const {
 if (BinaryOperatorBits.HasFPFeatures)
   return getStoredFPFeatures();
 return FPOptionsOverride();

diff  --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 0273e50683716..159010713f434 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -7224,7 +7224,7 @@ ExpectedStmt 
ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
   return BinaryOperator::Create(
   Importer.getToContext(), ToLHS, ToRHS, E->getOpcode(), ToType,
   E->getValueKind(), E->getObjectKind(), ToOperatorLoc,
-  E->getFPFeatures(Importer.getFromContext().getLangOpts()));
+  E->getFPFeatures());
 }
 
 ExpectedStmt ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) 
{
@@ -7335,7 +7335,7 @@ 
ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
   return CompoundAssignOperator::Create(
   Importer.getToContext(), ToLHS, ToRHS, E->getOpcode(), ToType,
   E->getValueKind(), E->getObjectKind(), ToOperatorLoc,
-  E->getFPFeatures(Importer.getFromContext().getLangOpts()),
+  E->getFPFeatures(),
   ToComputationLHSType, ToComputationResultType);
 }
 

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ee3f9c6767fa9..30c1f5c978945 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7381,7 +7381,7 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
   return BinaryOperator::Create(Context, BO->getLHS(), RHS.get(), BO_Comma,
 BO->getType(), BO->getValueKind(),
 BO->getObjectKind(), BO->getOperatorLoc(),
-BO->getFPFeatures(getLangOpts()));
+BO->getFPFeatures());
 }
   }
 

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c52e12d3eb9ba..86d92158da8df 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -11186,7 +11186,7 @@ 
TreeTransform::TransformBinaryOperator(BinaryOperator *E) {
 return getDerived().RebuildBinaryOperator(
 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
   Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
-  FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts()));
+  FPOptionsOverride NewOverrides(E->getFPFeatures());
   getSema().CurFPFeatures =
   NewOverrides.applyOverrides(getSema().getLangOpts());
   getSema().FpPragmaStack.CurrentValue = NewOverrides;
@@ -11253,7 +11253,7 @@ ExprResult
 TreeTransform::TransformCompoundAssignOperator(
   CompoundAssignOperator 
*E) {
   Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
-  FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts()));
+  FPOptionsOverride NewOverrides(E->getFPFeatures());
   getSema().CurFPFeatures =
   NewOverrides.applyOverrides(getSema().getLangOpts());
   getSema().FpPragmaStack.CurrentValue = NewOverrides;



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


[clang] f7819ce - [FPEnv] Allow CompoundStmt to keep FP options

2022-07-03 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-07-03T17:06:26+07:00
New Revision: f7819ce166bcc472108cf7c05f86edcf4ee9e6cf

URL: 
https://github.com/llvm/llvm-project/commit/f7819ce166bcc472108cf7c05f86edcf4ee9e6cf
DIFF: 
https://github.com/llvm/llvm-project/commit/f7819ce166bcc472108cf7c05f86edcf4ee9e6cf.diff

LOG: [FPEnv] Allow CompoundStmt to keep FP options

This is a recommit of b822efc7404bf09ccfdc1ab7657475026966c3b2,
reverted in dc34d8df4c48b3a8f474360970cae8a58e6c84f0. The commit caused
fails because the test ast-print-fp-pragmas.c did not specify particular
target, and it failed on targets which do not support constrained
intrinsics. The original commit message is below.

AST does not have special nodes for pragmas. Instead a pragma modifies
some state variables of Sema, which in turn results in modified
attributes of AST nodes. This technique applies to floating point
operations as well. Every AST node that can depend on FP options keeps
current set of them.

This technique works well for options like exception behavior or fast
math options. They represent instructions to the compiler how to modify
code generation for the affected nodes. However treatment of FP control
modes has problems with this technique. Modifying FP control mode
(like rounding direction) usually requires operations on hardware, like
writing to control registers. It must be done prior to the first
operation that depends on the control mode. In particular, such
operations are required for implementation of `pragma STDC FENV_ROUND`,
compiler should set up necessary rounding direction at the beginning of
compound statement where the pragma occurs. As there is no representation
for pragmas in AST, the code generation becomes a complicated task in
this case.

To solve this issue FP options are kept inside CompoundStmt. Unlike to FP
options in expressions, these does not affect any operation on FP values,
but only inform the codegen about the FP options that act in the body of
the statement. As all pragmas that modify FP environment may occurs only
at the start of compound statement or at global level, such solution
works for all relevant pragmas. The options are kept as a difference
from the options in the enclosing compound statement or default options,
it helps codegen to set only changed control modes.

Differential Revision: https://reviews.llvm.org/D123952

Added: 
clang/test/AST/ast-dump-pragma-json.c
clang/test/AST/ast-print-fp-pragmas.c

Modified: 
clang/include/clang/AST/JSONNodeDumper.h
clang/include/clang/AST/Stmt.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/ScopeInfo.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/JSONNodeDumper.cpp
clang/lib/AST/Stmt.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/Basic/LangOptions.cpp
clang/lib/CodeGen/CGCoroutine.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaStmt.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/test/AST/ast-dump-fpfeatures.cpp

Removed: 




diff  --git a/clang/include/clang/AST/JSONNodeDumper.h 
b/clang/include/clang/AST/JSONNodeDumper.h
index 5638df42a1c5..ed49e0007a18 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -160,6 +160,7 @@ class JSONNodeDumper
   std::string createPointerRepresentation(const void *Ptr);
   llvm::json::Object createQualType(QualType QT, bool Desugar = true);
   llvm::json::Object createBareDeclRef(const Decl *D);
+  llvm::json::Object createFPOptions(FPOptionsOverride FPO);
   void writeBareDeclRef(const Decl *D);
   llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
   llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier );
@@ -317,6 +318,7 @@ class JSONNodeDumper
   void VisitGotoStmt(const GotoStmt *GS);
   void VisitWhileStmt(const WhileStmt *WS);
   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
+  void VisitCompoundStmt(const CompoundStmt *IS);
 
   void VisitNullTemplateArgument(const TemplateArgument );
   void VisitTypeTemplateArgument(const TemplateArgument );

diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 653ce4b4b90c..49a66a1ea5b8 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -19,6 +19,7 @@
 #include "clang/Basic/CapturedStmt.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -128,6 +129,10 @@ class alignas(void *) Stmt {
 
 unsigned : NumStmtBits;
 
+/// 

[clang] dc34d8d - Revert "[FPEnv] Allow CompoundStmt to keep FP options"

2022-07-01 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-07-01T15:42:39+07:00
New Revision: dc34d8df4c48b3a8f474360970cae8a58e6c84f0

URL: 
https://github.com/llvm/llvm-project/commit/dc34d8df4c48b3a8f474360970cae8a58e6c84f0
DIFF: 
https://github.com/llvm/llvm-project/commit/dc34d8df4c48b3a8f474360970cae8a58e6c84f0.diff

LOG: Revert "[FPEnv] Allow CompoundStmt to keep FP options"

On some buildbots test `ast-print-fp-pragmas.c` fails, need to investigate it.

This reverts commit 0401fd12d4aa0553347fe34d666fb236d8719173.
This reverts commit b822efc7404bf09ccfdc1ab7657475026966c3b2.

Added: 


Modified: 
clang/include/clang/AST/JSONNodeDumper.h
clang/include/clang/AST/Stmt.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/ScopeInfo.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/JSONNodeDumper.cpp
clang/lib/AST/Stmt.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/Basic/LangOptions.cpp
clang/lib/CodeGen/CGCoroutine.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaStmt.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/test/AST/ast-dump-fpfeatures.cpp

Removed: 
clang/test/AST/ast-dump-pragma-json.c
clang/test/AST/ast-print-fp-pragmas.c



diff  --git a/clang/include/clang/AST/JSONNodeDumper.h 
b/clang/include/clang/AST/JSONNodeDumper.h
index ed49e0007a189..5638df42a1c50 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -160,7 +160,6 @@ class JSONNodeDumper
   std::string createPointerRepresentation(const void *Ptr);
   llvm::json::Object createQualType(QualType QT, bool Desugar = true);
   llvm::json::Object createBareDeclRef(const Decl *D);
-  llvm::json::Object createFPOptions(FPOptionsOverride FPO);
   void writeBareDeclRef(const Decl *D);
   llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
   llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier );
@@ -318,7 +317,6 @@ class JSONNodeDumper
   void VisitGotoStmt(const GotoStmt *GS);
   void VisitWhileStmt(const WhileStmt *WS);
   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
-  void VisitCompoundStmt(const CompoundStmt *IS);
 
   void VisitNullTemplateArgument(const TemplateArgument );
   void VisitTypeTemplateArgument(const TemplateArgument );

diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 49a66a1ea5b86..653ce4b4b90c5 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -19,7 +19,6 @@
 #include "clang/Basic/CapturedStmt.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -129,10 +128,6 @@ class alignas(void *) Stmt {
 
 unsigned : NumStmtBits;
 
-/// True if the compound statement has one or more pragmas that set some
-/// floating-point features.
-unsigned HasFPFeatures : 1;
-
 unsigned NumStmts;
   };
 
@@ -1403,9 +1398,8 @@ class NullStmt : public Stmt {
 };
 
 /// CompoundStmt - This represents a group of statements like { stmt stmt }.
-class CompoundStmt final
-: public Stmt,
-  private llvm::TrailingObjects {
+class CompoundStmt final : public Stmt,
+   private llvm::TrailingObjects 
{
   friend class ASTStmtReader;
   friend TrailingObjects;
 
@@ -1415,49 +1409,27 @@ class CompoundStmt final
   /// The location of the closing "}".
   SourceLocation RBraceLoc;
 
-  CompoundStmt(ArrayRef Stmts, FPOptionsOverride FPFeatures,
-   SourceLocation LB, SourceLocation RB);
+  CompoundStmt(ArrayRef Stmts, SourceLocation LB, SourceLocation RB);
   explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {}
 
   void setStmts(ArrayRef Stmts);
 
-  /// Set FPOptionsOverride in trailing storage. Used only by Serialization.
-  void setStoredFPFeatures(FPOptionsOverride F) {
-assert(hasStoredFPFeatures());
-*getTrailingObjects() = F;
-  }
-
-  size_t numTrailingObjects(OverloadToken) const {
-return CompoundStmtBits.NumStmts;
-  }
-
 public:
   static CompoundStmt *Create(const ASTContext , ArrayRef Stmts,
-  FPOptionsOverride FPFeatures, SourceLocation LB,
-  SourceLocation RB);
+  SourceLocation LB, SourceLocation RB);
 
   // Build an empty compound statement with a location.
   explicit CompoundStmt(SourceLocation Loc)
   : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(Loc) {
 CompoundStmtBits.NumStmts = 0;
-CompoundStmtBits.HasFPFeatures 

[clang] 0401fd1 - Fix warning on unhandled enumeration value

2022-07-01 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-07-01T15:17:29+07:00
New Revision: 0401fd12d4aa0553347fe34d666fb236d8719173

URL: 
https://github.com/llvm/llvm-project/commit/0401fd12d4aa0553347fe34d666fb236d8719173
DIFF: 
https://github.com/llvm/llvm-project/commit/0401fd12d4aa0553347fe34d666fb236d8719173.diff

LOG: Fix warning on unhandled enumeration value

Added: 


Modified: 
clang/lib/AST/StmtPrinter.cpp

Removed: 




diff  --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index f2aa8fb2659d..983fd39874f0 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -198,6 +198,8 @@ void StmtPrinter::PrintFPPragmas(CompoundStmt *S) {
 if (!FEnvAccess || EM != LangOptions::FPE_Strict) {
   Indent() << "#pragma clang fp exceptions(";
   switch (FPO.getSpecifiedExceptionModeOverride()) {
+  default:
+break;
   case LangOptions::FPE_Ignore:
 OS << "ignore";
 break;



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


[clang] b822efc - [FPEnv] Allow CompoundStmt to keep FP options

2022-07-01 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-07-01T14:32:33+07:00
New Revision: b822efc7404bf09ccfdc1ab7657475026966c3b2

URL: 
https://github.com/llvm/llvm-project/commit/b822efc7404bf09ccfdc1ab7657475026966c3b2
DIFF: 
https://github.com/llvm/llvm-project/commit/b822efc7404bf09ccfdc1ab7657475026966c3b2.diff

LOG: [FPEnv] Allow CompoundStmt to keep FP options

AST does not have special nodes for pragmas. Instead a pragma modifies
some state variables of Sema, which in turn results in modified
attributes of AST nodes. This technique applies to floating point
operations as well. Every AST node that can depend on FP options keeps
current set of them.

This technique works well for options like exception behavior or fast
math options. They represent instructions to the compiler how to modify
code generation for the affected nodes. However treatment of FP control
modes has problems with this technique. Modifying FP control mode
(like rounding direction) usually requires operations on hardware, like
writing to control registers. It must be done prior to the first
operation that depends on the control mode. In particular, such
operations are required for implementation of `pragma STDC FENV_ROUND`,
compiler should set up necessary rounding direction at the beginning of
compound statement where the pragma occurs. As there is no representation
for pragmas in AST, the code generation becomes a complicated task in
this case.

To solve this issue FP options are kept inside CompoundStmt. Unlike to FP
options in expressions, these does not affect any operation on FP values,
but only inform the codegen about the FP options that act in the body of
the statement. As all pragmas that modify FP environment may occurs only
at the start of compound statement or at global level, such solution
works for all relevant pragmas. The options are kept as a difference
from the options in the enclosing compound statement or default options,
it helps codegen to set only changed control modes.

Differential Revision: https://reviews.llvm.org/D123952

Added: 
clang/test/AST/ast-dump-pragma-json.c
clang/test/AST/ast-print-fp-pragmas.c

Modified: 
clang/include/clang/AST/JSONNodeDumper.h
clang/include/clang/AST/Stmt.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/ScopeInfo.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/JSONNodeDumper.cpp
clang/lib/AST/Stmt.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/Basic/LangOptions.cpp
clang/lib/CodeGen/CGCoroutine.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaStmt.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/test/AST/ast-dump-fpfeatures.cpp

Removed: 




diff  --git a/clang/include/clang/AST/JSONNodeDumper.h 
b/clang/include/clang/AST/JSONNodeDumper.h
index 5638df42a1c50..ed49e0007a189 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -160,6 +160,7 @@ class JSONNodeDumper
   std::string createPointerRepresentation(const void *Ptr);
   llvm::json::Object createQualType(QualType QT, bool Desugar = true);
   llvm::json::Object createBareDeclRef(const Decl *D);
+  llvm::json::Object createFPOptions(FPOptionsOverride FPO);
   void writeBareDeclRef(const Decl *D);
   llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
   llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier );
@@ -317,6 +318,7 @@ class JSONNodeDumper
   void VisitGotoStmt(const GotoStmt *GS);
   void VisitWhileStmt(const WhileStmt *WS);
   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
+  void VisitCompoundStmt(const CompoundStmt *IS);
 
   void VisitNullTemplateArgument(const TemplateArgument );
   void VisitTypeTemplateArgument(const TemplateArgument );

diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 653ce4b4b90c5..49a66a1ea5b86 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -19,6 +19,7 @@
 #include "clang/Basic/CapturedStmt.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -128,6 +129,10 @@ class alignas(void *) Stmt {
 
 unsigned : NumStmtBits;
 
+/// True if the compound statement has one or more pragmas that set some
+/// floating-point features.
+unsigned HasFPFeatures : 1;
+
 unsigned NumStmts;
   };
 
@@ -1398,8 +1403,9 @@ class NullStmt : public Stmt {
 };
 
 /// CompoundStmt - This represents a group of statements like { stmt stmt }.
-class 

[clang] 706e89d - Fix interaction of pragma FENV_ACCESS with other pragmas

2022-06-22 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-06-22T15:13:54+07:00
New Revision: 706e89db97d3dea63dac1ee2c5a26cb2af9651a2

URL: 
https://github.com/llvm/llvm-project/commit/706e89db97d3dea63dac1ee2c5a26cb2af9651a2
DIFF: 
https://github.com/llvm/llvm-project/commit/706e89db97d3dea63dac1ee2c5a26cb2af9651a2.diff

LOG: Fix interaction of pragma FENV_ACCESS with other pragmas

Previously `#pragma STDC FENV_ACCESS ON` always set dynamic rounding
mode and strict exception handling. It is not correct in the presence
of other pragmas that also modify rounding mode and exception handling.
For example, the effect of previous pragma FENV_ROUND could be
cancelled, which is not conformant with the C standard. Also
`#pragma STDC FENV_ACCESS OFF` turned off only FEnvAccess flag, leaving
rounding mode and exception handling unchanged, which is incorrect in
general case.

Concrete rounding and exception mode depend on a combination of several
factors like various pragmas and command-line options. During the review
of this patch an idea was proposed that the semantic actions associated
with such pragmas should only set appropriate flags. Actual rounding
mode and exception handling should be calculated taking into account the
state of all relevant options. In such implementation the pragma
FENV_ACCESS should not override properties set by other pragmas but
should set them if such setting is absent.

To implement this approach the following main changes are made:

- Field `FPRoundingMode` is removed from `LangOptions`. Actually there
  are no options that set it to arbitrary rounding mode, the choice was
  only `dynamic` or `tonearest`. Instead, a new boolean flag
  `RoundingMath` is added, with the same meaning as the corresponding
  command-line option.

- Type `FPExceptionModeKind` now has possible value `FPE_Default`. It
  does not represent any particular exception mode but indicates that
  such mode was not set and default value should be used. It allows to
  distinguish the case:

{
#pragma STDC FENV_ACCESS ON
...
}

  where the pragma must set FPE_Strict, from the case:

{
#pragma clang fp exceptions(ignore)
#pragma STDC FENV_ACCESS ON
...
}

  where exception mode should remain `FPE_Ignore`.

  - Class `FPOptions` has now methods `getRoundingMode` and
  `getExceptionMode`, which calculates the respective properties from
  other specified FP properties.

  - Class `LangOptions` has now methods `getDefaultRoundingMode` and
  `getDefaultExceptionMode`, which calculates default modes from the
  specified options and should be used instead of `getRoundingMode` and
  `getFPExceptionMode` of the same class.

Differential Revision: https://reviews.llvm.org/D126364

Added: 


Modified: 
clang/include/clang/Basic/FPOptions.def
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Driver/Options.td
clang/include/clang/Sema/Sema.h
clang/lib/AST/ExprConstant.cpp
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/Frontend/CompilerInstance.cpp
clang/lib/Parse/ParsePragma.cpp
clang/lib/Sema/SemaAttr.cpp
clang/test/AST/ast-dump-fpfeatures.cpp
clang/test/CodeGen/pragma-fenv_access.c

Removed: 




diff  --git a/clang/include/clang/Basic/FPOptions.def 
b/clang/include/clang/Basic/FPOptions.def
index 224c1827144f5..1dfbbb549c874 100644
--- a/clang/include/clang/Basic/FPOptions.def
+++ b/clang/include/clang/Basic/FPOptions.def
@@ -14,9 +14,10 @@
 
 // OPTION(name, type, width, previousName)
 OPTION(FPContractMode, LangOptions::FPModeKind, 2, First)
-OPTION(RoundingMode, LangOptions::RoundingMode, 3, FPContractMode)
-OPTION(FPExceptionMode, LangOptions::FPExceptionModeKind, 2, RoundingMode)
-OPTION(AllowFEnvAccess, bool, 1, FPExceptionMode)
+OPTION(RoundingMath, bool, 1, FPContractMode)
+OPTION(ConstRoundingMode, LangOptions::RoundingMode, 3, RoundingMath)
+OPTION(SpecifiedExceptionMode, LangOptions::FPExceptionModeKind, 2, 
ConstRoundingMode)
+OPTION(AllowFEnvAccess, bool, 1, SpecifiedExceptionMode)
 OPTION(AllowFPReassociate, bool, 1, AllowFEnvAccess)
 OPTION(NoHonorNaNs, bool, 1, AllowFPReassociate)
 OPTION(NoHonorInfs, bool, 1, NoHonorNaNs)

diff  --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index aa346ba239391..c41b5ddc7fa11 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -311,8 +311,8 @@ COMPATIBLE_LANGOPT(CLFiniteMathOnly , 1, 0, 
"__FINITE_MATH_ONLY__ predefined mac
 /// FP_CONTRACT mode (on/off/fast).
 BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP 
contraction type")
 COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating 
point")
-BENIGN_ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, 
RoundingMode::NearestTiesToEven, "FP 

[clang] 6117784 - [NFC] Remove unused function parameter

2022-06-14 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-06-14T22:00:59+07:00
New Revision: 6117784c5f2b70d0adb71afb50903f2dc457996a

URL: 
https://github.com/llvm/llvm-project/commit/6117784c5f2b70d0adb71afb50903f2dc457996a
DIFF: 
https://github.com/llvm/llvm-project/commit/6117784c5f2b70d0adb71afb50903f2dc457996a.diff

LOG: [NFC] Remove unused function parameter

Added: 


Modified: 
clang/lib/AST/ExprConstant.cpp

Removed: 




diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 3c62a83618a13..65782fbb1eaea 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2552,18 +2552,15 @@ static bool HandleFloatToIntCast(EvalInfo , const 
Expr *E,
   return true;
 }
 
-/// Get rounding mode used for evaluation of the specified expression.
-/// \param[out] DynamicRM Is set to true is the requested rounding mode is
-///   dynamic.
+/// Get rounding mode to use in evaluation of the specified expression.
+///
 /// If rounding mode is unknown at compile time, still try to evaluate the
 /// expression. If the result is exact, it does not depend on rounding mode.
 /// So return "tonearest" mode instead of "dynamic".
-static llvm::RoundingMode getActiveRoundingMode(EvalInfo , const Expr *E,
-bool ) {
+static llvm::RoundingMode getActiveRoundingMode(EvalInfo , const Expr *E) 
{
   llvm::RoundingMode RM =
   E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
-  DynamicRM = (RM == llvm::RoundingMode::Dynamic);
-  if (DynamicRM)
+  if (RM == llvm::RoundingMode::Dynamic)
 RM = llvm::RoundingMode::NearestTiesToEven;
   return RM;
 }
@@ -2613,8 +2610,7 @@ static bool HandleFloatToFloatCast(EvalInfo , const 
Expr *E,
QualType SrcType, QualType DestType,
APFloat ) {
   assert(isa(E) || isa(E));
-  bool DynamicRM;
-  llvm::RoundingMode RM = getActiveRoundingMode(Info, E, DynamicRM);
+  llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
   APFloat::opStatus St;
   APFloat Value = Result;
   bool ignored;
@@ -2849,8 +2845,7 @@ static bool handleIntIntBinOp(EvalInfo , const Expr 
*E, const APSInt ,
 static bool handleFloatFloatBinOp(EvalInfo , const BinaryOperator *E,
   APFloat , BinaryOperatorKind Opcode,
   const APFloat ) {
-  bool DynamicRM;
-  llvm::RoundingMode RM = getActiveRoundingMode(Info, E, DynamicRM);
+  llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
   APFloat::opStatus St;
   switch (Opcode) {
   default:



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


[clang] 5537b22 - Make CompoundStmtBitfields::NumStmts not a bit-field

2022-05-20 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2022-05-20T14:20:09+07:00
New Revision: 5537b22ccbdc562929949844f9f816cf720e5205

URL: 
https://github.com/llvm/llvm-project/commit/5537b22ccbdc562929949844f9f816cf720e5205
DIFF: 
https://github.com/llvm/llvm-project/commit/5537b22ccbdc562929949844f9f816cf720e5205.diff

LOG: Make CompoundStmtBitfields::NumStmts not a bit-field

Number of statements in CompoundStmt is kept in a bit-field of the common
part of Stmt. The field has 24 bits for the number. To allocate a new
bit field (as attempted in https://reviews.llvm.org/D123952), this
number must be reduced, maximal number of statements in a compound
statement becomes smaller. It can result in compilation errors of some
programs.

With this change the number of statements is kept in a field of type
'unsigned int' rather than in bit-field. To make room in CompoundStmtBitfields
LBraceLoc is moved to fields of CompoundStmt.

Differential Revision: https://reviews.llvm.org/D125635

Added: 


Modified: 
clang/include/clang/AST/Stmt.h
clang/lib/AST/Stmt.cpp
clang/lib/Serialization/ASTReaderStmt.cpp

Removed: 




diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 1135981319c1a..653ce4b4b90c5 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -128,10 +128,7 @@ class alignas(void *) Stmt {
 
 unsigned : NumStmtBits;
 
-unsigned NumStmts : 32 - NumStmtBits;
-
-/// The location of the opening "{".
-SourceLocation LBraceLoc;
+unsigned NumStmts;
   };
 
   class LabelStmtBitfields {
@@ -1406,7 +1403,10 @@ class CompoundStmt final : public Stmt,
   friend class ASTStmtReader;
   friend TrailingObjects;
 
-  /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits.
+  /// The location of the opening "{".
+  SourceLocation LBraceLoc;
+
+  /// The location of the closing "}".
   SourceLocation RBraceLoc;
 
   CompoundStmt(ArrayRef Stmts, SourceLocation LB, SourceLocation RB);
@@ -1420,9 +1420,8 @@ class CompoundStmt final : public Stmt,
 
   // Build an empty compound statement with a location.
   explicit CompoundStmt(SourceLocation Loc)
-  : Stmt(CompoundStmtClass), RBraceLoc(Loc) {
+  : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(Loc) {
 CompoundStmtBits.NumStmts = 0;
-CompoundStmtBits.LBraceLoc = Loc;
   }
 
   // Build an empty compound statement.
@@ -1505,10 +1504,10 @@ class CompoundStmt final : public Stmt,
 return const_cast(this)->getStmtExprResult();
   }
 
-  SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; }
+  SourceLocation getBeginLoc() const { return LBraceLoc; }
   SourceLocation getEndLoc() const { return RBraceLoc; }
 
-  SourceLocation getLBracLoc() const { return CompoundStmtBits.LBraceLoc; }
+  SourceLocation getLBracLoc() const { return LBraceLoc; }
   SourceLocation getRBracLoc() const { return RBraceLoc; }
 
   static bool classof(const Stmt *T) {

diff  --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index be19d3b2cce2c..d562717bf6b22 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -363,10 +363,9 @@ int64_t Stmt::getID(const ASTContext ) const {
 
 CompoundStmt::CompoundStmt(ArrayRef Stmts, SourceLocation LB,
SourceLocation RB)
-: Stmt(CompoundStmtClass), RBraceLoc(RB) {
+: Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
   CompoundStmtBits.NumStmts = Stmts.size();
   setStmts(Stmts);
-  CompoundStmtBits.LBraceLoc = LB;
 }
 
 void CompoundStmt::setStmts(ArrayRef Stmts) {

diff  --git a/clang/lib/Serialization/ASTReaderStmt.cpp 
b/clang/lib/Serialization/ASTReaderStmt.cpp
index 77ea1b95d5be5..09342de1eee96 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -155,7 +155,7 @@ void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
   while (NumStmts--)
 Stmts.push_back(Record.readSubStmt());
   S->setStmts(Stmts);
-  S->CompoundStmtBits.LBraceLoc = readSourceLocation();
+  S->LBraceLoc = readSourceLocation();
   S->RBraceLoc = readSourceLocation();
 }
 



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


[clang] 04c3071 - [Driver] Flush file in locked area

2021-02-26 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2021-02-26T19:02:54+07:00
New Revision: 04c3071c16d799a4406c1742f239e8381c00b2b8

URL: 
https://github.com/llvm/llvm-project/commit/04c3071c16d799a4406c1742f239e8381c00b2b8
DIFF: 
https://github.com/llvm/llvm-project/commit/04c3071c16d799a4406c1742f239e8381c00b2b8.diff

LOG: [Driver] Flush file in locked area

When writing report file by option -proc-stat-report some part of output
can be written to unlocked file because destructor of raw_fd_ostream
calls `flush()`. In high thread contention environment it can result in
file operation failure. With this change `flush` is called explicitly when
file is locked, so call of `flush()` in the destructor does not cause
write to file.

Added: 


Modified: 
clang/lib/Driver/Driver.cpp

Removed: 




diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 5aa0011d80ef..84bee2ae9d07 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4069,6 +4069,7 @@ void Driver::BuildJobs(Compilation ) const {
   return;
 }
 OS << Buffer;
+OS.flush();
   }
 });
   }



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


[clang] 9faedb2 - [Driver] Quote executable in reports generated by -fproc-stat-report

2020-11-17 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-11-17T15:16:09+07:00
New Revision: 9faedb2d7146d29bfd0f601e2a4a90b546cdaf04

URL: 
https://github.com/llvm/llvm-project/commit/9faedb2d7146d29bfd0f601e2a4a90b546cdaf04
DIFF: 
https://github.com/llvm/llvm-project/commit/9faedb2d7146d29bfd0f601e2a4a90b546cdaf04.diff

LOG: [Driver] Quote executable in reports generated by -fproc-stat-report

The option -fproc-stat-report= makes driver to generate child
process resource comsumption report. In the report executable name was
not quoted and it made parsing the report more difficult. With this
change the executable name is surrounded by quotation marks.

Added: 


Modified: 
clang/lib/Driver/Driver.cpp

Removed: 




diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 5f4e7f271764..fb258197cfdd 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -3964,7 +3964,9 @@ void Driver::BuildJobs(Compilation ) const {
 // CSV format.
 std::string Buffer;
 llvm::raw_string_ostream Out(Buffer);
-Out << llvm::sys::path::filename(Cmd.getExecutable()) << ',';
+llvm::sys::printArg(Out, 
llvm::sys::path::filename(Cmd.getExecutable()),
+/*Quote*/ true);
+Out << ',';
 if (Cmd.getOutputFilenames().empty())
   Out << "\"\"";
 else



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


[clang] 92d7a84 - [Driver] Add option -fproc-stat-report

2020-11-12 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-11-13T14:15:42+07:00
New Revision: 92d7a84e128a20cd23e3129dee82c48f1750966a

URL: 
https://github.com/llvm/llvm-project/commit/92d7a84e128a20cd23e3129dee82c48f1750966a
DIFF: 
https://github.com/llvm/llvm-project/commit/92d7a84e128a20cd23e3129dee82c48f1750966a.diff

LOG: [Driver] Add option -fproc-stat-report

The new option `-fproc-stat-info=` can be used to generate report
about used memory and execution tile of each stage of compilation.
Documentation for this option can be found in `UserManual.rst`. The
option can be used in parallel builds.

Differential Revision: https://reviews.llvm.org/D78903

Added: 
clang/test/Driver/report-stat.c

Modified: 
clang/docs/UsersManual.rst
clang/include/clang/Driver/Job.h
clang/include/clang/Driver/Options.td
clang/lib/Driver/Driver.cpp
clang/lib/Driver/Job.cpp

Removed: 




diff  --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 9601ff48c777..2c59ba929ef4 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -747,6 +747,51 @@ Current limitations
translated from debug annotations. That translation can be lossy,
which results in some remarks having no location information.
 
+Options to Emit Resource Consumption Reports
+
+
+These are options that report execution time and consumed memory of 
diff erent
+compilations steps.
+
+.. option:: -fproc-stat-report=
+
+  This option requests driver to print used memory and execution time of each
+  compilation step. The ``clang`` driver during execution calls 
diff erent tools,
+  like compiler, assembler, linker etc. With this option the driver reports
+  total execution time, the execution time spent in user mode and peak memory
+  usage of each the called tool. Value of the option specifies where the report
+  is sent to. If it specifies a regular file, the data are saved to this file 
in
+  CSV format:
+
+.. code-block:: console
+
+   $ clang -fproc-stat-report=abc foo.c
+   $ cat abc
+   clang-11,"/tmp/foo-123456.o",92000,84000,87536
+   ld,"a.out",900,8000,53568
+
+  The data on each row represent:
+  
+  * file name of the tool executable,
+  * output file name in quotes,
+  * total execution time in microseconds,
+  * execution time in user mode in microseconds,
+  * peak memory usage in Kb.
+  
+  It is possible to specify this option without any value. In this case 
statistics
+  is printed on standard output in human readable format:
+  
+.. code-block:: console
+
+  $ clang -fproc-stat-report foo.c
+  clang-11: output=/tmp/foo-855a8e.o, total=68.000 ms, user=60.000 ms, 
mem=86920 Kb
+  ld: output=a.out, total=8.000 ms, user=4.000 ms, mem=52320 Kb
+  
+  The report file specified in the option is locked for write, so this option
+  can be used to collect statistics in parallel builds. The report file is not
+  cleared, new data is appended to it, thus making posible to accumulate build
+  statistics.
+
 Other Options
 -
 Clang options that don't fit neatly into other categories.

diff  --git a/clang/include/clang/Driver/Job.h 
b/clang/include/clang/Driver/Job.h
index 8a348c8048d0..199387cddd5c 100644
--- a/clang/include/clang/Driver/Job.h
+++ b/clang/include/clang/Driver/Job.h
@@ -140,6 +140,9 @@ class Command {
   /// See Command::setEnvironment
   std::vector Environment;
 
+  /// Information on executable run provided by OS.
+  mutable Optional ProcStat;
+
   /// When a response file is needed, we try to put most arguments in an
   /// exclusive file, while others remains as regular command line arguments.
   /// This functions fills a vector with the regular command line arguments,
@@ -212,6 +215,10 @@ class Command {
 return OutputFilenames;
   }
 
+  Optional getProcessStatistics() const {
+return ProcStat;
+  }
+
 protected:
   /// Optionally print the filenames to be compiled
   void PrintFileNames() const;

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 245e6765d613..2d22151c6496 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1964,6 +1964,10 @@ can be analyzed with chrome://tracing or `Speedscope App
 def ftime_trace_granularity_EQ : Joined<["-"], "ftime-trace-granularity=">, 
Group,
   HelpText<"Minimum time granularity (in microseconds) traced by time 
profiler">,
   Flags<[CC1Option, CoreOption]>;
+def fproc_stat_report : Joined<["-"], "fproc-stat-report">, Group,
+  HelpText<"Print subprocess statistics">;
+def fproc_stat_report_EQ : Joined<["-"], "fproc-stat-report=">, Group,
+  HelpText<"Save subprocess statistics to the given file">;
 def ftlsmodel_EQ : Joined<["-"], "ftls-model=">, Group, 
Flags<[CC1Option]>;
 def ftrapv : Flag<["-"], "ftrapv">, Group, Flags<[CC1Option]>,
   HelpText<"Trap on integer overflow">;

diff  --git 

[clang] 20b4f4f - [Driver] Add callback to Command execution

2020-11-04 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-11-05T12:21:40+07:00
New Revision: 20b4f4f76030f8712824c91b5f0b0a611476f747

URL: 
https://github.com/llvm/llvm-project/commit/20b4f4f76030f8712824c91b5f0b0a611476f747
DIFF: 
https://github.com/llvm/llvm-project/commit/20b4f4f76030f8712824c91b5f0b0a611476f747.diff

LOG: [Driver] Add callback to Command execution

Summary:
Object of type `Compilation` now can keep a callback that is called
after each execution of `Command`. This must simplify adaptation of
clang in custom distributions and allow facilities like collection of
execution statistics.

Reviewers: rsmith, rjmccall, Eugene.Zelenko

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D78899

Added: 


Modified: 
clang/include/clang/Driver/Compilation.h
clang/lib/Driver/Compilation.cpp
clang/unittests/Driver/ToolChainTest.cpp

Removed: 




diff  --git a/clang/include/clang/Driver/Compilation.h 
b/clang/include/clang/Driver/Compilation.h
index 70b901434487..89a43b5b7dc0 100644
--- a/clang/include/clang/Driver/Compilation.h
+++ b/clang/include/clang/Driver/Compilation.h
@@ -115,6 +115,11 @@ class Compilation {
   /// Optional redirection for stdin, stdout, stderr.
   std::vector> Redirects;
 
+  /// Callback called after compilation job has been finished.
+  /// Arguments of the callback are the compilation job as an instance of
+  /// class Command and the exit status of the corresponding child process.
+  std::function PostCallback;
+
   /// Whether we're compiling for diagnostic purposes.
   bool ForDiagnostics = false;
 
@@ -212,6 +217,14 @@ class Compilation {
 return FailureResultFiles;
   }
 
+  /// Installs a handler that is executed when a compilation job is finished.
+  /// The arguments of the callback specify the compilation job as an instance
+  /// of class Command and the exit status of the child process executed that
+  /// job.
+  void setPostCallback(const std::function ) {
+PostCallback = CB;
+  }
+
   /// Returns the sysroot path.
   StringRef getSysRoot() const;
 

diff  --git a/clang/lib/Driver/Compilation.cpp 
b/clang/lib/Driver/Compilation.cpp
index 05ee5091396b..d33055739080 100644
--- a/clang/lib/Driver/Compilation.cpp
+++ b/clang/lib/Driver/Compilation.cpp
@@ -193,6 +193,8 @@ int Compilation::ExecuteCommand(const Command ,
   std::string Error;
   bool ExecutionFailed;
   int Res = C.Execute(Redirects, , );
+  if (PostCallback)
+PostCallback(C, Res);
   if (!Error.empty()) {
 assert(Res && "Error string set with 0 result code!");
 getDriver().Diag(diag::err_drv_command_failure) << Error;

diff  --git a/clang/unittests/Driver/ToolChainTest.cpp 
b/clang/unittests/Driver/ToolChainTest.cpp
index 227f7c76b8a1..35060563ab97 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -289,4 +289,28 @@ TEST(ToolChainTest, CommandOutput) {
   EXPECT_EQ("a.out", ExeFile);
 }
 
+TEST(ToolChainTest, PostCallback) {
+  IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
+  IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
+  struct TestDiagnosticConsumer : public DiagnosticConsumer {};
+  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+  IntrusiveRefCntPtr InMemoryFileSystem(
+  new llvm::vfs::InMemoryFileSystem);
+
+  // The executable path must not exist.
+  Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
+  "clang LLVM compiler", InMemoryFileSystem);
+  CCDriver.setCheckInputsExist(false);
+  std::unique_ptr CC(
+  CCDriver.BuildCompilation({"/home/test/bin/clang", "foo.cpp"}));
+  bool CallbackHasCalled = false;
+  CC->setPostCallback(
+  [&](const Command , int Ret) { CallbackHasCalled = true; });
+  const JobList  = CC->getJobs();
+  auto  = Jobs.getJobs().front();
+  const Command *FailingCmd = nullptr;
+  CC->ExecuteCommand(*CmdCompile, FailingCmd);
+  EXPECT_TRUE(CallbackHasCalled);
+}
+
 } // end anonymous namespace.



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


[clang] ee63acc - Put back the test pragma-fp-exc.cpp

2020-11-02 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-11-03T13:18:40+07:00
New Revision: ee63acc37e319cdab6accd677fdf772ea3683867

URL: 
https://github.com/llvm/llvm-project/commit/ee63acc37e319cdab6accd677fdf772ea3683867
DIFF: 
https://github.com/llvm/llvm-project/commit/ee63acc37e319cdab6accd677fdf772ea3683867.diff

LOG: Put back the test pragma-fp-exc.cpp

This test was removed in 5963e028e714 because it failed on cores where
support of constrained intrinsics was limited. Now this test is enabled
only on x86.

Added: 
clang/test/CodeGen/pragma-fp-exc.cpp

Modified: 


Removed: 




diff  --git a/clang/test/CodeGen/pragma-fp-exc.cpp 
b/clang/test/CodeGen/pragma-fp-exc.cpp
new file mode 100644
index ..ff47173739db
--- /dev/null
+++ b/clang/test/CodeGen/pragma-fp-exc.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | 
FileCheck --check-prefix=CHECK-DEF %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu 
-ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck 
--check-prefix=CHECK-STRICT %s
+
+// REQUIRES: x86-registered-target
+
+float func_01(float x, float y, float z) {
+  float res = x + y;
+  {
+#pragma clang fp exceptions(maytrap)
+res += z;
+  }
+  return res;
+}
+// CHECK-DEF-LABEL: @_Z7func_01fff
+// CHECK-DEF:   call float @llvm.experimental.constrained.fadd.f32(float 
{{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
+// CHECK-DEF:   call float @llvm.experimental.constrained.fadd.f32(float 
{{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
+
+// CHECK-STRICT-LABEL: @_Z7func_01fff
+// CHECK-STRICT:   call float 
@llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata 
!"round.tonearest", metadata !"fpexcept.strict")
+// CHECK-STRICT:   call float 
@llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata 
!"round.tonearest", metadata !"fpexcept.maytrap")



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


[clang] 5963e02 - Temporarily remove test CodeGen/pragma-fp-exc

2020-10-31 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-10-31T19:48:44+07:00
New Revision: 5963e028e7145d68b70be128d13e26a02095a0ad

URL: 
https://github.com/llvm/llvm-project/commit/5963e028e7145d68b70be128d13e26a02095a0ad
DIFF: 
https://github.com/llvm/llvm-project/commit/5963e028e7145d68b70be128d13e26a02095a0ad.diff

LOG: Temporarily remove test CodeGen/pragma-fp-exc

This test fails on buildbots where CPU architecture does not fully
support constrained intrinsics.

Added: 


Modified: 


Removed: 
clang/test/CodeGen/pragma-fp-exc.cpp



diff  --git a/clang/test/CodeGen/pragma-fp-exc.cpp 
b/clang/test/CodeGen/pragma-fp-exc.cpp
deleted file mode 100644
index c51b7e63204c..
--- a/clang/test/CodeGen/pragma-fp-exc.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck 
--check-prefix=CHECK-DEF %s
-// RUN: %clang_cc1 -triple %itanium_abi_triple -ffp-exception-behavior=strict 
-emit-llvm -o - %s | FileCheck --check-prefix=CHECK-STRICT %s
-
-float func_01(float x, float y, float z) {
-  float res = x + y;
-  {
-#pragma clang fp exceptions(maytrap)
-res += z;
-  }
-  return res;
-}
-// CHECK-DEF-LABEL: @_Z7func_01fff
-// CHECK-DEF:   call float @llvm.experimental.constrained.fadd.f32(float 
{{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.ignore")
-// CHECK-DEF:   call float @llvm.experimental.constrained.fadd.f32(float 
{{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
-
-// CHECK-STRICT-LABEL: @_Z7func_01fff
-// CHECK-STRICT:   call float 
@llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata 
!"round.tonearest", metadata !"fpexcept.strict")
-// CHECK-STRICT:   call float 
@llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata 
!"round.tonearest", metadata !"fpexcept.maytrap")



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


[clang] 6021cbe - Add option 'exceptions' to pragma clang fp

2020-10-31 Thread Serge Pavlov via cfe-commits

Author: Serge Pavlov
Date: 2020-10-31T17:36:12+07:00
New Revision: 6021cbea4d346d8ff059f8dd74ba7d520646be03

URL: 
https://github.com/llvm/llvm-project/commit/6021cbea4d346d8ff059f8dd74ba7d520646be03
DIFF: 
https://github.com/llvm/llvm-project/commit/6021cbea4d346d8ff059f8dd74ba7d520646be03.diff

LOG: Add option 'exceptions' to pragma clang fp

Pragma 'clang fp' is extended to support a new option, 'exceptions'. It
allows to specify floating point exception behavior more flexibly.

Differential Revision: https://reviews.llvm.org/D89849

Added: 
clang/test/CodeGen/pragma-fp-exc.cpp

Modified: 
clang/docs/LanguageExtensions.rst
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParsePragma.cpp
clang/lib/Sema/SemaAttr.cpp
clang/test/Parser/pragma-fp.cpp

Removed: 




diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index a90485d9f799..e17e4e1c46a7 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3182,7 +3182,7 @@ The pragma can take two values: ``on`` and ``off``.
   float f(float x, float y, float z)
   {
 // Enable floating point reassociation across statements
-#pragma fp reassociate(on)
+#pragma clang fp reassociate(on)
 float t = x + y;
 float v = t + z;
   }
@@ -3211,6 +3211,31 @@ The pragma can also be used with ``off`` which turns FP 
contraction off for a
 section of the code. This can be useful when fast contraction is otherwise
 enabled for the translation unit with the ``-ffp-contract=fast`` flag.
 
+
+``#pragma clang fp exceptions`` specifies floating point exception behavior. It
+may take one the the values: ``ignore``, ``maytrap`` or ``strict``. Meaning of
+these values is same as for `constrained floating point intrinsics 
`_.
+
+.. code-block:: c++
+
+  {
+// Preserve floating point exceptions
+#pragma clang fp exceptions(strict)
+z = x + y;
+if (fetestexcept(FE_OVERFLOW))
+ ...
+  }
+
+A ``#pragma clang fp`` pragma may contain any number of options:
+
+.. code-block:: c++
+
+  void func(float *dest, float a, float b) {
+#pragma clang fp exceptions(maytrap) contract(fast) reassociate(on)
+...
+  }
+
+
 The ``#pragma float_control`` pragma allows precise floating-point
 semantics and floating-point exception behavior to be specified
 for a section of the source code. This pragma can only appear at file scope or

diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 0fd4eb5323de..c0a5a2b4c144 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1388,12 +1388,13 @@ def err_pragma_loop_invalid_option : Error<
   "pipeline, pipeline_initiation_interval, vectorize_predicate, or 
distribute">;
 
 def err_pragma_fp_invalid_option : Error<
-  "%select{invalid|missing}0 option%select{ %1|}0; expected 'contract' or 
'reassociate'">;
+  "%select{invalid|missing}0 option%select{ %1|}0; expected 'contract', 
'reassociate' or 'exceptions'">;
 def err_pragma_fp_invalid_argument : Error<
-  "unexpected argument '%0' to '#pragma clang fp %1'; "
+  "unexpected argument '%0' to '#pragma clang fp %1'; expected "
   "%select{"
-  "expected 'fast' or 'on' or 'off'|"
-  "expected 'on' or 'off'}2">;
+  "'fast' or 'on' or 'off'|"
+  "'on' or 'off'|"
+  "'ignore', 'maytrap' or 'strict'}2">;
 
 def err_pragma_invalid_keyword : Error<
   "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 
'assume_safety'}1 or 'disable'">;

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4be3c23652e1..3afd417bb2a2 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9896,6 +9896,10 @@ class Sema final {
   /// \#pragma STDC FENV_ACCESS
   void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled);
 
+  /// Called on well formed '\#pragma clang fp' that has option 'exceptions'.
+  void ActOnPragmaFPExceptions(SourceLocation Loc,
+   LangOptions::FPExceptionModeKind);
+
   /// Called to set constant rounding mode for floating point operations.
   void setRoundingMode(SourceLocation Loc, llvm::RoundingMode);
 

diff  --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 278e6f50deba..64de2cf5d7f1 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -2858,11 +2858,12 @@ void PragmaOptimizeHandler::HandlePragma(Preprocessor 
,
 namespace {
 /// Used as the annotation value for tok::annot_pragma_fp.
 struct TokFPAnnotValue {
-  enum FlagKinds { Contract, Reassociate };
+  enum FlagKinds { Contract, Reassociate, Exceptions };
   enum FlagValues { On, Off, Fast };
 
-  

  1   2   3   4   >