[PATCH] D86921: [FPEnv] Partially implement #pragma STDC FENV_ROUND

2020-09-04 Thread Serge Pavlov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa633da5391b0: [FPEnv] Partially implement #pragma STDC 
FENV_ROUND (authored by sepavloff).

Changed prior to commit:
  https://reviews.llvm.org/D86921?vs=289110=289901#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86921/new/

https://reviews.llvm.org/D86921

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/AST/ast-dump-fpfeatures.cpp
  clang/test/Parser/pragma-fenv_round.c

Index: clang/test/Parser/pragma-fenv_round.c
===
--- /dev/null
+++ clang/test/Parser/pragma-fenv_round.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -Wignored-pragmas -verify %s
+
+#pragma STDC FENV_ROUND ON   // expected-warning {{invalid or unsupported rounding mode}}
+
+float func_01(int x, float y) {
+  if (x)
+return y + 2;
+  #pragma STDC FENV_ROUND FE_DOWNWARD // expected-error{{'#pragma STDC FENV_ROUND' can only appear at file scope or at the start of a compound statement}}
+  // expected-warning@-1{{pragma STDC FENV_ROUND is not supported}}
+  return x + y;
+}
Index: clang/test/AST/ast-dump-fpfeatures.cpp
===
--- clang/test/AST/ast-dump-fpfeatures.cpp
+++ clang/test/AST/ast-dump-fpfeatures.cpp
@@ -34,4 +34,69 @@
 // CHECK-NEXT:   ParmVarDecl {{.*}} x 'float'
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT:   ReturnStmt
-// CHECK-NEXT: CallExpr {{.*}} FPContractMode=0
\ No newline at end of file
+// CHECK-NEXT: CallExpr {{.*}} FPContractMode=0
+
+
+
+
+#pragma STDC FENV_ROUND FE_DOWNWARD
+
+float func_10(float x, float y) {
+  return x + y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_10 'float (float, float)'
+// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=3
+
+float func_11(float x, float y) {
+  if (x < 0) {
+#pragma STDC FENV_ROUND FE_UPWARD
+return x + y;
+  }
+  return x - y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_11 'float (float, float)'
+// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=2
+// CHECK: BinaryOperator {{.*}} 'float' '-' RoundingMode=3
+
+
+#pragma STDC FENV_ROUND FE_DYNAMIC
+
+float func_12(float x, float y) {
+  return x + y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_12 'float (float, float)'
+// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=1
+
+#pragma STDC FENV_ROUND FE_TONEAREST
+
+float func_13(float x, float y) {
+  return x + y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_13 'float (float, float)'
+// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=1
+
+
+template 
+T func_14(T x, T y) {
+#pragma STDC FENV_ROUND FE_TOWARDZERO
+  return x + y;
+}
+
+float func_15(float x, float y) {
+#pragma STDC FPENV_ROUND FE_DOWNWARD
+  return func_14(x, y);
+}
+
+// CHECK-LABEL: FunctionTemplateDecl {{.*}} func_14
+// CHECK: FunctionDecl {{.*}} func_14 'T (T, T)'
+// CHECK:   CompoundStmt
+// CHECK-NEXT:ReturnStmt
+// CHECK-NEXT:  BinaryOperator {{.*}} '+' RoundingMode=0
+// CHECK: FunctionDecl {{.*}} func_14 'float (float, float)'
+// CHECK:   CompoundStmt
+// CHECK-NEXT:ReturnStmt
+// CHECK-NEXT:  BinaryOperator {{.*}} 'float' '+' RoundingMode=0
Index: clang/lib/Sema/SemaAttr.cpp
===
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -979,6 +979,11 @@
 }
 
 void Sema::setRoundingMode(SourceLocation Loc, llvm::RoundingMode FPR) {
+  // C2x: 7.6.2p3  If the FE_DYNAMIC mode is specified and FENV_ACCESS is "off",
+  // the translator may assume that the default rounding mode is in effect.
+  if (FPR == llvm::RoundingMode::Dynamic && !CurFPFeatures.getAllowFEnvAccess())
+FPR = llvm::RoundingMode::NearestTiesToEven;
+
   FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
   NewFPFeatures.setRoundingModeOverride(FPR);
   FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -783,6 +783,9 @@
   case tok::annot_pragma_fenv_access:
 HandlePragmaFEnvAccess();
 return nullptr;
+  case tok::annot_pragma_fenv_round:
+HandlePragmaFEnvRound();
+return nullptr;
   case tok::annot_pragma_float_control:
 HandlePragmaFloatControl();
 return nullptr;
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ 

[PATCH] D86921: [FPEnv] Partially implement #pragma STDC FENV_ROUND

2020-09-03 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86921/new/

https://reviews.llvm.org/D86921

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


[PATCH] D86921: [FPEnv] Partially implement #pragma STDC FENV_ROUND

2020-09-01 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff created this revision.
sepavloff added reviewers: rsmith, rjmccall, kpn, andrew.w.kaylor, steven_wu, 
mibintc, shafik.
Herald added a subscriber: dexonsmith.
Herald added a project: clang.
sepavloff requested review of this revision.

This change implements pragma STDC FENV_ROUND, which is introduced by
the extension to standard (TS 18661-1). The pragma is implemented only
in frontend, it sets apprpriate state of FPOptions stored in Sema. Use
of these bits in constant evaluation adn/or code generator is not in the
scope of this change.

Parser issues warning on unsuppored pragma when it encounteres pragma
STDC FENV_ROUND, however it makes syntax checks and updates Sema state
as if the pragma were supported.

Primary purpose of the partial implementation is to facilitate
development of non-default floating poin environment. Previously a
developer cannot set non-default rounding mode in sources, this mades
preparing tests for say constant evaluation  substantially complicated.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86921

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/AST/ast-dump-fpfeatures.cpp
  clang/test/Parser/pragma-fenv_round.c

Index: clang/test/Parser/pragma-fenv_round.c
===
--- /dev/null
+++ clang/test/Parser/pragma-fenv_round.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -Wignored-pragmas -verify %s
+
+#pragma STDC FENV_ROUND ON   // expected-warning {{invalid or unsupported rounding mode}}
+
+float func_01(int x, float y) {
+  if (x)
+return y + 2;
+  #pragma STDC FENV_ROUND FE_DOWNWARD // expected-error{{'#pragma STDC FENV_ROUND' can only appear at file scope or at the start of a compound statement}}
+  // expected-warning@-1{{pragma STDC FENV_ROUND is not supported}}
+  return x + y;
+}
Index: clang/test/AST/ast-dump-fpfeatures.cpp
===
--- clang/test/AST/ast-dump-fpfeatures.cpp
+++ clang/test/AST/ast-dump-fpfeatures.cpp
@@ -34,4 +34,69 @@
 // CHECK-NEXT:   ParmVarDecl {{.*}} x 'float'
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT:   ReturnStmt
-// CHECK-NEXT: CallExpr {{.*}} FPContractMode=0
\ No newline at end of file
+// CHECK-NEXT: CallExpr {{.*}} FPContractMode=0
+
+
+
+
+#pragma STDC FENV_ROUND FE_DOWNWARD
+
+float func_10(float x, float y) {
+  return x + y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_10 'float (float, float)'
+// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=3
+
+float func_11(float x, float y) {
+  if (x < 0) {
+#pragma STDC FENV_ROUND FE_UPWARD
+return x + y;
+  }
+  return x - y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_11 'float (float, float)'
+// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=2
+// CHECK: BinaryOperator {{.*}} 'float' '-' RoundingMode=3
+
+
+#pragma STDC FENV_ROUND FE_DYNAMIC
+
+float func_12(float x, float y) {
+  return x + y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_12 'float (float, float)'
+// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=1
+
+#pragma STDC FENV_ROUND FE_TONEAREST
+
+float func_13(float x, float y) {
+  return x + y;
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} func_13 'float (float, float)'
+// CHECK: BinaryOperator {{.*}} 'float' '+' RoundingMode=1
+
+
+template 
+T func_14(T x, T y) {
+#pragma STDC FENV_ROUND FE_TOWARDZERO
+  return x + y;
+}
+
+float func_15(float x, float y) {
+#pragma STDC FPENV_ROUND FE_DOWNWARD
+  return func_14(x, y);
+}
+
+// CHECK-LABEL: FunctionTemplateDecl {{.*}} func_14
+// CHECK: FunctionDecl {{.*}} func_14 'T (T, T)'
+// CHECK:   CompoundStmt
+// CHECK-NEXT:ReturnStmt
+// CHECK-NEXT:  BinaryOperator {{.*}} '+' RoundingMode=0
+// CHECK: FunctionDecl {{.*}} func_14 'float (float, float)'
+// CHECK:   CompoundStmt
+// CHECK-NEXT:ReturnStmt
+// CHECK-NEXT:  BinaryOperator {{.*}} 'float' '+' RoundingMode=0
Index: clang/lib/Sema/SemaAttr.cpp
===
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -979,6 +979,11 @@
 }
 
 void Sema::setRoundingMode(SourceLocation Loc, llvm::RoundingMode FPR) {
+  // C2x: 7.6.2p3  If the FE_DYNAMIC mode is specified and FENV_ACCESS is "off",
+  // the translator may assume that the default rounding mode is in effect.
+  if (FPR == llvm::RoundingMode::Dynamic && !CurFPFeatures.getAllowFEnvAccess())
+FPR = llvm::RoundingMode::NearestTiesToEven;
+
   FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
   NewFPFeatures.setRoundingModeOverride(FPR);