Re: [PATCH] Don't allow mask/sse/mmx mov in TLS code sequences.

2021-11-21 Thread Hongtao Liu via Gcc-patches
On Fri, Nov 19, 2021 at 3:53 PM Uros Bizjak via Gcc-patches
 wrote:
>
> On Fri, Nov 19, 2021 at 8:50 AM Uros Bizjak  wrote:
> >
> > On Fri, Nov 19, 2021 at 2:14 AM liuhongt  wrote:
> > >
> > > >Why is the above declared as a special memory constraint? Also the
> > > Change to define_memory_constraint since it's ok for
> > > reload can make them match by converting the operand to the form
> > > ‘(mem (reg X))’.where X is a base register (from the register class 
> > > specified
> > > by BASE_REG_CLASS
> > >
> > > >predicate comment is missing and the description should say something
> > > >like:
> > > >
> > > >@internal TLS address that allows insn using non-integer registers
> > > Changed.
> > >
> > > >I think it is better to avoid negative logic. So, something like
> > > >
> > > >Return true if the TLS address requires insn using integer registers.
> > > >
> > > >bool
> > > >ix86_gpr_tls_address_pattern_p
> > > >
> > > >(and use not in the predicate)
> > >
> > > Changed.
> > >
> > > >> +{
> > > >> +  gcc_assert (MEM_P (mem));
> > > >> +
> > > >> +  rtx addr = XEXP (mem, 0);
> > > >> +  subrtx_var_iterator::array_type array;
> > > >> +  FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
> > > >> +{
> > > >> +  rtx op = *iter;
> > > >> +  if (GET_CODE (op) == UNSPEC)
> > > >> +   switch (XINT (op, 1))
> > > >> + {
> > > >> + case UNSPEC_GOTNTPOFF:
> > > >> +   return false;
> > > >> + case UNSPEC_TPOFF:
> > > >> +   if (!TARGET_64BIT)
> > > >> + return false;
> > > >> +   break;
> > > >> + default:
> > > >> +   break;
> > > >> + }
> > > >> +  /* Should iter.skip_subrtxes ();
> > > >> +if there's no inner UNSPEC in addr???.  */
> > >
> > > >You should figure the above before submitting the patch.
> > > ix86_print_operand_address_as shows there could be inner UNSPEC in addr, 
> > > so
> > > remove comments.
> > >
> > > >Can you please minimize the testcase?
> > > Done;
> > >
> > > As change in assembler, refer to [1], this patch disallow mask/sse/mmx
> > > mov in TLS code sequences which require integer MOV instructions.
> > >
> > > [1] 
> > > https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=d7e3e627027fcf37d63e284144fe27ff4eba36b5
> > >
> > > gcc/ChangeLog:
> > >
> > > PR target/103275
> > > * config/i386/i386-protos.h (ix86_gpr_tls_address_pattern_p):
> > > Declare.
> > > * config/i386/i386.c (ix86_gpr_tls_address_pattern_p): New
> > > function.
> > > * config/i386/i386.md (*movsi_internal): Don't allow
> > > mask/sse/mmx move in TLS code sequences.
> > > (*movdi_internal): Ditto.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * gcc.target/i386/pr103275.c: New test.
> >
> > OK, with a small comment adjustment below.
>
> Ops, sorry, I was too fast. You can simplify the patch to change the
> constraint from
>
> *km to *kBk
>
> Then no renumbering is needed.
Yes, changed, thanks for the review.
this is the final patch i'm checking in.
>
> Uros.
>
> >
> > Thanks,
> > Uros.
> >
> > > ---
> > >  gcc/config/i386/constraints.md   |  5 ++
> > >  gcc/config/i386/i386-protos.h|  1 +
> > >  gcc/config/i386/i386.c   | 32 +
> > >  gcc/config/i386/i386.md  | 18 ++---
> > >  gcc/testsuite/gcc.target/i386/pr103275.c | 83 
> > >  5 files changed, 130 insertions(+), 9 deletions(-)
> > >  create mode 100644 gcc/testsuite/gcc.target/i386/pr103275.c
> > >
> > > diff --git a/gcc/config/i386/constraints.md 
> > > b/gcc/config/i386/constraints.md
> > > index eaa582d2055..15c5950ee6f 100644
> > > --- a/gcc/config/i386/constraints.md
> > > +++ b/gcc/config/i386/constraints.md
> > > @@ -185,6 +185,11 @@ (define_special_memory_constraint "Bc"
> > >(and (match_operand 0 "memory_operand")
> > > (match_test "constant_address_p (XEXP (op, 0))")))
> > >
> > > +(define_memory_constraint "Bk"
> > > +  "@internal TLS address that allows insn using non-integer registers."
> > > +  (and (match_operand 0 "memory_operand")
> > > +   (not (match_test "ix86_gpr_tls_address_pattern_p (op)"
> > > +
> > >  (define_special_memory_constraint "Bn"
> > >"@internal Memory operand without REX prefix."
> > >(match_operand 0 "norex_memory_operand"))
> > > diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
> > > index 7782cf1163f..941e91636d8 100644
> > > --- a/gcc/config/i386/i386-protos.h
> > > +++ b/gcc/config/i386/i386-protos.h
> > > @@ -240,6 +240,7 @@ extern unsigned int ix86_get_callcvt (const_tree);
> > >  #endif
> > >
> > >  extern rtx ix86_tls_module_base (void);
> > > +extern bool ix86_gpr_tls_address_pattern_p (rtx);
> > >  extern bool ix86_tls_address_pattern_p (rtx);
> > >  extern rtx ix86_rewrite_tls_address (rtx);
> > >
> > > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> > > index 42c47d2b12b..68079e4230e 10064

Re: [PATCH] Don't allow mask/sse/mmx mov in TLS code sequences.

2021-11-18 Thread Uros Bizjak via Gcc-patches
On Fri, Nov 19, 2021 at 8:50 AM Uros Bizjak  wrote:
>
> On Fri, Nov 19, 2021 at 2:14 AM liuhongt  wrote:
> >
> > >Why is the above declared as a special memory constraint? Also the
> > Change to define_memory_constraint since it's ok for
> > reload can make them match by converting the operand to the form
> > ‘(mem (reg X))’.where X is a base register (from the register class 
> > specified
> > by BASE_REG_CLASS
> >
> > >predicate comment is missing and the description should say something
> > >like:
> > >
> > >@internal TLS address that allows insn using non-integer registers
> > Changed.
> >
> > >I think it is better to avoid negative logic. So, something like
> > >
> > >Return true if the TLS address requires insn using integer registers.
> > >
> > >bool
> > >ix86_gpr_tls_address_pattern_p
> > >
> > >(and use not in the predicate)
> >
> > Changed.
> >
> > >> +{
> > >> +  gcc_assert (MEM_P (mem));
> > >> +
> > >> +  rtx addr = XEXP (mem, 0);
> > >> +  subrtx_var_iterator::array_type array;
> > >> +  FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
> > >> +{
> > >> +  rtx op = *iter;
> > >> +  if (GET_CODE (op) == UNSPEC)
> > >> +   switch (XINT (op, 1))
> > >> + {
> > >> + case UNSPEC_GOTNTPOFF:
> > >> +   return false;
> > >> + case UNSPEC_TPOFF:
> > >> +   if (!TARGET_64BIT)
> > >> + return false;
> > >> +   break;
> > >> + default:
> > >> +   break;
> > >> + }
> > >> +  /* Should iter.skip_subrtxes ();
> > >> +if there's no inner UNSPEC in addr???.  */
> >
> > >You should figure the above before submitting the patch.
> > ix86_print_operand_address_as shows there could be inner UNSPEC in addr, so
> > remove comments.
> >
> > >Can you please minimize the testcase?
> > Done;
> >
> > As change in assembler, refer to [1], this patch disallow mask/sse/mmx
> > mov in TLS code sequences which require integer MOV instructions.
> >
> > [1] 
> > https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=d7e3e627027fcf37d63e284144fe27ff4eba36b5
> >
> > gcc/ChangeLog:
> >
> > PR target/103275
> > * config/i386/i386-protos.h (ix86_gpr_tls_address_pattern_p):
> > Declare.
> > * config/i386/i386.c (ix86_gpr_tls_address_pattern_p): New
> > function.
> > * config/i386/i386.md (*movsi_internal): Don't allow
> > mask/sse/mmx move in TLS code sequences.
> > (*movdi_internal): Ditto.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.target/i386/pr103275.c: New test.
>
> OK, with a small comment adjustment below.

Ops, sorry, I was too fast. You can simplify the patch to change the
constraint from

*km to *kBk

Then no renumbering is needed.

Uros.

>
> Thanks,
> Uros.
>
> > ---
> >  gcc/config/i386/constraints.md   |  5 ++
> >  gcc/config/i386/i386-protos.h|  1 +
> >  gcc/config/i386/i386.c   | 32 +
> >  gcc/config/i386/i386.md  | 18 ++---
> >  gcc/testsuite/gcc.target/i386/pr103275.c | 83 
> >  5 files changed, 130 insertions(+), 9 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr103275.c
> >
> > diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
> > index eaa582d2055..15c5950ee6f 100644
> > --- a/gcc/config/i386/constraints.md
> > +++ b/gcc/config/i386/constraints.md
> > @@ -185,6 +185,11 @@ (define_special_memory_constraint "Bc"
> >(and (match_operand 0 "memory_operand")
> > (match_test "constant_address_p (XEXP (op, 0))")))
> >
> > +(define_memory_constraint "Bk"
> > +  "@internal TLS address that allows insn using non-integer registers."
> > +  (and (match_operand 0 "memory_operand")
> > +   (not (match_test "ix86_gpr_tls_address_pattern_p (op)"
> > +
> >  (define_special_memory_constraint "Bn"
> >"@internal Memory operand without REX prefix."
> >(match_operand 0 "norex_memory_operand"))
> > diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
> > index 7782cf1163f..941e91636d8 100644
> > --- a/gcc/config/i386/i386-protos.h
> > +++ b/gcc/config/i386/i386-protos.h
> > @@ -240,6 +240,7 @@ extern unsigned int ix86_get_callcvt (const_tree);
> >  #endif
> >
> >  extern rtx ix86_tls_module_base (void);
> > +extern bool ix86_gpr_tls_address_pattern_p (rtx);
> >  extern bool ix86_tls_address_pattern_p (rtx);
> >  extern rtx ix86_rewrite_tls_address (rtx);
> >
> > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> > index 42c47d2b12b..68079e4230e 100644
> > --- a/gcc/config/i386/i386.c
> > +++ b/gcc/config/i386/i386.c
> > @@ -11468,6 +11468,38 @@ legitimize_tls_address (rtx x, enum tls_model 
> > model, bool for_mov)
> >return dest;
> >  }
> >
> > +/* Return true if the TLS address requires insn using integer registers.
> > +   NB: it's different from ix86_tls_address_pattern_p since it also matchs
> > +   gottpoff/gotntpoff.
>
> The above NB comment is not neede

Re: [PATCH] Don't allow mask/sse/mmx mov in TLS code sequences.

2021-11-18 Thread Uros Bizjak via Gcc-patches
On Fri, Nov 19, 2021 at 2:14 AM liuhongt  wrote:
>
> >Why is the above declared as a special memory constraint? Also the
> Change to define_memory_constraint since it's ok for
> reload can make them match by converting the operand to the form
> ‘(mem (reg X))’.where X is a base register (from the register class specified
> by BASE_REG_CLASS
>
> >predicate comment is missing and the description should say something
> >like:
> >
> >@internal TLS address that allows insn using non-integer registers
> Changed.
>
> >I think it is better to avoid negative logic. So, something like
> >
> >Return true if the TLS address requires insn using integer registers.
> >
> >bool
> >ix86_gpr_tls_address_pattern_p
> >
> >(and use not in the predicate)
>
> Changed.
>
> >> +{
> >> +  gcc_assert (MEM_P (mem));
> >> +
> >> +  rtx addr = XEXP (mem, 0);
> >> +  subrtx_var_iterator::array_type array;
> >> +  FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
> >> +{
> >> +  rtx op = *iter;
> >> +  if (GET_CODE (op) == UNSPEC)
> >> +   switch (XINT (op, 1))
> >> + {
> >> + case UNSPEC_GOTNTPOFF:
> >> +   return false;
> >> + case UNSPEC_TPOFF:
> >> +   if (!TARGET_64BIT)
> >> + return false;
> >> +   break;
> >> + default:
> >> +   break;
> >> + }
> >> +  /* Should iter.skip_subrtxes ();
> >> +if there's no inner UNSPEC in addr???.  */
>
> >You should figure the above before submitting the patch.
> ix86_print_operand_address_as shows there could be inner UNSPEC in addr, so
> remove comments.
>
> >Can you please minimize the testcase?
> Done;
>
> As change in assembler, refer to [1], this patch disallow mask/sse/mmx
> mov in TLS code sequences which require integer MOV instructions.
>
> [1] 
> https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=d7e3e627027fcf37d63e284144fe27ff4eba36b5
>
> gcc/ChangeLog:
>
> PR target/103275
> * config/i386/i386-protos.h (ix86_gpr_tls_address_pattern_p):
> Declare.
> * config/i386/i386.c (ix86_gpr_tls_address_pattern_p): New
> function.
> * config/i386/i386.md (*movsi_internal): Don't allow
> mask/sse/mmx move in TLS code sequences.
> (*movdi_internal): Ditto.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/pr103275.c: New test.

OK, with a small comment adjustment below.

Thanks,
Uros.

> ---
>  gcc/config/i386/constraints.md   |  5 ++
>  gcc/config/i386/i386-protos.h|  1 +
>  gcc/config/i386/i386.c   | 32 +
>  gcc/config/i386/i386.md  | 18 ++---
>  gcc/testsuite/gcc.target/i386/pr103275.c | 83 
>  5 files changed, 130 insertions(+), 9 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr103275.c
>
> diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
> index eaa582d2055..15c5950ee6f 100644
> --- a/gcc/config/i386/constraints.md
> +++ b/gcc/config/i386/constraints.md
> @@ -185,6 +185,11 @@ (define_special_memory_constraint "Bc"
>(and (match_operand 0 "memory_operand")
> (match_test "constant_address_p (XEXP (op, 0))")))
>
> +(define_memory_constraint "Bk"
> +  "@internal TLS address that allows insn using non-integer registers."
> +  (and (match_operand 0 "memory_operand")
> +   (not (match_test "ix86_gpr_tls_address_pattern_p (op)"
> +
>  (define_special_memory_constraint "Bn"
>"@internal Memory operand without REX prefix."
>(match_operand 0 "norex_memory_operand"))
> diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
> index 7782cf1163f..941e91636d8 100644
> --- a/gcc/config/i386/i386-protos.h
> +++ b/gcc/config/i386/i386-protos.h
> @@ -240,6 +240,7 @@ extern unsigned int ix86_get_callcvt (const_tree);
>  #endif
>
>  extern rtx ix86_tls_module_base (void);
> +extern bool ix86_gpr_tls_address_pattern_p (rtx);
>  extern bool ix86_tls_address_pattern_p (rtx);
>  extern rtx ix86_rewrite_tls_address (rtx);
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 42c47d2b12b..68079e4230e 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -11468,6 +11468,38 @@ legitimize_tls_address (rtx x, enum tls_model model, 
> bool for_mov)
>return dest;
>  }
>
> +/* Return true if the TLS address requires insn using integer registers.
> +   NB: it's different from ix86_tls_address_pattern_p since it also matchs
> +   gottpoff/gotntpoff.

The above NB comment is not needed, the fact is obvious from the code.

> +   It's used to prevent KMOV/VMOV in TLS code sequences which require integer
> +   MOV instructions, refer to PR103275.  */
> +bool
> +ix86_gpr_tls_address_pattern_p (rtx mem)
> +{
> +  gcc_assert (MEM_P (mem));
> +
> +  rtx addr = XEXP (mem, 0);
> +  subrtx_var_iterator::array_type array;
> +  FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
> +{
> +  rtx op = *iter;
> +  if (GET_CODE (op) == UNSPEC)
> 

[PATCH] Don't allow mask/sse/mmx mov in TLS code sequences.

2021-11-18 Thread liuhongt via Gcc-patches
>Why is the above declared as a special memory constraint? Also the
Change to define_memory_constraint since it's ok for
reload can make them match by converting the operand to the form
‘(mem (reg X))’.where X is a base register (from the register class specified
by BASE_REG_CLASS

>predicate comment is missing and the description should say something
>like:
>
>@internal TLS address that allows insn using non-integer registers
Changed.

>I think it is better to avoid negative logic. So, something like
>
>Return true if the TLS address requires insn using integer registers.
>
>bool
>ix86_gpr_tls_address_pattern_p
>
>(and use not in the predicate)

Changed.

>> +{
>> +  gcc_assert (MEM_P (mem));
>> +
>> +  rtx addr = XEXP (mem, 0);
>> +  subrtx_var_iterator::array_type array;
>> +  FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
>> +{
>> +  rtx op = *iter;
>> +  if (GET_CODE (op) == UNSPEC)
>> +   switch (XINT (op, 1))
>> + {
>> + case UNSPEC_GOTNTPOFF:
>> +   return false;
>> + case UNSPEC_TPOFF:
>> +   if (!TARGET_64BIT)
>> + return false;
>> +   break;
>> + default:
>> +   break;
>> + }
>> +  /* Should iter.skip_subrtxes ();
>> +if there's no inner UNSPEC in addr???.  */

>You should figure the above before submitting the patch.
ix86_print_operand_address_as shows there could be inner UNSPEC in addr, so
remove comments.

>Can you please minimize the testcase?
Done;

As change in assembler, refer to [1], this patch disallow mask/sse/mmx
mov in TLS code sequences which require integer MOV instructions.

[1] 
https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=d7e3e627027fcf37d63e284144fe27ff4eba36b5

gcc/ChangeLog:

PR target/103275
* config/i386/i386-protos.h (ix86_gpr_tls_address_pattern_p):
Declare.
* config/i386/i386.c (ix86_gpr_tls_address_pattern_p): New
function.
* config/i386/i386.md (*movsi_internal): Don't allow
mask/sse/mmx move in TLS code sequences.
(*movdi_internal): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr103275.c: New test.
---
 gcc/config/i386/constraints.md   |  5 ++
 gcc/config/i386/i386-protos.h|  1 +
 gcc/config/i386/i386.c   | 32 +
 gcc/config/i386/i386.md  | 18 ++---
 gcc/testsuite/gcc.target/i386/pr103275.c | 83 
 5 files changed, 130 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr103275.c

diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index eaa582d2055..15c5950ee6f 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -185,6 +185,11 @@ (define_special_memory_constraint "Bc"
   (and (match_operand 0 "memory_operand")
(match_test "constant_address_p (XEXP (op, 0))")))
 
+(define_memory_constraint "Bk"
+  "@internal TLS address that allows insn using non-integer registers."
+  (and (match_operand 0 "memory_operand")
+   (not (match_test "ix86_gpr_tls_address_pattern_p (op)"
+
 (define_special_memory_constraint "Bn"
   "@internal Memory operand without REX prefix."
   (match_operand 0 "norex_memory_operand"))
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 7782cf1163f..941e91636d8 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -240,6 +240,7 @@ extern unsigned int ix86_get_callcvt (const_tree);
 #endif
 
 extern rtx ix86_tls_module_base (void);
+extern bool ix86_gpr_tls_address_pattern_p (rtx);
 extern bool ix86_tls_address_pattern_p (rtx);
 extern rtx ix86_rewrite_tls_address (rtx);
 
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 42c47d2b12b..68079e4230e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11468,6 +11468,38 @@ legitimize_tls_address (rtx x, enum tls_model model, 
bool for_mov)
   return dest;
 }
 
+/* Return true if the TLS address requires insn using integer registers.
+   NB: it's different from ix86_tls_address_pattern_p since it also matchs
+   gottpoff/gotntpoff.
+   It's used to prevent KMOV/VMOV in TLS code sequences which require integer
+   MOV instructions, refer to PR103275.  */
+bool
+ix86_gpr_tls_address_pattern_p (rtx mem)
+{
+  gcc_assert (MEM_P (mem));
+
+  rtx addr = XEXP (mem, 0);
+  subrtx_var_iterator::array_type array;
+  FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
+{
+  rtx op = *iter;
+  if (GET_CODE (op) == UNSPEC)
+   switch (XINT (op, 1))
+ {
+ case UNSPEC_GOTNTPOFF:
+   return true;
+ case UNSPEC_TPOFF:
+   if (!TARGET_64BIT)
+ return true;
+   break;
+ default:
+   break;
+ }
+}
+
+  return false;
+}
+
 /* Return true if OP refers to a TLS address.  */
 bool
 ix86_tls_address_pattern_p (rtx op)
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386

Re: [PATCH] Don't allow mask/sse/mmx mov in TLS code sequences.

2021-11-18 Thread Uros Bizjak via Gcc-patches
On Thu, Nov 18, 2021 at 8:18 AM liuhongt  wrote:
>
> As change in assembler, refer to [1], this patch disallow mask/sse/mmx
> mov in TLS code sequences which require integer MOV instructions.
>
> [1] 
> https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=d7e3e627027fcf37d63e284144fe27ff4eba36b5
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> Ok for trunk and GCC11 upstream branch?
>
> gcc/ChangeLog:
>
> PR target/103275
> * config/i386/i386-protos.h (ix86_notls_memory): Declare.
> * config/i386/i386.c (ix86_notls_memory): New function.
> * config/i386/i386.md (*movsi_internal): Don't allow
> mask/sse/mmx move in TLS code sequences.
> (*movdi_internal): Ditto.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/pr103275.c: New test.
> ---
>  gcc/config/i386/constraints.md   |   5 +
>  gcc/config/i386/i386-protos.h|   1 +
>  gcc/config/i386/i386.c   |  34 ++
>  gcc/config/i386/i386.md  |  18 +--
>  gcc/testsuite/gcc.target/i386/pr103275.c | 148 +++
>  5 files changed, 197 insertions(+), 9 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr103275.c
>
> diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
> index 87cceac4cfb..489c76164a1 100644
> --- a/gcc/config/i386/constraints.md
> +++ b/gcc/config/i386/constraints.md
> @@ -186,6 +186,11 @@ (define_special_memory_constraint "Bc"
>(and (match_operand 0 "memory_operand")
> (match_test "constant_address_p (XEXP (op, 0))")))
>
> +(define_special_memory_constraint "Bk"
> +  "@internal notls memory operand."
> +  (and (match_operand 0 "memory_operand")
> +   (match_test "ix86_notls_memory (op)")))

Why is the above declared as a special memory constraint? Also the
predicate comment is missing and the description should say something
like:

@internal TLS address that allows insn using non-integer registers

>  (define_special_memory_constraint "Bn"
>"@internal Memory operand without REX prefix."
>(match_operand 0 "norex_memory_operand"))
> diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
> index 7e05510c679..1fb09be8b7e 100644
> --- a/gcc/config/i386/i386-protos.h
> +++ b/gcc/config/i386/i386-protos.h
> @@ -243,6 +243,7 @@ extern unsigned int ix86_get_callcvt (const_tree);
>  #endif
>
>  extern rtx ix86_tls_module_base (void);
> +extern bool ix86_notls_memory (rtx);
>  extern bool ix86_tls_address_pattern_p (rtx);
>  extern rtx ix86_rewrite_tls_address (rtx);
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index c246c8736f5..f1b7f57b0ca 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -11628,6 +11628,40 @@ legitimize_tls_address (rtx x, enum tls_model model, 
> bool for_mov)
>return dest;
>  }
>
> +/* Return true if it's not tls memory,
> +   NB: it's different from ix86_tls_address_pattern_p since it also matchs
> +   gottpoff/gotntpoff.
> +   It's used to prevent KMOV/VMOV in TLS code sequences which require integer
> +   MOV instructions, refer to PR103275.  */
> +bool
> +ix86_notls_memory (rtx mem)

I think it is better to avoid negative logic. So, something like

Return true if the TLS address requires insn using integer registers.

bool
ix86_gpr_tls_address_pattern_p

(and use not in the predicate)

> +{
> +  gcc_assert (MEM_P (mem));
> +
> +  rtx addr = XEXP (mem, 0);
> +  subrtx_var_iterator::array_type array;
> +  FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
> +{
> +  rtx op = *iter;
> +  if (GET_CODE (op) == UNSPEC)
> +   switch (XINT (op, 1))
> + {
> + case UNSPEC_GOTNTPOFF:
> +   return false;
> + case UNSPEC_TPOFF:
> +   if (!TARGET_64BIT)
> + return false;
> +   break;
> + default:
> +   break;
> + }
> +  /* Should iter.skip_subrtxes ();
> +if there's no inner UNSPEC in addr???.  */

You should figure the above before submitting the patch.

> +}
> +
> +  return true;
> +}
> +
>  /* Return true if OP refers to a TLS address.  */
>  bool
>  ix86_tls_address_pattern_p (rtx op)
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index 7b2de60706d..9feba81974b 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -2164,9 +2164,9 @@ (define_split
>
>  (define_insn "*movdi_internal"
>[(set (match_operand:DI 0 "nonimmediate_operand"
> -"=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r 
> ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m,*k")
> +"=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r 
> ,?*Yd,?r,?*v,?*y,?*x,*k,*k,*k ,*r,*m,*k")
> (match_operand:DI 1 "general_operand"
> -"riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,v,*Yd,r   ,*v,r  
> ,*x ,*y ,*r,*km,*k,*k,CBC"))]
> +"riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r  ,C ,*v,Bk,*v,v,*Yd,r   ,*v,r  
> ,*x ,*y ,*r,*k,*Bk,*k,*k,CBC"))]
>"!(

[PATCH] Don't allow mask/sse/mmx mov in TLS code sequences.

2021-11-17 Thread liuhongt via Gcc-patches
As change in assembler, refer to [1], this patch disallow mask/sse/mmx
mov in TLS code sequences which require integer MOV instructions.

[1] 
https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=d7e3e627027fcf37d63e284144fe27ff4eba36b5

Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
Ok for trunk and GCC11 upstream branch?

gcc/ChangeLog:

PR target/103275
* config/i386/i386-protos.h (ix86_notls_memory): Declare.
* config/i386/i386.c (ix86_notls_memory): New function.
* config/i386/i386.md (*movsi_internal): Don't allow
mask/sse/mmx move in TLS code sequences.
(*movdi_internal): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr103275.c: New test.
---
 gcc/config/i386/constraints.md   |   5 +
 gcc/config/i386/i386-protos.h|   1 +
 gcc/config/i386/i386.c   |  34 ++
 gcc/config/i386/i386.md  |  18 +--
 gcc/testsuite/gcc.target/i386/pr103275.c | 148 +++
 5 files changed, 197 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr103275.c

diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 87cceac4cfb..489c76164a1 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -186,6 +186,11 @@ (define_special_memory_constraint "Bc"
   (and (match_operand 0 "memory_operand")
(match_test "constant_address_p (XEXP (op, 0))")))
 
+(define_special_memory_constraint "Bk"
+  "@internal notls memory operand."
+  (and (match_operand 0 "memory_operand")
+   (match_test "ix86_notls_memory (op)")))
+
 (define_special_memory_constraint "Bn"
   "@internal Memory operand without REX prefix."
   (match_operand 0 "norex_memory_operand"))
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 7e05510c679..1fb09be8b7e 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -243,6 +243,7 @@ extern unsigned int ix86_get_callcvt (const_tree);
 #endif
 
 extern rtx ix86_tls_module_base (void);
+extern bool ix86_notls_memory (rtx);
 extern bool ix86_tls_address_pattern_p (rtx);
 extern rtx ix86_rewrite_tls_address (rtx);
 
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index c246c8736f5..f1b7f57b0ca 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11628,6 +11628,40 @@ legitimize_tls_address (rtx x, enum tls_model model, 
bool for_mov)
   return dest;
 }
 
+/* Return true if it's not tls memory,
+   NB: it's different from ix86_tls_address_pattern_p since it also matchs
+   gottpoff/gotntpoff.
+   It's used to prevent KMOV/VMOV in TLS code sequences which require integer
+   MOV instructions, refer to PR103275.  */
+bool
+ix86_notls_memory (rtx mem)
+{
+  gcc_assert (MEM_P (mem));
+
+  rtx addr = XEXP (mem, 0);
+  subrtx_var_iterator::array_type array;
+  FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
+{
+  rtx op = *iter;
+  if (GET_CODE (op) == UNSPEC)
+   switch (XINT (op, 1))
+ {
+ case UNSPEC_GOTNTPOFF:
+   return false;
+ case UNSPEC_TPOFF:
+   if (!TARGET_64BIT)
+ return false;
+   break;
+ default:
+   break;
+ }
+  /* Should iter.skip_subrtxes ();
+if there's no inner UNSPEC in addr???.  */
+}
+
+  return true;
+}
+
 /* Return true if OP refers to a TLS address.  */
 bool
 ix86_tls_address_pattern_p (rtx op)
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 7b2de60706d..9feba81974b 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2164,9 +2164,9 @@ (define_split
 
 (define_insn "*movdi_internal"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-"=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r 
,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m,*k")
+"=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r 
,?*Yd,?r,?*v,?*y,?*x,*k,*k,*k ,*r,*m,*k")
(match_operand:DI 1 "general_operand"
-"riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,v,*Yd,r   ,*v,r  ,*x 
,*y ,*r,*km,*k,*k,CBC"))]
+"riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r  ,C ,*v,Bk,*v,v,*Yd,r   ,*v,r  ,*x 
,*y ,*r,*k,*Bk,*k,*k,CBC"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& ix86_hardreg_mov_ok (operands[0], operands[1])"
 {
@@ -2228,7 +2228,7 @@ (define_insn "*movdi_internal"
   [(set (attr "isa")
  (cond [(eq_attr "alternative" "0,1,17,18")
  (const_string "nox64")
-   (eq_attr "alternative" "2,3,4,5,10,11,23,25")
+   (eq_attr "alternative" "2,3,4,5,10,11,23,26")
  (const_string "x64")
(eq_attr "alternative" "19,20")
  (const_string "x64_sse2")
@@ -2249,9 +2249,9 @@ (define_insn "*movdi_internal"
  (const_string "ssemov")
(eq_attr "alternative" "21,22")
  (const_string "ssecvt")
-   (eq_attr "alternative" "23,24,25,26")
+   (eq_attr "alternativ