This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/71050] [7 regression] test case gcc.target/powerpc/lhs-1.c fails starting with r236066
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 11 May 2016 09:25:18 +0000
- Subject: [Bug tree-optimization/71050] [7 regression] test case gcc.target/powerpc/lhs-1.c fails starting with r236066
- Auto-submitted: auto-generated
- References: <bug-71050-4 at http dot gcc dot gnu dot org/bugzilla/>
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.