xtensa: fix PR target/65416
diff mbox series

Message ID 20180618221054.19970-1-jcmvbkbc@gmail.com
State New
Headers show
Series
  • xtensa: fix PR target/65416
Related show

Commit Message

Max Filippov June 18, 2018, 10:10 p.m. UTC
The issue is caused by reordering of stack pointer update after stack
space allocation with instructions that write to the allocated stack
space. In windowed ABI register spill area for the previous call frame
is located just below the stack pointer and may be reloaded back into
the register file on movsp.
Implement allocate_stack pattern for windowed ABI configuration and
insert an instruction that prevents reordering of frame memory access
and stack pointer update.

gcc/
2018-06-17  Max Filippov  <jcmvbkbc@gmail.com>

	* config/xtensa/xtensa.md (UNSPEC_FRAME_BLOCKAGE): New unspec
	constant.
	(allocate_stack, frame_blockage, *frame_blockage): New patterns.
---
 gcc/config/xtensa/xtensa.md | 46 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

Comments

augustine.sterling@gmail.com June 19, 2018, 5:11 p.m. UTC | #1
On Mon, Jun 18, 2018 at 3:10 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:

> gcc/
> 2018-06-17  Max Filippov  <jcmvbkbc@gmail.com>
>
>         * config/xtensa/xtensa.md (UNSPEC_FRAME_BLOCKAGE): New unspec
>         constant.
>         (allocate_stack, frame_blockage, *frame_blockage): New patterns.
>

This is OK.
Max Filippov June 19, 2018, 6:30 p.m. UTC | #2
On Tue, Jun 19, 2018 at 10:11 AM, augustine.sterling@gmail.com
<augustine.sterling@gmail.com> wrote:
> On Mon, Jun 18, 2018 at 3:10 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
>>
>> gcc/
>> 2018-06-17  Max Filippov  <jcmvbkbc@gmail.com>
>>
>>         * config/xtensa/xtensa.md (UNSPEC_FRAME_BLOCKAGE): New unspec
>>         constant.
>>         (allocate_stack, frame_blockage, *frame_blockage): New patterns.
>
>
> This is OK.

Thanks. Applied to trunk. Will also backport to gcc-7 and gcc-6 branches.

Patch
diff mbox series

diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 84967dbedc08..209f839cfb0f 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -38,6 +38,7 @@ 
   (UNSPEC_MEMW		11)
   (UNSPEC_LSETUP_START  12)
   (UNSPEC_LSETUP_END    13)
+  (UNSPEC_FRAME_BLOCKAGE 14)
 
   (UNSPECV_SET_FP	1)
   (UNSPECV_ENTRY	2)
@@ -1676,6 +1677,32 @@ 
 
 ;; Miscellaneous instructions.
 
+;; In windowed ABI stack pointer adjustment must happen before any access
+;; to the space allocated on stack is allowed, otherwise register spill
+;; area may be clobbered.  That's what frame blockage is supposed to enforce.
+
+(define_expand "allocate_stack"
+  [(set (match_operand 0 "nonimmed_operand")
+        (minus (reg A1_REG) (match_operand 1 "add_operand")))
+   (set (reg A1_REG)
+        (minus (reg A1_REG) (match_dup 1)))]
+  "TARGET_WINDOWED_ABI"
+{
+  if (CONST_INT_P (operands[1]))
+    {
+      rtx neg_op0 = GEN_INT (-INTVAL (operands[1]));
+      emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, neg_op0));
+    }
+  else
+    {
+      emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
+			     operands[1]));
+    }
+  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
+  emit_insn (gen_frame_blockage ());
+  DONE;
+})
+
 (define_expand "prologue"
   [(const_int 0)]
   ""
@@ -1767,6 +1794,25 @@ 
   [(set_attr "length" "0")
    (set_attr "type" "nop")])
 
+;; Do not schedule instructions accessing memory before this point.
+
+(define_expand "frame_blockage"
+  [(set (match_dup 0)
+        (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
+  ""
+{
+  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+  MEM_VOLATILE_P (operands[0]) = 1;
+  operands[1] = stack_pointer_rtx;
+})
+
+(define_insn "*frame_blockage"
+  [(set (match_operand:BLK 0 "" "")
+        (unspec:BLK [(match_operand:SI 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
+  ""
+  ""
+  [(set_attr "length" "0")])
+
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 0))]
   ""