https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96457
Bug ID: 96457 Summary: PRE gets confused by punned load handling Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org Target Milestone: --- int flag; union { double f; unsigned long long i; } u; void foo(); unsigned long long i; unsigned long long test () { double f = 0.; if (flag) { foo (); f = u.f; } else i = u.i; f = u.f + f; return f; } here we fail to PRE the load of u.f because PHI translation to the else path fails since we run into /* If we'd have to convert things we would need to validate if we can insert the translated expression. So fail here for now - we cannot insert an alias with a different type in the VN tables either, as that would assert. */ if (result && !useless_type_conversion_p (ref->type, TREE_TYPE (result))) return NULL; because we found a value for u.f there, that of u.i (because we value-number them the same). If one replaces 'i = u.i;' with 'foo ();' we appropriately insert a load from u.f in the else path and remove the partial redundancy.