RISC-V: Make sure stack is always aligned during adjusting

Message ID CA+yXCZA1VmmZKLuXof0HydU-cvzpfDt3muCPYcZ8bgQwHfrFCg@mail.gmail.com
State New
Headers show
Series
  • RISC-V: Make sure stack is always aligned during adjusting
Related show

Commit Message

Kito Cheng April 18, 2018, 11:59 a.m.
Hi all:

I've hit a bug when running gcc testsuite with gc trunk on our
internal simulator, C extension may generate non-aligned
stack in some program point.

Verified with gcc testsuite on rv32imac/rv32ima elf.

Fail case:
riscv32-elf-gcc -march=rv32imac gcc/testsuite/gcc.dg/graph
ite/interchange-6.c  -O2 -ffast-math -floop-nest-opt
imize -o - -S
...
        .type   main, @function
main:
       li      t1,-81920
       addi    sp,sp,-36 # <-- stack not aligned here!
...


gcc/ChangeLog:

2018-04-18  Kito Cheng  <kito.cheng@gmail.com>

       * config/riscv/riscv.c (riscv_first_stack_step): Round up min
       step and round down max step to make sure stack always aligned.

Comments

Jim Wilson April 19, 2018, 12:42 a.m. | #1
On Wed, Apr 18, 2018 at 4:59 AM, Kito Cheng <kito.cheng@gmail.com> wrote:
+  HOST_WIDE_INT min_first_step =
+    RISCV_STACK_ALIGN (frame->total_size - frame->fp_sp_offset);
+  HOST_WIDE_INT max_first_step =
+    ROUND_DOWN (IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8,
+               PREFERRED_STACK_BOUNDARY / 8);
+  HOST_WIDE_INT min_second_step =
+    RISCV_STACK_ALIGN (frame->total_size - max_first_step);

IMM_REACH and PREFERRED_STACK_BOUNDARY are aligned values, so I don't
see the point of rounding max_first_step.  Similarly,
frame->total_size and max_first_step are aligned values, so I don't
see the point of rounding min_second_step.  I do see that rounding
min_first_step is useful.  I'd like to add just that one statement
change unless you have a reason for the others.

I tested this with the following

+  if (min_first_step != RISCV_STACK_ALIGN (min_first_step))
+    abort ();
+  if (max_first_step != RISCV_STACK_ALIGN (max_first_step))
+    abort ();
+  if (min_second_step != RISCV_STACK_ALIGN (min_second_step))
+    abort ();

doing 32/64 elf/linux cross builds and testsuite runs.  It failed for
a 32-bit target before I rounded min_first_step.  With that one
change, I saw no further failures.

Jim

Patch

From cf75c573ec9c8e5071e54a3cfba377fd0cb5bf3d Mon Sep 17 00:00:00 2001
From: Kito Cheng <kito.cheng@gmail.com>
Date: Wed, 18 Apr 2018 17:51:35 +0800
Subject: [PATCH] RISC-V: Make sure stack is always aligned during adjusting
 stack.

gcc/ChangeLog:

2018-04-18  Kito Cheng  <kito.cheng@gmail.com>

	* config/riscv/riscv.c (riscv_first_stack_step): Round up min
	step and round down max step to make sure stack always aligned.
---
 gcc/config/riscv/riscv.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 2870177fa97..eca1cacf015 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -3507,9 +3507,13 @@  riscv_first_stack_step (struct riscv_frame_info *frame)
   if (SMALL_OPERAND (frame->total_size))
     return frame->total_size;
 
-  HOST_WIDE_INT min_first_step = frame->total_size - frame->fp_sp_offset;
-  HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8;
-  HOST_WIDE_INT min_second_step = frame->total_size - max_first_step;
+  HOST_WIDE_INT min_first_step =
+    RISCV_STACK_ALIGN (frame->total_size - frame->fp_sp_offset);
+  HOST_WIDE_INT max_first_step =
+    ROUND_DOWN (IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8,
+		PREFERRED_STACK_BOUNDARY / 8);
+  HOST_WIDE_INT min_second_step =
+    RISCV_STACK_ALIGN (frame->total_size - max_first_step);
   gcc_assert (min_first_step <= max_first_step);
 
   /* As an optimization, use the least-significant bits of the total frame
-- 
2.11.2