Re: [PATCH] gcc: xtensa: fix PR target/108919

2023-02-25 Thread Max Filippov via Gcc-patches
Hi Suwa-san,

On Sat, Feb 25, 2023 at 3:33 AM Takayuki 'January June' Suwa
 wrote:
> On 2023/02/25 19:01, Max Filippov wrote:
> > diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
> > index e52fba082550..babe7f0ebd68 100644
> > --- a/gcc/config/xtensa/xtensa.cc
> > +++ b/gcc/config/xtensa/xtensa.cc
> > @@ -2183,8 +2183,10 @@ xtensa_emit_movcc (bool inverted, bool isfp, bool 
> > isbool, rtx *operands)
> >
> >
> >  void
> > -xtensa_prepare_expand_call (int callop, rtx *operands)
> > +xtensa_expand_call (int callop, rtx *operands)
> >  {
> > +  rtx call;
> > +  rtx call_insn;
>
> ;; This should be rtx_insn* rather than rtx,
> -  rtx call_insn;
> +  rtx_insn *call_insn;
>
> >rtx addr = XEXP (operands[callop], 0);
> >
> >if (flag_pic && SYMBOL_REF_P (addr)
> > @@ -2202,6 +2204,27 @@ xtensa_prepare_expand_call (int callop, rtx 
> > *operands)
> >Pmode);
> >XEXP (operands[callop], 0) = reg;
> >  }
> > +
> > +  call = gen_rtx_CALL (VOIDmode, operands[callop], operands[callop + 1]);
> > +
> > +  if (callop)
> > +call_insn = emit_call_insn (gen_rtx_SET (operands[0], call));
> > +  else
> > +call_insn = emit_call_insn (call);
>
> ;; Simpler,
>call = gen_rtx_CALL (VOIDmode, operands[callop], operands[callop + 1]);
> -
>if (callop)
> -call_insn = emit_call_insn (gen_rtx_SET (operands[0], call));
> -  else
> -call_insn = emit_call_insn (call);
> +call = gen_rtx_SET (operands[0], call);
> +  call_insn = emit_call_insn (call);

Thank you for the review!

> (I had just removed "WIP" from the set of backported patches to the 
> esp8266/Arduino toolchain,
> so I am worried that it was a bit premature, but relieved soon to find that 
> it has nothing to do
> with the CALL0 ABI...)

Unrelated indeed, just popped up during the recent testing.

-- 
Thanks.
-- Max


Re: [PATCH] gcc: xtensa: fix PR target/108919

2023-02-25 Thread Takayuki 'January June' Suwa via Gcc-patches
Hello, Max:

On 2023/02/25 19:01, Max Filippov wrote:

> gcc/
>   PR target/108919
> 
>   * config/xtensa/xtensa-protos.h
>   (xtensa_prepare_expand_call): Rename to xtensa_expand_call.
>   * config/xtensa/xtensa.cc (xtensa_prepare_expand_call): Rename
>   to xtensa_expand_call.
>   (xtensa_expand_call): Emit the call and add a clobber expression
>   for the static chain to it in case of windowed ABI.
>   * config/xtensa/xtensa.md (call, call_value, sibcall)
>   (sibcall_value): Call xtensa_expand_call and complete expansion
>   right after that call.
> 
> gcc/testduite/
>   * gcc.target/xtensa/pr108919.c: New test.
> ---
>  gcc/config/xtensa/xtensa-protos.h  |  2 +-
>  gcc/config/xtensa/xtensa.cc| 25 +++-
>  gcc/config/xtensa/xtensa.md| 12 --
>  gcc/testsuite/gcc.target/xtensa/pr108919.c | 46 ++
>  4 files changed, 79 insertions(+), 6 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/xtensa/pr108919.c
> 
> diff --git a/gcc/config/xtensa/xtensa-protos.h 
> b/gcc/config/xtensa/xtensa-protos.h
> index ecd0f0c8d108..c81cf94323ac 100644
> --- a/gcc/config/xtensa/xtensa-protos.h
> +++ b/gcc/config/xtensa/xtensa-protos.h
> @@ -53,7 +53,7 @@ extern void xtensa_expand_atomic (enum rtx_code, rtx, rtx, 
> rtx, bool);
>  extern void xtensa_emit_loop_end (rtx_insn *, rtx *);
>  extern char *xtensa_emit_branch (bool, rtx *);
>  extern char *xtensa_emit_movcc (bool, bool, bool, rtx *);
> -extern void xtensa_prepare_expand_call (int, rtx *);
> +extern void xtensa_expand_call (int, rtx *);
>  extern char *xtensa_emit_call (int, rtx *);
>  extern char *xtensa_emit_sibcall (int, rtx *);
>  extern bool xtensa_tls_referenced_p (rtx);
> diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
> index e52fba082550..babe7f0ebd68 100644
> --- a/gcc/config/xtensa/xtensa.cc
> +++ b/gcc/config/xtensa/xtensa.cc
> @@ -2183,8 +2183,10 @@ xtensa_emit_movcc (bool inverted, bool isfp, bool 
> isbool, rtx *operands)
>  
>  
>  void
> -xtensa_prepare_expand_call (int callop, rtx *operands)
> +xtensa_expand_call (int callop, rtx *operands)
>  {
> +  rtx call;
> +  rtx call_insn;

;; This should be rtx_insn* rather than rtx,
-  rtx call_insn;
+  rtx_insn *call_insn;

>rtx addr = XEXP (operands[callop], 0);
>  
>if (flag_pic && SYMBOL_REF_P (addr)
> @@ -2202,6 +2204,27 @@ xtensa_prepare_expand_call (int callop, rtx *operands)
>Pmode);
>XEXP (operands[callop], 0) = reg;
>  }
> +
> +  call = gen_rtx_CALL (VOIDmode, operands[callop], operands[callop + 1]);
> +
> +  if (callop)
> +call_insn = emit_call_insn (gen_rtx_SET (operands[0], call));
> +  else
> +call_insn = emit_call_insn (call);

