From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6475 invoked by alias); 10 Nov 2015 17:32:09 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 6464 invoked by uid 89); 10 Nov 2015 17:32:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (146.101.78.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 10 Nov 2015 17:32:05 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-15-FLOy6hepSey-bd7cdeMZkA-1; Tue, 10 Nov 2015 17:32:00 +0000 Received: from [10.2.206.200] ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 10 Nov 2015 17:32:00 +0000 Message-ID: <56422A10.80500@arm.com> Date: Tue, 10 Nov 2015 17:32:00 -0000 From: Kyrill Tkachov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches CC: Ramana Radhakrishnan , Richard Earnshaw Subject: [PATCH][ARM] PR 68149 Fix ICE in unaligned_loaddi split X-MC-Unique: FLOy6hepSey-bd7cdeMZkA-1 Content-Type: multipart/mixed; boundary="------------020307070806050303040405" X-IsSubscribed: yes X-SW-Source: 2015-11/txt/msg01253.txt.bz2 This is a multi-part message in MIME format. --------------020307070806050303040405 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Content-length: 1781 Hi all, This ICE in this PR occurs when we're trying to split unaligned_loaddi into= two SImode unaligned loads. The problem is in the addressing mode. When reload was picking the address= ing mode we accepted an offset of -256 because the mode in the pattern is advertised as DImode and that was a= ccepted by the legitimate address hooks because they thought it was a NEON load (DImode is in VALID_NEON_DREG= _MODE). However, the splitter wants to generate two normal SImode unaligned loads using that address, for which= -256 is not valid, so we ICE in gen_lowpart. The only way unaligned_loaddi could be generated was through the gen_movmem= _ldrd_strd expansion that implements a memmove using LDRD and STRD sequences. If the memmove source is not align= ed we can't use LDRDs so the code generates unaligned_loaddi patterns and expects them to be split into two n= ormal loads after reload. Similarly for unaligned store destinations. This patch just explicitly generates the two unaligned SImode loads or stor= es when appropriate inside gen_movmem_ldrd_strd. This makes the unaligned_loaddi and unaligned_stored= i patterns unused, so we can remove them. This patch fixes the ICe in gcc.target/aarch64/advsimd-intrinsics/vldX.c se= en with -mthumb -mcpu=3Dcortex-a15 -mfpu=3Dneon-vfpv4 -mfloat-abi=3Dhard -mfp16-for= mat=3Dieee so no new testcase is added. Bootstrapped and tested on arm-none-linux-gnueabihf. Ok for trunk? Thanks, Kyrill 2015-11-10 Kyrylo Tkachov PR target/68149 * config/arm/arm.md (unaligned_loaddi): Delete. (unaligned_storedi): Likewise. * config/arm/arm.c (gen_movmem_ldrd_strd): Don't generate unaligned DImode memory ops. Instead perform two back-to-back unalgined SImode ops. --------------020307070806050303040405 Content-Type: text/x-patch; name=arm-unaligned-movmem.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="arm-unaligned-movmem.patch" Content-length: 4304 commit 51849126dbef9ebdd95e0ee4dbcd84361e22c992 Author: Kyrylo Tkachov Date: Tue Nov 3 17:36:38 2015 +0000 [ARM] Fix ICE in unaligned_loaddi split diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 71e704c..eafcb9c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -14911,21 +14911,41 @@ gen_movmem_ldrd_strd (rtx *operands) if (!(dst_aligned || src_aligned)) return arm_gen_movmemqi (operands); =20 - src =3D adjust_address (src, DImode, 0); - dst =3D adjust_address (dst, DImode, 0); + /* If the either src or dst is unaligned we'll be accessing it as pairs + of unaligned SImode accesses. Otherwise we can generate DImode + ldrd/strd instructions. */ + src =3D adjust_address (src, src_aligned ? DImode : SImode, 0); + dst =3D adjust_address (dst, dst_aligned ? DImode : SImode, 0); + while (len >=3D 8) { len -=3D 8; reg0 =3D gen_reg_rtx (DImode); + rtx low_reg =3D NULL_RTX; + rtx hi_reg =3D NULL_RTX; + + if (!src_aligned || !dst_aligned) + { + low_reg =3D gen_lowpart (SImode, reg0); + hi_reg =3D gen_highpart_mode (SImode, DImode, reg0); + } if (src_aligned) emit_move_insn (reg0, src); else - emit_insn (gen_unaligned_loaddi (reg0, src)); + { + emit_insn (gen_unaligned_loadsi (low_reg, src)); + src =3D next_consecutive_mem (src); + emit_insn (gen_unaligned_loadsi (hi_reg, src)); + } =20 if (dst_aligned) emit_move_insn (dst, reg0); else - emit_insn (gen_unaligned_storedi (dst, reg0)); + { + emit_insn (gen_unaligned_storesi (dst, low_reg)); + dst =3D next_consecutive_mem (dst); + emit_insn (gen_unaligned_storesi (dst, hi_reg)); + } =20 src =3D next_consecutive_mem (src); dst =3D next_consecutive_mem (dst); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 1e40b17..42f961f 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4362,59 +4362,6 @@ (define_insn "unaligned_storehi" (set_attr "predicable_short_it" "yes,no") (set_attr "type" "store1")]) =20 -;; Unaligned double-word load and store. -;; Split after reload into two unaligned single-word accesses. -;; It prevents lower_subreg from splitting some other aligned -;; double-word accesses too early. Used for internal memcpy. - -(define_insn_and_split "unaligned_loaddi" - [(set (match_operand:DI 0 "s_register_operand" "=3Dl,r") - (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")] - UNSPEC_UNALIGNED_LOAD))] - "unaligned_access && TARGET_32BIT" - "#" - "&& reload_completed" - [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD)) - (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))] - { - operands[2] =3D gen_highpart (SImode, operands[0]); - operands[0] =3D gen_lowpart (SImode, operands[0]); - operands[3] =3D gen_highpart (SImode, operands[1]); - operands[1] =3D gen_lowpart (SImode, operands[1]); - - /* If the first destination register overlaps with the base address, - swap the order in which the loads are emitted. */ - if (reg_overlap_mentioned_p (operands[0], operands[1])) - { - std::swap (operands[1], operands[3]); - std::swap (operands[0], operands[2]); - } - } - [(set_attr "arch" "t2,any") - (set_attr "length" "4,8") - (set_attr "predicable" "yes") - (set_attr "type" "load2")]) - -(define_insn_and_split "unaligned_storedi" - [(set (match_operand:DI 0 "memory_operand" "=3Do,o") - (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")] - UNSPEC_UNALIGNED_STORE))] - "unaligned_access && TARGET_32BIT" - "#" - "&& reload_completed" - [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE)) - (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))] - { - operands[2] =3D gen_highpart (SImode, operands[0]); - operands[0] =3D gen_lowpart (SImode, operands[0]); - operands[3] =3D gen_highpart (SImode, operands[1]); - operands[1] =3D gen_lowpart (SImode, operands[1]); - } - [(set_attr "arch" "t2,any") - (set_attr "length" "4,8") - (set_attr "predicable" "yes") - (set_attr "type" "store2")]) - =20 (define_insn "*extv_reg" [(set (match_operand:SI 0 "s_register_operand" "=3Dr") --------------020307070806050303040405--