On Fri, Jun 11, 2021 at 10:46 PM H.J. Lu <hjl.to...@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
>

Reply via email to