On Sun, Jan 19, 2020 at 2:58 PM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> To add x32 support to -mtls-dialect=gnu2, we need to replace DI with
> P in GNU2 TLS patterns.  Since thread pointer is in ptr_mode, PLUS in
> GNU2 TLS address computation must be done in ptr_mode to support
> -maddress-mode=long.  Also drop the "q" suffix from lea to support
> both "lea foo@TLSDESC(%rip), %eax" and "foo@TLSDESC(%rip), %rax".

Please use "lea%z0" instead.

> Tested on Linux/x86-64.  OK for master?
>
> Thanks.
>
> H.J.
> ---
> gcc/
>
>         PR target/93319
>         * config/i386/i386.c (legitimize_tls_address): Pass Pmode to
>         gen_tls_dynamic_gnu2_64.  Compute GNU2 TLS address in ptr_mode.
>         * config/i386/i386.md (tls_dynamic_gnu2_64): Renamed to ...
>         (@tls_dynamic_gnu2_64_<mode>): This.  Replace DI with P.
>         (*tls_dynamic_gnu2_lea_64): Renamed to ...
>         (*tls_dynamic_gnu2_lea_64_<mode>): This.  Replace DI with P.
>         Remove the {q} suffix from lea.
>         (*tls_dynamic_gnu2_call_64): Renamed to ...
>         (*tls_dynamic_gnu2_call_64_<mode>): This.  Replace DI with P.
>         (*tls_dynamic_gnu2_combine_64): Renamed to ...
>         (*tls_dynamic_gnu2_combine_64_<mode>): This.  Replace DI with P.
>         Pass Pmode to gen_tls_dynamic_gnu2_64.
>
> gcc/testsuite/
>
>         PR target/93319
>         * gcc.target/i386/pr93319-1a.c: New test.
>         * gcc.target/i386/pr93319-1b.c: Likewise.
>         * gcc.target/i386/pr93319-1c.c: Likewise.
>         * gcc.target/i386/pr93319-1d.c: Likewise.
> ---
>  gcc/config/i386/i386.c                     | 31 +++++++++++--
>  gcc/config/i386/i386.md                    | 54 +++++++++++-----------
>  gcc/testsuite/gcc.target/i386/pr93319-1a.c | 24 ++++++++++
>  gcc/testsuite/gcc.target/i386/pr93319-1b.c |  7 +++
>  gcc/testsuite/gcc.target/i386/pr93319-1c.c |  7 +++
>  gcc/testsuite/gcc.target/i386/pr93319-1d.c |  7 +++
>  6 files changed, 99 insertions(+), 31 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr93319-1a.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr93319-1b.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr93319-1c.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr93319-1d.c
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 2c087a4a3e0..8c437dbe1f3 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -10764,12 +10764,24 @@ legitimize_tls_address (rtx x, enum tls_model 
> model, bool for_mov)
>        if (TARGET_GNU2_TLS)
>         {
>           if (TARGET_64BIT)
> -           emit_insn (gen_tls_dynamic_gnu2_64 (dest, x));
> +           emit_insn (gen_tls_dynamic_gnu2_64 (Pmode, dest, x));
>           else
>             emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
>
>           tp = get_thread_pointer (Pmode, true);
> -         dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, tp, dest));
> +
> +         /* NB: Since thread pointer is in ptr_mode, make sure that
> +            PLUS is done in ptr_mode.  */
> +         if (Pmode != ptr_mode)
> +           {
> +             tp = lowpart_subreg (ptr_mode, tp, Pmode);
> +             dest = lowpart_subreg (ptr_mode, dest, Pmode);
> +             dest = gen_rtx_PLUS (ptr_mode, tp, dest);
> +             dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
> +           }
> +         else
> +           dest = gen_rtx_PLUS (Pmode, tp, dest);
> +         dest = force_reg (Pmode, dest);

Sholdn't we use

tp = get_thread_pointer (ptr_mode, true);

then? If Pmode == ptr_mode, then we have the same functionality,
otherwise we don't have to subreg tp to ptr_mode.

Can we use the same approach as in ix86_zero_extend_to_Pmode here, like:

dest = gen_rtx_PLUS (ptr_mode, tp, dest);
dest = force_reg (Pmode, convert_to_mode (Pmode, dest, 1));

Uros.

