x86: Replace ix86_red_zone_size with ix86_red_zone_used

Message ID 20210611204643.253863-1-hjl.tools@gmail.com
State New
Headers show
Series
  • x86: Replace ix86_red_zone_size with ix86_red_zone_used
Related show

Commit Message

David Malcolm via Gcc-patches June 11, 2021, 8:46 p.m.
Add red_zone_used to machine_function to track if red zone is used.
When expanding function prologue, set red_zone_used to true if red
zone is used.

gcc/

	PR target/pr101023
	* config/i386/i386.c (ix86_expand_prologue): Set red_zone_used
	to true if red zone is used.
	(ix86_output_indirect_jmp): Replace ix86_red_zone_size with
	ix86_red_zone_used.
	* config/i386/i386.h (machine_function): Add red_zone_used.
	(ix86_red_zone_size): Removed.
	(ix86_red_zone_used): New.
	* config/i386/i386.md (peephole2 patterns): Replace
	ix86_red_zone_size with ix86_red_zone_used.

gcc/testsuite/

	PR target/pr101023
	* g++.target/i386/pr101023a.C: New test.
	* g++.target/i386/pr101023b.C: Likewise.
---
 gcc/config/i386/i386.c                    |  6 ++-
 gcc/config/i386/i386.h                    |  5 +-
 gcc/config/i386/i386.md                   |  8 +--
 gcc/testsuite/g++.target/i386/pr101023a.C | 62 +++++++++++++++++++++++
 gcc/testsuite/g++.target/i386/pr101023b.C |  5 ++
 5 files changed, 80 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/i386/pr101023a.C
 create mode 100644 gcc/testsuite/g++.target/i386/pr101023b.C

-- 
2.31.1

Comments

David Malcolm via Gcc-patches June 13, 2021, 11:22 a.m. | #1
On Fri, Jun 11, 2021 at 10:46 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>

> Add red_zone_used to machine_function to track if red zone is used.

> When expanding function prologue, set red_zone_used to true if red

> zone is used.

>

> gcc/

>

>         PR target/pr101023

>         * config/i386/i386.c (ix86_expand_prologue): Set red_zone_used

>         to true if red zone is used.

>         (ix86_output_indirect_jmp): Replace ix86_red_zone_size with

>         ix86_red_zone_used.

>         * config/i386/i386.h (machine_function): Add red_zone_used.

>         (ix86_red_zone_size): Removed.

>         (ix86_red_zone_used): New.

>         * config/i386/i386.md (peephole2 patterns): Replace

>         ix86_red_zone_size with ix86_red_zone_used.

>

> gcc/testsuite/

>

>         PR target/pr101023

>         * g++.target/i386/pr101023a.C: New test.

>         * g++.target/i386/pr101023b.C: Likewise.


LGTM.

Thanks,
Uros.

> ---

>  gcc/config/i386/i386.c                    |  6 ++-

>  gcc/config/i386/i386.h                    |  5 +-

>  gcc/config/i386/i386.md                   |  8 +--

>  gcc/testsuite/g++.target/i386/pr101023a.C | 62 +++++++++++++++++++++++

>  gcc/testsuite/g++.target/i386/pr101023b.C |  5 ++

>  5 files changed, 80 insertions(+), 6 deletions(-)

>  create mode 100644 gcc/testsuite/g++.target/i386/pr101023a.C

>  create mode 100644 gcc/testsuite/g++.target/i386/pr101023b.C

>

> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c

> index 05b8dc806cd..a61255857ff 100644

> --- a/gcc/config/i386/i386.c

> +++ b/gcc/config/i386/i386.c

> @@ -8401,10 +8401,14 @@ ix86_expand_prologue (void)

>                    || frame.stack_pointer_offset < CHECK_STACK_LIMIT))

>         {

>           ix86_emit_save_regs_using_mov (frame.reg_save_offset);

> +         cfun->machine->red_zone_used = true;

>           int_registers_saved = true;

>         }

>      }

>

> +  if (frame.red_zone_size != 0)

> +    cfun->machine->red_zone_used = true;

> +

>    if (stack_realign_fp)

