[Bug rtl-optimization/87485] [9 Regression] Compile time hog w/ -O2 -fschedule-insns -fno-guess-branch-probability -fno-isolate-erroneous-paths-dereference -fno-omit-frame-pointer -fno-split-wide-types -fno-tree-ccp -fno-tree-sra

ubizjak at gmail dot com gcc-bugzilla@gcc.gnu.org
Thu Nov 22 20:54:00 GMT 2018


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!


More information about the Gcc-bugs mailing list