From patchwork Tue Feb 16 17:19:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Clifton X-Patchwork-Id: 583580 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 172DC1402D8 for ; Wed, 17 Feb 2016 04:19:22 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ox935QIX; 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:from :to:cc:subject:date:message-id:mime-version:content-type; q=dns; s=default; b=knY2DqaxjNNrGU0eccSp6UFlXTYcmLmJRh3XgOliMjn9/3kcvC XJ4bejYJ8UghGjXMx2JeZetrETjgUsr5GMVeNbKNBAy+A+2XpAYbWiXVKoFB6fme 0hebiQFMCjLyN6BeVFIoBMBJfpK1gN528gtZVJTFnE7282eteq0GX9r90= 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-type; s= default; bh=DcwzlvpjECnkMmSiCweCgzGmmB8=; b=ox935QIXVL4425mGCiIE X7I9ePFzfrze1T881fBUbZmSKoukbREmgDCN99ncpbq5iHJD4Q1IPMsjVg2bFGJo UE+szUfyBpdjnn6V4DKMdTTt0JVz03dIMEdYB6Vd5Ih6NqofhlMnSVoijMz79cgV 6FbTaXeKZYWYrkeD/NAe+fk= Received: (qmail 8762 invoked by alias); 16 Feb 2016 17:19:13 -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 8747 invoked by uid 89); 16 Feb 2016 17:19:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=dressed, Whilst, sprintf, jb X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 16 Feb 2016 17:19:11 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 832848E6EF; Tue, 16 Feb 2016 17:19:10 +0000 (UTC) Received: from littlehelper.redhat.com (vpn1-5-22.ams2.redhat.com [10.36.5.22]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u1GHJ8Vo002046 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 16 Feb 2016 12:19:09 -0500 From: Nick Clifton To: richard.earnshaw@arm.com, ramana.radhakrishnan@arm.com Cc: gcc-patches@gcc.gnu.org Subject: RFC: Fix ARMv3 support Date: Tue, 16 Feb 2016 17:19:07 +0000 Message-ID: <87lh6k8tf8.fsf@redhat.com> MIME-Version: 1.0 X-IsSubscribed: yes Hi Richard, Hi Ramana, The ARM backend has some problems compiling for the old ARMv3 architecture. See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62254 for an example of this. v3 is very old now, and I am not sure how much interest there is in continuing to support it, but I am trying to help reduce the gcc priority bug list, so here goes... The attached patch fixes the problem, albeit not in a very subtle way. The problem is that arm_reload_[out|in]_hi is being called for a register->register move because the v3 architecture does not support 16-bit register moves. Rather than trace the problem back to the real source and fix it, I chose to just allow the reload functions to generate an SImode register move instead. Probably not the best solution, but it appears to work. The attached patch also includes the test cases derived from PR 62254 and PR 69610 (which is a duplicate of PR 62254). Including all three tests might be overkill, but it seemed like a good idea to be a little bit paranoid, just in case. Whilst testing the patch I also discovered that interworking is enabled by default, which is a problem for v3 code generation, so I added a fix to (silently) disable interworking if the target architecture does not support Thumb instructions. Any comments or criticisms before I apply the patch ? Cheers Nick gcc/ChangeLog 2016-02-16 Nick Clifton PR target/62554 PR target/69610 * config/arm/arm.c (arm_option_override_internal): Disable interworking if the target does not support thumb instructions. (arm_reload_in_hi): Handle the case where a register to register move needs reloading because there is no simple pattern to handle it. (arm_reload_out_hi): Likewise. gcc/testsuite/ChangeLog 2016-02-16 Nick Clifton PR target/62554 PR target/69610 * gcc.target/arm/pr62554.c: New test. * gcc.target/arm/pr69610-1.c: New test. * gcc.target/arm/pr69610-2.c: New test. Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c (revision 233443) +++ gcc/config/arm/arm.c (working copy) @@ -2874,6 +2874,14 @@ { arm_override_options_after_change_1 (opts); + if (TARGET_INTERWORK && !ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB)) + { + /* The default is to enable interworking, so this warning message would + be confusing to users who have just compiled with, eg, -march=armv3. */ + /* warning (0, "ignoring -minterwork because target CPU does not support THUMB"); */ + opts->x_target_flags &= ~MASK_INTERWORK; + } + if (TARGET_THUMB_P (opts->x_target_flags) && !(ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB))) { @@ -15440,6 +15448,17 @@ else /* The slot is out of range, or was dressed up in a SUBREG. */ base = reg_equiv_address (REGNO (ref)); + + /* PR 62554: If there is no equivalent memory location then just move + the value as an SImode register move. This happens when the target + architecure variant does not have an HImode register move. */ + if (base == NULL) + { + gcc_assert (REG_P (operands[0])); + emit_insn (gen_movsi (gen_rtx_SUBREG (SImode, operands[0], 0), + gen_rtx_SUBREG (SImode, ref, 0))); + return; + } } else base = find_replacement (&XEXP (ref, 0)); @@ -15557,6 +15576,17 @@ else /* The slot is out of range, or was dressed up in a SUBREG. */ base = reg_equiv_address (REGNO (ref)); + + /* PR 62554: If there is no equivalent memory location then just move + the value as an SImode register move. This happens when the target + architecure variant does not have an HImode register move. */ + if (base == NULL) + { + gcc_assert (REG_P (outval)); + emit_insn (gen_movsi (gen_rtx_SUBREG (SImode, ref, 0), + gen_rtx_SUBREG (SImode, outval, 0))); + return; + } } else base = find_replacement (&XEXP (ref, 0)); @@ -19619,6 +19649,7 @@ break; case ARM_FT_INTERWORKED: + gcc_assert (arm_arch5 || arm_arch4t); sprintf (instr, "bx%s\t%%|lr", conditional); break; --- /dev/null 2016-02-16 08:27:18.513962320 +0000 +++ gcc/testsuite/gcc.target/arm/pr62254.c 2016-02-16 16:47:30.479378118 +0000 @@ -0,0 +1,50 @@ +/* Check that pre ARMv4 compilation still works. */ +/* { dg-do compile } */ +/* { dg-options "-marm -march=armv3 -O" } */ + +typedef struct +{ + char bits; + short val; +} code; + +union uu +{ + short us; + char b[2]; +}; + +int a, b, c, f, g, h; +code *d; + +code e; + +int +fn1 (void) +{ + char i; + do + if (e.bits) + { + dodist: + f = c; + if (e.bits & 6) + { + ++i; + if (g) + do + { + union uu j; + j.b[1] = a; + h = j.us; + } + while (fn1); + } + else + { + e = d[b]; + goto dodist; + } + } + while (i); +} --- /dev/null 2016-02-16 08:27:18.513962320 +0000 +++ gcc/testsuite/gcc.target/arm/pr69610-1.c 2016-02-16 16:51:48.987779288 +0000 @@ -0,0 +1,13 @@ +/* Check that pre ARMv4 compilation still works. */ +/* { dg-do compile } */ +/* { dg-options "-marm -march=armv3 -ftree-ter" } */ + +typedef unsigned short v16u16 __attribute__ ((vector_size (16))); +typedef unsigned int v16u32 __attribute__ ((vector_size (16))); + +unsigned short +foo (v16u16 v16u16_1, v16u32 v16u32_1) +{ + v16u16_1 += (v16u16) v16u32_1; + return v16u16_1[5] + v16u32_1[1]; +} --- /dev/null 2016-02-16 08:27:18.513962320 +0000 +++ gcc/testsuite/gcc.target/arm/pr69610-2.c 2016-02-16 16:51:27.119660758 +0000 @@ -0,0 +1,32 @@ +/* Check that pre ARMv4 compilation still works. */ +/* { dg-do compile } */ +/* { dg-options "-marm -march=armv3 -O2 -fno-forward-propagate" } */ + +typedef short v16u16 __attribute__ ((vector_size (16))); +typedef unsigned v16u32 __attribute__ ((vector_size (16))); +typedef long long v16u64 __attribute__ ((vector_size (16))); + +unsigned +foo + (int + u16_0, + unsigned + u32_0, + int + u64_0, + int + u16_1, + unsigned + u64_1, + v16u16 + v16u16_0, + v16u32 + v16u32_0, + v16u64 v16u64_0, v16u16 v16u16_1, v16u32 v16u32_1, v16u64 v16u64_1) +{ + v16u16_1[3] -= v16u32_0[0]; + v16u16_0 -= (v16u16) v16u32_0; + return u16_0 + u32_0 + u64_0 + u16_1 + + v16u16_0[0] + v16u16_0[2] + v16u16_0[3] + v16u16_0[4] + v16u16_0[5] + v16u32_0[0] + v16u32_0[1] + v16u32_0[3] + v16u64_0[1] + + v16u16_1[2] + v16u16_1[3] + v16u16_1[5] + v16u16_1[7] + v16u32_1[0] + v16u32_1[3] + v16u64_1[0] + v16u64_1[1]; +}