>      {

>        int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;

> @@ -15915,7 +15919,7 @@ ix86_output_indirect_jmp (rtx call_op)

>      {

>        /* We can't have red-zone since "call" in the indirect thunk

>           pushes the return address onto stack, destroying red-zone.  */

> -      if (ix86_red_zone_size != 0)

> +      if (ix86_red_zone_used)

>         gcc_unreachable ();

>

>        ix86_output_indirect_branch (call_op, "%0", true);

> diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h

> index 919d0b2418a..182b3275991 100644

> --- a/gcc/config/i386/i386.h

> +++ b/gcc/config/i386/i386.h

> @@ -2663,6 +2663,9 @@ struct GTY(()) machine_function {

>       invalid calls.  */

>    BOOL_BITFIELD silent_p : 1;

>

> +  /* True if red zone is used.  */

> +  BOOL_BITFIELD red_zone_used : 1;

> +

>    /* The largest alignment, in bytes, of stack slot actually used.  */

>    unsigned int max_used_stack_alignment;

>

> @@ -2693,7 +2696,7 @@ extern GTY(()) tree ms_va_list_type_node;

>  #define ix86_current_function_calls_tls_descriptor \

>    (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG))

>  #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack)

> -#define ix86_red_zone_size (cfun->machine->frame.red_zone_size)

> +#define ix86_red_zone_used (cfun->machine->red_zone_used)

>

>  /* Control behavior of x86_file_start.  */

>  #define X86_FILE_START_VERSION_DIRECTIVE false

> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md

> index 7743c61ec86..6e4abf32e7c 100644

> --- a/gcc/config/i386/i386.md

> +++ b/gcc/config/i386/i386.md

> @@ -20491,7 +20491,7 @@ (define_peephole2

>               (clobber (mem:BLK (scratch)))])]

>    "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())

>     && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)

> -   && ix86_red_zone_size == 0"

> +   && !ix86_red_zone_used"

>    [(clobber (match_dup 1))

>     (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))

>               (clobber (mem:BLK (scratch)))])])

> @@ -20505,7 +20505,7 @@ (define_peephole2

>               (clobber (mem:BLK (scratch)))])]

>    "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())

>     && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)

> -   && ix86_red_zone_size == 0"

> +   && !ix86_red_zone_used"

>    [(clobber (match_dup 1))

>     (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))

>     (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))

> @@ -20520,7 +20520,7 @@ (define_peephole2

>               (clobber (reg:CC FLAGS_REG))])]

>    "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())

>     && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)

> -   && ix86_red_zone_size == 0"

> +   && !ix86_red_zone_used"

>    [(clobber (match_dup 1))

>     (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])

>

> @@ -20532,7 +20532,7 @@ (define_peephole2

>               (clobber (reg:CC FLAGS_REG))])]

>    "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())

>     && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)

> -   && ix86_red_zone_size == 0"

> +   && !ix86_red_zone_used"

>    [(clobber (match_dup 1))

>     (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))

>     (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])

> diff --git a/gcc/testsuite/g++.target/i386/pr101023a.C b/gcc/testsuite/g++.target/i386/pr101023a.C

> new file mode 100644

> index 00000000000..fbcce68beef

> --- /dev/null

> +++ b/gcc/testsuite/g++.target/i386/pr101023a.C

> @@ -0,0 +1,62 @@

> +// PR target/101023

> +// { dg-do run { target { ! ia32 } } }

> +// { dg-options "-O2 -mtune=opteron -mstackrealign --param=hot-bb-frequency-fraction=1" }

> +

> +struct S {

> +  __attribute__((noipa)) int m1 ();

> +  __attribute__((noipa)) void m2 ();

> +};

> +struct T {

> +  __attribute__((noipa)) virtual S m3 ();

> +};

> +struct U : T {

> +  int u;

> +  __attribute__((noipa)) U (int);

> +};

> +int *a;

> +S *b;

> +int c;

> +

> +int

> +S::m1 ()

> +{

> +  return 0;

> +}

> +

> +void

> +S::m2 ()

> +{

> +}

> +

> +S

> +T::m3 ()

> +{

> +  return S ();

> +}

> +

> +U::U (int) : u (4)

> +{

> +}

> +

> +__attribute__((noipa)) int

> +foo ()

> +{

> +  if (a)

> +    return 0;

> +  U d(c);

> +  S *e = b;

> +  e->m2 ();

> +  return e->m1();

> +}

> +

> +int

> +main ()

> +{

> +  register int r12 __asm ("r12") = 1;

> +  register int rax __asm ("rax") = 2;

> +  asm volatile ("" : "+r" (r12), "+r" (rax));

> +  foo ();

> +  asm volatile ("" : "+r" (r12));

> +  if (r12 != 1)

> +    __builtin_abort ();

> +}

> diff --git a/gcc/testsuite/g++.target/i386/pr101023b.C b/gcc/testsuite/g++.target/i386/pr101023b.C

> new file mode 100644

> index 00000000000..b19791c8ffb

> --- /dev/null

> +++ b/gcc/testsuite/g++.target/i386/pr101023b.C

> @@ -0,0 +1,5 @@

> +// PR target/101023

> +// { dg-do run { target { ! ia32 } } }

> +// { dg-options "-O2 -mno-red-zone -mtune=opteron -mstackrealign --param=hot-bb-frequency-fraction=1" }

> +

> +#include "pr101023a.C"

> --

> 2.31.1

