Bug 122770 - gcc doesn't trigger FE_INVALID when the arithmetic/logical operation is considered INVALID in compliance with IEEE-754 Section-7.2
Summary: gcc doesn't trigger FE_INVALID when the arithmetic/logical operation is consi...
Status: RESOLVED DUPLICATE of bug 34678
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 14.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL: https://www.godbolt.org/z/c1foMGjbo
Keywords: false-negative
Depends on:
Blocks:
 
Reported: 2025-11-20 00:42 UTC by Mohamed
Modified: 2025-11-20 06:01 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mohamed 2025-11-20 00:42:12 UTC
GCC doesn't seem to comply with IEEE-754 Section 7.2 on INVALID operation.
The section 7.2 according to IEEE-754, found in: (https://www.gnu.org/software/libc/manual/html_node/FP-Exceptions.html)
(https://www-users.cse.umn.edu/~vinals/tspot_files/phys4041/2020/IEEE%20Standard%20754-2019.pdf)

The exceptions defined in IEEE 754 are:

‘Invalid Operation’

This exception is raised if the given operands are invalid for the operation to be performed. Examples are (see IEEE 754, section 7):

    1-Addition or subtraction: ∞ - ∞. (But ∞ + ∞ = ∞).
    2-Multiplication: 0 · ∞.
    3-Division: 0/0 or ∞/∞.
    4-Remainder: x REM y, where y is zero or x is infinite.
    5-Square root if the operand is less than zero. More generally, any mathematical function evaluated outside its domain produces this exception.
    6-Conversion of a floating-point number to an integer or decimal string, when the number cannot be represented in the target format (due to overflow, infinity, or NaN).
    7-Conversion of an unrecognizable input string.
    8-Comparison via predicates involving < or >, when one or other of the operands is NaN. You can prevent this exception by using the unordered comparison functions instead.


It seems that GCC 14.1.0 deosn't raise the FE_INVALID on points 6 and 8, with the following results:

(pinf >= qnan): 0
No Exception reported

(zero <= snan): 0
No Exception reported

static_cast<std::int32_t>(some_finite_large_double): 2147483647
No Exception reported

for the program

```
    const auto pinf = std::numeric_limits<double>::infinity();
    const auto ninf = std::copysign(pinf, -1.0);
    const auto qnan = std::numeric_limits<double>::quiet_NaN();
    const auto snan = std::numeric_limits<double>::signaling_NaN();
    constexpr auto some_finite_large_double{
        598008216632976371697735644702348584536405246902083247220875921706093794716375762404103004004990504111786204800430166155026589905240121409306972824498630058082565445957748647537262486126146850127872.0};
    const double zero{0.0};
    // see point 8
    {
        volatile auto result = (pinf >= qnan);
        fe_status = check_fe();
        std::cout << "\n";
        std::cout << "(pinf >= qnan): " << result << "\n";
        std::cout << fe_status << "\n";
    }
    // see point 8
    {
        volatile auto result = (zero <= snan);
        fe_status = check_fe();
        std::cout << "\n";
        std::cout << "(zero <= snan): " << result << "\n";
        std::cout << fe_status << "\n";
    }
    // see point 6
    {
        volatile auto result = static_cast<std::int32_t>(some_finite_large_double);
        fe_status = check_fe();
        std::cout << "\n";
        std::cout << "static_cast<std::int32_t>(double): " << result << "\n";
        std::cout << fe_status << "\n";
    }

```

gcc command:
`g++-14 -o test -std=c++17 fe_invalid.cpp -O2 -frounding-math -fsignaling-nans -ftrapping-math -fno-builtin -fno-strict-aliasing -fwrapv`


So, for comaparison of NaNs and quantization for finite large numbers, e.g. casting to smaller int32_t. The gcc is not reporting/triggering FE_INVALID

While with clang using `-ffp-exception-behavior=strict`, all of the them report FE_INVALID as expected.

```
clang++-19 -o test -std=c++20 fe_invalid.cpp -O2 -ffp-exception-behavior=strict && ./test

...

(pinf >= qnan): 0
FE_INVALID 

(zero <= snan): 0
FE_INVALID 

static_cast<std::int32_t>(double): -2147483648
FE_INVALID 

```

Using clang command:
`clang++-19 -o test -std=c++20 fe_invalid.cpp -O2 -ffp-exception-behavior=strict`

The results are consistent between x86-64, armv8.1-a and armv9.2-a
Comment 1 Drea Pinski 2025-11-20 00:50:47 UTC
>for the program


This is only a snip of code and not a full program.
Comment 2 Mohamed 2025-11-20 00:53:25 UTC
Full comparison between gcc and clang along with issue reproduction can be found here: https://www.godbolt.org/z/c1foMGjbo
Comment 3 Xi Ruoyao 2025-11-20 06:01:23 UTC
The C and C++ standards only madate this part of IEEE-754 when #pragma FENV_ACCESS on, which is not implemented by GCC yet.

*** This bug has been marked as a duplicate of bug 34678 ***