https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99258
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jsm28 at gcc dot gnu.org, | |rguenth at gcc dot gnu.org Keywords| |wrong-code Last reconfirmed| |2021-02-25 Ever confirmed|0 |1 Component|tree-optimization |middle-end Status|UNCONFIRMED |NEW --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Confirmed. Happens already during gimplification which does else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)) && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode) { /* Historically, the compiler has treated a bare reference to a non-BLKmode volatile lvalue as forcing a load. */ ... } else /* We can't do anything useful with a volatile reference to an incomplete type, so just throw it away. Likewise for a BLKmode type, since any implicit inner load should already have been turned into an explicit one by the gimplification process. */ *expr_p = NULL; throwing away the load. GIMPLE indeed requires a LHS for a load and we'd need to introduce a temporary aggregate here. Which should be possible for non-VLA, non TREE_ADDRESSABLE types. Thus the condition could be amended to not look at the types mode but verify its size is constant and the type is not addressable (though the code explicitely says a TREE_ADDRESSABLE type is OK). Note relaxing the mode check to constant size can cause arbitrarily big temporaries being generated on the stack so I'm not sure that's good. Alternatively open-coding elementwise reads would be a possibility (for a load into a temporary we might emit a memcpy call in the end). Alternatively we could invent some internal function taking an aggregate argument and emit .USE (*x); and leave the actual generation of the load to RTL expansion.