>

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 05b8dc806cd..a61255857ff 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -8401,10 +8401,14 @@  ix86_expand_prologue (void)
 		   || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
 	{
 	  ix86_emit_save_regs_using_mov (frame.reg_save_offset);
+	  cfun->machine->red_zone_used = true;
 	  int_registers_saved = true;
 	}
     }
 
+  if (frame.red_zone_size != 0)
+    cfun->machine->red_zone_used = true;
+
   if (stack_realign_fp)
     {
       int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
@@ -15915,7 +15919,7 @@  ix86_output_indirect_jmp (rtx call_op)
     {
       /* We can't have red-zone since "call" in the indirect thunk
          pushes the return address onto stack, destroying red-zone.  */
-      if (ix86_red_zone_size != 0)
+      if (ix86_red_zone_used)
 	gcc_unreachable ();
 
       ix86_output_indirect_branch (call_op, "%0", true);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 919d0b2418a..182b3275991 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2663,6 +2663,9 @@  struct GTY(()) machine_function {
      invalid calls.  */
   BOOL_BITFIELD silent_p : 1;
 
+  /* True if red zone is used.  */
+  BOOL_BITFIELD red_zone_used : 1;
+
   /* The largest alignment, in bytes, of stack slot actually used.  */
   unsigned int max_used_stack_alignment;
 
@@ -2693,7 +2696,7 @@  extern GTY(()) tree ms_va_list_type_node;
 #define ix86_current_function_calls_tls_descriptor \
   (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG))
 #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack)
-#define ix86_red_zone_size (cfun->machine->frame.red_zone_size)
+#define ix86_red_zone_used (cfun->machine->red_zone_used)
 
 /* Control behavior of x86_file_start.  */
 #define X86_FILE_START_VERSION_DIRECTIVE false
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 7743c61ec86..6e4abf32e7c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20491,7 +20491,7 @@  (define_peephole2
 	      (clobber (mem:BLK (scratch)))])]
   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
-   && ix86_red_zone_size == 0"
+   && !ix86_red_zone_used"
   [(clobber (match_dup 1))
    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
 	      (clobber (mem:BLK (scratch)))])])
@@ -20505,7 +20505,7 @@  (define_peephole2
 	      (clobber (mem:BLK (scratch)))])]
   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
-   && ix86_red_zone_size == 0"
+   && !ix86_red_zone_used"
   [(clobber (match_dup 1))
    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
@@ -20520,7 +20520,7 @@  (define_peephole2
 	      (clobber (reg:CC FLAGS_REG))])]
   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
-   && ix86_red_zone_size == 0"
+   && !ix86_red_zone_used"
   [(clobber (match_dup 1))
    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
 
@@ -20532,7 +20532,7 @@  (define_peephole2
 	      (clobber (reg:CC FLAGS_REG))])]
   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
-   && ix86_red_zone_size == 0"
+   && !ix86_red_zone_used"
   [(clobber (match_dup 1))
    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
diff --git a/gcc/testsuite/g++.target/i386/pr101023a.C b/gcc/testsuite/g++.target/i386/pr101023a.C
new file mode 100644
index 00000000000..fbcce68beef
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr101023a.C
@@ -0,0 +1,62 @@ 
+// PR target/101023
+// { dg-do run { target { ! ia32 } } }
+// { dg-options "-O2 -mtune=opteron -mstackrealign --param=hot-bb-frequency-fraction=1" }
+
+struct S {
+  __attribute__((noipa)) int m1 ();
+  __attribute__((noipa)) void m2 ();
+};
+struct T {
+  __attribute__((noipa)) virtual S m3 ();
+};
+struct U : T {
+  int u;
+  __attribute__((noipa)) U (int);
+};
+int *a;
+S *b;
+int c;
+
+int
+S::m1 ()
+{
+  return 0;
+}
+
+void
+S::m2 ()
+{
+}
+
+S
+T::m3 ()
+{
+  return S ();
+}
+
+U::U (int) : u (4)
+{
+}
+
+__attribute__((noipa)) int
+foo ()
+{
+  if (a)
+    return 0;
+  U d(c);
+  S *e = b;
+  e->m2 ();
+  return e->m1();
+}
+
+int
+main ()
+{
+  register int r12 __asm ("r12") = 1;
+  register int rax __asm ("rax") = 2;
+  asm volatile ("" : "+r" (r12), "+r" (rax));
+  foo ();
+  asm volatile ("" : "+r" (r12));
+  if (r12 != 1)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.target/i386/pr101023b.C b/gcc/testsuite/g++.target/i386/pr101023b.C
new file mode 100644
index 00000000000..b19791c8ffb
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr101023b.C
@@ -0,0 +1,5 @@ 
+// PR target/101023
+// { dg-do run { target { ! ia32 } } }
+// { dg-options "-O2 -mno-red-zone -mtune=opteron -mstackrealign --param=hot-bb-frequency-fraction=1" }
+
+#include "pr101023a.C"