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 >