https://gcc.gnu.org/g:3c5f42d64a7318745a712ef1cc53e8853e32961b

commit r17-4412-g3c5f42d64a7318745a712ef1cc53e8853e32961b
Author: Jakub Jelinek <[email protected]>
Date:   Fri Sep 18 11:04:56 2026 +0200

    testsuite: Fix up g++.dg/cpp29/std-floating1.C on powerpc64-linux
    
    Two spots in this test (which has been added to make sure we handle
    floating-point overflow, underflow and other cases as per
    https://wg21.link/P3899R3 during constant evaluation) fail when long double
    is IBM double double.
    The problem is that our real.cc emulation of this type is imprecise, we
    handle it basically as fixed 106 bit mantissa and exponent range of double,
    when it actually is an addition of two double values with some rules (the
    main one is that the upper double should be always equal to the whole value
    rounded to double).  So, it is effectively dynamic precision from 53 bits
    (for denormals) up to some 1000 something bits depending on the exact
    values.  Until we rewrite the real.cc emulation of this mode as operations
    on a pair of doubles (if ever), we have cases like
          /* Don't constant fold this floating point operation if the
             result may dependent upon the run-time rounding mode and
             flag_rounding_math is set, or if GCC's software emulation
             is unable to accurately represent the result.  */
          if ((flag_rounding_math
               || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
              && (inexact || !real_identical (&result, &value)))
            return NULL_TREE;
    and so instead of getting wrong results we choose not to constant evaluate
    it in some cases, in this testcase the minld/maxld and minld*minld cases are
    inexact and so we punt.
    
    The following patch makes those dg-bogus xfailed on IBM double double long
    double targets to make it clear that it is a bug, but expected one.
    
    2026-09-18  Jakub Jelinek  <[email protected]>
    
            * g++.dg/cpp29/std-floating1.C: Add 2 dg-bogus directives xfailed
            for long_double_is_ibm128 effective targets.
    
    Reviewed-by: Richard Biener <[email protected]>

Diff:
---
 gcc/testsuite/g++.dg/cpp29/std-floating1.C | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/cpp29/std-floating1.C 
b/gcc/testsuite/g++.dg/cpp29/std-floating1.C
index 504f76e4085e..4e8293b54fe3 100644
--- a/gcc/testsuite/g++.dg/cpp29/std-floating1.C
+++ b/gcc/testsuite/g++.dg/cpp29/std-floating1.C
@@ -46,11 +46,12 @@ constexpr long double snanld = __builtin_nansl ("");
 
 constexpr long double inf2ld = infld * 2.0L; // OK, also positive infinity
 constexpr long double zerold = minld / maxld; // OK, result cannot be 
represented, and is rounded to zero
+                                             // { dg-bogus "is not a constant 
expression" "" { xfail long_double_is_ibm128 } .-1 }
 constexpr long double oflold = maxld * 2.0L; // { dg-error "is not a constant 
expression" }
 constexpr long double nan2ld = nanld * 2.0L; // OK, propagating a NaN
 constexpr long double udefld = infld * 0.0L; // { dg-error "is not a constant 
expression" }
 constexpr long double div0ld = maxld / 0.0L; // { dg-error "is not a constant 
expression" }
-constexpr long double zero2ld = minld * minld;
+constexpr long double zero2ld = minld * minld; // { dg-bogus "is not a 
constant expression" "" { xfail long_double_is_ibm128 } }
 constexpr bool nancmpld = nanld < 0.0L;
 constexpr long double snan2ld = snanld * 2.0L;
 constexpr long double div02ld = 1.0L / 0.0L; // { dg-error "is not a constant 
expression" }

Reply via email to