https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61441
Bug ID: 61441 Summary: ARM aarch64 fails to quiet signaling NaN Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: aurelien at aurel32 dot net Host: aarch64-unknown-linux-gnu Target: aarch64-unknown-linux-gnu Build: aarch64-unknown-linux-gnu Consider the following code: #define _GNU_SOURCE #include <stdio.h> #include <math.h> int main (void) { float sNaN = __builtin_nansf (""); double x = (double) sNaN; return issignaling(x); } It correctly returns 0 at -O0 optimisation level, but returns 1 at -O1 and -O2 optimisation levels. Here is the generated assembly code at -O0: 0000000000400630 <main>: 400630: a9be7bfd stp x29, x30, [sp,#-32]! 400634: 910003fd mov x29, sp 400638: 18000160 ldr w0, 400664 <main+0x34> 40063c: b9001fa0 str w0, [x29,#28] 400640: b9401fa0 ldr w0, [x29,#28] 400644: 1e270000 fmov s0, w0 400648: 1e22c000 fcvt d0, s0 40064c: 9e660000 fmov x0, d0 400650: f9000ba0 str x0, [x29,#16] 400654: fd400ba0 ldr d0, [x29,#16] 400658: 97ffff8e bl 400490 <__issignaling@plt> 40065c: a8c27bfd ldp x29, x30, [sp],#32 400660: d65f03c0 ret 400664: 7fa00000 .word 0x7fa00000 Here is the generated assembly code at -O1: 0000000000400630 <main>: 400630: a9bf7bfd stp x29, x30, [sp,#-16]! 400634: 910003fd mov x29, sp 400638: 5c000080 ldr d0, 400648 <main+0x18> 40063c: 97ffff95 bl 400490 <__issignaling@plt> 400640: a8c17bfd ldp x29, x30, [sp],#16 400644: d65f03c0 ret 400648: 00000000 .word 0x00000000 40064c: 7ff40000 .word 0x7ff40000 As you can see at -O1, the sNaN constant is propagated, and the propagated value is loaded and passed directly to issignaling. Quoting the IEEE Std 754 standard: "Under default exception handling, any operation signaling an invalid operation exception and for which a floating-point result is to be delivered shall deliver a quiet NaN." So it looks like the copy propagation is not done correctly, the sNaN should be silenced in the process.