https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72771
Alan Modra <amodra at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |amodra at gmail dot com --- Comment #4 from Alan Modra <amodra at gmail dot com> --- Created attachment 39060 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39060&action=edit possible fix What's happening here is that before reload the floathisf2_internal insn shown above has a pseudo for operand 1 that didn't get a hard reg. The pseudo happens to be equivalent to a constant so the first reload action is to substitute in the constant. Now a constant isn't allowed in any of the operand 1 alternatives, and the Z (indexed or indirect mem) alternative is chosen as best, mostly because that alternative needs fewer scratch regs. The choice is silly in this case because forcing the HImode constant to memory results in more insns to reload the value than a simple "li reg,value". Anyway, once we have the constant in memory, rs6000_legitimize_reload_address comes into play and blindly assumes that a toc reference is good. Which is not the case, but since legitimize_reload_address has said it has fixed the mem, reload decides nothing more needs doing. This problem is potentially going to bite us on any insn that allows a mem but not the offsettable variety. After writing this patch and better understanding what is going on, I'm wondering why this pattern even has a Z alternative. I can't envisage any scenario where we'd want to load a QI or HI constant from memory. In all cases it's better to simply use "li". Even the equivalent HI floatuns pattern with worst case constants in the range 0x800 to 0xffff can be rematerialized inline with just two insns.