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

            Bug ID: 90032
           Summary: [MSP430] reload uses wrong stack slot for variable
                    after setjmp/longjmp
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jozefl.gcc at gmail dot com
  Target Milestone: ---

Created attachment 46118
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46118&action=edit
tester.i

gcc.dg/torture/stackalign/setjmp-1.c fails at execution for msp430-elf at -O1.
An RTL optimization added in r255136 exposed the failure, but if I make this
optimization in the source of the test, then versions of GCC before this also
fail, back to GCC 7. It passes with gcc-6.4, but again that is just because the
RTL at reload is different.

I've attached a reduced testcase (tester.i) based on setjmp-1.c.
> msp430-elf-gcc -O1 -msim tester.i
The failure occurs because the wrong stack slot is used as the first argument
to strcmp.
R1 is the stack pointer, R12 stores the first argument to functions.
>       MOV.W   R12, 20(R1)    ; The address of the string is stored in 20(R1)
>       MOV.W   #25972, @R12   ; "te"
>       MOV.W   #29811, 2(R12) ; "st"
>    .... (No other modifications of R1)
>    .... preparing jmp_buf
>       CALL    #sub2
>    .... Label for return from longjmp
>       MOV.W   @R1, R12      ; The address of the string is actually in 20(R1)
>       CALL    #strcmp
Whether the test fails or not seems gated on if frame_pointer_needed == true
for main(). When there is "more" RTL code (i.e. before the revisions that added
the problematic optimizations), then frame_pointer_needed == true so the
address of the "test" string will be used as an offset from the frame pointer,
instead of the stack pointer.

TARGET_FRAME_POINTER_REQUIRED () always returns false for msp430, but if I make
it return true if
  (cfun->has_nonlocal_label || cfun->calls_setjmp)
then the test passes and the following code is generated.

The frame pointer is R4, but it is not fixed.
>       MOV.W   R12, -2(R4)
>       MOV.W   #25972, @R12
>       MOV.W   #29811, 2(R12)
>         .... (No other modifications of R4)
>       CALL    #sub2
>         .... Label for return from longjmp
>       MOV.W   -2(R4), R12  ; -2(R4) contains the correct address of "test"

I've attached the assembly file, IRA and reload dumps for tester.i when
compiled with current trunk.

Reply via email to