;; Simpler,
   call = gen_rtx_CALL (VOIDmode, operands[callop], operands[callop + 1]);
-
   if (callop)
-call_insn = emit_call_insn (gen_rtx_SET (operands[0], call));
-  else
-call_insn = emit_call_insn (call);
+call = gen_rtx_SET (operands[0], call);
+  call_insn = emit_call_insn (call);

> +
> +  if (TARGET_WINDOWED_ABI)
> +{
> +  /*
> +   * Windowed xtensa ABI specifies that static chain pointer is passed
> +   * in memory below the caller stack pointer, which means that the 
> callee
> +   * will likely clobber it if it's a non-leaf function.
> +   * Add the clobber expression for the static chain to the function call
> +   * expression list so that it is not assumed to be live across the 
> call.
> +   */
> +  rtx clob = gen_rtx_CLOBBER (Pmode, xtensa_static_chain (NULL, false));
> +  CALL_INSN_FUNCTION_USAGE (call_insn) =
> + gen_rtx_EXPR_LIST (Pmode, clob, CALL_INSN_FUNCTION_USAGE (call_insn));
> +}
>  }
>  
>  
> diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
> index cf25beb83d54..b60dec2447f3 100644
> --- a/gcc/config/xtensa/xtensa.md
> +++ b/gcc/config/xtensa/xtensa.md
> @@ -2333,7 +2333,8 @@
>(match_operand 1 "" ""))]
>""
>  {
> -  xtensa_prepare_expand_call (0, operands);
> +  xtensa_expand_call (0, operands);
> +  DONE;
>  })
>  
>  (define_insn "call_internal"
> @@ -2353,7 +2354,8 @@
> (match_operand 2 "" "")))]
>""
>  {
> -  xtensa_prepare_expand_call (1, operands);
> +  xtensa_expand_call (1, operands);
> +  DONE;
>  })
>  
>  (define_insn "call_value_internal"
> @@ -2373,7 +2375,8 @@
>(match_operand 1 "" ""))]
>"!TARGET_WINDOWED_ABI"
>  {
> -  xtensa_prepare_expand_call (0, operands);
> +  xtensa_expand_call (0, operands);
> +  DONE;
>  })
>  
>  (define_insn "sibcall_internal"
> @@ -2393,7 +2396,8 @@
> (match_operand 2 "" "")))]
>"!TARGET_WINDOWED_ABI"
>  {
> -  xtensa_prepare_expand_call (1, operands);
> +  xtensa_expand_call (1, operands);
> +  DONE;
>  })
>  
>  (define_insn "sibcall_value_internal"
> diff --git a/gcc/testsuite/gcc.target/xtensa/pr108919.c 
> 

[PATCH] gcc: xtensa: fix PR target/108919

2023-02-25 Thread Max Filippov via Gcc-patches
gcc/
PR target/108919

* config/xtensa/xtensa-protos.h
(xtensa_prepare_expand_call): Rename to xtensa_expand_call.
* config/xtensa/xtensa.cc (xtensa_prepare_expand_call): Rename
to xtensa_expand_call.
(xtensa_expand_call): Emit the call and add a clobber expression
for the static chain to it in case of windowed ABI.
* config/xtensa/xtensa.md (call, call_value, sibcall)
(sibcall_value): Call xtensa_expand_call and complete expansion
right after that call.

gcc/testduite/
* gcc.target/xtensa/pr108919.c: New test.
---
 gcc/config/xtensa/xtensa-protos.h  |  2 +-
 gcc/config/xtensa/xtensa.cc| 25 +++-
 gcc/config/xtensa/xtensa.md| 12 --
 gcc/testsuite/gcc.target/xtensa/pr108919.c | 46 ++
 4 files changed, 79 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/xtensa/pr108919.c

diff --git a/gcc/config/xtensa/xtensa-protos.h 
b/gcc/config/xtensa/xtensa-protos.h
index ecd0f0c8d108..c81cf94323ac 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -53,7 +53,7 @@ extern void xtensa_expand_atomic (enum rtx_code, rtx, rtx, 
rtx, bool);
 extern void xtensa_emit_loop_end (rtx_insn *, rtx *);
 extern char *xtensa_emit_branch (bool, rtx *);
 extern char *xtensa_emit_movcc (bool, bool, bool, rtx *);
-extern void xtensa_prepare_expand_call (int, rtx *);
+extern void xtensa_expand_call (int, rtx *);
 extern char *xtensa_emit_call (int, rtx *);
 extern char *xtensa_emit_sibcall (int, rtx *);
 extern bool xtensa_tls_referenced_p (rtx);
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index e52fba082550..babe7f0ebd68 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -2183,8 +2183,10 @@ xtensa_emit_movcc (bool inverted, bool isfp, bool 
isbool, rtx *operands)
 
 
 void
-xtensa_prepare_expand_call (int callop, rtx *operands)
+xtensa_expand_call (int callop, rtx *operands)
 {
+  rtx call;
+  rtx call_insn;
   rtx addr = XEXP (operands[callop], 0);
 
   if (flag_pic && SYMBOL_REF_P (addr)
@@ -2202,6 +2204,27 @@ xtensa_prepare_expand_call (int callop, rtx *operands)
 Pmode);
   XEXP (operands[callop], 0) = reg;
 }
+
+  call = gen_rtx_CALL (VOIDmode, operands[callop], operands[callop + 1]);
+
+  if (callop)
+call_insn = emit_call_insn (gen_rtx_SET (operands[0], call));
+  else
+call_insn = emit_call_insn (call);
+
+  if (TARGET_WINDOWED_ABI)
+{
+  /*
+   * Windowed xtensa ABI specifies that static chain pointer is passed
+   * in memory below the caller stack pointer, which means that the callee
+   * will likely clobber it if it's a non-leaf function.
+   * Add the clobber expression for the static chain to the function call
+   * expression list so that it is not assumed to be live across the call.
+   */
+  rtx clob = gen_rtx_CLOBBER (Pmode, xtensa_static_chain (NULL, false));
+  CALL_INSN_FUNCTION_USAGE (call_insn) =
+   gen_rtx_EXPR_LIST (Pmode, clob, CALL_INSN_FUNCTION_USAGE (call_insn));
+}
 }
 
 
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index cf25beb83d54..b60dec2447f3 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -2333,7 +2333,8 @@
 (match_operand 1 "" ""))]
   ""
 {
-  xtensa_prepare_expand_call (0, operands);
+  xtensa_expand_call (0, operands);
+  DONE;
 })
 
 (define_insn "call_internal"
@@ -2353,7 +2354,8 @@
  (match_operand 2 "" "")))]
   ""
 {
-  xtensa_prepare_expand_call (1, operands);
+  xtensa_expand_call (1, operands);
+  DONE;
 })
 
 (define_insn "call_value_internal"
@@ -2373,7 +2375,8 @@
 (match_operand 1 "" ""))]
   "!TARGET_WINDOWED_ABI"
 {
-  xtensa_prepare_expand_call (0, operands);
+  xtensa_expand_call (0, operands);
+  DONE;
 })
 
 (define_insn "sibcall_internal"
@@ -2393,7 +2396,8 @@
  (match_operand 2 "" "")))]
   "!TARGET_WINDOWED_ABI"
 {
-  xtensa_prepare_expand_call (1, operands);
+  xtensa_expand_call (1, operands);
+  DONE;
 })
 
 (define_insn "sibcall_value_internal"
diff --git a/gcc/testsuite/gcc.target/xtensa/pr108919.c 
b/gcc/testsuite/gcc.target/xtensa/pr108919.c
new file mode 100644
index ..300b6fd10a99
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xtensa/pr108919.c
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+
+#ifdef __XTENSA_CALL0_ABI__
+void __xtensa_libgcc_window_spill (void)
+{
+}
+#else
+void __xtensa_libgcc_window_spill (void);
+#endif
+
+__attribute__((noinline)) void h (void)
+{
+  __xtensa_libgcc_window_spill ();
+}
+
+int f (int u, int v)
+{
+  int a = u;
+  int s;
+
+  __attribute__((noinline,pure)) int nested1 (int b)
+  {
+  h();
+  return a + b;
+  }
+
+  __attribute__((noinline,pure)) int nested2 (int b)
+  {
+  h();
+  return a - b;
+  }
+
+  s = nested1 (v);
+