Need sanity check on DSE vs expander issue

Jeff Law law@redhat.com
Fri Dec 20 02:20:00 GMT 2019


I need a sanity check here.

Given this code:

> typedef union { long double value; unsigned int word[4]; } memory_long_double;
> static unsigned int ored_words[4];
> static void add_to_ored_words (long double x)
> {
>   memory_long_double m;
>   size_t i;
>   memset (&m, 0, sizeof (m));
>   m.value = x;
>   for (i = 0; i < 4; i++)
>     {
>       ored_words[i] |= m.word[i];
>     }
> }
> 

DSE is removing the memset as it thinks the assignment to m.value is
going to set the entire union.

But when we translate that into RTL we use XFmode:

> ;; m.value ={v} x_6(D);
> 
> (insn 7 6 0 (set (mem/v/j/c:XF (plus:DI (reg/f:DI 77 virtual-stack-vars)
>                 (const_int -16 [0xfffffffffffffff0])) [2 m.value+0 S16 A128])
>         (reg/v:XF 86 [ x ])) "j.c":13:11 -1
>      (nil))
> 

That (of course) only writes 80 bits of data because of XFmode, leaving
48 bits uninitialized.  We then read those bits, or-ing the
uninitialized data into ored_words and all hell breaks loose later.

Am I losing my mind?  ISTM that dse and the expander have to agree on
how much data is written by the store to m.value.

Jeff



More information about the Gcc mailing list