https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87485
--- Comment #19 from Uroš Bizjak <ubizjak at gmail dot com> --- (In reply to Vladimir Makarov from comment #18) > (In reply to Vladimir Makarov from comment #17) > > I've reproduced it. Clearly, it is some bug in LRA conflict calculation. > > I will be working on it. > > I investigated it more. Before scheduling we have > > (insn 60 122 61 7 (parallel [ > (set (subreg:DI (reg:TI 125) 0) > (zero_extend:DI (udiv:SI (reg:SI 116) > (reg:SI 119)))) > (set (reg:SI 118) > (umod:SI (reg:SI 116) > (reg:SI 119))) > (clobber (reg:CC 17 flags)) > ... > > (insn 90 69 92 7 (set (reg/i:SI 0 ax) > (const_int 0 [0])) "pr87485.c":34:1 67 {*movsi_internal} > (nil)) > > After scheduling we have > > (insn 90 54 60 7 (set (reg/i:SI 0 ax) > (const_int 0 [0])) "pr87485.c":34:1 67 {*movsi_internal} > (nil)) > (insn 60 90 61 7 (parallel [ > (set (subreg:DI (reg:TI 125) 0) > (zero_extend:DI (udiv:SI (reg:SI 116) > (reg:SI 119)))) > (set (reg:SI 118) > (umod:SI (reg:SI 116) > (reg:SI 119))) > (clobber (reg:CC 17 flags)) This happens when return pair gets split in expand_function_end. sched1 pass has certain code that marks both instructions as CANT_MOVE (c.f. a comment in add_branch_dependencies: Insns setting TARGET_CLASS_LIKELY_SPILLED_P registers (usually return values) are not moved before reload because we can wind up with register allocation failures. ) stack protect epilogue code gets inserted in between return pair, so the final assignment to a hard register gets away from the USE insn. The above code is ineffective in case of split return pair. So, expand_function_end should be fixed to emit an assignment to a function value hard reg just before use insn. Some parts of the compiler (sched1 and mode switching passes) depend on an unbroken return pair!