[PATCH] D130907: [Clang] Use pragma FENV_ROUND to reset rounding mode settings.

Serge Pavlov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 1 08:16:15 PDT 2022


sepavloff created this revision.
sepavloff added reviewers: rjmccall, aaron.ballman, kpn.
Herald added a project: All.
sepavloff requested review of this revision.
Herald added a project: clang.

Now starting from the first use of `pragma FENV_ROUND` rounding mode
becomes user-defined and there is no way to return back to initial
state. Default rounding mode and the same explicitly defined one result
in different AST. For example, the code:

  float func_04(float x, float y) {
    return x + y;
  }

produces AST where the FP operation is represented with the node:

  `-BinaryOperator 0x25d6e2cecb8 <col:10, col:14> 'float' '+'

The same code with `#pragma STDC FENV_ROUND FE_TONEAREST` before the
function definition produces slightly different representation:

  `-BinaryOperator 0x1832c1a4ce8 <col:10, col:14> 'float' '+' ConstRoundingMode=tonearest

Code generation is not changed in this case because `tonearest` is the
rounding mode in default FP environment. However if an AST object has
an override for a FP property, it considered as explicitly specified
and is preserved in some cases where default property may be overridden.

Default rounding mode is `dynamic` according to the C2x standard
draft (7.6.2p3):

  ... If no FENV_ROUND pragma is in effect, or the specified constant
  rounding mode is FE_DYNAMIC, rounding is according to the mode
  specified by the dynamic floating-point environment ...

So pragma `FENV_ROUND FE_DYNAMIC` must reset rounding to default state,
but now it only adds related override:

  `-BinaryOperator 0x1cb8cfaaec8 <col:10, col:14> 'float' '+' ConstRoundingMode=dynamic

This change fixes the pragma behavior. If `FENV_ROUND FE_DYNAMIC` is
specified without `FENV_ACCESS ON`, the rounding mode override is
removed, which effectively establish default rounding mode state.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130907

Files:
  clang/lib/Sema/SemaStmt.cpp
  clang/test/AST/ast-dump-fpfeatures.cpp


Index: clang/test/AST/ast-dump-fpfeatures.cpp
===================================================================
--- clang/test/AST/ast-dump-fpfeatures.cpp
+++ clang/test/AST/ast-dump-fpfeatures.cpp
@@ -109,7 +109,18 @@
 }
 
 // CHECK-LABEL: FunctionDecl {{.*}} func_12 'float (float, float)'
+// CHECK:         BinaryOperator {{.*}} 'float' '+'
+
+#pragma STDC FENV_ROUND FE_DYNAMIC
+#pragma STDC FENV_ACCESS ON
+
+float func_12a(float x, float y) {
+  return x + y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_12a 'float (float, float)'
 // CHECK:         BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=dynamic
+#pragma STDC FENV_ACCESS OFF
 
 #pragma STDC FENV_ROUND FE_TONEAREST
 
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -391,7 +391,14 @@
 }
 
 void Sema::ActOnAfterCompoundStatementLeadingPragmas() {
-  if (getCurFPFeatures().isFPConstrained()) {
+  FPOptions &FPO = getCurFPFeatures();
+  if (FPO.getConstRoundingMode() == llvm::RoundingMode::Dynamic &&
+      !FPO.getAllowFEnvAccess()) {
+    // If dynamic rounding mode is specified in absence of FENV_ACCESS, treat it
+    // as setting default rounding mode.
+    FpPragmaStack.CurrentValue.clearConstRoundingModeOverride();
+  }
+  if (FPO.isFPConstrained()) {
     FunctionScopeInfo *FSI = getCurFunction();
     assert(FSI);
     FSI->setUsesFPIntrin();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D130907.449024.patch
Type: text/x-patch
Size: 1458 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220801/510a81af/attachment-0001.bin>


More information about the cfe-commits mailing list