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

Hongtao Liu crazylht@gmail.com
Mon Nov 22 03:19:04 GMT 2021


On Fri, Nov 19, 2021 at 3:53 PM Uros Bizjak via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Fri, Nov 19, 2021 at 8:50 AM Uros Bizjak <ubizjak@gmail.com> wrote:
> >
> > On Fri, Nov 19, 2021 at 2:14 AM liuhongt <hongtao.liu@intel.com> 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 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)
> > > +       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/i386.md
> > > index 97325e38676..82b85b26059 100644
> > > --- a/gcc/config/i386/i386.md
> > > +++ b/gcc/config/i386/i386.md
> > > @@ -2085,9 +2085,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])"
> > >  {
> > > @@ -2149,7 +2149,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")
> > > @@ -2170,9 +2170,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 "alternative" "23,24,25,26,27")
> > >               (const_string "mskmov")
> > > -           (eq_attr "alternative" "27")
> > > +           (eq_attr "alternative" "28")
> > >               (const_string "msklog")
> > >             (and (match_operand 0 "register_operand")
> > >                  (match_operand 1 "pic_32bit_operand"))
> > > @@ -2306,9 +2306,9 @@ (define_peephole2
> > >
> > >  (define_insn "*movsi_internal"
> > >    [(set (match_operand:SI 0 "nonimmediate_operand"
> > > -    "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
> > > +    "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*k,*rm,*k")
> > >         (match_operand:SI 1 "general_operand"
> > > -    "g ,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,*v,r  ,*r,*km,*k ,CBC"))]
> > > +    "g ,re,C ,*y,Bk ,*y,*y,r  ,C ,*v,Bk,*v,*v,r  ,*r,*k, *Bk,*k ,CBC"))]
> > >    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
> > >     && ix86_hardreg_mov_ok (operands[0], operands[1])"
> > >  {
> > > @@ -2373,9 +2373,9 @@ (define_insn "*movsi_internal"
> > >               (const_string "sselog1")
> > >             (eq_attr "alternative" "9,10,11,12,13")
> > >               (const_string "ssemov")
> > > -           (eq_attr "alternative" "14,15,16")
> > > +           (eq_attr "alternative" "14,15,16,17")
> > >               (const_string "mskmov")
> > > -           (eq_attr "alternative" "17")
> > > +           (eq_attr "alternative" "18")
> > >               (const_string "msklog")
> > >             (and (match_operand 0 "register_operand")
> > >                  (match_operand 1 "pic_32bit_operand"))
> > > diff --git a/gcc/testsuite/gcc.target/i386/pr103275.c b/gcc/testsuite/gcc.target/i386/pr103275.c
> > > new file mode 100644
> > > index 00000000000..c93413f3cde
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.target/i386/pr103275.c
> > > @@ -0,0 +1,83 @@
> > > +/* { dg-do compile { target ia32 } }  */
> > > +/* { dg-options "-O2 -march=tigerlake -fPIC" } */
> > > +/* { dg-final { scan-assembler-not {(?n)kmovd.*@gotntpoff} } }  */
> > > +
> > > +typedef unsigned short uint16_t;
> > > +typedef int int32_t;
> > > +typedef unsigned int uint32_t;
> > > +typedef unsigned char uint8_t;
> > > +
> > > +typedef uint32_t in_addr_t;
> > > +struct in_addr { in_addr_t s_addr; };
> > > +
> > > +extern __thread const uint16_t * __libc_tsd_CTYPE_B __attribute__ ((tls_model ("initial-exec")));
> > > +extern __thread int __libc_errno __attribute__ ((tls_model ("initial-exec")));
> > > +
> > > +extern unsigned long strtoul (const char*, char**, int);
> > > +extern uint32_t __bswap_32 (in_addr_t);
> > > +int
> > > +inet_aton_end (const char *cp, struct in_addr *addr, const char **endp)
> > > +{
> > > +  static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
> > > +  in_addr_t val;
> > > +  char c;
> > > +  union iaddr
> > > +  {
> > > +    uint8_t bytes[4];
> > > +    uint32_t word;
> > > +  } res;
> > > +  uint8_t *pp = res.bytes;
> > > +  int digit;
> > > +
> > > +  int saved_errno = __libc_errno;
> > > +  __libc_errno = 0;
> > > +  res.word = 0;
> > > +  c = *cp;
> > > +
> > > +  for (;;)
> > > +    {
> > > +      if (c < '0' || c > '9')
> > > +       goto ret_0;
> > > +      {
> > > +       char *endp;
> > > +       unsigned long ul = strtoul (cp, &endp, 0);
> > > +       if (ul == 0x7fffffffL && __libc_errno == 34)
> > > +         goto ret_0;
> > > +       if (ul > 0xfffffffful)
> > > +         goto ret_0;
> > > +       val = ul;
> > > +       digit = cp != endp;
> > > +       cp = endp;
> > > +      }
> > > +      c = *cp;
> > > +      if (c == '.')
> > > +       {
> > > +         if (pp > res.bytes + 2 || val > 0xff)
> > > +           goto ret_0;
> > > +         *pp++ = val;
> > > +         c = *++cp;
> > > +       }
> > > +      else
> > > +       break;
> > > +    }
> > > +
> > > +  if (!(__libc_tsd_CTYPE_B[(int)c] & 8192))
> > > +    goto ret_0;
> > > +
> > > +  if (!digit)
> > > +    goto ret_0;
> > > +
> > > +  if (val > max[pp - res.bytes])
> > > +    goto ret_0;
> > > +
> > > +  if (addr != 0)
> > > +    addr->s_addr = res.word | __bswap_32 (val);
> > > +  *endp = cp;
> > > +
> > > +  __libc_errno = saved_errno;
> > > +  return 1;
> > > +
> > > + ret_0:
> > > +  __libc_errno = saved_errno;
> > > +  return 0;
> > > +}
> > > --
> > > 2.18.1
> > >



-- 
BR,
Hongtao
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Don-t-allow-mask-sse-mmx-mov-in-TLS-code-sequences.patch
Type: application/octet-stream
Size: 6954 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc-patches/attachments/20211122/13ab570f/attachment.obj>


More information about the Gcc-patches mailing list