https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90020
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> --- So looking at one issue I can see is code-hoisting hoisting MEM[(struct window *)window_6(D) + -5B].contents across a call that might not return. This can only happen for calls we can alias-disambiguate against which means in this case pure calls. For example for divisions we guard against this case my checking whether it may trap and there was an earlier call that might not return. That is missing for memory referneces. <bb 2> [local count: 1073741824]: # VUSE <.MEM_5(D)> _1 = WINDOWP (window_6(D)); if (_1 != 0) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [local count: 536870913]: # VUSE <.MEM_5(D)> _2 = MEM[(struct window *)window_6(D) + -5B].contents; # VUSE <.MEM_5(D)> _3 = BUFFERP (_2); _8 = (int) _3; <bb 4> [local count: 1073741824]: # iftmp.1_4 = PHI <_8(3), 0(2)> # VUSE <.MEM_5(D)> CHECK_TYPE (iftmp.1_4, 4856B, window_6(D)); # VUSE <.MEM_5(D)> _7 = MEM[(struct window *)window_6(D) + -5B].contents; # VUSE <.MEM_5(D)> return _7; But fixing that on the GIMPLE level doesn't make the issue go away since we have similar functionality on RTL which triggers (and is the older issue since GIMPLE can do hoisting only since GCC 7).