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

Reply via email to