[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/spavloff closed https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
spavloff wrote: > The changes should come with a release note so that users know about the > behavioral change, but otherwise LGTM. Pragma FENV_ROUND is still officially unsupported, compiler issues a warning about this. It is https://github.com/llvm/llvm-project/pull/89617 that makes FENV_ROUND supported, it requires release note. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/AaronBallman approved this pull request. The changes should come with a release note so that users know about the behavioral change, but otherwise LGTM. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
spavloff wrote: Are there any other comments? Can this PR be considered as approved? https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/jcranmer-intel commented: I'm generally happy with the testing and semantics at this point. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
@@ -79,3 +79,16 @@ float V7 = []() -> float { 0x0.01p0F); }(); // CHECK: @V7 = {{.*}} float 1.00e+00 + +template struct L { + constexpr L() : value(V) {} + float value; +}; + +#pragma STDC FENV_ROUND FE_DOWNWARD spavloff wrote: Explicit instantiation also should use the rounding mode at the point of definition. It is possible that the template is instantiated in two translation units and rounding mode is different at the points of instantiation. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/spavloff updated https://github.com/llvm/llvm-project/pull/90877 >From 5d906b537636ca0d8706a8a888dd78edfbec684f Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Thu, 2 May 2024 22:28:05 +0700 Subject: [PATCH 01/10] [clang] Use constant rounding mode for floating literals Conversion of floating-point literal to binary representation must be made using constant rounding mode, which can be changed using pragma FENV_ROUND. For example, the literal "0.1F" should be representes by either 0.09994 or 0.10001 depending on the rounding direction. --- clang/include/clang/Lex/LiteralSupport.h | 10 -- clang/lib/Lex/LiteralSupport.cpp | 6 +++--- clang/lib/Sema/SemaExpr.cpp | 3 ++- clang/test/AST/const-fpfeatures.c| 6 ++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 2ed42d1c5f9aae..705021fcfa5b11 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -118,12 +118,10 @@ class NumericLiteralParser { /// bits of the result and return true. Otherwise, return false. bool GetIntegerValue(llvm::APInt &Val); - /// GetFloatValue - Convert this numeric literal to a floating value, using - /// the specified APFloat fltSemantics (specifying float, double, etc). - /// The optional bool isExact (passed-by-reference) has its value - /// set to true if the returned APFloat can represent the number in the - /// literal exactly, and false otherwise. - llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result); + /// Convert this numeric literal to a floating value, using the specified + /// APFloat fltSemantics (specifying float, double, etc) and rounding mode. + llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM); /// GetFixedPointValue - Convert this numeric literal value into a /// scaled integer that represents this value. Returns true if an overflow diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 9c0cbea5052cb2..3df0391bdda772 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1520,7 +1520,8 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } llvm::APFloat::opStatus -NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { +NumericLiteralParser::GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM) { using llvm::APFloat; unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin); @@ -1534,8 +1535,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { Str = Buffer; } - auto StatusOrErr = - Result.convertFromString(Str, APFloat::rmNearestTiesToEven); + auto StatusOrErr = Result.convertFromString(Str, RM); assert(StatusOrErr && "Invalid floating point representation"); return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr : APFloat::opInvalidOp; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0cca02c338954a..db96c8692f2516 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3858,7 +3858,8 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, using llvm::APFloat; APFloat Val(Format); - APFloat::opStatus result = Literal.GetFloatValue(Val); + APFloat::opStatus result = + Literal.GetFloatValue(Val, S.CurFPFeatures.getRoundingMode()); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 6600ea27405d9c..247245c776fed1 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -19,6 +19,9 @@ float FI1u = 0xU; float _Complex C1u = C0; // CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 } +float FLu = 0.1F; +// CHECK: @FLu = {{.*}} float 0x3FB98000 + #pragma STDC FENV_ROUND FE_DOWNWARD @@ -35,3 +38,6 @@ float FI1d = 0xU; float _Complex C1d = C0; // CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 } + +float FLd = 0.1F; +// CHECK: @FLd = {{.*}} float 0x3FB9A000 >From a6fad25517b283c4b282324595d1e84f99717e16 Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Fri, 3 May 2024 13:45:36 +0700 Subject: [PATCH 02/10] Fix typo --- clang/test/AST/const-fpfeatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 247245c776fed1..276d46b70c21d9 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -20,7 +20,7 @@
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/spavloff updated https://github.com/llvm/llvm-project/pull/90877 >From 5d906b537636ca0d8706a8a888dd78edfbec684f Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Thu, 2 May 2024 22:28:05 +0700 Subject: [PATCH 1/8] [clang] Use constant rounding mode for floating literals Conversion of floating-point literal to binary representation must be made using constant rounding mode, which can be changed using pragma FENV_ROUND. For example, the literal "0.1F" should be representes by either 0.09994 or 0.10001 depending on the rounding direction. --- clang/include/clang/Lex/LiteralSupport.h | 10 -- clang/lib/Lex/LiteralSupport.cpp | 6 +++--- clang/lib/Sema/SemaExpr.cpp | 3 ++- clang/test/AST/const-fpfeatures.c| 6 ++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 2ed42d1c5f9aae..705021fcfa5b11 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -118,12 +118,10 @@ class NumericLiteralParser { /// bits of the result and return true. Otherwise, return false. bool GetIntegerValue(llvm::APInt &Val); - /// GetFloatValue - Convert this numeric literal to a floating value, using - /// the specified APFloat fltSemantics (specifying float, double, etc). - /// The optional bool isExact (passed-by-reference) has its value - /// set to true if the returned APFloat can represent the number in the - /// literal exactly, and false otherwise. - llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result); + /// Convert this numeric literal to a floating value, using the specified + /// APFloat fltSemantics (specifying float, double, etc) and rounding mode. + llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM); /// GetFixedPointValue - Convert this numeric literal value into a /// scaled integer that represents this value. Returns true if an overflow diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 9c0cbea5052cb2..3df0391bdda772 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1520,7 +1520,8 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } llvm::APFloat::opStatus -NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { +NumericLiteralParser::GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM) { using llvm::APFloat; unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin); @@ -1534,8 +1535,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { Str = Buffer; } - auto StatusOrErr = - Result.convertFromString(Str, APFloat::rmNearestTiesToEven); + auto StatusOrErr = Result.convertFromString(Str, RM); assert(StatusOrErr && "Invalid floating point representation"); return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr : APFloat::opInvalidOp; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0cca02c338954a..db96c8692f2516 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3858,7 +3858,8 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, using llvm::APFloat; APFloat Val(Format); - APFloat::opStatus result = Literal.GetFloatValue(Val); + APFloat::opStatus result = + Literal.GetFloatValue(Val, S.CurFPFeatures.getRoundingMode()); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 6600ea27405d9c..247245c776fed1 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -19,6 +19,9 @@ float FI1u = 0xU; float _Complex C1u = C0; // CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 } +float FLu = 0.1F; +// CHECK: @FLu = {{.*}} float 0x3FB98000 + #pragma STDC FENV_ROUND FE_DOWNWARD @@ -35,3 +38,6 @@ float FI1d = 0xU; float _Complex C1d = C0; // CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 } + +float FLd = 0.1F; +// CHECK: @FLd = {{.*}} float 0x3FB9A000 >From a6fad25517b283c4b282324595d1e84f99717e16 Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Fri, 3 May 2024 13:45:36 +0700 Subject: [PATCH 2/8] Fix typo --- clang/test/AST/const-fpfeatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 247245c776fed1..276d46b70c21d9 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -20,7 +20,7 @@ floa
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 1aeb64c8ec7b96b2301929d8a325a6e1d9ddaa2f cf6ff55ad4a45875a821b3ac82c22bb7917b4d67 -- clang/include/clang/Lex/LiteralSupport.h clang/lib/Lex/LiteralSupport.cpp clang/lib/Sema/SemaExpr.cpp clang/test/AST/const-fpfeatures.c clang/test/AST/const-fpfeatures.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index da107a6844..a344d1281e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3861,8 +3861,7 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, llvm::RoundingMode RM = S.CurFPFeatures.getRoundingMode(); if (RM == llvm::RoundingMode::Dynamic) RM = llvm::RoundingMode::NearestTiesToEven; - APFloat::opStatus result = - Literal.GetFloatValue(Val, RM); + APFloat::opStatus result = Literal.GetFloatValue(Val, RM); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). `` https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 1aeb64c8ec7b96b2301929d8a325a6e1d9ddaa2f aeb607513587924106081213335f73ba6eb0 -- clang/include/clang/Lex/LiteralSupport.h clang/lib/Lex/LiteralSupport.cpp clang/lib/Sema/SemaExpr.cpp clang/test/AST/const-fpfeatures.c clang/test/AST/const-fpfeatures.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index da107a6844..a344d1281e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3861,8 +3861,7 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, llvm::RoundingMode RM = S.CurFPFeatures.getRoundingMode(); if (RM == llvm::RoundingMode::Dynamic) RM = llvm::RoundingMode::NearestTiesToEven; - APFloat::opStatus result = - Literal.GetFloatValue(Val, RM); + APFloat::opStatus result = Literal.GetFloatValue(Val, RM); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). `` https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
@@ -79,3 +79,16 @@ float V7 = []() -> float { 0x0.01p0F); }(); // CHECK: @V7 = {{.*}} float 1.00e+00 + +template struct L { + constexpr L() : value(V) {} + float value; +}; + +#pragma STDC FENV_ROUND FE_DOWNWARD jcranmer-intel wrote: The interaction of these pragmas with C++ is underspecified, although for the most part, you can make pretty reasonable expectations about what the results should be. I'm also planning on bringing a paper to C++ to clarify the semantics somewhat, with the intent mostly being "just don't allow the pragma in most places." That said, templates do add in all sorts of fun extra complexity, and there are at least three scenarios worth testing (with regards to interpretation of constants within the template body): * Implicit template instantiation (you already test this) * Explicit template instantiation * Template specialization I can definitely agree that implicit template instantiation should inherit from the rounding mode of the definition. Template specialization probably *shouldn't* inherit from the original template definition. Explicit instantiation... I'm not sure? I can argue that one either way. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
jcranmer-intel wrote: I've been doing some testing, and I do want to confirm my understanding of the C standard here. >From what I can tell, macro expansion (phase 4) happens before constants are >parsed (phase 7). As a result, if you have code like this: ```c #define CONSTANT 0.1f ``` the interpretation of `0.1f` depends on the state of the pragma at point of use of the macro, not point of declaration of the macro. Given that pragmas can be defined with `_Pragma`, with lambdas or statement expressions (albeit neither of which is standard C), it should be possible to create a macro that evaluates a constant with a given rounding mode: ```c++ #define rendevous(x) _Pragma(#x) #define CONSTANT(RM, x) ([](){ rendevous(STDC FENV_ROUND RM); return x; })()) ``` This does seem to indeed be the behavior of the current implementation, but I would like to see some tests in the test code confirming that it's the macro use, not the `#define` that determines the interpretation of the constant, and another test for the `_Pragma` case. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/spavloff updated https://github.com/llvm/llvm-project/pull/90877 >From 5d906b537636ca0d8706a8a888dd78edfbec684f Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Thu, 2 May 2024 22:28:05 +0700 Subject: [PATCH 1/7] [clang] Use constant rounding mode for floating literals Conversion of floating-point literal to binary representation must be made using constant rounding mode, which can be changed using pragma FENV_ROUND. For example, the literal "0.1F" should be representes by either 0.09994 or 0.10001 depending on the rounding direction. --- clang/include/clang/Lex/LiteralSupport.h | 10 -- clang/lib/Lex/LiteralSupport.cpp | 6 +++--- clang/lib/Sema/SemaExpr.cpp | 3 ++- clang/test/AST/const-fpfeatures.c| 6 ++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 2ed42d1c5f9aae9..705021fcfa5b11b 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -118,12 +118,10 @@ class NumericLiteralParser { /// bits of the result and return true. Otherwise, return false. bool GetIntegerValue(llvm::APInt &Val); - /// GetFloatValue - Convert this numeric literal to a floating value, using - /// the specified APFloat fltSemantics (specifying float, double, etc). - /// The optional bool isExact (passed-by-reference) has its value - /// set to true if the returned APFloat can represent the number in the - /// literal exactly, and false otherwise. - llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result); + /// Convert this numeric literal to a floating value, using the specified + /// APFloat fltSemantics (specifying float, double, etc) and rounding mode. + llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM); /// GetFixedPointValue - Convert this numeric literal value into a /// scaled integer that represents this value. Returns true if an overflow diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 9c0cbea5052cb23..3df0391bdda772f 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1520,7 +1520,8 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } llvm::APFloat::opStatus -NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { +NumericLiteralParser::GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM) { using llvm::APFloat; unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin); @@ -1534,8 +1535,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { Str = Buffer; } - auto StatusOrErr = - Result.convertFromString(Str, APFloat::rmNearestTiesToEven); + auto StatusOrErr = Result.convertFromString(Str, RM); assert(StatusOrErr && "Invalid floating point representation"); return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr : APFloat::opInvalidOp; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0cca02c338954a1..db96c8692f2516f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3858,7 +3858,8 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, using llvm::APFloat; APFloat Val(Format); - APFloat::opStatus result = Literal.GetFloatValue(Val); + APFloat::opStatus result = + Literal.GetFloatValue(Val, S.CurFPFeatures.getRoundingMode()); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 6600ea27405d9c8..247245c776fed17 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -19,6 +19,9 @@ float FI1u = 0xU; float _Complex C1u = C0; // CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 } +float FLu = 0.1F; +// CHECK: @FLu = {{.*}} float 0x3FB98000 + #pragma STDC FENV_ROUND FE_DOWNWARD @@ -35,3 +38,6 @@ float FI1d = 0xU; float _Complex C1d = C0; // CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 } + +float FLd = 0.1F; +// CHECK: @FLd = {{.*}} float 0x3FB9A000 >From a6fad25517b283c4b282324595d1e84f99717e16 Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Fri, 3 May 2024 13:45:36 +0700 Subject: [PATCH 2/7] Fix typo --- clang/test/AST/const-fpfeatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 247245c776fed17..276d46b70c21d93 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -20,7 +20
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
@@ -79,3 +79,16 @@ float V7 = []() -> float { 0x0.01p0F); }(); // CHECK: @V7 = {{.*}} float 1.00e+00 + +template struct L { + constexpr L() : value(V) {} + float value; +}; + +#pragma STDC FENV_ROUND FE_DOWNWARD erichkeane wrote: >Does this test address your concern: >https://github.com/spavloff/llvm-project/blob/aeb607513587924106081213335f73ba6eb0/clang/test/AST/ast-dump-fpfeatures.cpp#L124-L143 > ? That one does not. I'm more looking for: ``` template void foo(){} #pragma STDC FENV_ROUND FE_DOWNWARD foo(); #pragma STDC FENV_ROUND FE_UPWARD foo(); ``` Then confirming that there are two separate instantiations of `foo`. >>All instantiations of a function template use the rounding mode specified in >>the template definition. Otherwise we would have bad things like two >>instantiations in different translation units that use different rounding >>modes. Right, that was very much my concern, the ODR implications of that are scary. So jsut the 1 test above, and I think _I_ am good about this, though having @jcranmer-intel and/or @zahiraam review would also be appreciated. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
@@ -79,3 +79,16 @@ float V7 = []() -> float { 0x0.01p0F); }(); // CHECK: @V7 = {{.*}} float 1.00e+00 + +template struct L { + constexpr L() : value(V) {} + float value; +}; + +#pragma STDC FENV_ROUND FE_DOWNWARD spavloff wrote: > Does the FENV_ROUND exclusively change the behavior of literals? I thought it > messed with math as well? Of course, FENV_ROUND affects any math, but this patch fixes misbehavior of literals only. And the note was about different expectation. Assignment isn't an operation that depends on rounding mode, but changing the snippet to such: ``` template void foo() { #pragma STDC FENV_ROUND FE_DOWNWARD T Val = V + 1; } ``` would make use of the rounding mode. In this case the addition in `foo` would be evaluated using rounding down, but the literal is converted to AST object using rounding up. > I'm more concerned about a case where the point-of-instantiation and the > template have different rounding modes. Does this test address your concern: https://github.com/spavloff/llvm-project/blob/aeb607513587924106081213335f73ba6eb0/clang/test/AST/ast-dump-fpfeatures.cpp#L124-L143 ? > One thing to ensure: can we have an AST test (like your 'foo' example) that > shows that they are different instantiations? Are there any cases where we > could get two instantiation-requests spelled differently, but because of > different rounding modes, are the same instantiation? All instantiations of a function template use the rounding mode specified in the template definition. Otherwise we would have bad things like two instantiations in different translation units that use different rounding modes. The rounding mode is attached to AST nodes in the AST representation for function templates, tests in `AST/ast-dump-fpfeatures.cpp` check this property. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
@@ -79,3 +79,16 @@ float V7 = []() -> float { 0x0.01p0F); }(); // CHECK: @V7 = {{.*}} float 1.00e+00 + +template struct L { + constexpr L() : value(V) {} + float value; +}; + +#pragma STDC FENV_ROUND FE_DOWNWARD erichkeane wrote: > In this snippet `Val` in `foo()` should be `float > 0x3FB9A000` (rounded upward), because the literal `0.1F` is in the > region, where `#pragma STDC FENV_ROUND FE_UPDWARD` is in effect. The body of > `foo` does not contain literals. Hmm... ok, then the feature isn't quite what I expected it was. Does the `FENV_ROUND` exclusively change the behavior of literals? I thought it messed with math as well? (I thought it was on assignment, but perhaps not!). I'm more concerned about a case where the point-of-instantiation and the template have different rounding modes. But I see this patch is exclusively for literals, so we can let that go. One thing to ensure: can we have an AST test (like your 'foo' example) that shows that they are different instantiations? Are there any cases where we could get two instantiation-requests spelled differently, but because of different rounding modes, are the same instantiation? https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
@@ -79,3 +79,16 @@ float V7 = []() -> float { 0x0.01p0F); }(); // CHECK: @V7 = {{.*}} float 1.00e+00 + +template struct L { + constexpr L() : value(V) {} + float value; +}; + +#pragma STDC FENV_ROUND FE_DOWNWARD spavloff wrote: In this snippet `Val` in `foo()` should be `float 0x3FB9A000` (rounded upward), because the literal `0.1F` is in the region, where `#pragma STDC FENV_ROUND FE_UPDWARD` is in effect. The body of `foo` does not contain literals. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
@@ -79,3 +79,16 @@ float V7 = []() -> float { 0x0.01p0F); }(); // CHECK: @V7 = {{.*}} float 1.00e+00 + +template struct L { + constexpr L() : value(V) {} + float value; +}; + +#pragma STDC FENV_ROUND FE_DOWNWARD erichkeane wrote: Ah, I see that github ate the first line of my comment, see above, i'v eedited it. https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/spavloff updated https://github.com/llvm/llvm-project/pull/90877 >From 5d906b537636ca0d8706a8a888dd78edfbec684f Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Thu, 2 May 2024 22:28:05 +0700 Subject: [PATCH 1/5] [clang] Use constant rounding mode for floating literals Conversion of floating-point literal to binary representation must be made using constant rounding mode, which can be changed using pragma FENV_ROUND. For example, the literal "0.1F" should be representes by either 0.09994 or 0.10001 depending on the rounding direction. --- clang/include/clang/Lex/LiteralSupport.h | 10 -- clang/lib/Lex/LiteralSupport.cpp | 6 +++--- clang/lib/Sema/SemaExpr.cpp | 3 ++- clang/test/AST/const-fpfeatures.c| 6 ++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 2ed42d1c5f9aae..705021fcfa5b11 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -118,12 +118,10 @@ class NumericLiteralParser { /// bits of the result and return true. Otherwise, return false. bool GetIntegerValue(llvm::APInt &Val); - /// GetFloatValue - Convert this numeric literal to a floating value, using - /// the specified APFloat fltSemantics (specifying float, double, etc). - /// The optional bool isExact (passed-by-reference) has its value - /// set to true if the returned APFloat can represent the number in the - /// literal exactly, and false otherwise. - llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result); + /// Convert this numeric literal to a floating value, using the specified + /// APFloat fltSemantics (specifying float, double, etc) and rounding mode. + llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM); /// GetFixedPointValue - Convert this numeric literal value into a /// scaled integer that represents this value. Returns true if an overflow diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 9c0cbea5052cb2..3df0391bdda772 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1520,7 +1520,8 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } llvm::APFloat::opStatus -NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { +NumericLiteralParser::GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM) { using llvm::APFloat; unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin); @@ -1534,8 +1535,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { Str = Buffer; } - auto StatusOrErr = - Result.convertFromString(Str, APFloat::rmNearestTiesToEven); + auto StatusOrErr = Result.convertFromString(Str, RM); assert(StatusOrErr && "Invalid floating point representation"); return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr : APFloat::opInvalidOp; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0cca02c338954a..db96c8692f2516 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3858,7 +3858,8 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, using llvm::APFloat; APFloat Val(Format); - APFloat::opStatus result = Literal.GetFloatValue(Val); + APFloat::opStatus result = + Literal.GetFloatValue(Val, S.CurFPFeatures.getRoundingMode()); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 6600ea27405d9c..247245c776fed1 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -19,6 +19,9 @@ float FI1u = 0xU; float _Complex C1u = C0; // CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 } +float FLu = 0.1F; +// CHECK: @FLu = {{.*}} float 0x3FB98000 + #pragma STDC FENV_ROUND FE_DOWNWARD @@ -35,3 +38,6 @@ float FI1d = 0xU; float _Complex C1d = C0; // CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 } + +float FLd = 0.1F; +// CHECK: @FLd = {{.*}} float 0x3FB9A000 >From a6fad25517b283c4b282324595d1e84f99717e16 Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Fri, 3 May 2024 13:45:36 +0700 Subject: [PATCH 2/5] Fix typo --- clang/test/AST/const-fpfeatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 247245c776fed1..276d46b70c21d9 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -20,7 +20,7 @@ floa
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
@@ -79,3 +79,16 @@ float V7 = []() -> float { 0x0.01p0F); }(); // CHECK: @V7 = {{.*}} float 1.00e+00 + +template struct L { + constexpr L() : value(V) {} + float value; +}; + +#pragma STDC FENV_ROUND FE_DOWNWARD erichkeane wrote: I meant something like: ``` template void foo() { #pragma STDC FENV_ROUND FE_DOWNWARD T Val = V; // Should be: { float 0x3FB98000 } } #pragma STDC FENV_ROUND FE_UPDWARD foo(); https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/spavloff updated https://github.com/llvm/llvm-project/pull/90877 >From 5d906b537636ca0d8706a8a888dd78edfbec684f Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Thu, 2 May 2024 22:28:05 +0700 Subject: [PATCH 1/4] [clang] Use constant rounding mode for floating literals Conversion of floating-point literal to binary representation must be made using constant rounding mode, which can be changed using pragma FENV_ROUND. For example, the literal "0.1F" should be representes by either 0.09994 or 0.10001 depending on the rounding direction. --- clang/include/clang/Lex/LiteralSupport.h | 10 -- clang/lib/Lex/LiteralSupport.cpp | 6 +++--- clang/lib/Sema/SemaExpr.cpp | 3 ++- clang/test/AST/const-fpfeatures.c| 6 ++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 2ed42d1c5f9aae..705021fcfa5b11 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -118,12 +118,10 @@ class NumericLiteralParser { /// bits of the result and return true. Otherwise, return false. bool GetIntegerValue(llvm::APInt &Val); - /// GetFloatValue - Convert this numeric literal to a floating value, using - /// the specified APFloat fltSemantics (specifying float, double, etc). - /// The optional bool isExact (passed-by-reference) has its value - /// set to true if the returned APFloat can represent the number in the - /// literal exactly, and false otherwise. - llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result); + /// Convert this numeric literal to a floating value, using the specified + /// APFloat fltSemantics (specifying float, double, etc) and rounding mode. + llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM); /// GetFixedPointValue - Convert this numeric literal value into a /// scaled integer that represents this value. Returns true if an overflow diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 9c0cbea5052cb2..3df0391bdda772 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1520,7 +1520,8 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } llvm::APFloat::opStatus -NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { +NumericLiteralParser::GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM) { using llvm::APFloat; unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin); @@ -1534,8 +1535,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { Str = Buffer; } - auto StatusOrErr = - Result.convertFromString(Str, APFloat::rmNearestTiesToEven); + auto StatusOrErr = Result.convertFromString(Str, RM); assert(StatusOrErr && "Invalid floating point representation"); return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr : APFloat::opInvalidOp; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0cca02c338954a..db96c8692f2516 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3858,7 +3858,8 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, using llvm::APFloat; APFloat Val(Format); - APFloat::opStatus result = Literal.GetFloatValue(Val); + APFloat::opStatus result = + Literal.GetFloatValue(Val, S.CurFPFeatures.getRoundingMode()); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 6600ea27405d9c..247245c776fed1 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -19,6 +19,9 @@ float FI1u = 0xU; float _Complex C1u = C0; // CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 } +float FLu = 0.1F; +// CHECK: @FLu = {{.*}} float 0x3FB98000 + #pragma STDC FENV_ROUND FE_DOWNWARD @@ -35,3 +38,6 @@ float FI1d = 0xU; float _Complex C1d = C0; // CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 } + +float FLd = 0.1F; +// CHECK: @FLd = {{.*}} float 0x3FB9A000 >From a6fad25517b283c4b282324595d1e84f99717e16 Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Fri, 3 May 2024 13:45:36 +0700 Subject: [PATCH 2/4] Fix typo --- clang/test/AST/const-fpfeatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 247245c776fed1..276d46b70c21d9 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -20,7 +20,7 @@ floa
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/spavloff updated https://github.com/llvm/llvm-project/pull/90877 >From 5d906b537636ca0d8706a8a888dd78edfbec684f Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Thu, 2 May 2024 22:28:05 +0700 Subject: [PATCH 1/2] [clang] Use constant rounding mode for floating literals Conversion of floating-point literal to binary representation must be made using constant rounding mode, which can be changed using pragma FENV_ROUND. For example, the literal "0.1F" should be representes by either 0.09994 or 0.10001 depending on the rounding direction. --- clang/include/clang/Lex/LiteralSupport.h | 10 -- clang/lib/Lex/LiteralSupport.cpp | 6 +++--- clang/lib/Sema/SemaExpr.cpp | 3 ++- clang/test/AST/const-fpfeatures.c| 6 ++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 2ed42d1c5f9aae..705021fcfa5b11 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -118,12 +118,10 @@ class NumericLiteralParser { /// bits of the result and return true. Otherwise, return false. bool GetIntegerValue(llvm::APInt &Val); - /// GetFloatValue - Convert this numeric literal to a floating value, using - /// the specified APFloat fltSemantics (specifying float, double, etc). - /// The optional bool isExact (passed-by-reference) has its value - /// set to true if the returned APFloat can represent the number in the - /// literal exactly, and false otherwise. - llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result); + /// Convert this numeric literal to a floating value, using the specified + /// APFloat fltSemantics (specifying float, double, etc) and rounding mode. + llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM); /// GetFixedPointValue - Convert this numeric literal value into a /// scaled integer that represents this value. Returns true if an overflow diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 9c0cbea5052cb2..3df0391bdda772 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1520,7 +1520,8 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } llvm::APFloat::opStatus -NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { +NumericLiteralParser::GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM) { using llvm::APFloat; unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin); @@ -1534,8 +1535,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { Str = Buffer; } - auto StatusOrErr = - Result.convertFromString(Str, APFloat::rmNearestTiesToEven); + auto StatusOrErr = Result.convertFromString(Str, RM); assert(StatusOrErr && "Invalid floating point representation"); return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr : APFloat::opInvalidOp; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0cca02c338954a..db96c8692f2516 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3858,7 +3858,8 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, using llvm::APFloat; APFloat Val(Format); - APFloat::opStatus result = Literal.GetFloatValue(Val); + APFloat::opStatus result = + Literal.GetFloatValue(Val, S.CurFPFeatures.getRoundingMode()); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 6600ea27405d9c..247245c776fed1 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -19,6 +19,9 @@ float FI1u = 0xU; float _Complex C1u = C0; // CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 } +float FLu = 0.1F; +// CHECK: @FLu = {{.*}} float 0x3FB98000 + #pragma STDC FENV_ROUND FE_DOWNWARD @@ -35,3 +38,6 @@ float FI1d = 0xU; float _Complex C1d = C0; // CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 } + +float FLd = 0.1F; +// CHECK: @FLd = {{.*}} float 0x3FB9A000 >From a6fad25517b283c4b282324595d1e84f99717e16 Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Fri, 3 May 2024 13:45:36 +0700 Subject: [PATCH 2/2] Fix typo --- clang/test/AST/const-fpfeatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 247245c776fed1..276d46b70c21d9 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -20,7 +20,7 @@ floa
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
erichkeane wrote: Also, test failures are related to this patch! https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
@@ -3858,7 +3858,8 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, using llvm::APFloat; APFloat Val(Format); - APFloat::opStatus result = Literal.GetFloatValue(Val); + APFloat::opStatus result = erichkeane wrote: Does this work right in templates? Can we get a test that validates that a NTTP or Dependent value where the rounding mode is set either around or inside the function does the math right? https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/erichkeane commented: probably needs a release note https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Serge Pavlov (spavloff) Changes Conversion of floating-point literal to binary representation must be made using constant rounding mode, which can be changed using pragma FENV_ROUND. For example, the literal "0.1F" should be representes by either 0.09994 or 0.10001 depending on the rounding direction. --- Full diff: https://github.com/llvm/llvm-project/pull/90877.diff 4 Files Affected: - (modified) clang/include/clang/Lex/LiteralSupport.h (+4-6) - (modified) clang/lib/Lex/LiteralSupport.cpp (+3-3) - (modified) clang/lib/Sema/SemaExpr.cpp (+2-1) - (modified) clang/test/AST/const-fpfeatures.c (+6) ``diff diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 2ed42d1c5f9aae..705021fcfa5b11 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -118,12 +118,10 @@ class NumericLiteralParser { /// bits of the result and return true. Otherwise, return false. bool GetIntegerValue(llvm::APInt &Val); - /// GetFloatValue - Convert this numeric literal to a floating value, using - /// the specified APFloat fltSemantics (specifying float, double, etc). - /// The optional bool isExact (passed-by-reference) has its value - /// set to true if the returned APFloat can represent the number in the - /// literal exactly, and false otherwise. - llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result); + /// Convert this numeric literal to a floating value, using the specified + /// APFloat fltSemantics (specifying float, double, etc) and rounding mode. + llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM); /// GetFixedPointValue - Convert this numeric literal value into a /// scaled integer that represents this value. Returns true if an overflow diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 9c0cbea5052cb2..3df0391bdda772 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1520,7 +1520,8 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } llvm::APFloat::opStatus -NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { +NumericLiteralParser::GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM) { using llvm::APFloat; unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin); @@ -1534,8 +1535,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { Str = Buffer; } - auto StatusOrErr = - Result.convertFromString(Str, APFloat::rmNearestTiesToEven); + auto StatusOrErr = Result.convertFromString(Str, RM); assert(StatusOrErr && "Invalid floating point representation"); return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr : APFloat::opInvalidOp; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0cca02c338954a..db96c8692f2516 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3858,7 +3858,8 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, using llvm::APFloat; APFloat Val(Format); - APFloat::opStatus result = Literal.GetFloatValue(Val); + APFloat::opStatus result = + Literal.GetFloatValue(Val, S.CurFPFeatures.getRoundingMode()); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 6600ea27405d9c..247245c776fed1 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -19,6 +19,9 @@ float FI1u = 0xU; float _Complex C1u = C0; // CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 } +float FLu = 0.1F; +// CHECK: @FLu = {{.*}} float 0x3FB98000 + #pragma STDC FENV_ROUND FE_DOWNWARD @@ -35,3 +38,6 @@ float FI1d = 0xU; float _Complex C1d = C0; // CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 } + +float FLd = 0.1F; +// CHECK: @FLd = {{.*}} float 0x3FB9A000 `` https://github.com/llvm/llvm-project/pull/90877 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use constant rounding mode for floating literals (PR #90877)
https://github.com/spavloff created https://github.com/llvm/llvm-project/pull/90877 Conversion of floating-point literal to binary representation must be made using constant rounding mode, which can be changed using pragma FENV_ROUND. For example, the literal "0.1F" should be representes by either 0.09994 or 0.10001 depending on the rounding direction. >From 5d906b537636ca0d8706a8a888dd78edfbec684f Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Thu, 2 May 2024 22:28:05 +0700 Subject: [PATCH] [clang] Use constant rounding mode for floating literals Conversion of floating-point literal to binary representation must be made using constant rounding mode, which can be changed using pragma FENV_ROUND. For example, the literal "0.1F" should be representes by either 0.09994 or 0.10001 depending on the rounding direction. --- clang/include/clang/Lex/LiteralSupport.h | 10 -- clang/lib/Lex/LiteralSupport.cpp | 6 +++--- clang/lib/Sema/SemaExpr.cpp | 3 ++- clang/test/AST/const-fpfeatures.c| 6 ++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 2ed42d1c5f9aae..705021fcfa5b11 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -118,12 +118,10 @@ class NumericLiteralParser { /// bits of the result and return true. Otherwise, return false. bool GetIntegerValue(llvm::APInt &Val); - /// GetFloatValue - Convert this numeric literal to a floating value, using - /// the specified APFloat fltSemantics (specifying float, double, etc). - /// The optional bool isExact (passed-by-reference) has its value - /// set to true if the returned APFloat can represent the number in the - /// literal exactly, and false otherwise. - llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result); + /// Convert this numeric literal to a floating value, using the specified + /// APFloat fltSemantics (specifying float, double, etc) and rounding mode. + llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM); /// GetFixedPointValue - Convert this numeric literal value into a /// scaled integer that represents this value. Returns true if an overflow diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 9c0cbea5052cb2..3df0391bdda772 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1520,7 +1520,8 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } llvm::APFloat::opStatus -NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { +NumericLiteralParser::GetFloatValue(llvm::APFloat &Result, +llvm::RoundingMode RM) { using llvm::APFloat; unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin); @@ -1534,8 +1535,7 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { Str = Buffer; } - auto StatusOrErr = - Result.convertFromString(Str, APFloat::rmNearestTiesToEven); + auto StatusOrErr = Result.convertFromString(Str, RM); assert(StatusOrErr && "Invalid floating point representation"); return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr : APFloat::opInvalidOp; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0cca02c338954a..db96c8692f2516 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3858,7 +3858,8 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, using llvm::APFloat; APFloat Val(Format); - APFloat::opStatus result = Literal.GetFloatValue(Val); + APFloat::opStatus result = + Literal.GetFloatValue(Val, S.CurFPFeatures.getRoundingMode()); // Overflow is always an error, but underflow is only an error if // we underflowed to zero (APFloat reports denormals as underflow). diff --git a/clang/test/AST/const-fpfeatures.c b/clang/test/AST/const-fpfeatures.c index 6600ea27405d9c..247245c776fed1 100644 --- a/clang/test/AST/const-fpfeatures.c +++ b/clang/test/AST/const-fpfeatures.c @@ -19,6 +19,9 @@ float FI1u = 0xU; float _Complex C1u = C0; // CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 } +float FLu = 0.1F; +// CHECK: @FLu = {{.*}} float 0x3FB98000 + #pragma STDC FENV_ROUND FE_DOWNWARD @@ -35,3 +38,6 @@ float FI1d = 0xU; float _Complex C1d = C0; // CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 } + +float FLd = 0.1F; +// CHECK: @FLd = {{.*}} float 0x3FB9A000 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits