From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 4FD933858D37 for ; Tue, 30 Apr 2024 01:15:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4FD933858D37 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4FD933858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714439715; cv=none; b=Rhr/kaIRRU1GmBDDPKhcqdW4pXjqbTmdIKfpAy2AfCzYzrqVy5sXNtLlsr4YtpGIOX/S6fXIkZ3sXJgqsZBkTOEor6QpqDfckWaaCdyVmiyzhFKhg5OBkpmPsGK2po/bIpvGXLxLEQjtN0rxpkdjoDPAe5YhPSTGFeJAhKvxC90= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714439715; c=relaxed/simple; bh=mnlV5hRgC7W8Rs98m/72Hpwh1wuUNNtBKzZ3nVn/vu8=; h=Subject:To:From:Message-ID:Date:MIME-Version; b=Z3CEf7nSgBjZivvs5/WZsjFKK0nQ4ihi355yljNEkHgp0gft2JNzvZUVgLc8rOtrsroXqsZDxYCDjl6tBqe05Wpo0N9gjRMR6WA3kNd3oHQ7Mn+ta2hLaq7eL5vhMbOgXp9QE3O1N+0CI9R2sHU7BHKOULlq8pX3mJ9YLr8gcqI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from loongson.cn (unknown [10.20.4.107]) by gateway (Coremail) with SMTP id _____8Ax5eodRjBmSzcFAA--.5727S3; Tue, 30 Apr 2024 09:15:09 +0800 (CST) Received: from [10.20.4.107] (unknown [10.20.4.107]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Bxut0aRjBmxrUKAA--.25883S3; Tue, 30 Apr 2024 09:15:07 +0800 (CST) Subject: Re: [pushed][PATCH][gcc-13] LoongArch: Fix eh_return epilogue for normal returns. To: gcc-patches@gcc.gnu.org Cc: xry111@xry111.site, i@xen0n.name, xuchenghua@loongson.cn, Yang Yujie References: <20240429080949.32621-1-chenglulu@loongson.cn> From: Lulu Cheng Message-ID: Date: Tue, 30 Apr 2024 09:15:06 +0800 User-Agent: Mozilla/5.0 (X11; Linux loongarch64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <20240429080949.32621-1-chenglulu@loongson.cn> Content-Type: text/plain; charset=gbk; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-CM-TRANSID:AQAAf8Bxut0aRjBmxrUKAA--.25883S3 X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBj93XoW3Xr15WrWUGF1xuryDtFW7Jrc_yoW3CF1rpr Z7ZFnxAr48JwnxGryDJ343XFn3Cr4xKw1293W3t34xCw47Zr9rZF18Kr9FqF1ktw1kCr1I qF4kJa1Y93WUJ3cCm3ZEXasCq-sJn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUv0b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r106r15M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_ Gr0_Gr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx1l5I 8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AK xVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IY64vIr41lc7I2V7IY0VAS07AlzV AYIcxG8wCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E 14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIx kGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAF wI0_Jr0_Gr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r 4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Jr0_GrUvcSsGvfC2KfnxnUUI43ZEXa7IU8wNVDUU UUU== X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00,GIT_PATCH_0,KAM_DMARC_STATUS,KAM_SHORT,MIME_CHARSET_FARAWAY,NICE_REPLY_A,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 List-Id: Pushed to r13-8661. ÔÚ 2024/4/29 ÏÂÎç4:09, Lulu Cheng дµÀ: > From: Yang Yujie > > On LoongArch, the regitsters $r4 - $r7 (EH_RETURN_DATA_REGNO) will be saved > and restored in the function prologue and epilogue if the given function calls > __builtin_eh_return. This causes the return value to be overwritten on normal > return paths and breaks a rare case of libgcc's _Unwind_RaiseException. > > gcc/ChangeLog: > > PR target/114848 > * config/loongarch/loongarch.cc: Do not restore the saved eh_return > data registers ($r4-$r7) for a normal return of a function that calls > __builtin_eh_return elsewhere. > * config/loongarch/loongarch-protos.h: Same. > * config/loongarch/loongarch.md: Same. > > gcc/testsuite/ChangeLog: > > * gcc.target/loongarch/eh_return-normal-return.c: New test. > > (cherry picked from commit 4b421728289e6f1caa0dfaa953a11698ab95d37d) > --- > gcc/config/loongarch/loongarch-protos.h | 2 +- > gcc/config/loongarch/loongarch.cc | 35 ++++++++++++----- > gcc/config/loongarch/loongarch.md | 23 ++++++++++- > .../loongarch/eh_return-normal-return.c | 38 +++++++++++++++++++ > 4 files changed, 85 insertions(+), 13 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/loongarch/eh_return-normal-return.c > > diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h > index 35cc77c7367..0f608ee5179 100644 > --- a/gcc/config/loongarch/loongarch-protos.h > +++ b/gcc/config/loongarch/loongarch-protos.h > @@ -60,7 +60,7 @@ enum loongarch_symbol_type { > extern rtx loongarch_emit_move (rtx, rtx); > extern HOST_WIDE_INT loongarch_initial_elimination_offset (int, int); > extern void loongarch_expand_prologue (void); > -extern void loongarch_expand_epilogue (bool); > +extern void loongarch_expand_epilogue (int); > extern bool loongarch_can_use_return_insn (void); > > extern bool loongarch_symbolic_constant_p (rtx, enum loongarch_symbol_type *); > diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc > index f47a5fc2ad7..2238858cd6a 100644 > --- a/gcc/config/loongarch/loongarch.cc > +++ b/gcc/config/loongarch/loongarch.cc > @@ -1012,7 +1012,8 @@ loongarch_save_restore_reg (machine_mode mode, int regno, HOST_WIDE_INT offset, > > static void > loongarch_for_each_saved_reg (HOST_WIDE_INT sp_offset, > - loongarch_save_restore_fn fn) > + loongarch_save_restore_fn fn, > + bool skip_eh_data_regs_p) > { > HOST_WIDE_INT offset; > > @@ -1021,7 +1022,15 @@ loongarch_for_each_saved_reg (HOST_WIDE_INT sp_offset, > for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) > if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) > { > - loongarch_save_restore_reg (word_mode, regno, offset, fn); > + /* Special care needs to be taken for $r4-$r7 (EH_RETURN_DATA_REGNO) > + when returning normally from a function that calls > + __builtin_eh_return. In this case, these registers are saved but > + should not be restored, or the return value may be clobbered. */ > + > + if (!(skip_eh_data_regs_p > + && GP_ARG_FIRST <= regno && regno < GP_ARG_FIRST + 4)) > + loongarch_save_restore_reg (word_mode, regno, offset, fn); > + > offset -= UNITS_PER_WORD; > } > > @@ -1290,7 +1299,7 @@ loongarch_expand_prologue (void) > GEN_INT (-step1)); > RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; > size -= step1; > - loongarch_for_each_saved_reg (size, loongarch_save_reg); > + loongarch_for_each_saved_reg (size, loongarch_save_reg, false); > } > > /* Set up the frame pointer, if we're using one. */ > @@ -1375,11 +1384,13 @@ loongarch_can_use_return_insn (void) > return reload_completed && cfun->machine->frame.total_size == 0; > } > > -/* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P > - says which. */ > +/* Expand function epilogue using the following insn patterns: > + "epilogue" (style == NORMAL_RETURN) > + "sibcall_epilogue" (style == SIBCALL_RETURN) > + "eh_return" (style == EXCEPTION_RETURN) */ > > void > -loongarch_expand_epilogue (bool sibcall_p) > +loongarch_expand_epilogue (int style) > { > /* Split the frame into two. STEP1 is the amount of stack we should > deallocate before restoring the registers. STEP2 is the amount we > @@ -1396,7 +1407,8 @@ loongarch_expand_epilogue (bool sibcall_p) > bool need_barrier_p > = (get_frame_size () + cfun->machine->frame.arg_pointer_offset) != 0; > > - if (!sibcall_p && loongarch_can_use_return_insn ()) > + /* Handle simple returns. */ > + if (style == NORMAL_RETURN && loongarch_can_use_return_insn ()) > { > emit_jump_insn (gen_return ()); > return; > @@ -1472,7 +1484,9 @@ loongarch_expand_epilogue (bool sibcall_p) > > /* Restore the registers. */ > loongarch_for_each_saved_reg (frame->total_size - step2, > - loongarch_restore_reg); > + loongarch_restore_reg, > + crtl->calls_eh_return > + && style != EXCEPTION_RETURN); > > if (need_barrier_p) > loongarch_emit_stack_tie (); > @@ -1493,11 +1507,12 @@ loongarch_expand_epilogue (bool sibcall_p) > } > > /* Add in the __builtin_eh_return stack adjustment. */ > - if (crtl->calls_eh_return) > + if (crtl->calls_eh_return && style == EXCEPTION_RETURN) > emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, > EH_RETURN_STACKADJ_RTX)); > > - if (!sibcall_p) > + /* Emit return unless doing sibcall. */ > + if (style != SIBCALL_RETURN) > emit_jump_insn (gen_simple_return_internal (ra)); > } > > diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md > index 830eaaea90e..acf1269b402 100644 > --- a/gcc/config/loongarch/loongarch.md > +++ b/gcc/config/loongarch/loongarch.md > @@ -115,6 +115,11 @@ (define_constants > (T1_REGNUM 13) > (S0_REGNUM 23) > > + ;; Return path styles > + (NORMAL_RETURN 0) > + (SIBCALL_RETURN 1) > + (EXCEPTION_RETURN 2) > + > ;; PIC long branch sequences are never longer than 100 bytes. > (MAX_PIC_BRANCH_LENGTH 100) > ]) > @@ -2947,7 +2952,7 @@ (define_expand "epilogue" > [(const_int 2)] > "" > { > - loongarch_expand_epilogue (false); > + loongarch_expand_epilogue (NORMAL_RETURN); > DONE; > }) > > @@ -2955,7 +2960,7 @@ (define_expand "sibcall_epilogue" > [(const_int 2)] > "" > { > - loongarch_expand_epilogue (true); > + loongarch_expand_epilogue (SIBCALL_RETURN); > DONE; > }) > > @@ -3012,6 +3017,20 @@ (define_expand "eh_return" > emit_insn (gen_eh_set_ra_di (operands[0])); > else > emit_insn (gen_eh_set_ra_si (operands[0])); > + > + emit_jump_insn (gen_eh_return_internal ()); > + emit_barrier (); > + DONE; > +}) > + > +(define_insn_and_split "eh_return_internal" > + [(eh_return)] > + "" > + "#" > + "epilogue_completed" > + [(const_int 0)] > +{ > + loongarch_expand_epilogue (EXCEPTION_RETURN); > DONE; > }) > > diff --git a/gcc/testsuite/gcc.target/loongarch/eh_return-normal-return.c b/gcc/testsuite/gcc.target/loongarch/eh_return-normal-return.c > new file mode 100644 > index 00000000000..f8f3965f894 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/eh_return-normal-return.c > @@ -0,0 +1,38 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2" } */ > + > +#include > + > +int foo () __attribute__((noinline)); > +int main (); > + > +int > +foo () { > + > + int t; > + > + /* prevent optimization using asm */ > + asm ("" : "=r" (t) : "0" (-1)); > + asm ("" : "=r" (t) : "0" (t ? 1 : 0)); > + > + if (t == 0) > + /* never reached */ > + __builtin_eh_return (0, __builtin_return_address (0)); > + > + else if (t == 1) > + /* return here */ > + return 202312; > + > + else > + /* never reached: prevent vrp optimization in main */ > + return 0; > +} > + > +int > +main () > +{ > + if (foo() == 202312) > + return 0; > + else > + abort (); > +}