From patchwork Mon Nov 28 05:29:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fei Gao X-Patchwork-Id: 61137 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C9B3D38532FA for ; Mon, 28 Nov 2022 05:29:50 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from zg8tmtyylji0my4xnjeumjiw.icoremail.net (zg8tmtyylji0my4xnjeumjiw.icoremail.net [162.243.161.220]) by sourceware.org (Postfix) with SMTP id 25BFD3857C48 for ; Mon, 28 Nov 2022 05:29:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 25BFD3857C48 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from localhost.localdomain (unknown [10.12.130.31]) by app2 (Coremail) with SMTP id EggMCgDXtS8iR4RjisETAA--.65016S5; Mon, 28 Nov 2022 13:29:10 +0800 (CST) From: Fei Gao To: gcc-patches@gcc.gnu.org Cc: kito.cheng@gmail.com, palmer@dabbelt.com, Fei Gao Subject: [PATCH 1/1] RISC-V: fix stack access before allocation. Date: Mon, 28 Nov 2022 05:29:04 +0000 Message-Id: <20221128052904.36217-2-gaofei@eswincomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221128052904.36217-1-gaofei@eswincomputing.com> References: <20221128052904.36217-1-gaofei@eswincomputing.com> X-CM-TRANSID: EggMCgDXtS8iR4RjisETAA--.65016S5 X-Coremail-Antispam: 1UD129KBjvJXoWxXr17ArW5JF18CF15CF1Utrb_yoWrZF4xpa 13GFsIyrWrJFyxGr1xKFy8Ja13GwsYgry5u3s7Ar1Ikr4rJrW29FsrKa13Ar13GFWjgwnI kFW3uw13uw4jq3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUPa14x267AKxVW8JVW5JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26r1Y6r1xM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY02Avz4vE-syl42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1l4IxYO2xFxVAFwI0_Jrv_JF1lx2IqxVAq x4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r 1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF 7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxV WUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjfU FsqXDUUUU X-CM-SenderInfo: xjdrwv3l6h245lqf0zpsxwx03jof0z/ X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" In current riscv stack frame allocation, 2 steps are used. The first step allocates memories at least for callee saved GPRs and FPRs, and the second step allocates the rest if stack size is greater than signed 12-bit range. But it's observed in some cases, like gcc.target/riscv/stack_frame.c in my patch, callee saved FPRs fail to be included in the first step allocation, so we get generated instructions like this: li t0,-16384 addi sp,sp,-48 addi t0,t0,752 ... fsw fs4,-4(sp) #issue here of accessing before allocation ... add sp,sp,t0 "fsw fs4,-4(sp)" has issue here of accessing stack before allocation. Although "add sp,sp,t0" reserves later the memory for fs4, it exposes a risk when an interrupt comes in between "fsw fs4,-4(sp)" and "add sp,sp,t0", resulting in a corruption in the stack storing fs4 after interrupt context saving and a failure to get the correct value of fs4 later. This patch fixes issue above, adapts testcases identified in regression tests, and add a new testcase for the change. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_first_stack_step): gcc/testsuite/ChangeLog: * gcc.target/riscv/pr93304.c: Adapt testcase for the change, constrain match to assembly instructions only. * gcc.target/riscv/rvv/base/spill-11.c: Adapt testcase for the change. * gcc.target/riscv/stack_frame.c: New test. --- gcc/config/riscv/riscv.cc | 2 +- gcc/testsuite/gcc.target/riscv/pr93304.c | 2 +- .../gcc.target/riscv/rvv/base/spill-11.c | 3 +-- gcc/testsuite/gcc.target/riscv/stack_frame.c | 26 +++++++++++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/stack_frame.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 7ec4ce97e6c..8d94765b4ba 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -4903,7 +4903,7 @@ riscv_first_stack_step (struct riscv_frame_info *frame) return frame_total_constant_size; HOST_WIDE_INT min_first_step = - RISCV_STACK_ALIGN ((frame->total_size - frame->fp_sp_offset).to_constant()); + RISCV_STACK_ALIGN ((frame->total_size - frame->frame_pointer_offset).to_constant()); HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8; HOST_WIDE_INT min_second_step = frame_total_constant_size - max_first_step; gcc_assert (min_first_step <= max_first_step); diff --git a/gcc/testsuite/gcc.target/riscv/pr93304.c b/gcc/testsuite/gcc.target/riscv/pr93304.c index ce2dc4d6921..76975ff81c5 100644 --- a/gcc/testsuite/gcc.target/riscv/pr93304.c +++ b/gcc/testsuite/gcc.target/riscv/pr93304.c @@ -16,4 +16,4 @@ foo (void) regradless of the REG_ALLOC_ORDER. In theory, t2 should not used in such small program if regrename not executed incorrectly, because t0-a2 should be enough. */ -/* { dg-final { scan-assembler-not "t2" } } */ +/* { dg-final { scan-assembler-not {\t[a-zA-Z0-9]+\t.*t2} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c index c2f68b86d90..f5223491665 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/spill-11.c @@ -21,9 +21,8 @@ void fn3 (char*); ** slli\tt1,t0,1 ** add\tsp,sp,t1 ** li\tt0,8192 -** addi\tt0,t0,-208 +** addi\tt0,t0,-192 ** add\tsp,sp,t0 -** addi\tsp,sp,16 ** tail\t__riscv_restore_2 */ int stack_save_restore_2 (float a1, float a2, float a3, float a4, diff --git a/gcc/testsuite/gcc.target/riscv/stack_frame.c b/gcc/testsuite/gcc.target/riscv/stack_frame.c new file mode 100644 index 00000000000..485a52d5133 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/stack_frame.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv32imafc -mabi=ilp32f" } */ +char my_getchar(); +float getf(); + +float foo() +{ + char volatile array[3120]; + float volatile farray[3120]; + float sum = 0; + float f1 = getf(); + float f2 = getf(); + float f3 = getf(); + float f4 = getf(); + + for (int i = 0; i < 3120; i++) + { + array[i] = my_getchar(); + farray[i] = my_getchar() * 1.2; + sum += array[i] + farray[i] + f1 + f2 + f3 + f4; + } + + return sum; +} + +/* { dg-final { scan-assembler-not {,-[0-9]+\(sp\)} } } */