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?
[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]$
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.
(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.
(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.
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.
i386 backend should define HONOR_SNANS.
Does -fsignaling-nans work here?
*** Bug 103406 has been marked as a duplicate of this bug. ***