aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorliuhongt <hongtao.liu@intel.com>2021-11-17 15:48:37 +0800
committerliuhongt <hongtao.liu@intel.com>2021-11-22 11:24:11 +0800
commitb5844cb0bc8c7d9be2ff1ecded249cad82b9b71c (patch)
treec198cb62c5ac097569b97a3ce23cd727eba4a068 /gcc
parent2b5b8610e985e23a0c2e0272339ab074a750e240 (diff)
downloadgcc-b5844cb0bc8c7d9be2ff1ecded249cad82b9b71c.zip
gcc-b5844cb0bc8c7d9be2ff1ecded249cad82b9b71c.tar.gz
gcc-b5844cb0bc8c7d9be2ff1ecded249cad82b9b71c.tar.bz2
Don't allow mask/sse/mmx mov in TLS code sequences.
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/constraints.md (Bk): New define_memory_constraint. * 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i386/constraints.md5
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c30
-rw-r--r--gcc/config/i386/i386.md8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr103275.c83
5 files changed, 123 insertions, 4 deletions
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 87cceac..6b291a0 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -186,6 +186,11 @@
(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 7e05510..1cd2197 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_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 7fe271b..10bfa0e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11628,6 +11628,36 @@ 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.
+ 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 7b2de60..03d401e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2164,9 +2164,9 @@
(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 ,*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,*kBk,*k,*k,CBC"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& ix86_hardreg_mov_ok (operands[0], operands[1])"
{
@@ -2385,9 +2385,9 @@
(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 ,*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,*kBk,*k ,CBC"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& ix86_hardreg_mov_ok (operands[0], operands[1])"
{
diff --git a/gcc/testsuite/gcc.target/i386/pr103275.c b/gcc/testsuite/gcc.target/i386/pr103275.c
new file mode 100644
index 0000000..c93413f
--- /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;
+}