From patchwork Tue Jun 9 18:09:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 482331 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 2715A140332 for ; Wed, 10 Jun 2015 04:39:12 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=jqTDqC6O; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; q=dns; s=default; b=GYo50irS4CvMHoG1KN fjvTzEHa9HU60u9gL8cfm4iAHE1ZtrNbhWaZ1TAT46/FniuQxHERKdkCnKfhog62 CVWpIZ5jXZHYxEOjx5ulTOUdxDGF1xAb+tp64Qj56n0FycngOoMGQNgT5ai00BOK LPDsfv85sY3XulTUcO4XXaN5g= 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 :mime-version:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; s=default; bh=m3g0MkXSpC20wNFuLa2+NrXG +DY=; b=jqTDqC6Oz7nKdH0Plnky3IGfisJGNXTlsn7VhuTU6gS2k1SADWpIkXyK FZjlI9SCD+8LpSmQn0CsO9RUClcOLbR4RK8DpDj4O5CUZpDkTmmLbl1b4Z05keLc ly2sMej8PF3vw6tMNCSGeNYTPGzGsncN0YjRc2jrErVq/JkOUx8= Received: (qmail 72574 invoked by alias); 9 Jun 2015 18:39:02 -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 72559 invoked by uid 89); 9 Jun 2015 18:39:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-ob0-f172.google.com Received: from mail-ob0-f172.google.com (HELO mail-ob0-f172.google.com) (209.85.214.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 09 Jun 2015 18:39:00 +0000 Received: by obbqz1 with SMTP id qz1so18679287obb.3 for ; Tue, 09 Jun 2015 11:38:59 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.60.176.37 with SMTP id cf5mr20724556oec.19.1433873368505; Tue, 09 Jun 2015 11:09:28 -0700 (PDT) Received: by 10.60.147.170 with HTTP; Tue, 9 Jun 2015 11:09:28 -0700 (PDT) In-Reply-To: <20150609162132.GE10247@tucnak.redhat.com> References: <20150609115739.GZ10247@tucnak.redhat.com> <20150609125703.GA10247@tucnak.redhat.com> <20150609133905.GB10247@tucnak.redhat.com> <20150609142638.GC10247@tucnak.redhat.com> <20150609162132.GE10247@tucnak.redhat.com> Date: Tue, 9 Jun 2015 20:09:28 +0200 Message-ID: Subject: Re: [PATCH] Fix ix86_split_long_move collision handling with TLS (PR target/66470) From: Uros Bizjak To: Jakub Jelinek Cc: "H.J. Lu" , "gcc-patches@gcc.gnu.org" On Tue, Jun 9, 2015 at 6:21 PM, Jakub Jelinek wrote: > On Tue, Jun 09, 2015 at 06:16:32PM +0200, Uros Bizjak wrote: >> > something? Would it be acceptable to just guard the changes in the patch >> > with !TARGET_X32 and let H.J. deal with that target? I'm afraid I'm lost >> > when to ZERO_EXTEND addr (if needed at all), etc. >> >> If you wish, I can take your patch and take if further. -mx32 is a >> delicate beast... > > If you could, it would be appreciated, I'm quite busy with OpenMP 4.1 stuff > now. > Note that for -m64/-mx32 it will be much harder to create a reproducer, > because to trigger the bug one has to convince the register allocator > to allocate the lhs of the load in certain registers (not that hard), > but also the index register (to be scaled, also not that hard) and > also the register holding the tls symbol immediate. Wonder if one has to > keep all but the two registers live across the load or something similar. Please find attach a patch that takes your idea slightly further. We find perhaps zero-extended UNSPEC_TP, and copy it for further use. At its place, we simply slap const0_rtx. We know that address to multi-word values has to be offsettable, which in case of x32 means that it is NOT zero-extended address. Uros. Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 224292) +++ config/i386/i386.c (working copy) @@ -22858,7 +22858,7 @@ ix86_split_long_move (rtx operands[]) Do an lea to the last part and use only one colliding move. */ else if (collisions > 1) { - rtx base; + rtx base, addr, tls_base = NULL_RTX; collisions = 1; @@ -22869,10 +22869,52 @@ ix86_split_long_move (rtx operands[]) if (GET_MODE (base) != Pmode) base = gen_rtx_REG (Pmode, REGNO (base)); - emit_insn (gen_rtx_SET (base, XEXP (part[1][0], 0))); + addr = XEXP (part[1][0], 0); + if (TARGET_TLS_DIRECT_SEG_REFS) + { + struct ix86_address parts; + int ok = ix86_decompose_address (addr, &parts); + gcc_assert (ok); + if (parts.seg != SEG_DEFAULT) + { + /* It is not valid to use %gs: or %fs: in + lea though, so we need to remove it from the + address used for lea and add it to each individual + memory loads instead. */ + rtx *x = &addr; + while (GET_CODE (*x) == PLUS) + { + for (i = 0; i < 2; i++) + { + rtx op = XEXP (*x, i); + if ((GET_CODE (op) == UNSPEC + && XINT (op, 1) == UNSPEC_TP) + || (GET_CODE (op) == ZERO_EXTEND + && GET_CODE (XEXP (op, 0)) == UNSPEC + && (XINT (XEXP (op, 0), 1) + == UNSPEC_TP))) + { + tls_base = XEXP (*x, i); + XEXP (*x, i) = const0_rtx; + break; + } + } + + if (tls_base) + break; + x = &XEXP (*x, 0); + } + gcc_assert (tls_base); + } + } + emit_insn (gen_rtx_SET (base, addr)); + if (tls_base) + base = gen_rtx_PLUS (GET_MODE (base), base, tls_base); part[1][0] = replace_equiv_address (part[1][0], base); for (i = 1; i < nparts; i++) { + if (tls_base) + base = copy_rtx (base); tmp = plus_constant (Pmode, base, UNITS_PER_WORD * i); part[1][i] = replace_equiv_address (part[1][i], tmp); }