https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67260
Alexander Monakov <amonakov at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |amonakov at gcc dot gnu.org
--- Comment #1 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
With Rich's prompt I've looked at this issue for fun. Here's a minimal
testcase:
#pragma GCC visibility push(hidden)
double _Complex foo(double _Complex arg);
double _Complex bar(double _Complex arg)
{ return foo(arg); }
I could reproduce it with current (6.0) trunk with -O2 -m2a-nofpu -fPIC.
The issue, the way I see it, is sh.md does this:
10479 (define_insn_and_split "sibcall_value_pcrel"
10480 [(set (match_operand 0 "" "=rf")
10481 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
10482 (match_operand 2 "" "")))
10483 (use (reg:SI FPSCR_MODES_REG))
10484 (clobber (match_scratch:SI 3 "=&k"))
10485 (return)]
10486 "TARGET_SH2 && !TARGET_FDPIC"
10487 "#"
10488 "reload_completed"
10489 [(const_int 0)]
10490 {
10491 rtx lab = PATTERN (gen_call_site ());
10492 rtx call_insn;
10493
10494 sh_expand_sym_label2reg (operands[3], operands[1], lab, true);
10495 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
10496 operands[3],
10497 operands[2],
10498 copy_rtx (lab)));
10499 SIBLING_CALL_P (call_insn) = 1;
10500 DONE;
10501 }
So it wants to pick a scratch register in SIBCALL_REGS ("k", r0-r7), but in the
circumstances r4-r7 are already used for argument passing, and r0-r3 are used
for the return value -- and GCC cannot know that the scratch reg wouldn't be
simultaneously live with those.
I must say I don't quite see the point of using match_scratch for the callee
address there. After all, it's making a sibcall, so GCC can simply pick r0 or
whatever's convenient, no?