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)