This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/71050] [7 regression] test case gcc.target/powerpc/lhs-1.c fails starting with r236066


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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |missed-optimization
   Target Milestone|---                         |7.0

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
On GIMPLE this is now "optimized" to refer to the upper half of the double
with a BIT_FIELD_REF of the parameter d and the union is optimized away.
Ideally this results in (subreg:SI (reg:DF ...) 4) or an equivalent highpart.

It looks like expansion spills this to memory (in theory ok, you'd get sth
equivalent to the union) but then sth messes up things badly.  The GIMPLE
transform doesn't factor in that the store to u->val isn't dead after it.

RTL opt/target bug.

Equivalent code for pre-r236066 would be

unsigned int f (double d, words *u)
{
  u->val = d;
  return ((unsigned int *)&d)[1];
}

and compiling with -fno-strict-aliasing.

With -mcpu=power8 I get

f:
        mfvsrd 9,1
        stfd 1,0(4)
        srdi 3,9,32
        blr

Expansion does a df->di move and then extracts the bits via a shift.


So, as I suspected it might be neccessary to restrict the kind of
"subregs" we create.  The transform was designed to avoid the union for
the variant

typedef union {
    double val;
    struct {
        unsigned int w1;
        unsigned int w2;
    };
} words;

unsigned int f (double d)
{
  words u;
  u.val = d;
  return u.w2;
}

but even for that RTL opts cannot recover the original code it seems
as the backend lies to the middle-end(?) in claiming it can do

(insn 6 5 7 (set (reg:DI 158)
        (subreg:DI (reg/v:DF 156 [ d ]) 0)) t.c:13 -1
     (nil))

but in reality it later goes through memory for this which when done
at expansion time would have resulted in the same code as when being
present with the union.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]