https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93934

--- Comment #23 from Zoltan Vajda <vajdaz at protonmail dot com> ---
(In reply to Uroš Bizjak from comment #20)
> (In reply to jos...@codesourcery.com from comment #16)
> > I don't think this bug is anything to do with -fsignaling-nans, for the 
> > same reason as applies to bug 58416 and bug 71460.
> 
> The situation is hopeless from the beginning. Please consider this testcase:
> 
> --cut here--
> #include <cpuid.h>
> #include <fenv.h>
> 
> double
> __attribute__((noinline,noipa))
> foo (double a, double b, char c)
> {
>   return c ? a : b;
> }
> 
> int main ()
> {
>   double a = __builtin_nans ("");
>   double b = 42.0;
> 
>   feclearexcept (FE_INVALID);
>   foo (a, b, 0);
>   if (fetestexcept (FE_INVALID))
>     __builtin_abort ();
> 
>   return 0;
> }
> --cut here--
> 
> $ gcc -O2 -m32 -march=i686 -lm fcmov.c
> $ ./a.out 
> Aborted (core dumped)
> $ gcc -O2 -m32 -march=i386 -lm fcmov.c
> $ ./a.out 
> Aborted (core dumped)
> 
> Because the compiler generates:
> 
> foo:
>         cmpb    $0, 20(%esp)
>         fldl    12(%esp)
>         fldl    4(%esp)
>         fcmove  %st(1), %st
>         fstp    %st(1)
>         ret
> 
> in the former case and:
> 
> foo:
>         fldl    4(%esp)
>         fldl    12(%esp)
>         cmpb    $0, 20(%esp)
>         jne     .L4
>         fstp    %st(1)
>         jmp     .L2
> .L4:
>         fstp    %st(0)
> .L2:
>         ret
> 
> in the later.
> 
> Since the ABI specifies the operand size on the stack, the above code will
> always trap.

There is a small but very important difference between this example and my
example.

In this example the compiler may assume that objects 'a' and 'b' both are
initialized at the beginning of the function execution (calling a function with
uninitialized input by value would be UB). Therefore you may argue that
accessing both of them is fine. If you feed foo() with SNaN through 'a', it
will always abort, independent of 'c'.

In my example there is an uninitialized object when the function execution
starts (local variable 'result') , and at C++ level there is no execution path
that would result in accessing this object before initialization. In spite of
this, at ASM level, the object is accessed before initialization. I don't see
any argument that makes this access valid. My example function aborts randomly,
independent of the input. The behavior depends on some random data on the
stack.

Reply via email to