[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-10-09 Thread Joao Moreira via Phabricator via cfe-commits
joaomoreira added a comment.

I noticed that this commit breaks MUSL 1.2.0. Here is an isolated test-case 
that illustrates the issue:

https://godbolt.org/z/6bdnEh


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


Re: [PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-29 Thread Serge Pavlov via cfe-commits
The change https://reviews.llvm.org/rG4e4f926e83cf removes the problematic
test.
Sorry for troubles.

Thanks,
--Serge


On Wed, Sep 30, 2020 at 2:55 AM Petr Hosek via Phabricator <
revi...@reviews.llvm.org> wrote:

> phosek added a comment.
>
> In D87822#2301293 , @sepavloff
> wrote:
>
> > In D87822#2301194 ,
> @leonardchan wrote:
> >
> >> Thanks for looking into it. We have that commit but it still seems to be
> >> failing for us with the same error.
> >
> > In D88498  this test is removed
> because use of rounding mode changed. So you could just remove this test to
> fix the bot.
>
> Can we revert this change and reland it later with the fix? It's been 3
> days now and our bots are still red.
>
>
> Repository:
>   rG LLVM Github Monorepo
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D87822/new/
>
> https://reviews.llvm.org/D87822
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-29 Thread Petr Hosek via Phabricator via cfe-commits
phosek added a comment.

In D87822#2301293 , @sepavloff wrote:

> In D87822#2301194 , @leonardchan 
> wrote:
>
>> Thanks for looking into it. We have that commit but it still seems to be
>> failing for us with the same error.
>
> In D88498  this test is removed because use 
> of rounding mode changed. So you could just remove this test to fix the bot.

Can we revert this change and reland it later with the fix? It's been 3 days 
now and our bots are still red.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-29 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff added a comment.

In D87822#2301194 , @leonardchan wrote:

> Thanks for looking into it. We have that commit but it still seems to be
> failing for us with the same error.

In D88498  this test is removed because use of 
rounding mode changed. So you could just remove this test to fix the bot.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-29 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

Commented in that review, but that patch has the wrong fix: it's based on the 
targets LLVM is configured with rather than the current test target.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


Re: [PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-29 Thread Leonard Chan via cfe-commits
Thanks for looking into it. We have that commit but it still seems to be
failing for us with the same error.

On Tue, Sep 29, 2020 at 12:58 AM Serge Pavlov  wrote:

> Hi!
>
> This issue must be fixed by: https://reviews.llvm.org/rGf91b9c0f9858
> Do you have recent changes from the trunk?
>
> Thanks,
> --Serge
>
>
> On Tue, Sep 29, 2020 at 4:22 AM Leonard Chan via Phabricator <
> revi...@reviews.llvm.org> wrote:
>
>> leonardchan added a comment.
>>
>> Hi! It looks like this is causing a test failure on our aach64 builders (
>> https://luci-milo.appspot.com/p/fuchsia/builders/ci/clang-linux-arm64/b8868095822628984976?
>> ):
>>
>>   [1113/1114] Running the Clang regression tests
>>   llvm-lit:
>> /b/s/w/ir/k/staging/llvm_build/bin/../../../llvm-project/llvm/utils/lit/lit/llvm/config.py:379:
>> note: using clang: /b/s/w/ir/k/staging/llvm_build/bin/clang
>>   -- Testing: 26708 tests, 256 workers --
>>   Testing:
>>   FAIL: Clang :: AST/const-fpfeatures-diag.c (269 of 26708)
>>    TEST 'Clang :: AST/const-fpfeatures-diag.c' FAILED
>> 
>>   Script:
>>   --
>>   : 'RUN: at line 1';   /b/s/w/ir/k/staging/llvm_build/bin/clang -cc1
>> -internal-isystem /b/s/w/ir/k/staging/llvm_build/lib/clang/12.0.0/include
>> -nostdsysteminc -verify -ffp-exception-behavior=strict -Wno-unknown-pragmas
>> /b/s/w/ir/k/llvm-project/clang/test/AST/const-fpfeatures-diag.c
>>   --
>>   Exit Code: 1
>>
>>   Command Output (stderr):
>>   --
>>   error: 'error' diagnostics expected but not seen:
>> File /b/s/w/ir/k/llvm-project/clang/test/AST/const-fpfeatures-diag.c
>> Line 8: initializer element is not a compile-time constant
>>   error: 'warning' diagnostics seen but not expected:
>> (frontend): overriding currently unsupported use of floating point
>> exceptions on this target
>>   2 errors generated.
>>
>>   --
>>
>>   
>>   Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
>>   
>>   Failed Tests (1):
>> Clang :: AST/const-fpfeatures-diag.c
>>
>> Would you mind taking a look and sending out a fix? Thanks.
>>
>>
>> Repository:
>>   rG LLVM Github Monorepo
>>
>> CHANGES SINCE LAST ACTION
>>   https://reviews.llvm.org/D87822/new/
>>
>> https://reviews.llvm.org/D87822
>>
>>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-29 Thread Serge Pavlov via cfe-commits
Hi!

This issue must be fixed by: https://reviews.llvm.org/rGf91b9c0f9858
Do you have recent changes from the trunk?

Thanks,
--Serge


On Tue, Sep 29, 2020 at 4:22 AM Leonard Chan via Phabricator <
revi...@reviews.llvm.org> wrote:

> leonardchan added a comment.
>
> Hi! It looks like this is causing a test failure on our aach64 builders (
> https://luci-milo.appspot.com/p/fuchsia/builders/ci/clang-linux-arm64/b8868095822628984976?
> ):
>
>   [1113/1114] Running the Clang regression tests
>   llvm-lit:
> /b/s/w/ir/k/staging/llvm_build/bin/../../../llvm-project/llvm/utils/lit/lit/llvm/config.py:379:
> note: using clang: /b/s/w/ir/k/staging/llvm_build/bin/clang
>   -- Testing: 26708 tests, 256 workers --
>   Testing:
>   FAIL: Clang :: AST/const-fpfeatures-diag.c (269 of 26708)
>    TEST 'Clang :: AST/const-fpfeatures-diag.c' FAILED
> 
>   Script:
>   --
>   : 'RUN: at line 1';   /b/s/w/ir/k/staging/llvm_build/bin/clang -cc1
> -internal-isystem /b/s/w/ir/k/staging/llvm_build/lib/clang/12.0.0/include
> -nostdsysteminc -verify -ffp-exception-behavior=strict -Wno-unknown-pragmas
> /b/s/w/ir/k/llvm-project/clang/test/AST/const-fpfeatures-diag.c
>   --
>   Exit Code: 1
>
>   Command Output (stderr):
>   --
>   error: 'error' diagnostics expected but not seen:
> File /b/s/w/ir/k/llvm-project/clang/test/AST/const-fpfeatures-diag.c
> Line 8: initializer element is not a compile-time constant
>   error: 'warning' diagnostics seen but not expected:
> (frontend): overriding currently unsupported use of floating point
> exceptions on this target
>   2 errors generated.
>
>   --
>
>   
>   Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
>   
>   Failed Tests (1):
> Clang :: AST/const-fpfeatures-diag.c
>
> Would you mind taking a look and sending out a fix? Thanks.
>
>
> Repository:
>   rG LLVM Github Monorepo
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D87822/new/
>
> https://reviews.llvm.org/D87822
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-28 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added a comment.

Hi! It looks like this is causing a test failure on our aach64 builders 
(https://luci-milo.appspot.com/p/fuchsia/builders/ci/clang-linux-arm64/b8868095822628984976?):

  [1113/1114] Running the Clang regression tests
  llvm-lit: 
/b/s/w/ir/k/staging/llvm_build/bin/../../../llvm-project/llvm/utils/lit/lit/llvm/config.py:379:
 note: using clang: /b/s/w/ir/k/staging/llvm_build/bin/clang
  -- Testing: 26708 tests, 256 workers --
  Testing: 
  FAIL: Clang :: AST/const-fpfeatures-diag.c (269 of 26708)
   TEST 'Clang :: AST/const-fpfeatures-diag.c' FAILED 

  Script:
  --
  : 'RUN: at line 1';   /b/s/w/ir/k/staging/llvm_build/bin/clang -cc1 
-internal-isystem /b/s/w/ir/k/staging/llvm_build/lib/clang/12.0.0/include 
-nostdsysteminc -verify -ffp-exception-behavior=strict -Wno-unknown-pragmas 
/b/s/w/ir/k/llvm-project/clang/test/AST/const-fpfeatures-diag.c
  --
  Exit Code: 1
  
  Command Output (stderr):
  --
  error: 'error' diagnostics expected but not seen: 
File /b/s/w/ir/k/llvm-project/clang/test/AST/const-fpfeatures-diag.c Line 
8: initializer element is not a compile-time constant
  error: 'warning' diagnostics seen but not expected: 
(frontend): overriding currently unsupported use of floating point 
exceptions on this target
  2 errors generated.
  
  --
  
  
  Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
  
  Failed Tests (1):
Clang :: AST/const-fpfeatures-diag.c

Would you mind taking a look and sending out a fix? Thanks.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-26 Thread Serge Pavlov via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6314f412a83d: [FPEnv] Evaluate constant expressions under 
non-default rounding modes (authored by sepavloff).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/AST/const-fpfeatures-diag.c
  clang/test/AST/const-fpfeatures.c
  clang/test/AST/const-fpfeatures.cpp

Index: clang/test/AST/const-fpfeatures.cpp
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -S -emit-llvm -triple i386-linux -std=c++2a -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+// nextUp(1.F) == 0x1.02p0F
+
+constexpr float add_round_down(float x, float y) {
+  #pragma STDC FENV_ROUND FE_DOWNWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+constexpr float add_round_up(float x, float y) {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+float V1 = add_round_down(1.0F, 0x0.01p0F);
+float V2 = add_round_up(1.0F, 0x0.01p0F);
+// CHECK: @V1 = {{.*}} float 1.00e+00
+// CHECK: @V2 = {{.*}} float 0x3FF02000
+
+constexpr float add_cast_round_down(float x, double y) {
+  #pragma STDC FENV_ROUND FE_DOWNWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+constexpr float add_cast_round_up(float x, double y) {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+float V3 = add_cast_round_down(1.0F, 0x0.01p0F);
+float V4 = add_cast_round_up(1.0F, 0x0.01p0F);
+
+// CHECK: @V3 = {{.*}} float 1.00e+00
+// CHECK: @V4 = {{.*}} float 0x3FF02000
+
+// The next three variables use the same function as initializer, only rounding
+// modes differ.
+
+float V5 = []() -> float {
+  return [](float x, float y)->float {
+#pragma STDC FENV_ROUND FE_UPWARD
+return x + y;
+  }([](float x, float y) -> float {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  return x + y;
+}(1.0F, 0x0.01p0F),
+  0x0.01p0F);
+}();
+// CHECK: @V5 = {{.*}} float 0x3FF04000
+
+float V6 = []() -> float {
+  return [](float x, float y)->float {
+#pragma STDC FENV_ROUND FE_DOWNWARD
+return x + y;
+  }([](float x, float y) -> float {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  return x + y;
+}(1.0F, 0x0.01p0F),
+  0x0.01p0F);
+}();
+// CHECK: @V6 = {{.*}} float 0x3FF02000
+
+float V7 = []() -> float {
+  return [](float x, float y)->float {
+#pragma STDC FENV_ROUND FE_DOWNWARD
+return x + y;
+  }([](float x, float y) -> float {
+  #pragma STDC FENV_ROUND FE_DOWNWARD
+  return x + y;
+}(1.0F, 0x0.01p0F),
+  0x0.01p0F);
+}();
+// CHECK: @V7 = {{.*}} float 1.00e+00
Index: clang/test/AST/const-fpfeatures.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -S -emit-llvm -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+// nextUp(1.F) == 0x1.02p0F
+
+const double _Complex C0 = 0x1.01p0 + 0x1.01p0I;
+
+#pragma STDC FENV_ROUND FE_UPWARD
+
+float F1u = 1.0F + 0x0.02p0F;
+float F2u = 1.0F + 0x0.01p0F;
+float F3u = 0x1.01p0;
+// CHECK: @F1u = {{.*}} float 0x3FF02000
+// CHECK: @F2u = {{.*}} float 0x3FF02000
+// CHECK: @F3u = {{.*}} float 0x3FF02000
+
+float _Complex C1u = C0;
+// CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 }
+
+
+#pragma STDC FENV_ROUND FE_DOWNWARD
+
+float F1d = 1.0F + 0x0.02p0F;
+float F2d = 1.0F + 0x0.01p0F;
+float F3d = 0x1.01p0;
+
+// CHECK: @F1d = {{.*}} float 0x3FF02000
+// CHECK: @F2d = {{.*}} float 1.00e+00
+// CHECK: @F3d = {{.*}} float 1.00e+00
+
+float _Complex C1d = C0;
+// CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 }
Index: clang/test/AST/const-fpfeatures-diag.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures-diag.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify -ffp-exception-behavior=strict -Wno-unknown-pragmas %s
+
+#pragma STDC FENV_ROUND FE_DYNAMIC
+
+// nextUp(1.F) == 0x1.02p0F
+
+float F1 = 0x1.00p0F + 0x0.02p0F;
+float F2 = 0x1.00p0F + 0x0.01p0F; // expected-error{{initializer element is not a compile-time constant}}
Index: clang/lib/Sema/SemaAttr.cpp
===
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -981,7 +981,9 @@
 void Sema::setRoundingMode(SourceLocation Loc

[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-24 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:2438
+/// Check if the given evaluation result is allowed for constant evaluation.
+static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E,
+ APFloat::opStatus St) {

mibintc wrote:
> If the result is this false, shall this routine create a Note diag explaining 
> the false result? 
It makes sense. Added respective diagnostics.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-24 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff updated this revision to Diff 294230.
sepavloff added a comment.

Added diagnostic message


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/AST/const-fpfeatures-diag.c
  clang/test/AST/const-fpfeatures.c
  clang/test/AST/const-fpfeatures.cpp

Index: clang/test/AST/const-fpfeatures.cpp
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -S -emit-llvm -triple i386-linux -std=c++2a -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+// nextUp(1.F) == 0x1.02p0F
+
+constexpr float add_round_down(float x, float y) {
+  #pragma STDC FENV_ROUND FE_DOWNWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+constexpr float add_round_up(float x, float y) {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+float V1 = add_round_down(1.0F, 0x0.01p0F);
+float V2 = add_round_up(1.0F, 0x0.01p0F);
+// CHECK: @V1 = {{.*}} float 1.00e+00
+// CHECK: @V2 = {{.*}} float 0x3FF02000
+
+constexpr float add_cast_round_down(float x, double y) {
+  #pragma STDC FENV_ROUND FE_DOWNWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+constexpr float add_cast_round_up(float x, double y) {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+float V3 = add_cast_round_down(1.0F, 0x0.01p0F);
+float V4 = add_cast_round_up(1.0F, 0x0.01p0F);
+
+// CHECK: @V3 = {{.*}} float 1.00e+00
+// CHECK: @V4 = {{.*}} float 0x3FF02000
+
+// The next three variables use the same function as initializer, only rounding
+// modes differ.
+
+float V5 = []() -> float {
+  return [](float x, float y)->float {
+#pragma STDC FENV_ROUND FE_UPWARD
+return x + y;
+  }([](float x, float y) -> float {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  return x + y;
+}(1.0F, 0x0.01p0F),
+  0x0.01p0F);
+}();
+// CHECK: @V5 = {{.*}} float 0x3FF04000
+
+float V6 = []() -> float {
+  return [](float x, float y)->float {
+#pragma STDC FENV_ROUND FE_DOWNWARD
+return x + y;
+  }([](float x, float y) -> float {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  return x + y;
+}(1.0F, 0x0.01p0F),
+  0x0.01p0F);
+}();
+// CHECK: @V6 = {{.*}} float 0x3FF02000
+
+float V7 = []() -> float {
+  return [](float x, float y)->float {
+#pragma STDC FENV_ROUND FE_DOWNWARD
+return x + y;
+  }([](float x, float y) -> float {
+  #pragma STDC FENV_ROUND FE_DOWNWARD
+  return x + y;
+}(1.0F, 0x0.01p0F),
+  0x0.01p0F);
+}();
+// CHECK: @V7 = {{.*}} float 1.00e+00
Index: clang/test/AST/const-fpfeatures.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -S -emit-llvm -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+// nextUp(1.F) == 0x1.02p0F
+
+const double _Complex C0 = 0x1.01p0 + 0x1.01p0I;
+
+#pragma STDC FENV_ROUND FE_UPWARD
+
+float F1u = 1.0F + 0x0.02p0F;
+float F2u = 1.0F + 0x0.01p0F;
+float F3u = 0x1.01p0;
+// CHECK: @F1u = {{.*}} float 0x3FF02000
+// CHECK: @F2u = {{.*}} float 0x3FF02000
+// CHECK: @F3u = {{.*}} float 0x3FF02000
+
+float _Complex C1u = C0;
+// CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 }
+
+
+#pragma STDC FENV_ROUND FE_DOWNWARD
+
+float F1d = 1.0F + 0x0.02p0F;
+float F2d = 1.0F + 0x0.01p0F;
+float F3d = 0x1.01p0;
+
+// CHECK: @F1d = {{.*}} float 0x3FF02000
+// CHECK: @F2d = {{.*}} float 1.00e+00
+// CHECK: @F3d = {{.*}} float 1.00e+00
+
+float _Complex C1d = C0;
+// CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 }
Index: clang/test/AST/const-fpfeatures-diag.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures-diag.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify -ffp-exception-behavior=strict -Wno-unknown-pragmas %s
+
+#pragma STDC FENV_ROUND FE_DYNAMIC
+
+// nextUp(1.F) == 0x1.02p0F
+
+float F1 = 0x1.00p0F + 0x0.02p0F;
+float F2 = 0x1.00p0F + 0x0.01p0F; // expected-error{{initializer element is not a compile-time constant}}
Index: clang/lib/Sema/SemaAttr.cpp
===
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -981,7 +981,9 @@
 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

[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-24 Thread Melanie Blower via Phabricator via cfe-commits
mibintc added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:2438
+/// Check if the given evaluation result is allowed for constant evaluation.
+static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E,
+ APFloat::opStatus St) {

If the result is this false, shall this routine create a Note diag explaining 
the false result? 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-24 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/lib/AST/ExprConstant.cpp:2427
+FPOptions FPFeatures = Cast->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+RM = FPFeatures.getRoundingMode();
+  }

sepavloff wrote:
> rjmccall wrote:
> > sepavloff wrote:
> > > rjmccall wrote:
> > > > I think the options really need to be passed in or else correctness is 
> > > > somewhat doomed here.
> > > > 
> > > > For example, the call to CompoundAssignSubobjectHandler needs to 
> > > > propagate this down from the operator expression.
> > > It is guaranteed by the way AST is built, no?
> > > 
> > > As FP options may be changed only by pragmas and the pragmas can be 
> > > specified only at file or block level, all sub-expression are evaluated 
> > > at the same options.
> > Yes, but you can't actually reliably recover those settings from E unless 
> > you're sure E is one of a few kinds of expression.  The concern is that E 
> > might end up being some closely-related expression that isn't actually the 
> > expression that carries the current settings, and then we'll fall back on 
> > using the global defaults.  It's much more correct-by-construction to pass 
> > the settings down from the caller based on the caller's static knowledge of 
> > which expression is under consideration, and I think you'll see that that's 
> > pretty straightforward in practice.
> This is a peculiarity of `CompoundAssignOperator`, which itself makes 
> conversion, without `CastExpr`. I added `assert` to ensure that other nodes 
> cannot appear here. Also some tests with conversion in 
> `CompoundAssignOperator` were added.
Alright, well, I don't understand the reluctance to pass this down, but I won't 
insist.  LGTM.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-24 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:2427
+FPOptions FPFeatures = Cast->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+RM = FPFeatures.getRoundingMode();
+  }

rjmccall wrote:
> sepavloff wrote:
> > rjmccall wrote:
> > > I think the options really need to be passed in or else correctness is 
> > > somewhat doomed here.
> > > 
> > > For example, the call to CompoundAssignSubobjectHandler needs to 
> > > propagate this down from the operator expression.
> > It is guaranteed by the way AST is built, no?
> > 
> > As FP options may be changed only by pragmas and the pragmas can be 
> > specified only at file or block level, all sub-expression are evaluated at 
> > the same options.
> Yes, but you can't actually reliably recover those settings from E unless 
> you're sure E is one of a few kinds of expression.  The concern is that E 
> might end up being some closely-related expression that isn't actually the 
> expression that carries the current settings, and then we'll fall back on 
> using the global defaults.  It's much more correct-by-construction to pass 
> the settings down from the caller based on the caller's static knowledge of 
> which expression is under consideration, and I think you'll see that that's 
> pretty straightforward in practice.
This is a peculiarity of `CompoundAssignOperator`, which itself makes 
conversion, without `CastExpr`. I added `assert` to ensure that other nodes 
cannot appear here. Also some tests with conversion in `CompoundAssignOperator` 
were added.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-24 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff updated this revision to Diff 293974.
sepavloff marked an inline comment as done.
sepavloff added a comment.

Updated patch

- improved Expr::getFPFeaturesInEffect,
- added tests for _Complex,
- added tests for constexpr,
- added chech in HandleFloatToFloatCast,
- implemented printing FPOptions in CompoundAssignOperator.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

Files:
  clang/include/clang/AST/Expr.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/AST/const-fpfeatures-diag.c
  clang/test/AST/const-fpfeatures.c
  clang/test/AST/const-fpfeatures.cpp

Index: clang/test/AST/const-fpfeatures.cpp
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -S -emit-llvm -triple i386-linux -std=c++2a -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+// nextUp(1.F) == 0x1.02p0F
+
+constexpr float add_round_down(float x, float y) {
+  #pragma STDC FENV_ROUND FE_DOWNWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+constexpr float add_round_up(float x, float y) {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+float V1 = add_round_down(1.0F, 0x0.01p0F);
+float V2 = add_round_up(1.0F, 0x0.01p0F);
+// CHECK: @V1 = {{.*}} float 1.00e+00
+// CHECK: @V2 = {{.*}} float 0x3FF02000
+
+constexpr float add_cast_round_down(float x, double y) {
+  #pragma STDC FENV_ROUND FE_DOWNWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+constexpr float add_cast_round_up(float x, double y) {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  float res = x;
+  res += y;
+  return res;
+}
+
+float V3 = add_cast_round_down(1.0F, 0x0.01p0F);
+float V4 = add_cast_round_up(1.0F, 0x0.01p0F);
+
+// CHECK: @V3 = {{.*}} float 1.00e+00
+// CHECK: @V4 = {{.*}} float 0x3FF02000
+
+// The next three variables use the same function as initializer, only rounding
+// modes differ.
+
+float V5 = []() -> float {
+  return [](float x, float y)->float {
+#pragma STDC FENV_ROUND FE_UPWARD
+return x + y;
+  }([](float x, float y) -> float {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  return x + y;
+}(1.0F, 0x0.01p0F),
+  0x0.01p0F);
+}();
+// CHECK: @V5 = {{.*}} float 0x3FF04000
+
+float V6 = []() -> float {
+  return [](float x, float y)->float {
+#pragma STDC FENV_ROUND FE_DOWNWARD
+return x + y;
+  }([](float x, float y) -> float {
+  #pragma STDC FENV_ROUND FE_UPWARD
+  return x + y;
+}(1.0F, 0x0.01p0F),
+  0x0.01p0F);
+}();
+// CHECK: @V6 = {{.*}} float 0x3FF02000
+
+float V7 = []() -> float {
+  return [](float x, float y)->float {
+#pragma STDC FENV_ROUND FE_DOWNWARD
+return x + y;
+  }([](float x, float y) -> float {
+  #pragma STDC FENV_ROUND FE_DOWNWARD
+  return x + y;
+}(1.0F, 0x0.01p0F),
+  0x0.01p0F);
+}();
+// CHECK: @V7 = {{.*}} float 1.00e+00
Index: clang/test/AST/const-fpfeatures.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -S -emit-llvm -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+// nextUp(1.F) == 0x1.02p0F
+
+const double _Complex C0 = 0x1.01p0 + 0x1.01p0I;
+
+#pragma STDC FENV_ROUND FE_UPWARD
+
+float F1u = 1.0F + 0x0.02p0F;
+float F2u = 1.0F + 0x0.01p0F;
+float F3u = 0x1.01p0;
+// CHECK: @F1u = {{.*}} float 0x3FF02000
+// CHECK: @F2u = {{.*}} float 0x3FF02000
+// CHECK: @F3u = {{.*}} float 0x3FF02000
+
+float _Complex C1u = C0;
+// CHECK: @C1u = {{.*}} { float, float } { float 0x3FF02000, float 0x3FF02000 }
+
+
+#pragma STDC FENV_ROUND FE_DOWNWARD
+
+float F1d = 1.0F + 0x0.02p0F;
+float F2d = 1.0F + 0x0.01p0F;
+float F3d = 0x1.01p0;
+
+// CHECK: @F1d = {{.*}} float 0x3FF02000
+// CHECK: @F2d = {{.*}} float 1.00e+00
+// CHECK: @F3d = {{.*}} float 1.00e+00
+
+float _Complex C1d = C0;
+// CHECK: @C1d = {{.*}} { float, float } { float 1.00e+00, float 1.00e+00 }
Index: clang/test/AST/const-fpfeatures-diag.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures-diag.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify -ffp-exception-behavior=strict -Wno-unknown-pragmas %s
+
+#pragma STDC FENV_ROUND FE_DYNAMIC
+
+// nextUp(1.F) == 0x1.02p0F
+
+float F1 = 0x1.00p0F + 0x0.02p0F;
+float F2 = 0x1.00p0F + 0x0.01p0F; // expected-error{{initializer element is not a compile-time constant}}
Index: clang/lib/Sema/SemaAttr.cpp
===
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -981,7 +981,9 @@
 void Sema::setRoundin

[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-18 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:2462
+  return true;
+}
+

Thanks, these look good.



Comment at: clang/lib/AST/ExprConstant.cpp:2427
+FPOptions FPFeatures = Cast->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+RM = FPFeatures.getRoundingMode();
+  }

sepavloff wrote:
> rjmccall wrote:
> > I think the options really need to be passed in or else correctness is 
> > somewhat doomed here.
> > 
> > For example, the call to CompoundAssignSubobjectHandler needs to propagate 
> > this down from the operator expression.
> It is guaranteed by the way AST is built, no?
> 
> As FP options may be changed only by pragmas and the pragmas can be specified 
> only at file or block level, all sub-expression are evaluated at the same 
> options.
Yes, but you can't actually reliably recover those settings from E unless 
you're sure E is one of a few kinds of expression.  The concern is that E might 
end up being some closely-related expression that isn't actually the expression 
that carries the current settings, and then we'll fall back on using the global 
defaults.  It's much more correct-by-construction to pass the settings down 
from the caller based on the caller's static knowledge of which expression is 
under consideration, and I think you'll see that that's pretty straightforward 
in practice.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-18 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff marked an inline comment as done.
sepavloff added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:2427
+FPOptions FPFeatures = Cast->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+RM = FPFeatures.getRoundingMode();
+  }

rjmccall wrote:
> I think the options really need to be passed in or else correctness is 
> somewhat doomed here.
> 
> For example, the call to CompoundAssignSubobjectHandler needs to propagate 
> this down from the operator expression.
It is guaranteed by the way AST is built, no?

As FP options may be changed only by pragmas and the pragmas can be specified 
only at file or block level, all sub-expression are evaluated at the same 
options.



Comment at: clang/lib/AST/ExprConstant.cpp:2678
+// operation. If the result is exact, it does not depend on rounding mode.
+RM = llvm::RoundingMode::NearestTiesToEven;
+  APFloat::opStatus St;

rjmccall wrote:
> Feels like you should have a helper function like 
> `getActiveRoundingMode(Info, FPFeatures)`
It required implementation of statically polymorphic method 
`Expr::getFPFeaturesInEffect` but finally code looks better.



Comment at: clang/lib/AST/ExprConstant.cpp:2712
+  //   initializer,
+  // the evaluation probably need to be rejected.
+

rjmccall wrote:
> Is this processing something you can extract meaningfully into a common 
> function that works with an opStatus, so that you can just write `if 
> (!checkFloatingPointFailure(Info, E, status, fpFeatures)) return false;` in 
> all these places?
Good idea, thank you. I used a bit different name to have positive semantics.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-18 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff updated this revision to Diff 292841.
sepavloff added a comment.

Updated patch


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

Files:
  clang/include/clang/AST/Expr.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/AST/const-fpfeatures-diag.c
  clang/test/AST/const-fpfeatures.c

Index: clang/test/AST/const-fpfeatures.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -S -emit-llvm -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+// nextUp(1.F) == 0x1.02p0F
+
+#pragma STDC FENV_ROUND FE_UPWARD
+
+float F1u = 1.0F + 0x0.02p0F;
+float F2u = 1.0F + 0x0.01p0F;
+float F3u = 0x1.01p0;
+// CHECK: @F1u = {{.*}} float 0x3FF02000
+// CHECK: @F2u = {{.*}} float 0x3FF02000
+// CHECK: @F3u = {{.*}} float 0x3FF02000
+
+#pragma STDC FENV_ROUND FE_DOWNWARD
+
+float F1d = 1.0F + 0x0.02p0F;
+float F2d = 1.0F + 0x0.01p0F;
+float F3d = 0x1.01p0;
+
+// CHECK: @F1d = {{.*}} float 0x3FF02000
+// CHECK: @F2d = {{.*}} float 1.00e+00
+// CHECK: @F3d = {{.*}} float 1.00e+00
Index: clang/test/AST/const-fpfeatures-diag.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures-diag.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify -ffp-exception-behavior=strict -Wno-unknown-pragmas %s
+
+#pragma STDC FENV_ROUND FE_DYNAMIC
+
+// nextUp(1.F) == 0x1.02p0F
+
+float F1 = 0x1.00p0F + 0x0.02p0F;
+float F2 = 0x1.00p0F + 0x0.01p0F; // expected-error{{initializer element is not a compile-time constant}}
Index: clang/lib/Sema/SemaAttr.cpp
===
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -981,7 +981,9 @@
 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())
+  if (FPR == llvm::RoundingMode::Dynamic &&
+  !CurFPFeatures.getAllowFEnvAccess() &&
+  CurFPFeatures.getFPExceptionMode() == LangOptions::FPE_Ignore)
 FPR = llvm::RoundingMode::NearestTiesToEven;
 
   FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -2418,14 +2418,59 @@
   return true;
 }
 
+/// Get rounding mode used for evaluation of the specified expression.
+/// \param[out] DynamicRM Is set to true is the requested rounding mode is
+///   dynamic.
+/// If rounding mode is unknown at compile time, still try to evaluate the
+/// expression. If the result is exact, it does not depend on rounding mode.
+/// So return "tonearest" mode instead of "dynamic".
+static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E,
+bool &DynamicRM) {
+  llvm::RoundingMode RM =
+  E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
+  DynamicRM = (RM == llvm::RoundingMode::Dynamic);
+  if (DynamicRM)
+RM = llvm::RoundingMode::NearestTiesToEven;
+  return RM;
+}
+
+/// Check if the given evaluation result is allowed for constant evaluation.
+static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E,
+ APFloat::opStatus St) {
+  FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+  if ((St & APFloat::opInexact) &&
+  FPO.getRoundingMode() == llvm::RoundingMode::Dynamic) {
+// Inexact result means that it depends on rounding mode. If the requested
+// mode is dynamic, the evaluation cannot be made in compile time.
+Info.FFDiag(E);
+return false;
+  }
+
+  if (St & APFloat::opStatus::opInvalidOp) {
+// There is no usefully definable result.
+Info.FFDiag(E);
+return false;
+  }
+
+  // FIXME: if:
+  // - evaluation triggered other FP exception, and
+  // - exception mode is not "ignore", and
+  // - the expression being evaluated is not a part of global variable
+  //   initializer,
+  // the evaluation probably need to be rejected.
+  return true;
+}
+
 static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E,
QualType SrcType, QualType DestType,
APFloat &Result) {
+  bool DynamicRM;
+  llvm::RoundingMode RM = getActiveRoundingMode(Info, E, DynamicRM);
+  APFloat::opStatus St;
   APFloat Value = Result;
   bool ignored;
-  Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
- A

[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-17 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:2427
+FPOptions FPFeatures = Cast->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+RM = FPFeatures.getRoundingMode();
+  }

I think the options really need to be passed in or else correctness is somewhat 
doomed here.

For example, the call to CompoundAssignSubobjectHandler needs to propagate this 
down from the operator expression.



Comment at: clang/lib/AST/ExprConstant.cpp:2678
+// operation. If the result is exact, it does not depend on rounding mode.
+RM = llvm::RoundingMode::NearestTiesToEven;
+  APFloat::opStatus St;

Feels like you should have a helper function like `getActiveRoundingMode(Info, 
FPFeatures)`



Comment at: clang/lib/AST/ExprConstant.cpp:2712
+  //   initializer,
+  // the evaluation probably need to be rejected.
+

Is this processing something you can extract meaningfully into a common 
function that works with an opStatus, so that you can just write `if 
(!checkFloatingPointFailure(Info, E, status, fpFeatures)) return false;` in all 
these places?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87822

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


[PATCH] D87822: [FPEnv] Evaluate constant expressions under non-default rounding modes

2020-09-17 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff created this revision.
sepavloff added reviewers: rsmith, rjmccall, mibintc, kpn.
Herald added a project: clang.
sepavloff requested review of this revision.

The change implements evaluation of constant floating point expressions
under non-default rounding modes. The main objective was to support
evaluation of global variable initializers, where constant rounding mode
may be specified by `#pragma STDC FENV_ROUND`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D87822

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/test/AST/const-fpfeatures-diag.c
  clang/test/AST/const-fpfeatures.c

Index: clang/test/AST/const-fpfeatures.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -S -emit-llvm -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+// nextUp(1.F) == 0x1.02p0F
+
+#pragma STDC FENV_ROUND FE_UPWARD
+
+float F1u = 1.0F + 0x0.02p0F;
+float F2u = 1.0F + 0x0.01p0F;
+float F3u = 0x1.01p0;
+// CHECK: @F1u = {{.*}} float 0x3FF02000
+// CHECK: @F2u = {{.*}} float 0x3FF02000
+// CHECK: @F3u = {{.*}} float 0x3FF02000
+
+#pragma STDC FENV_ROUND FE_DOWNWARD
+
+float F1d = 1.0F + 0x0.02p0F;
+float F2d = 1.0F + 0x0.01p0F;
+float F3d = 0x1.01p0;
+
+// CHECK: @F1d = {{.*}} float 0x3FF02000
+// CHECK: @F2d = {{.*}} float 1.00e+00
+// CHECK: @F3d = {{.*}} float 1.00e+00
Index: clang/test/AST/const-fpfeatures-diag.c
===
--- /dev/null
+++ clang/test/AST/const-fpfeatures-diag.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify -ffp-exception-behavior=strict -Wno-unknown-pragmas %s
+
+#pragma STDC FENV_ROUND FE_DYNAMIC
+
+// nextUp(1.F) == 0x1.02p0F
+
+float F1 = 0x1.00p0F + 0x0.02p0F;
+float F2 = 0x1.00p0F + 0x0.01p0F; // expected-error{{initializer element is not a compile-time constant}}
Index: clang/lib/Sema/SemaAttr.cpp
===
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -981,7 +981,9 @@
 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())
+  if (FPR == llvm::RoundingMode::Dynamic &&
+  !CurFPFeatures.getAllowFEnvAccess() &&
+  CurFPFeatures.getFPExceptionMode() == LangOptions::FPE_Ignore)
 FPR = llvm::RoundingMode::NearestTiesToEven;
 
   FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -2421,10 +2421,29 @@
 static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E,
QualType SrcType, QualType DestType,
APFloat &Result) {
+  llvm::RoundingMode RM = llvm::RoundingMode::NearestTiesToEven;
+  if (auto Cast = dyn_cast(E)) {
+FPOptions FPFeatures = Cast->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+RM = FPFeatures.getRoundingMode();
+  }
+  bool DynamicRM = RM == llvm::RoundingMode::Dynamic;
+  if (DynamicRM)
+// If rounding mode is unknown at compile time, still try to execute the
+// operation. If the result is exact, it does not depend on rounding mode.
+RM = llvm::RoundingMode::NearestTiesToEven;
+
+  APFloat::opStatus St;
   APFloat Value = Result;
   bool ignored;
-  Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
- APFloat::rmNearestTiesToEven, &ignored);
+  St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
+
+  // FIXME: if:
+  // - evaluation triggered some FP exception, and
+  // - exception mode is not "ignore", and
+  // - the expression being evaluated is not a part of global variable
+  //   initializer,
+  // the evaluation probably need to be rejected.
+
   return true;
 }
 
@@ -2647,31 +2666,51 @@
 }
 
 /// Perform the given binary floating-point operation, in-place, on LHS.
-static bool handleFloatFloatBinOp(EvalInfo &Info, const Expr *E,
+static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E,
   APFloat &LHS, BinaryOperatorKind Opcode,
   const APFloat &RHS) {
+  FPOptions FPFeatures = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+  llvm::RoundingMode RM = FPFeatures.getRoundingMode();
+  bool DynamicRM = RM == llvm::RoundingMode::Dynamic;
+  if (DynamicRM)
+// If rounding mode is unknown at compile time, still try to execute the
+// operation. If the result is exact, it does not depend on rounding mode.
+RM = llvm::Ro