From patchwork Fri Nov 19 01:14:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Liu, Hongtao" X-Patchwork-Id: 47915 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 495C03857C5B for ; Fri, 19 Nov 2021 01:15:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 495C03857C5B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1637284504; bh=h//At8SFhOalz98ZPa+JObFxZaZMBR2KCOv4IYWWbuU=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=wtm/4seS/EAWAWEpgfWRhVfll1Oy8NDSah8CYflgcmjUZJLtJ9cSlUXLs9JTw1yIK vrDr9By4QI9LmlToHZCd0hMSd+Tvi5+8U5oWaD/kYl08f7QbyfUEXmNmDuXSSnfsT3 B6E9Dzlvkk33i0bnEnc7/C8RQuVGkMBMimaeqMtQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by sourceware.org (Postfix) with ESMTPS id 084293858422 for ; Fri, 19 Nov 2021 01:14:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 084293858422 X-IronPort-AV: E=McAfee;i="6200,9189,10172"; a="221547899" X-IronPort-AV: E=Sophos;i="5.87,246,1631602800"; d="scan'208";a="221547899" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Nov 2021 17:14:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,246,1631602800"; d="scan'208";a="495649621" Received: from scymds01.sc.intel.com ([10.148.94.138]) by orsmga007.jf.intel.com with ESMTP; 18 Nov 2021 17:14:31 -0800 Received: from shliclel320.sh.intel.com (shliclel320.sh.intel.com [10.239.236.50]) by scymds01.sc.intel.com with ESMTP id 1AJ1ETiB004009; Thu, 18 Nov 2021 17:14:30 -0800 To: gcc-patches@gcc.gnu.org Subject: [PATCH] Don't allow mask/sse/mmx mov in TLS code sequences. Date: Fri, 19 Nov 2021 09:14:29 +0800 Message-Id: <20211119011429.59776-1-hongtao.liu@intel.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: liuhongt via Gcc-patches From: "Liu, Hongtao" Reply-To: liuhongt Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "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/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; +}