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;