From patchwork Sat Oct 12 14:57:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 283005 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 050812C00E9 for ; Sun, 13 Oct 2013 01:57:23 +1100 (EST) 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=vWm8RjHybbryhIJR9D HD2o4aH0Eyc1iP5pohMxh3gE1TRpvhryD7cK53rDfXOssw4m7+sGNr3ng42u3hNx E3W5hX81Ccjsd9cXKwUlr2a0kQ70PFWKCGnn+piefRLzqPjzioohioDm3x65aYOE f71XpaHvvsqTQWrKJmBPDQhf4= 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=ltRsSlPEUUWLsZUgcP0CiyhO wMA=; b=q9a3xbmiP+UkiH/E+u+DYeI4lhwbeFLGAFIBKDZnzyufsHo0/ssmB5/u DIjP+iCE4FwxQXLk4VSJ5gDl6KXQbhU7BD8zT9k7BOT/nvIJwV4EaF6eznYqKU80 LRNGcMWtoo3mHJOtEayOm0N5zlB7cDmTLFGSFNXUiNr14Y/fiKM= Received: (qmail 24759 invoked by alias); 12 Oct 2013 14:57:17 -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 24749 invoked by uid 89); 12 Oct 2013 14:57:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 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-f180.google.com Received: from mail-ob0-f180.google.com (HELO mail-ob0-f180.google.com) (209.85.214.180) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sat, 12 Oct 2013 14:57:11 +0000 Received: by mail-ob0-f180.google.com with SMTP id wn1so3608880obc.39 for ; Sat, 12 Oct 2013 07:57:09 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.182.96.100 with SMTP id dr4mr19310412obb.22.1381589829568; Sat, 12 Oct 2013 07:57:09 -0700 (PDT) Received: by 10.76.75.71 with HTTP; Sat, 12 Oct 2013 07:57:09 -0700 (PDT) In-Reply-To: References: <20131011183844.GA26798@intel.com> Date: Sat, 12 Oct 2013 07:57:09 -0700 Message-ID: Subject: Re: PATCH: PR target/58690: internal compiler error: in copy_to_mode_reg, at explow.c:641 From: "H.J. Lu" To: Uros Bizjak Cc: "gcc-patches@gcc.gnu.org" X-IsSubscribed: yes On Sat, Oct 12, 2013 at 12:21 AM, Uros Bizjak wrote: > On Fri, Oct 11, 2013 at 8:38 PM, H.J. Lu wrote: > >> In x32, when a TLS address is in DImode and Pmode is SImode, >> copy_addr_to_reg will fail. This patch adds ix86_copy_addr_to_reg >> to first copy DImode address into a DImode register and then to generate >> SImode SUBREG in this case. Tested on x32. OK for trunk? >> >> 2013-10-11 H.J. Lu >> >> PR target/58690 >> * config/i386/i386.c (ix86_copy_addr_to_reg): New function. >> (ix86_expand_movmem): Replace copy_addr_to_reg with >> ix86_copy_addr_to_reg. >> (ix86_expand_setmem): Likewise. >> >> gcc/testsuite/ >> >> 2013-10-11 H.J. Lu >> >> PR target/58690 >> * gcc.target/i386/pr58690.c: New test >> >> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c >> index 37c1bec..e39d63db 100644 >> --- a/gcc/config/i386/i386.c >> +++ b/gcc/config/i386/i386.c >> @@ -22076,6 +22076,21 @@ counter_mode (rtx count_exp) >> return SImode; >> } >> >> +/* Copy the address to a register in Pmode. Support x32 TLS address in >> + DImode and Pmode in SImode. */ > > Copy the address to a Pmode register. This is used for x32 to truncate > DImode TLS address to a SImode register. > >> +static rtx >> +ix86_copy_addr_to_reg (rtx addr) >> +{ >> + if (GET_MODE (addr) != Pmode) >> + { >> + gcc_assert (GET_MODE (addr) == DImode && Pmode == SImode); >> + return gen_rtx_SUBREG (SImode, copy_to_mode_reg (DImode, addr), 0); >> + } >> + else >> + return copy_addr_to_reg (addr); >> +} > > No negative conditions please. Just switch arms of the if clause. > > OK with these changes. This is what I checked in. > Do we also need this patch on 4.8? Yes, it is also needed for 4.8. OK for 4.8 after a few days? > Thanks, > Uros. Thanks. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 37c1bec..aa15bc5 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -22076,6 +22076,21 @@ counter_mode (rtx count_exp) return SImode; } +/* Copy the address to a Pmode register. This is used for x32 to + truncate DImode TLS address to a SImode register. */ + +static rtx +ix86_copy_addr_to_reg (rtx addr) +{ + if (GET_MODE (addr) == Pmode) + return copy_addr_to_reg (addr); + else + { + gcc_assert (GET_MODE (addr) == DImode && Pmode == SImode); + return gen_rtx_SUBREG (SImode, copy_to_mode_reg (DImode, addr), 0); + } +} + /* When SRCPTR is non-NULL, output simple loop to move memory pointer to SRCPTR to DESTPTR via chunks of MODE unrolled UNROLL times, overall size is COUNT specified in bytes. When SRCPTR is NULL, output the @@ -23032,8 +23047,8 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp, if (!count) count_exp = copy_to_mode_reg (GET_MODE (count_exp), count_exp); - destreg = copy_addr_to_reg (XEXP (dst, 0)); - srcreg = copy_addr_to_reg (XEXP (src, 0)); + destreg = ix86_copy_addr_to_reg (XEXP (dst, 0)); + srcreg = ix86_copy_addr_to_reg (XEXP (src, 0)); unroll_factor = 1; move_mode = word_mode; @@ -23436,7 +23451,7 @@ ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp, rtx align_exp, if (!count) count_exp = copy_to_mode_reg (counter_mode (count_exp), count_exp); - destreg = copy_addr_to_reg (XEXP (dst, 0)); + destreg = ix86_copy_addr_to_reg (XEXP (dst, 0)); move_mode = word_mode; unroll_factor = 1; diff --git a/gcc/testsuite/gcc.target/i386/pr58690.c b/gcc/testsuite/gcc.target/ i386/pr58690.c new file mode 100644 index 0000000..87a87cc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr58690.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -maddress-mode=short" } */ + +struct gomp_thread +{ + char foo[41]; +}; +extern __thread struct gomp_thread gomp_tls_data; +void +foo (void) +{ + __builtin_memset (&gomp_tls_data, '\0', sizeof (gomp_tls_data)); +} gnu-6:pts/14[22]> cat /tmp/pr58690.patch /export/gnu/import/git/src gcc/ 2013-10-12 H.J. Lu PR target/58690 * config/i386/i386.c (ix86_copy_addr_to_reg): New function. (ix86_expand_movmem): Replace copy_addr_to_reg with ix86_copy_addr_to_reg. (ix86_expand_setmem): Likewise. gcc/testsuite/ 2013-10-12 H.J. Lu PR target/58690 * gcc.target/i386/pr58690.c: New test diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 37c1bec..aa15bc5 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -22076,6 +22076,21 @@ counter_mode (rtx count_exp) return SImode; } +/* Copy the address to a Pmode register. This is used for x32 to + truncate DImode TLS address to a SImode register. */ + +static rtx +ix86_copy_addr_to_reg (rtx addr) +{ + if (GET_MODE (addr) == Pmode) + return copy_addr_to_reg (addr); + else + { + gcc_assert (GET_MODE (addr) == DImode && Pmode == SImode); + return gen_rtx_SUBREG (SImode, copy_to_mode_reg (DImode, addr), 0); + } +} + /* When SRCPTR is non-NULL, output simple loop to move memory pointer to SRCPTR to DESTPTR via chunks of MODE unrolled UNROLL times, overall size is COUNT specified in bytes. When SRCPTR is NULL, output the @@ -23032,8 +23047,8 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp, if (!count) count_exp = copy_to_mode_reg (GET_MODE (count_exp), count_exp); - destreg = copy_addr_to_reg (XEXP (dst, 0)); - srcreg = copy_addr_to_reg (XEXP (src, 0)); + destreg = ix86_copy_addr_to_reg (XEXP (dst, 0)); + srcreg = ix86_copy_addr_to_reg (XEXP (src, 0)); unroll_factor = 1; move_mode = word_mode; @@ -23436,7 +23451,7 @@ ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp, rtx align_exp, if (!count) count_exp = copy_to_mode_reg (counter_mode (count_exp), count_exp); - destreg = copy_addr_to_reg (XEXP (dst, 0)); + destreg = ix86_copy_addr_to_reg (XEXP (dst, 0)); move_mode = word_mode; unroll_factor = 1; diff --git a/gcc/testsuite/gcc.target/i386/pr58690.c b/gcc/testsuite/gcc.target/i386/pr58690.c new file mode 100644 index 0000000..87a87cc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr58690.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -maddress-mode=short" } */ + +struct gomp_thread +{ + char foo[41]; +}; +extern __thread struct gomp_thread gomp_tls_data; +void +foo (void) +{ + __builtin_memset (&gomp_tls_data, '\0', sizeof (gomp_tls_data)); +}