From patchwork Tue Nov 10 17:32:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyrylo Tkachov X-Patchwork-Id: 56341 Delivered-To: patch@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp900934lbb; Tue, 10 Nov 2015 09:32:23 -0800 (PST) X-Received: by 10.66.136.11 with SMTP id pw11mr7360625pab.87.1447176743345; Tue, 10 Nov 2015 09:32:23 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id t11si6265103pbs.244.2015.11.10.09.32.22 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Nov 2015 09:32:23 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-413537-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-return-413537-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-413537-patch=linaro.org@gcc.gnu.org; dkim=pass header.i=@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=OQSSqLKXhrOMAwwiPESGMJi9zBtPtsu8So/aqvQgARJ +Y75bQOKqYWgK1K3nwYKWM1jGRHXsiQdaQVg11DtfckvncPxyYqf4jyjDqkFuruY bHpkYeoGkoEU0pLcyuC+98JwlTDpHH2TbNJHkamtsoc0OguFZkIcjH3WLCnUg3Vk = 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 :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=WFlpbHZeIJY6lKtPbIQqtNp3iJs=; b=h7a+Dq4j9cyBGc+jD RW+Hr6mMN5BWCdPUiSSSYdxfbopF2rfv0b5VYh51GEhaxeUzzXq5mR1opp/6a5eg VnQHsa0O4BeADKqz8J7bsVLV+bq/tf7ydxloi5UpRh2H2oL+hArbIkyqXZmKL//8 ZIL2XwKmliuufzb4Xi+oQ85ulE= 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-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 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 X-IsSubscribed: yes 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 addressing mode we accepted an offset of -256 because the mode in the pattern is advertised as DImode and that was accepted 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 aligned we can't use LDRDs so the code generates unaligned_loaddi patterns and expects them to be split into two normal loads after reload. Similarly for unaligned store destinations. This patch just explicitly generates the two unaligned SImode loads or stores when appropriate inside gen_movmem_ldrd_strd. This makes the unaligned_loaddi and unaligned_storedi patterns unused, so we can remove them. This patch fixes the ICe in gcc.target/aarch64/advsimd-intrinsics/vldX.c seen with -mthumb -mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard -mfp16-format=ieee 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. 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); - src = adjust_address (src, DImode, 0); - dst = 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 = adjust_address (src, src_aligned ? DImode : SImode, 0); + dst = adjust_address (dst, dst_aligned ? DImode : SImode, 0); + while (len >= 8) { len -= 8; reg0 = gen_reg_rtx (DImode); + rtx low_reg = NULL_RTX; + rtx hi_reg = NULL_RTX; + + if (!src_aligned || !dst_aligned) + { + low_reg = gen_lowpart (SImode, reg0); + hi_reg = 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 = next_consecutive_mem (src); + emit_insn (gen_unaligned_loadsi (hi_reg, src)); + } 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 = next_consecutive_mem (dst); + emit_insn (gen_unaligned_storesi (dst, hi_reg)); + } src = next_consecutive_mem (src); dst = 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")]) -;; 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" "=l,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] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[3] = gen_highpart (SImode, operands[1]); - operands[1] = 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" "=o,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] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[3] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - } - [(set_attr "arch" "t2,any") - (set_attr "length" "4,8") - (set_attr "predicable" "yes") - (set_attr "type" "store2")]) - (define_insn "*extv_reg" [(set (match_operand:SI 0 "s_register_operand" "=r")