[PATCH] D86921: [FPEnv] Partially implement #pragma STDC FENV_ROUND
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
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
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);