https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93271
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target| |i?86-*-*
Last reconfirmed|2022-01-29 00:00:00 |2023-4-13
--- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue is that on some targets (like i386) a FP load/store isn't a noop
but alters the bit representation. SRA in this case sees aggregate
store/load and scalar float store/load (but this one conditional).
In case there's a non-FP load or store of the part of the aggregate that's
also accessed as float there's no way to correctly perform the scalar
ops _but at the very point they are done originally_.
So the issue is we're doing the replacement in a non-flow-sensitive manner.
Of course when done flow-sentitive then the replacement will be pointless.
For long/double it's the same. There is currently no predicate that will
tell whether a target implements no-op reg = FP-mem; FP-mem = reg; so the
only "safe" fix would be to avoid scalarization of FP parts when the
initialization isn't provably done with FP stores.
int main ()
{
+ float a$b;
union test a;
float _1;
float _2;
@@ -82,14 +70,16 @@
<bb 2> :
a = set (); [return slot optimization]
+ a$b_7 = a.b;
goto <bb 4>; [INV]
<bb 3> :
- _1 = a.b;
+ _1 = a$b_8;
_2 = _1 + 1.0e+0;
- a.b = _2;
+ a$b_11 = _2;
<bb 4> :
+ # a$b_8 = PHI <a$b_7(2), a$b_11(3)>
val.0_3 ={v} val;
if (val.0_3 != 0)
goto <bb 3>; [INV]
@@ -97,8 +87,8 @@
goto <bb 5>; [INV]
<bb 5> :
+ a.b = a$b_8;
get (a);
- a ={v} {CLOBBER(eol)};
return 0;