Bug 90032 - [MSP430] reload uses wrong stack slot for variable after setjmp/longjmp
Summary: [MSP430] reload uses wrong stack slot for variable after setjmp/longjmp
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-04-09 20:58 UTC by Jozef Lawrynowicz
Modified: 2019-04-09 21:01 UTC (History)
0 users

See Also:
Host:
Target: msp430-elf
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
tester.i (330 bytes, text/plain)
2019-04-09 20:58 UTC, Jozef Lawrynowicz
Details
tester.i (238 bytes, text/plain)
2019-04-09 20:59 UTC, Jozef Lawrynowicz
Details
tester.i ira dump (3.84 KB, text/plain)
2019-04-09 21:01 UTC, Jozef Lawrynowicz
Details
tester.i reload dump (3.02 KB, text/plain)
2019-04-09 21:01 UTC, Jozef Lawrynowicz
Details
tester.s (505 bytes, text/plain)
2019-04-09 21:01 UTC, Jozef Lawrynowicz
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jozef Lawrynowicz 2019-04-09 20:58:04 UTC
Created attachment 46118 [details]
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.
Comment 1 Jozef Lawrynowicz 2019-04-09 20:59:48 UTC
Created attachment 46119 [details]
tester.i
Comment 2 Jozef Lawrynowicz 2019-04-09 21:01:08 UTC
Created attachment 46120 [details]
tester.i ira dump
Comment 3 Jozef Lawrynowicz 2019-04-09 21:01:29 UTC
Created attachment 46121 [details]
tester.i reload dump
Comment 4 Jozef Lawrynowicz 2019-04-09 21:01:57 UTC
Created attachment 46122 [details]
tester.s