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();
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();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits