https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77439
Bug ID: 77439 Summary: [6/7 regression] wrong code for sibcall with longcall, APCS frame and VFP Product: gcc Version: 6.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: ebotcazou at gcc dot gnu.org Target Milestone: --- Created attachment 39531 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39531&action=edit Testcase The following change: 2014-04-25 Jiong Wang <jiong.w...@arm.com> * config/arm/predicates.md (call_insn_operand): Add long_call check. * config/arm/arm.md (sibcall, sibcall_value): Force the address to reg for long_call. * config/arm/arm.c (arm_function_ok_for_sibcall): Remove long_call restriction. has introduced a bug for sibcalls with longcall, APCS frame and VFP. For a longcall, any sibcall becomes an indirect sibcall and therefore requires a register to hold the target address. Now if all the argument registers are taken, this register will be IP but, for APCS frames and VFP, IP can be used in the sibcall epilogue to restore the VFP registers, so the target address is overwritten and the call goes astray. Testcase attached, compile it with e.g. -mapcs-frame -mfloat-abi=soft -O -foptimize-sibling-calls -ffunction-sections and you'll see for arm-eabi: sub ip, fp, #36 vldm ip!, {d8} sub sp, fp, #28 ldmfd sp, {r4, r5, r6, r7, fp, sp, lr} bx ip