>
>           if (GET_MODE (x) != Pmode)
>             x = gen_rtx_ZERO_EXTEND (Pmode, x);
> @@ -10821,7 +10833,7 @@ legitimize_tls_address (rtx x, enum tls_model model, 
> bool for_mov)
>           rtx tmp = ix86_tls_module_base ();
>
>           if (TARGET_64BIT)
> -           emit_insn (gen_tls_dynamic_gnu2_64 (base, tmp));
> +           emit_insn (gen_tls_dynamic_gnu2_64 (Pmode, base, tmp));
>           else
>             emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
>
> @@ -10864,7 +10876,18 @@ legitimize_tls_address (rtx x, enum tls_model model, 
> bool for_mov)
>
>        if (TARGET_GNU2_TLS)
>         {
> -         dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, dest, tp));
> +         /* NB: Since thread pointer is in ptr_mode, make sure that
> +            PLUS is done in ptr_mode.  */
> +         if (Pmode != ptr_mode)
> +           {
> +             tp = lowpart_subreg (ptr_mode, tp, Pmode);
> +             dest = lowpart_subreg (ptr_mode, dest, Pmode);
> +             dest = gen_rtx_PLUS (ptr_mode, tp, dest);
> +             dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
> +           }
> +         else
> +           dest = gen_rtx_PLUS (Pmode, tp, dest);
> +         dest = force_reg (Pmode, dest);
>
>           if (GET_MODE (x) != Pmode)
>             x = gen_rtx_ZERO_EXTEND (Pmode, x);
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index c9d2f338fe9..d53684096c4 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -15185,14 +15185,14 @@ (define_insn_and_split 
> "*tls_dynamic_gnu2_combine_32"
>    emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], 
> operands[2]));
>  })
>
> -(define_expand "tls_dynamic_gnu2_64"
> +(define_expand "@tls_dynamic_gnu2_64_<mode>"
>    [(set (match_dup 2)
> -       (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
> -                  UNSPEC_TLSDESC))
> +       (unspec:P [(match_operand 1 "tls_symbolic_operand")]
> +                 UNSPEC_TLSDESC))
>     (parallel
> -    [(set (match_operand:DI 0 "register_operand")
> -         (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
> -                    UNSPEC_TLSDESC))
> +    [(set (match_operand:P 0 "register_operand")
> +         (unspec:P [(match_dup 1) (match_dup 2) (reg:P SP_REG)]
> +                   UNSPEC_TLSDESC))
>       (clobber (reg:CC FLAGS_REG))])]
>    "TARGET_64BIT && TARGET_GNU2_TLS"
>  {
> @@ -15200,23 +15200,23 @@ (define_expand "tls_dynamic_gnu2_64"
>    ix86_tls_descriptor_calls_expanded_in_cfun = true;
>  })
>
> -(define_insn "*tls_dynamic_gnu2_lea_64"
> -  [(set (match_operand:DI 0 "register_operand" "=r")
> -       (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
> -                  UNSPEC_TLSDESC))]
> +(define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
> +  [(set (match_operand:P 0 "register_operand" "=r")
> +       (unspec:P [(match_operand 1 "tls_symbolic_operand")]
> +                 UNSPEC_TLSDESC))]
>    "TARGET_64BIT && TARGET_GNU2_TLS"
> -  "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
> +  "lea\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
>    [(set_attr "type" "lea")
> -   (set_attr "mode" "DI")
> +   (set_attr "mode" "<MODE>")
>     (set_attr "length" "7")
>     (set_attr "length_address" "4")])
>
> -(define_insn "*tls_dynamic_gnu2_call_64"
> -  [(set (match_operand:DI 0 "register_operand" "=a")
> -       (unspec:DI [(match_operand 1 "tls_symbolic_operand")
> -                   (match_operand:DI 2 "register_operand" "0")
> -                   (reg:DI SP_REG)]
> -                  UNSPEC_TLSDESC))
> +(define_insn "*tls_dynamic_gnu2_call_64_<mode>"
> +  [(set (match_operand:P 0 "register_operand" "=a")
> +       (unspec:P [(match_operand 1 "tls_symbolic_operand")
> +                  (match_operand:P 2 "register_operand" "0")
> +                  (reg:P SP_REG)]
> +                 UNSPEC_TLSDESC))
>     (clobber (reg:CC FLAGS_REG))]
>    "TARGET_64BIT && TARGET_GNU2_TLS"
>    "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
> @@ -15224,14 +15224,14 @@ (define_insn "*tls_dynamic_gnu2_call_64"
>     (set_attr "length" "2")
>     (set_attr "length_address" "0")])
>
> -(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
> -  [(set (match_operand:DI 0 "register_operand" "=&a")
> -       (plus:DI
> -        (unspec:DI [(match_operand 2 "tls_modbase_operand")
> -                    (match_operand:DI 3)
> -                    (reg:DI SP_REG)]
> -                   UNSPEC_TLSDESC)
> -        (const:DI (unspec:DI
> +(define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
> +  [(set (match_operand:P 0 "register_operand" "=&a")
> +       (plus:P
> +        (unspec:P [(match_operand 2 "tls_modbase_operand")
> +                    (match_operand:P 3)
> +                    (reg:P SP_REG)]
> +                  UNSPEC_TLSDESC)
> +        (const:P (unspec:P
>                     [(match_operand 1 "tls_symbolic_operand")]
>                     UNSPEC_DTPOFF))))
>     (clobber (reg:CC FLAGS_REG))]
> @@ -15241,7 +15241,7 @@ (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
>    [(set (match_dup 0) (match_dup 4))]
>  {
>    operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
> -  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
> +  emit_insn (gen_tls_dynamic_gnu2_64 (Pmode, operands[4], operands[1]));
>  })
>
>  (define_split
> diff --git a/gcc/testsuite/gcc.target/i386/pr93319-1a.c 
> b/gcc/testsuite/gcc.target/i386/pr93319-1a.c
> new file mode 100644
> index 00000000000..ba9d2b618c5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr93319-1a.c
> @@ -0,0 +1,24 @@
> +/* { dg-do compile { target { ! ia32 } } } */
> +/* { dg-require-effective-target maybe_x32 } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-require-effective-target tls_native } */
> +/* { dg-options "-mx32 -fPIC -mtls-dialect=gnu2" } */
> +
> +#include <stdio.h>
> +
> +extern __thread int bar;
> +static __thread int foo = 30;
> +
> +int *
> +test1 (void)
> +{
> +  printf ("foo: %d\n", foo);
> +  return &foo;
> +}
> +
> +int *
> +test2 (void)
> +{
> +  printf ("bar: %d\n", bar);
> +  return &bar;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr93319-1b.c 
> b/gcc/testsuite/gcc.target/i386/pr93319-1b.c
> new file mode 100644
> index 00000000000..788796a9a94
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr93319-1b.c
> @@ -0,0 +1,7 @@
> +/* { dg-do compile { target { ! ia32 } } } */
> +/* { dg-require-effective-target maybe_x32 } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-require-effective-target tls_native } */
> +/* { dg-options "-mx32 -O2 -fPIC -mtls-dialect=gnu2" } */
> +
> +#include "pr93319-1a.c"
> diff --git a/gcc/testsuite/gcc.target/i386/pr93319-1c.c 
> b/gcc/testsuite/gcc.target/i386/pr93319-1c.c
> new file mode 100644
> index 00000000000..8c462e904bd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr93319-1c.c
> @@ -0,0 +1,7 @@
> +/* { dg-do compile { target { ! ia32 } } } */
> +/* { dg-require-effective-target maybe_x32 } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-require-effective-target tls_native } */
> +/* { dg-options "-mx32 -O2 -fPIC -mtls-dialect=gnu2 -maddress-mode=long" } */
> +
> +#include "pr93319-1a.c"
> diff --git a/gcc/testsuite/gcc.target/i386/pr93319-1d.c 
> b/gcc/testsuite/gcc.target/i386/pr93319-1d.c
> new file mode 100644
> index 00000000000..7989e1c9fd4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr93319-1d.c
> @@ -0,0 +1,7 @@
> +/* { dg-do compile { target { ! ia32 } } } */
> +/* { dg-require-effective-target maybe_x32 } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-require-effective-target tls_native } */
> +/* { dg-options "-mx32 -fPIC -mtls-dialect=gnu2 -maddress-mode=long" } */
> +
> +#include "pr93319-1a.c"
> --
> 2.24.1
>

Reply via email to