Hi,

on 2024/5/16 12:08, Andrew Pinski wrote:
> 
> On Thu, May 16, 2024, 4:09 AM Kewen.Lin <li...@linux.ibm.com 
> <mailto:li...@linux.ibm.com>> wrote:
> 
>     Hi,
> 
>     As the associated test case in PR114846 shows, currently
>     with eh_return involved some register restoring for EH
>     RETURN DATA in epilogue can clobber the one which holding
>     the return value.  Referring to the existing handlings in
>     some other targets, this patch makes eh_return expander
>     call one new define_insn_and_split eh_return_internal which
>     directly calls rs6000_emit_epilogue with epilogue_type
>     EPILOGUE_TYPE_EH_RETURN instead of the previous treating
>     normal return with crtl->calls_eh_return specially.
> 
>     Bootstrapped and regtested on powerpc64-linux-gnu P8/P9 and
>     powerpc64le-linux-gnu P9 and P10.
> 
>     I'm going to push this next week if no objections.
> 
> 
> 
> Thanks for fixing this for powerpc. I hope my patch for aarch64 gets reviewed 
> soon and it will contain many more testcases. Hopefully someone will fix the 
> arm target too.
> 

Looking forward to that!  Thanks for contributing those new eh-return c-torture
test cases, I just tested all of them on LE, all passed. :)

BR,
Kewen

> Thanks,
> Andrew
> 
> 
> 
>     BR,
>     Kewen
>     -----
>             PR target/114846
> 
>     gcc/ChangeLog:
> 
>             * config/rs6000/rs6000-logue.cc (rs6000_emit_epilogue): As
>             EPILOGUE_TYPE_EH_RETURN would be passed as epilogue_type directly
>             now, adjust the relevant handlings on it.
>             * config/rs6000/rs6000.md (eh_return expander): Append by calling
>             gen_eh_return_internal and emit_barrier.
>             (eh_return_internal): New define_insn_and_split, call function
>             rs6000_emit_epilogue with epilogue type EPILOGUE_TYPE_EH_RETURN.
> 
>     gcc/testsuite/ChangeLog:
> 
>             * gcc.target/powerpc/pr114846.c: New test.
>     ---
>      gcc/config/rs6000/rs6000-logue.cc           |  7 +++----
>      gcc/config/rs6000/rs6000.md                 | 15 +++++++++++++++
>      gcc/testsuite/gcc.target/powerpc/pr114846.c | 20 ++++++++++++++++++++
>      3 files changed, 38 insertions(+), 4 deletions(-)
>      create mode 100644 gcc/testsuite/gcc.target/powerpc/pr114846.c
> 
>     diff --git a/gcc/config/rs6000/rs6000-logue.cc 
> b/gcc/config/rs6000/rs6000-logue.cc
>     index 60ba15a8bc3..bd5d56ba002 100644
>     --- a/gcc/config/rs6000/rs6000-logue.cc
>     +++ b/gcc/config/rs6000/rs6000-logue.cc
>     @@ -4308,9 +4308,6 @@ rs6000_emit_epilogue (enum epilogue_type 
> epilogue_type)
> 
>        rs6000_stack_t *info = rs6000_stack_info ();
> 
>     -  if (epilogue_type == EPILOGUE_TYPE_NORMAL && crtl->calls_eh_return)
>     -    epilogue_type = EPILOGUE_TYPE_EH_RETURN;
>     -
>        int strategy = info->savres_strategy;
>        bool using_load_multiple = !!(strategy & REST_MULTIPLE);
>        bool restoring_GPRs_inline = !!(strategy & REST_INLINE_GPRS);
>     @@ -4788,7 +4785,9 @@ rs6000_emit_epilogue (enum epilogue_type 
> epilogue_type)
> 
>        /* In the ELFv2 ABI we need to restore all call-saved CR fields from
>           *separate* slots if the routine calls __builtin_eh_return, so
>     -     that they can be independently restored by the unwinder.  */
>     +     that they can be independently restored by the unwinder.  Since
>     +     it is for CR fields restoring, it should be done for any epilogue
>     +     types (not EPILOGUE_TYPE_EH_RETURN specific).  */
>        if (DEFAULT_ABI == ABI_ELFv2 && crtl->calls_eh_return)
>          {
>            int i, cr_off = info->ehcr_offset;
>     diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
>     index ac5651d7420..d4120c3b9ce 100644
>     --- a/gcc/config/rs6000/rs6000.md
>     +++ b/gcc/config/rs6000/rs6000.md
>     @@ -14281,6 +14281,8 @@ (define_expand "eh_return"
>        ""
>      {
>        emit_insn (gen_eh_set_lr (Pmode, operands[0]));
>     +  emit_jump_insn (gen_eh_return_internal ());
>     +  emit_barrier ();
>        DONE;
>      })
> 
>     @@ -14297,6 +14299,19 @@ (define_insn_and_split "@eh_set_lr_<mode>"
>        DONE;
>      })
> 
>     +(define_insn_and_split "eh_return_internal"
>     +  [(eh_return)]
>     +  ""
>     +  "#"
>     +  "epilogue_completed"
>     +  [(const_int 0)]
>     +{
>     +  if (!TARGET_SCHED_PROLOG)
>     +    emit_insn (gen_blockage ());
>     +  rs6000_emit_epilogue (EPILOGUE_TYPE_EH_RETURN);
>     +  DONE;
>     +})
>     +
>      (define_insn "prefetch"
>        [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
>                  (match_operand:SI 1 "const_int_operand" "n")
>     diff --git a/gcc/testsuite/gcc.target/powerpc/pr114846.c 
> b/gcc/testsuite/gcc.target/powerpc/pr114846.c
>     new file mode 100644
>     index 00000000000..efe2300b73a
>     --- /dev/null
>     +++ b/gcc/testsuite/gcc.target/powerpc/pr114846.c
>     @@ -0,0 +1,20 @@
>     +/* { dg-do run } */
>     +/* { dg-require-effective-target builtin_eh_return } */
>     +
>     +/* Ensure it runs successfully.  */
>     +
>     +__attribute__ ((noipa))
>     +int f (int *a, long offset, void *handler)
>     +{
>     +  if (*a == 5)
>     +    return 5;
>     +  __builtin_eh_return (offset, handler);
>     +}
>     +
>     +int main ()
>     +{
>     +  int t = 5;
>     +  if (f (&t, 0, 0) != 5)
>     +    __builtin_abort ();
>     +  return 0;
>     +}
>     --
>     2.39.3
> 

Reply via email to