From patchwork Thu Jun 6 07:32:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudiu Zissulescu Ianculescu X-Patchwork-Id: 1110913 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-502439-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Nl8mXbDu"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="grRdcliT"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45KHS30nwWz9sDX for ; Thu, 6 Jun 2019 17:32:34 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version :content-transfer-encoding; q=dns; s=default; b=tlnqTH8NP861gDE3 ZVC+tSc7rXToo5CWQKzUngd6dnfQwKz6zPa3LraHCPBm/xZz8UVgdZEQYIG1ieLo it1BKPpdFZmFcSKZlDbcX7iKQIjwcIVst0GEzc0EWr2MPh6WDpStJ18hJIGa/ECS HfnVk5Cr8AZxKubV270nnp3aWk8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version :content-transfer-encoding; s=default; bh=x5DmSqtjPdFQ6lmNJNC0Wm 57fkc=; b=Nl8mXbDuqCOk5w2LZd/XOJjt/gnzi3pDMnRCKVSLaMjOGDdPMY1NZK vpiZAzM2cjUb7+pVx3ibhwX95bWV8mMU9k6VBzzy2Nxuj2f39et4ET4Iy3AAqaIY cYwRpAaTzjfnks3iy+vZU5H9/fZOd14RWUhtEMbpcC537BEs4A3es= Received: (qmail 57000 invoked by alias); 6 Jun 2019 07:32:27 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 56991 invoked by uid 89); 6 Jun 2019 07:32:27 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, KAM_STOCKGEN, LIKELY_SPAM_BODY, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=rr, wh X-HELO: mail-wr1-f54.google.com Received: from mail-wr1-f54.google.com (HELO mail-wr1-f54.google.com) (209.85.221.54) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 06 Jun 2019 07:32:25 +0000 Received: by mail-wr1-f54.google.com with SMTP id x4so1250033wrt.6 for ; Thu, 06 Jun 2019 00:32:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=BVXGxoxmVgyovk79flYhjl87MyiO6pAx+z76vrldMI4=; b=grRdcliTeEwlG4jrOuupQr9wrOLTuIWMY0tdS9pcW/wN8Uj/SrELApBPbFWYyl5QN0 8gsjKvWLQzDGNTTBSBVilHXAF1h/lDiNX9qoUqoS9GOVkCccL9vPK64PbKQdTiUZMXWg IAfKnQkum2P0w/XQ9bZRN9+FnjZR2pm03YDD4DcXF1oncoAYtkztZ441gaDu42DYT77C aLsjpzKETrlgqlPTnOEEPhVO2pJYPXLbgUYOGuO1IvcJ0+5iGV6wCJsqm1CSvVZMTKSk FOyxKDTz2T9Kn2cH39JEHTM8dy15QNzyLugBCAJf2t67Ba1D393S5S7cRQDl4c7ndMOc NDgQ== Received: from localhost.localdomain (5-12-234-75.residential.rdsnet.ro. [5.12.234.75]) by smtp.gmail.com with ESMTPSA id l190sm796310wml.25.2019.06.06.00.32.21 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 06 Jun 2019 00:32:21 -0700 (PDT) From: Claudiu Zissulescu To: gcc-patches@gcc.gnu.org Cc: andrew.burgess@embecosm.com, fbedard@synopsys.com, claziss@synopsys.com Subject: [PATCH] [ARC] Fix PR89838 Date: Thu, 6 Jun 2019 10:32:11 +0300 Message-Id: <20190606073211.6992-1-claziss@gmail.com> MIME-Version: 1.0 X-IsSubscribed: yes Hi Andrew, This is a proposed fix for bugzilla PR89838 issue. It also needs to be backported to gcc9 and, eventually, gcc8 branches. Ok to apply? Claudiu gcc/ xxxx-xx-xx Claudiu Zissulescu * config/arc/arc.c (arc_symbol_binds_local_p): New function. (arc_legitimize_pic_address): Simplify and cleanup the function. (SYMBOLIC_CONST): Remove. (prepare_pic_move): Likewise. (prepare_move_operands): Handle complex mov cases here. (arc_legitimize_address_0): Remove call to arc_legitimize_pic_address. (arc_legitimize_address): Remove call to arc_legitimize_tls_address. * config/arc/arc.md (movqi_insn): Allow Cm3 match. (movhi_insn): Likewise. /gcc/testsuite xxxx-xx-xx Claudiu Zissulescu * gcc.target/arc/pr89838.c: New file. --- gcc/config/arc/arc.c | 215 +++++++------------------ gcc/config/arc/arc.md | 8 +- gcc/testsuite/gcc.target/arc/pr89838.c | 16 ++ 3 files changed, 77 insertions(+), 162 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arc/pr89838.c diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 20dfae66370..a5ee5c49a8f 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -5986,130 +5986,47 @@ arc_legitimize_tls_address (rtx addr, enum tls_model model) } } -/* Legitimize a pic address reference in ORIG. - The return value is the legitimated address. - If OLDX is non-zero, it is the target to assign the address to first. */ +/* Return true if SYMBOL_REF X binds locally. */ -static rtx -arc_legitimize_pic_address (rtx orig, rtx oldx) +static bool +arc_symbol_binds_local_p (const_rtx x) { - rtx addr = orig; - rtx pat = orig; - rtx base; + return (SYMBOL_REF_DECL (x) + ? targetm.binds_local_p (SYMBOL_REF_DECL (x)) + : SYMBOL_REF_LOCAL_P (x)); +} + +/* Legitimize a pic address reference in ORIG. The return value is + the legitimated address. */ - if (oldx == orig) - oldx = NULL; +static rtx +arc_legitimize_pic_address (rtx addr) +{ + if (!flag_pic) + return addr; - if (GET_CODE (addr) == LABEL_REF) - ; /* Do nothing. */ - else if (GET_CODE (addr) == SYMBOL_REF) + switch (GET_CODE (addr)) { - enum tls_model model = SYMBOL_REF_TLS_MODEL (addr); - if (model != 0) - return arc_legitimize_tls_address (addr, model); - else if (!flag_pic) - return orig; - else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr)) - return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC); + case SYMBOL_REF: + /* TLS symbols are handled in different place. */ + if (SYMBOL_REF_TLS_MODEL (addr)) + return addr; /* This symbol must be referenced via a load from the Global Offset Table (@GOTPC). */ - pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT); - pat = gen_const_mem (Pmode, pat); - - if (oldx == NULL) - oldx = gen_reg_rtx (Pmode); - - emit_move_insn (oldx, pat); - pat = oldx; - } - else - { - if (GET_CODE (addr) == CONST) - { - addr = XEXP (addr, 0); - if (GET_CODE (addr) == UNSPEC) - { - /* Check that the unspec is one of the ones we generate? */ - return orig; - } - /* fwprop is placing in the REG_EQUIV notes constant pic - unspecs expressions. Then, loop may use these notes for - optimizations resulting in complex patterns that are not - supported by the current implementation. The following - two if-cases are simplifying the complex patters to - simpler ones. */ - else if (GET_CODE (addr) == MINUS) - { - rtx op0 = XEXP (addr, 0); - rtx op1 = XEXP (addr, 1); - gcc_assert (oldx); - gcc_assert (GET_CODE (op1) == UNSPEC); - - emit_move_insn (oldx, - gen_rtx_CONST (SImode, - arc_legitimize_pic_address (op1, - NULL_RTX))); - emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx))); - return oldx; - - } - else if (GET_CODE (addr) != PLUS) - { - rtx tmp = XEXP (addr, 0); - enum rtx_code code = GET_CODE (addr); - - /* It only works for UNARY operations. */ - gcc_assert (UNARY_P (addr)); - gcc_assert (GET_CODE (tmp) == UNSPEC); - gcc_assert (oldx); - - emit_move_insn - (oldx, - gen_rtx_CONST (SImode, - arc_legitimize_pic_address (tmp, - NULL_RTX))); - - emit_insn (gen_rtx_SET (oldx, - gen_rtx_fmt_ee (code, SImode, - oldx, const0_rtx))); - - return oldx; - } - else - { - gcc_assert (GET_CODE (addr) == PLUS); - if (GET_CODE (XEXP (addr, 0)) == UNSPEC) - return orig; - } - } - - if (GET_CODE (addr) == PLUS) - { - rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1); - - base = arc_legitimize_pic_address (op0, oldx); - pat = arc_legitimize_pic_address (op1, - base == oldx ? NULL_RTX : oldx); + if (!arc_symbol_binds_local_p (addr)) + return gen_const_mem (Pmode, arc_unspec_offset (addr, ARC_UNSPEC_GOT)); - if (base == op0 && pat == op1) - return orig; + /* Local symb: use @pcl to access it. */ + /* Fall through. */ + case LABEL_REF: + return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC); - if (GET_CODE (pat) == CONST_INT) - pat = plus_constant (Pmode, base, INTVAL (pat)); - else - { - if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1))) - { - base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0)); - pat = XEXP (pat, 1); - } - pat = gen_rtx_PLUS (Pmode, base, pat); - } - } + default: + break; } - return pat; + return addr; } /* Output address constant X to FILE, taking PIC into account. */ @@ -6271,28 +6188,6 @@ arc_output_pic_addr_const (FILE * file, rtx x, int code) } } -#define SYMBOLIC_CONST(X) \ -(GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == LABEL_REF \ - || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X))) - -/* Emit insns to move operands[1] into operands[0]. */ - -static void -prepare_pic_move (rtx *operands, machine_mode) -{ - if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]) - && flag_pic) - operands[1] = force_reg (Pmode, operands[1]); - else - { - rtx temp = (reload_in_progress ? operands[0] - : flag_pic? gen_reg_rtx (Pmode) : NULL_RTX); - operands[1] = arc_legitimize_pic_address (operands[1], temp); - } -} - - /* The function returning the number of words, at the beginning of an argument, must be put in registers. The returned value must be zero for arguments that are passed entirely in registers or that @@ -9072,30 +8967,38 @@ prepare_move_operands (rtx *operands, machine_mode mode) } } - if (mode == SImode && SYMBOLIC_CONST (operands[1])) + if (GET_CODE (operands[1]) == SYMBOL_REF) { - prepare_pic_move (operands, SImode); - - /* Disable any REG_EQUALs associated with the symref - otherwise the optimization pass undoes the work done - here and references the variable directly. */ + enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]); + if (MEM_P (operands[0]) && flag_pic) + operands[1] = force_reg (mode, operands[1]); + else if (model) + operands[1] = arc_legitimize_tls_address (operands[1], model); } + operands[1] = arc_legitimize_pic_address (operands[1]); + + /* Store instructions are limited, they only accept as address an + immediate, a register or a register plus a small immediate. */ if (MEM_P (operands[0]) - && !(reload_in_progress || reload_completed)) + && !move_dest_operand (operands[0], mode)) { - operands[1] = force_reg (mode, operands[1]); - if (!move_dest_operand (operands[0], mode)) - { - rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); - /* This is like change_address_1 (operands[0], mode, 0, 1) , - except that we can't use that function because it is static. */ - rtx pat = change_address (operands[0], mode, addr); - MEM_COPY_ATTRIBUTES (pat, operands[0]); - operands[0] = pat; - } + rtx tmp0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); + rtx tmp1 = change_address (operands[0], mode, tmp0); + MEM_COPY_ATTRIBUTES (tmp1, operands[0]); + operands[0] = tmp1; } + /* Check if it is constant but it is not legitimized. */ + if (CONSTANT_P (operands[1]) + && !arc_legitimate_constant_p (mode, operands[1])) + operands[1] = force_reg (mode, XEXP (operands[1], 0)); + else if (MEM_P (operands[0]) + && ((CONSTANT_P (operands[1]) + && !satisfies_constraint_Cm3 (operands[1])) + || MEM_P (operands[1]))) + operands[1] = force_reg (mode, operands[1]); + return false; } @@ -9566,11 +9469,10 @@ arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED, { rtx addr, inner; - if (flag_pic && SYMBOLIC_CONST (x)) - (x) = arc_legitimize_pic_address (x, 0); addr = x; if (GET_CODE (addr) == CONST) addr = XEXP (addr, 0); + if (GET_CODE (addr) == PLUS && CONST_INT_P (XEXP (addr, 1)) && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF @@ -9601,13 +9503,6 @@ arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED, static rtx arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode) { - if (GET_CODE (orig_x) == SYMBOL_REF) - { - enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x); - if (model != 0) - return arc_legitimize_tls_address (orig_x, model); - } - rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode); if (new_x) diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index 082b5bba6ec..ed29aa3d06e 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -672,7 +672,9 @@ core_3, archs4x, archs4xd, archs4xd_slow" [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w, w,???w,h, w,Rcq, S,!*x, r,r, Ucm,m,???m, m,Usc") (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL, I,?Rac,i,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))] "register_operand (operands[0], QImode) - || register_operand (operands[1], QImode)" + || register_operand (operands[1], QImode) + || (satisfies_constraint_Cm3 (operands[1]) + && memory_operand (operands[0], QImode))" "@ mov%? %0,%1%& mov%? %0,%1%& @@ -714,7 +716,9 @@ core_3, archs4x, archs4xd, archs4xd_slow" /* Don't use a LIMM that we could load with a single insn - we loose delay-slot filling opportunities. */ && !satisfies_constraint_I (operands[1]) - && satisfies_constraint_Usc (operands[0]))" + && satisfies_constraint_Usc (operands[0])) + || (satisfies_constraint_Cm3 (operands[1]) + && memory_operand (operands[0], HImode))" "@ mov%? %0,%1%& mov%? %0,%1%& diff --git a/gcc/testsuite/gcc.target/arc/pr89838.c b/gcc/testsuite/gcc.target/arc/pr89838.c new file mode 100644 index 00000000000..559434ac87e --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/pr89838.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-O2" } */ + +extern void foo (void); +extern void bar (void *); + +struct { + int __attribute__(()) a; + int __attribute__(()) b; +} __thread c __attribute__((tls_model("initial-exec"))); + +void foo (void) +{ + bar (&c.b); +}