Bug 45365 - X86 SSE FP add and multiply aren't commutative with 2 NaNs
Summary: X86 SSE FP add and multiply aren't commutative with 2 NaNs
Status: REOPENED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.5.3
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 103406 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-08-21 03:41 UTC by H.J. Lu
Modified: 2021-11-26 17:58 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-11-14 15:51:37


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2010-08-21 03:41:53 UTC
According to table 4-7 in chapter 4, Vol 1 of
IA32/Inte64 SDM, x86 FP add and multiply aren't
commutative with Qnan/Snan inputs. But we have

DEF_RTL_EXPR(PLUS, "plus", "ee", RTX_COMM_ARITH)
DEF_RTL_EXPR(MULT, "mult", "ee", RTX_COMM_ARITH)

That impacts x86 FP plus and mult patterns. Should
we introduce a new target option to disable x86
commutative FP plus and mult?
Comment 1 H.J. Lu 2010-08-21 03:54:07 UTC
[hjl@gnu-6 intrin]$ cat mulpd.c
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <emmintrin.h>

__m128d a;
__m128d b;
uint64_t av[] = {0x0, 0xfff8000000000000ULL};
uint64_t bv[] = {0xffefffffffffffffULL, 0x7fff2d4db6efd985ULL};
uint64_t expa[] = {0x8000000000000000ULL, 0xfff8000000000000ULL};
uint64_t expb[] = {0x8000000000000000ULL, 0x7fff2d4db6efd985ULL};

void check_mulpd(__m128d const* op0, __m128d const* op1,
		 uint64_t *exp)
{
    __m128d r = _mm_mul_pd (*op0, *op1);;
    if (memcmp (&r, exp, sizeof (r)))
      abort ();
}
    
int main()
{
    memcpy(&a, av, sizeof(a));
    memcpy(&b, bv, sizeof(b));
    check_mulpd(&a, &b, expa);
    check_mulpd(&b, &a, expb);
    return 0;
}
[hjl@gnu-6 intrin]$ make
gcc -g -o o0 mulpd.c
gcc -g -O2 -o o2 mulpd.c
./o2
./o0
make: *** [all] Aborted
[hjl@gnu-6 intrin]$ 
Comment 2 Andrew Pinski 2010-08-21 03:58:51 UTC
How are they are not commutative with respect of the NaNs?  Is it only when both are operands are NaNs, it causes an issue?  


If I read your testcase correctly, x87 and SSE both don't do IEEE FP correctly with respect of NaNs.  For multiply and add if either operand is a NaN, the result is also a NaN IIRC.
Comment 3 H.J. Lu 2010-08-21 04:10:30 UTC
(In reply to comment #2)
> How are they are not commutative with respect of the NaNs?  Is it only when
> both are operands are NaNs, it causes an issue?  
> 
> 
> If I read your testcase correctly, x87 and SSE both don't do IEEE FP correctly
> with respect of NaNs.  For multiply and add if either operand is a NaN, the
> result is also a NaN IIRC.

The difference is QNaN and SNaN. They are both NaNs, but not the same.

Comment 4 H.J. Lu 2010-08-21 04:14:43 UTC
(In reply to comment #2)
> How are they are not commutative with respect of the NaNs?  Is it only when
> both are operands are NaNs, it causes an issue?  
> 

Yes, only when both operands and NaNs with SSE FP.
Comment 5 H.J. Lu 2010-08-23 16:29:52 UTC
ICC people say

--
In my opinion, FP multiplication and addition should be considered commutative at both the C and intrinsic level.  The only case where the underlying instructions behave in a non-commutative manner is when both operands are NaN.  And in that case, even the IEEE-754 floating-point standard does not specify which operand NaN should be returned as the result.  The C standard doesn't distinguish between different NaN values at all.

If the programmer cares about this very subtle detail in the handling of NaNs, I think inline assembly is the right option.
---

Closing as WONTFIX.
Comment 6 H.J. Lu 2010-11-14 15:51:37 UTC
i386 backend should define HONOR_SNANS.
Comment 7 H.J. Lu 2010-11-14 15:53:28 UTC
Does -fsignaling-nans work here?
Comment 8 Roger Sayle 2021-11-26 17:58:38 UTC
*** Bug 103406 has been marked as a duplicate of this bug. ***