https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83370

            Bug ID: 83370
           Summary: [AARCH64]Tailcall register may be corrupted by
                    epilogue code
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: renlin at gcc dot gnu.org
  Target Milestone: ---

The following example generates incorrect code:

void (*f)();
int xx;
void tailcall (int i)
{
   int arr[5000];
   xx = arr[i];
   f();
}

When built with -O2 -ffixed-x0 -ffixed-x1 -ffixed-x2 -ffixed-x3 -ffixed-x4
-ffixed-x5 -ffixed-x6 -ffixed-x7 -ffixed-x8 -ffixed-x9 -ffixed-x10 -ffixed-x11
-ffixed-x12 -ffixed-x13 -ffixed-x14 -ffixed-x15 -ffixed-x17 -ffixed-x18

tailcall:
        mov     x16, 20016
        sub     sp, sp, x16
        adrp    x16, .LANCHOR0
        stp     x19, x30, [sp]
        add     x19, sp, 16
        ldr     s0, [x19, w0, sxtw 2]
        ldp     x19, x30, [sp]
        str     s0, [x16, #:lo12:.LANCHOR0]
        mov     x16, 20016
        add     sp, sp, x16
        br      x16   // oops

So the issue is there is nothing in the tail call instruction that prevents it
from using IP0/IP1 which are used as temporaries in the epilogue. We use the
temporary for frames of 4-64KB, so this issue is more likely today (previously
temporary was used only in frames larger than 16MBytes).

The problem appears to be that while we have explicit clobbers in a tailcall,
they are after the call, not before it:

(call_insn/j 16 12 17 2 (parallel [
            (call (mem:DI (reg/f:DI 84 [ f ]) [0 *f.0_2 S8 A8])
                (const_int 0 [0]))
            (return)
        ]) "tailcall.c":13 42 {*sibcall_insn}
     (expr_list:REG_DEAD (reg/f:DI 84 [ f ])
        (expr_list:REG_CALL_DECL (nil)
            (nil)))
    (expr_list (clobber (reg:DI 17 x17))
        (expr_list (clobber (reg:DI 16 x16))
            (nil))))

This issues affects gcc-5, gcc-6, gcc-7 and current trunk.

Reply via email to