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?