https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89012

Oleg Endo <olegendo at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-09-29
     Ever confirmed|0                           |1

--- Comment #6 from Oleg Endo <olegendo at gcc dot gnu.org> ---
The ashlsi3_d_call insn, alternative 1 seems to be the problem here, but I
think the same problem could happen for all other libcalls that expand to a
bsrf sequence.

In this particular case, something in the optimizers decides that moving the
shift instruction out of the loop is a good idea.  To do that, it copies the
shift instruction only -- which is "ashlsi3_d_call", which is the bsrf plus the
following label.  The label is generated once during RTL expansion.

This works for normal PIC code which calculates the call address and puts it in
a register first.  This happens only once during RTL expansion and the address
remains fixed.  Subsequent copies of the shift instruction (which is just a
jsr) work, because they re-use the calculated address.

In case of FDPIC, the use of bsrf will always require a unique address/offset
in the symbols.  It can't just make arbitrary copies of the shift instruction
(which is a bsrf) because the pre-calculated address/offset will be wrong.


1) If not already there, something needs to be added that allows re-generating
the address/offset of the copied/cloned instruction and also re-emitting the
constant load.  This is probably not so easy to do, as instructions can be
copied in many places during the compilation.

2) Postpone the calculation and emission of symbols and constant loads until a
very late stage of the compilation using very late splitters.

3) Use jsr instead of bsrf in the compiler and let the linker post-optimize
calls via relaxation (although linker relaxation on SH has been broken for a
long time).


I don't know much about PIC/FDPIC, but one thing I've noticed looks strange.
The right-shift pattern "ashrsi3_n" will result in

        bsrf    r1      ! 268   [c=5 l=2]  call_valuei_pcrel
        ...

        .long   ___ashrsi3@PLT-(.LPCS0+2-.)



While the left-shift pattern "ashlsi3_d_call" will result in

        bsrf    r6      ! 24    [c=80 l=2]  ashlsi3_d_call/1
        ...

        .long   ___ashlsi3_r0-(.LPCS0+2)

Reply via email to