[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
https://github.com/jcranmer-intel approved this pull request. https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
https://github.com/AaronBallman edited https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
https://github.com/AaronBallman approved this pull request. Changes LGTM unless @jcranmer-intel still has concerns. https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
tbaederr wrote: > Out of curiosity, why are they not using `__builtin_complex` as requested? I started out replacing a lot of those expressions with `__builtin_complex` but ended up just creating a variable for it so the lines don't get too unwieldy. But then I naturally just used an initlist instead of `__builtin_complex`. https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/90588 >From 4bcba4c08be471e8cf6fb52842f9a73e3c45639d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Tue, 30 Apr 2024 12:25:20 +0200 Subject: [PATCH] [clang] Report erroneous floating point results in _Complex math Use handleFloatFloatBinOp to properly diagnose NaN results and divisions by zero. --- clang/lib/AST/ExprConstant.cpp | 27 +--- clang/test/SemaCXX/complex-folding.cpp | 61 ++ 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f1aa19e4409e1..86fb396fabe2d 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -15209,11 +15209,21 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat = Result.getComplexFloatImag(); if (LHSReal) { assert(!RHSReal && "Cannot have two real operands for a complex op!"); -ResR = A * C; -ResI = A * D; +ResR = A; +ResI = A; +// ResR = A * C; +// ResI = A * D; +if (!handleFloatFloatBinOp(Info, E, ResR, BO_Mul, C) || +!handleFloatFloatBinOp(Info, E, ResI, BO_Mul, D)) + return false; } else if (RHSReal) { -ResR = C * A; -ResI = C * B; +// ResR = C * A; +// ResI = C * B; +ResR = C; +ResI = C; +if (!handleFloatFloatBinOp(Info, E, ResR, BO_Mul, A) || +!handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B)) + return false; } else { // In the fully general case, we need to handle NaNs and infinities // robustly. @@ -15289,8 +15299,13 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat = Result.getComplexFloatReal(); APFloat = Result.getComplexFloatImag(); if (RHSReal) { -ResR = A / C; -ResI = B / C; +ResR = A; +ResI = B; +// ResR = A / C; +// ResI = B / C; +if (!handleFloatFloatBinOp(Info, E, ResR, BO_Div, C) || +!handleFloatFloatBinOp(Info, E, ResI, BO_Div, C)) + return false; } else { if (LHSReal) { // No real optimizations we can do here, stub out with zero. diff --git a/clang/test/SemaCXX/complex-folding.cpp b/clang/test/SemaCXX/complex-folding.cpp index 054f159e9ce0d..7bfd36f156ea6 100644 --- a/clang/test/SemaCXX/complex-folding.cpp +++ b/clang/test/SemaCXX/complex-folding.cpp @@ -59,41 +59,48 @@ static_assert((1.25 / (0.25 - 0.75j)) == (0.5 + 1.5j)); // Test that infinities are preserved, don't turn into NaNs, and do form zeros // when the divisor. +constexpr _Complex float InfC = {1.0, __builtin_inf()}; +constexpr _Complex float InfInf = __builtin_inf() + InfC; +static_assert(__real__(InfInf) == __builtin_inf()); +static_assert(__imag__(InfInf) == __builtin_inf()); +static_assert(__builtin_isnan(__real__(InfInf * InfInf))); +static_assert(__builtin_isinf_sign(__imag__(InfInf * InfInf)) == 1); + static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * 1.0)) == 1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * 1.0)) == 1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) * 1.0)) == 1); static_assert(__builtin_isinf_sign(__real__(1.0 * (__builtin_inf() + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + __builtin_inf() * 1.0j))) == 1); - +static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + InfC))) == 1); static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (1.0 + 1.0j))) == 1); static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (__builtin_inf() + 1.0j))) == 1); static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (__builtin_inf() + 1.0j))) == 1); - -static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == 1); - -static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + __builtin_inf() * 1.0j) * (__builtin_inf() + __builtin_inf() * 1.0j))) == -1); - +static_assert(__builtin_isinf_sign(__real__((1.0 + InfC) * (1.0 + 1.0j))) == -1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) * (1.0 + 1.0j))) == 1); +static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + InfC))) == -1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + InfC))) == 1); +static_assert(__builtin_isinf_sign(__real__((1.0 +
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/90588 >From 4d121c1cdca78378a3200353071c9ff460e0fcbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Tue, 30 Apr 2024 12:25:20 +0200 Subject: [PATCH] [clang][Interp] Report erroneous floating point results in _Complex math Use handleFloatFloatBinOp to properly diagnose NaN results and divisions by zero. --- clang/lib/AST/ExprConstant.cpp | 27 +--- clang/test/SemaCXX/complex-folding.cpp | 61 ++ 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f1aa19e4409e1..86fb396fabe2d 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -15209,11 +15209,21 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat = Result.getComplexFloatImag(); if (LHSReal) { assert(!RHSReal && "Cannot have two real operands for a complex op!"); -ResR = A * C; -ResI = A * D; +ResR = A; +ResI = A; +// ResR = A * C; +// ResI = A * D; +if (!handleFloatFloatBinOp(Info, E, ResR, BO_Mul, C) || +!handleFloatFloatBinOp(Info, E, ResI, BO_Mul, D)) + return false; } else if (RHSReal) { -ResR = C * A; -ResI = C * B; +// ResR = C * A; +// ResI = C * B; +ResR = C; +ResI = C; +if (!handleFloatFloatBinOp(Info, E, ResR, BO_Mul, A) || +!handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B)) + return false; } else { // In the fully general case, we need to handle NaNs and infinities // robustly. @@ -15289,8 +15299,13 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat = Result.getComplexFloatReal(); APFloat = Result.getComplexFloatImag(); if (RHSReal) { -ResR = A / C; -ResI = B / C; +ResR = A; +ResI = B; +// ResR = A / C; +// ResI = B / C; +if (!handleFloatFloatBinOp(Info, E, ResR, BO_Div, C) || +!handleFloatFloatBinOp(Info, E, ResI, BO_Div, C)) + return false; } else { if (LHSReal) { // No real optimizations we can do here, stub out with zero. diff --git a/clang/test/SemaCXX/complex-folding.cpp b/clang/test/SemaCXX/complex-folding.cpp index 054f159e9ce0d..7bfd36f156ea6 100644 --- a/clang/test/SemaCXX/complex-folding.cpp +++ b/clang/test/SemaCXX/complex-folding.cpp @@ -59,41 +59,48 @@ static_assert((1.25 / (0.25 - 0.75j)) == (0.5 + 1.5j)); // Test that infinities are preserved, don't turn into NaNs, and do form zeros // when the divisor. +constexpr _Complex float InfC = {1.0, __builtin_inf()}; +constexpr _Complex float InfInf = __builtin_inf() + InfC; +static_assert(__real__(InfInf) == __builtin_inf()); +static_assert(__imag__(InfInf) == __builtin_inf()); +static_assert(__builtin_isnan(__real__(InfInf * InfInf))); +static_assert(__builtin_isinf_sign(__imag__(InfInf * InfInf)) == 1); + static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * 1.0)) == 1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * 1.0)) == 1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) * 1.0)) == 1); static_assert(__builtin_isinf_sign(__real__(1.0 * (__builtin_inf() + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + __builtin_inf() * 1.0j))) == 1); - +static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + InfC))) == 1); static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (1.0 + 1.0j))) == 1); static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (__builtin_inf() + 1.0j))) == 1); static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (__builtin_inf() + 1.0j))) == 1); - -static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == 1); - -static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + __builtin_inf() * 1.0j) * (__builtin_inf() + __builtin_inf() * 1.0j))) == -1); - +static_assert(__builtin_isinf_sign(__real__((1.0 + InfC) * (1.0 + 1.0j))) == -1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) * (1.0 + 1.0j))) == 1); +static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + InfC))) == -1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + InfC))) == 1);
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
https://github.com/jcranmer-intel commented: After banging my head on the desk trying to figure out why the tests were giving such strange results, I realized the issue... Could you please use `__builtin_complex` in the test to construct the complex infinities instead of `__builtin_infinity() * 1.0j`? https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
tbaederr wrote: Ping @jcranmer-intel, @hubert-reinterpretcast https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
AaronBallman wrote: The changes seem reasonable to me, but I'd like to hear from @jcranmer-intel and/or @hubert-reinterpretcast in terms of whether they agree with this direction. https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
https://github.com/tbaederr edited https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang]Report erroneous floating point results in _Complex math (PR #90588)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) Changes Use handleFloatFloatBinOp to properly diagnose NaN results and divisions by zero. Fixes #84871 --- Full diff: https://github.com/llvm/llvm-project/pull/90588.diff 2 Files Affected: - (modified) clang/lib/AST/ExprConstant.cpp (+21-6) - (modified) clang/test/SemaCXX/complex-folding.cpp (+44-29) ``diff diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f1aa19e4409e15..86fb396fabe2d9 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -15209,11 +15209,21 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat = Result.getComplexFloatImag(); if (LHSReal) { assert(!RHSReal && "Cannot have two real operands for a complex op!"); -ResR = A * C; -ResI = A * D; +ResR = A; +ResI = A; +// ResR = A * C; +// ResI = A * D; +if (!handleFloatFloatBinOp(Info, E, ResR, BO_Mul, C) || +!handleFloatFloatBinOp(Info, E, ResI, BO_Mul, D)) + return false; } else if (RHSReal) { -ResR = C * A; -ResI = C * B; +// ResR = C * A; +// ResI = C * B; +ResR = C; +ResI = C; +if (!handleFloatFloatBinOp(Info, E, ResR, BO_Mul, A) || +!handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B)) + return false; } else { // In the fully general case, we need to handle NaNs and infinities // robustly. @@ -15289,8 +15299,13 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat = Result.getComplexFloatReal(); APFloat = Result.getComplexFloatImag(); if (RHSReal) { -ResR = A / C; -ResI = B / C; +ResR = A; +ResI = B; +// ResR = A / C; +// ResI = B / C; +if (!handleFloatFloatBinOp(Info, E, ResR, BO_Div, C) || +!handleFloatFloatBinOp(Info, E, ResI, BO_Div, C)) + return false; } else { if (LHSReal) { // No real optimizations we can do here, stub out with zero. diff --git a/clang/test/SemaCXX/complex-folding.cpp b/clang/test/SemaCXX/complex-folding.cpp index 054f159e9ce0dd..d3e428f2b75cc2 100644 --- a/clang/test/SemaCXX/complex-folding.cpp +++ b/clang/test/SemaCXX/complex-folding.cpp @@ -57,43 +57,58 @@ static_assert(((1.25 + 0.5j) / (0.25 - 0.75j)) == (-0.1 + 1.7j)); static_assert(((1.25 + 0.5j) / 0.25) == (5.0 + 2.0j)); static_assert((1.25 / (0.25 - 0.75j)) == (0.5 + 1.5j)); -// Test that infinities are preserved, don't turn into NaNs, and do form zeros -// when the divisor. + static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * 1.0)) == 1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * 1.0)) == 1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * 1.0)) == 1); // expected-error {{static assertion}} \ + // expected-note {{produces a NaN}} static_assert(__builtin_isinf_sign(__real__(1.0 * (__builtin_inf() + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + __builtin_inf() * 1.0j))) == 1); - +static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + __builtin_inf() * 1.0j))) == 1); // expected-error {{static assertion}} \ + // expected-note {{produces a NaN}} static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (1.0 + 1.0j))) == 1); static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (__builtin_inf() + 1.0j))) == 1); static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (__builtin_inf() + 1.0j))) == 1); - -static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == 1); - -static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + __builtin_inf() * 1.0j) * (__builtin_inf() + __builtin_inf() * 1.0j))) == -1); - +static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == -1); // expected-error {{static assertion}} \ + // expected-note {{produces a NaN}} +static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == 1); // expected-error {{static
[clang] [clang]Report erroneous floating point results in _Complex math (PR #90588)
https://github.com/tbaederr edited https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits