From patchwork Mon Jun 17 11:14:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julian Brown X-Patchwork-Id: 251816 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 CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 1B7F12C029B for ; Mon, 17 Jun 2013 21:15:36 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=eywVnoFHn54y4JUmWjUu3aeHF8GBPDrAVip84VPYTGWYvJqw7h jr3SGqZwF3ZflAAcxbd8vxK8pMQW0ocHsF8XOAWYm8mv68raT6/eiDnMtjFE85I8 U06ON+eiW38Y3wqPs2aeXQhIeLICdiUy5VuRC2HHFYa0x2utMgUoGySCA= 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:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=+/he95oBuMPujjuQVrrgKGN0TDw=; b=t24aQTr1ks2V9mdZK+n4 jDmVuzfOeWY+/wskeni8QObLsKcJGCFXEXSEEHFXK6giSmqKDpyCAFBpWPUTK8Ls 3srBqDsZbQUQcv05eKsd3dJgCk6SDzzi0RCtlWfQvfrVy4kt/zpi0lPBXJO30w2d n8T8Q+hf3KZsR2DcGsRsYbk= Received: (qmail 25327 invoked by alias); 17 Jun 2013 11:15:30 -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 25308 invoked by uid 89); 17 Jun 2013 11:15:30 -0000 X-Spam-SWARE-Status: No, score=-3.7 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL autolearn=ham version=3.3.1 Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 17 Jun 2013 11:15:28 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1UoXPC-0007EX-J6 from Julian_Brown@mentor.com ; Mon, 17 Jun 2013 04:15:26 -0700 Received: from SVR-IES-FEM-02.mgc.mentorg.com ([137.202.0.106]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 17 Jun 2013 04:15:26 -0700 Received: from octopus (137.202.0.76) by SVR-IES-FEM-02.mgc.mentorg.com (137.202.0.106) with Microsoft SMTP Server id 14.2.247.3; Mon, 17 Jun 2013 12:15:23 +0100 Date: Mon, 17 Jun 2013 12:14:59 +0100 From: Julian Brown To: CC: Richard Earnshaw , Ramana Radhakrishnan Subject: [PATCH, ARM] Fix gcc.dg/pr48335-5.c ICE with NEON enabled Message-ID: <20130617121459.1443db75@octopus> MIME-Version: 1.0 X-Virus-Found: No Hi, This patch fixes an ICE where the compiler crashes (with NEON enabled) during expansion of an instruction such as: pr48335-5.c:17:1: error: unrecognizable insn: } ^ (insn 9 8 10 2 (set (reg:DI 116 [ s ]) (unspec:DI [ (mem/c:DI (plus:SI (reg/f:SI 105 virtual-stack-vars) (const_int -8 [0xfffffffffffffff8])) [2 S8 A32]) ] UNSPEC_MISALIGNED_ACCESS)) pr48335-5.c:15 -1 (nil)) pr48335-5.c:17:1: internal compiler error: in extract_insn, at recog.c:2158 The problem is that generic code (expr.c:expand_expr_real_1, case VIEW_CONVERT_EXPR) expects to be able to use movmisalign without explicitly checking that the operands match -- reminiscent of normal moves, which are generally expected to "always work". However, the current predicates on the NEON movmisalign insn patterns reject MEMs which refer to virtual registers such as the virtual-stack-vars above, leading to the ICE, even though the middle end would generally be capable of rewriting such an instruction into one which is valid. The fix for this is to tweak the operands for the instruction patterns in question to allow such virtual registers, pre-reload. This fixes gcc.dg/pr48335-5.c when the testsuite is run with "-march=armv7-a -mfpu=neon -mfloat-abi=softfp" options, with no other changes in results for gcc, g++ & libstdc++. OK to apply? Thanks, Julian ChangeLog gcc/ * config/arm/arm.c (neon_vector_mem_operand): Add strict argument. Permit virtual register pre-reload if !strict. (coproc_secondary_reload_class): Adjust for neon_vector_mem_operand change. * config/arm/arm-protos.h (neon_vector_mem_operand): Adjust prototype. * config/arm/neon.md (movmisalign): Use neon_perm_struct_or_reg_operand instead of neon_struct_or_register_operand. (*movmisalign_neon_load, *movmisalign_neon_store): Use neon_permissive_struct_operand instead of neon_struct_operand. * config/arm/constraints.md (Un, Um, Us): Adjust calls to neon_vector_mem_operand. * config/arm/predicates.md (neon_struct_operand): Adjust call to neon_vector_mem_operand. (neon_permissive_struct_operand): New. (neon_struct_or_register_operand): Rename to... (neon_perm_struct_or_reg_operand): This. Adjust call to neon_vector_mem_operand. Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c (revision 200070) +++ gcc/config/arm/arm.c (working copy) @@ -7863,7 +7863,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou && GET_CODE (SET_SRC (x)) == VEC_SELECT) { *total = rtx_cost (SET_DEST (x), code, 0, speed); - if (!neon_vector_mem_operand (SET_DEST (x), 2)) + if (!neon_vector_mem_operand (SET_DEST (x), 2, true)) *total += COSTS_N_INSNS (1); return true; } @@ -7874,7 +7874,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou { rtx mem = XEXP (XEXP (SET_SRC (x), 0), 0); *total = rtx_cost (mem, code, 0, speed); - if (!neon_vector_mem_operand (mem, 2)) + if (!neon_vector_mem_operand (mem, 2, true)) *total += COSTS_N_INSNS (1); return true; } @@ -10046,7 +10046,7 @@ arm_coproc_mem_operand (rtx op, bool wb) 2 - Element/structure loads (vld1) */ int -neon_vector_mem_operand (rtx op, int type) +neon_vector_mem_operand (rtx op, int type, bool strict) { rtx ind; @@ -10058,7 +10058,7 @@ neon_vector_mem_operand (rtx op, int typ || reg_mentioned_p (virtual_outgoing_args_rtx, op) || reg_mentioned_p (virtual_stack_dynamic_rtx, op) || reg_mentioned_p (virtual_stack_vars_rtx, op))) - return FALSE; + return !strict; /* Constants are converted into offsets from labels. */ if (!MEM_P (op)) @@ -10168,7 +10168,7 @@ coproc_secondary_reload_class (enum mach { if (!TARGET_NEON_FP16) return GENERAL_REGS; - if (s_register_operand (x, mode) || neon_vector_mem_operand (x, 2)) + if (s_register_operand (x, mode) || neon_vector_mem_operand (x, 2, true)) return NO_REGS; return GENERAL_REGS; } Index: gcc/config/arm/arm-protos.h =================================================================== --- gcc/config/arm/arm-protos.h (revision 200070) +++ gcc/config/arm/arm-protos.h (working copy) @@ -95,7 +95,7 @@ extern enum reg_class coproc_secondary_r extern bool arm_tls_referenced_p (rtx); extern int arm_coproc_mem_operand (rtx, bool); -extern int neon_vector_mem_operand (rtx, int); +extern int neon_vector_mem_operand (rtx, int, bool); extern int neon_struct_mem_operand (rtx); extern int arm_no_early_store_addr_dep (rtx, rtx); extern int arm_early_store_addr_dep (rtx, rtx); Index: gcc/config/arm/neon.md =================================================================== --- gcc/config/arm/neon.md (revision 200070) +++ gcc/config/arm/neon.md (working copy) @@ -241,8 +241,8 @@ }) (define_expand "movmisalign" - [(set (match_operand:VDQX 0 "neon_struct_or_register_operand") - (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_or_register_operand")] + [(set (match_operand:VDQX 0 "neon_perm_struct_or_reg_operand") + (unspec:VDQX [(match_operand:VDQX 1 "neon_perm_struct_or_reg_operand")] UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN" { @@ -255,7 +255,7 @@ }) (define_insn "*movmisalign_neon_store" - [(set (match_operand:VDX 0 "neon_struct_operand" "=Um") + [(set (match_operand:VDX 0 "neon_permissive_struct_operand" "=Um") (unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")] UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN" @@ -263,15 +263,16 @@ [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]) (define_insn "*movmisalign_neon_load" - [(set (match_operand:VDX 0 "s_register_operand" "=w") - (unspec:VDX [(match_operand:VDX 1 "neon_struct_operand" " Um")] + [(set (match_operand:VDX 0 "s_register_operand" "=w") + (unspec:VDX [(match_operand:VDX 1 "neon_permissive_struct_operand" + " Um")] UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vld1.\t{%P0}, %A1" [(set_attr "neon_type" "neon_vld1_1_2_regs")]) (define_insn "*movmisalign_neon_store" - [(set (match_operand:VQX 0 "neon_struct_operand" "=Um") + [(set (match_operand:VQX 0 "neon_permissive_struct_operand" "=Um") (unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")] UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN" @@ -279,8 +280,9 @@ [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]) (define_insn "*movmisalign_neon_load" - [(set (match_operand:VQX 0 "s_register_operand" "=w") - (unspec:VQX [(match_operand:VQX 1 "neon_struct_operand" " Um")] + [(set (match_operand:VQX 0 "s_register_operand" "=w") + (unspec:VQX [(match_operand:VQX 1 "neon_permissive_struct_operand" + " Um")] UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vld1.\t{%q0}, %A1" Index: gcc/config/arm/constraints.md =================================================================== --- gcc/config/arm/constraints.md (revision 200070) +++ gcc/config/arm/constraints.md (working copy) @@ -358,21 +358,21 @@ In ARM/Thumb-2 state a valid address for Neon doubleword vector load/store instructions." (and (match_code "mem") - (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 0)"))) + (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 0, true)"))) (define_memory_constraint "Um" "@internal In ARM/Thumb-2 state a valid address for Neon element and structure load/store instructions." (and (match_code "mem") - (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)"))) + (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, true)"))) (define_memory_constraint "Us" "@internal In ARM/Thumb-2 state a valid address for non-offset loads/stores of quad-word values in four ARM registers." (and (match_code "mem") - (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 1)"))) + (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 1, true)"))) (define_memory_constraint "Uq" "@internal Index: gcc/config/arm/predicates.md =================================================================== --- gcc/config/arm/predicates.md (revision 200070) +++ gcc/config/arm/predicates.md (working copy) @@ -634,10 +634,14 @@ (define_predicate "neon_struct_operand" (and (match_code "mem") - (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)"))) + (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, true)"))) -(define_predicate "neon_struct_or_register_operand" - (ior (match_operand 0 "neon_struct_operand") +(define_predicate "neon_permissive_struct_operand" + (and (match_code "mem") + (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, false)"))) + +(define_predicate "neon_perm_struct_or_reg_operand" + (ior (match_operand 0 "neon_permissive_struct_operand") (match_operand 0 "s_register_operand"))) (define_special_predicate "add_operator"