From patchwork Mon Jan 7 10:16:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom de Vries X-Patchwork-Id: 209889 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]) by ozlabs.org (Postfix) with SMTP id 08FE62C007B for ; Mon, 7 Jan 2013 21:16:54 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1358158615; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC: Subject:References:In-Reply-To:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=vxTZHB2VyUhvyw6VFSCe2byaI2I=; b=rTQHhzCphSmipDz0y8fGCTMQAfOL+dWHhsyQjTK5KeDqCFDrqAMeEupAbSN2nG Trrm06rGQ0N2mfNilpA8G9kEYI9MvnO2/rEHh9TWNaZAHlncsPycYOhDfjJTbKW7 vmk1uEaqgnHa02cMyYcUe19qkU7RmXzVQcXlBH2uptLCk= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:X-Forwarded-Message-Id:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=LmzVngGOuWr4JfX1Iwn2ZYLFdmrg2EJRSKoESFA65Yya4tSpLizqwD/ITG5gSt 9PgqE2xXbmeKwoLDu/Gy8/0esGk/om5eqM7d1YXZa4z93Ryem5SSE6U87N5DLpnN 0EAKzQG+TYQDnHWoS5JeJpWR/HMP1B8NvILWPM/xrDY1g=; Received: (qmail 12462 invoked by alias); 7 Jan 2013 10:16:42 -0000 Received: (qmail 12439 invoked by uid 22791); 7 Jan 2013 10:16:40 -0000 X-SWARE-Spam-Status: No, hits=-4.4 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 07 Jan 2013 10:16:31 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1Ts9ks-0001A9-4y from Tom_deVries@mentor.com ; Mon, 07 Jan 2013 02:16:30 -0800 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 7 Jan 2013 02:16:29 -0800 Received: from [127.0.0.1] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.1.289.1; Mon, 7 Jan 2013 10:16:27 +0000 Message-ID: <50EAA074.3050402@mentor.com> Date: Mon, 7 Jan 2013 11:16:20 +0100 From: Tom de Vries User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: Richard Henderson CC: Steve Ellcey , Andrew Pinski , "gcc-patches@gcc.gnu.org" Subject: [PATCH] Fix PR55876 - Make generation of paradoxical subreg in widen_operand more robust References: <50EA9FDD.6000803@mentor.com> In-Reply-To: <50EA9FDD.6000803@mentor.com> X-Forwarded-Message-Id: <50EA9FDD.6000803@mentor.com> 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 [with CC to gcc-patches] -------- Original Message -------- Subject: [PATCH] Fix PR55876 - Make generation of paradoxical subreg in widen_operand more robust Date: Mon, 07 Jan 2013 11:13:49 +0100 From: Tom de Vries To: Richard Henderson CC: Steve Ellcey , Andrew Pinski Richard, Consider test-case test.c: ... static inline unsigned char bar (const char *b) { unsigned char used = 0; int i; for (i = 0; i < 4; ++i) if (b[i] != 'F') used = 1; return used; } static char buffer[8]; unsigned char foo (void) { return bar (buffer) ? 0 : 1; } ... When compiling test.c with a mips compiler, this ICE triggers: ... $ ./install/bin/mips-linux-gnu-gcc -O3 test.c -S -mabi=64 -march=mips64 test.c: In function 'foo': test.c:19:3: internal compiler error: in gen_rtx_SUBREG, at emit-rtl.c:776 return bar (buffer) ? 0 : 1; ... The ICE is introduced by revision r193539 discussed at http://gcc.gnu.org/ml/gcc-patches/2012-11/msg01148.html . The representation of foo just before expand is this: ... foo () { unsigned charD.13 usedD.1407; charD.2 _7; unsigned charD.13 _13; charD.2 _19; charD.2 _28; charD.2 _37; ;; basic block 2, loop depth 0 ;; pred: ENTRY # VUSE <.MEM_1(D)> _19 = MEM[(const charD.2 *)&bufferD.1387]; used_20 = _19 != 70 ? 1 : 0; # VUSE <.MEM_1(D)> _28 = MEM[(const charD.2 *)&bufferD.1387 + 1B]; used_29 = _28 == 70 ? used_20 : 1; # VUSE <.MEM_1(D)> _37 = MEM[(const charD.2 *)&bufferD.1387 + 2B]; used_38 = _37 == 70 ? used_29 : 1; # VUSE <.MEM_1(D)> _7 = MEM[(const charD.2 *)&bufferD.1387 + 3B]; used_10 = _7 == 70 ? used_38 : 1; _13 = used_10 ^ 1; # VUSE <.MEM_1(D)> return _13; ;; succ: EXIT } ... The used_10 operand is in a DImode reg because r193539 allows it to be promoted while expanding used_10 = _7 == 70 ? used_38 : 1 in expand_cond_expr_using_cmove. The ICE happens during expansion of _13 = used_10 ^ 1 when trying to widen the DIMode reg for use_10 from QImode to SImode: ... #6 0x085d7da5 in widen_operand (op=0xf7cd2ec0, mode=SImode, oldmode=QImode, unsignedp=1, no_extend=1) at /home/vries/local/mips/upstream/src/gcc-mainline/gcc/optabs.c:333 333 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0); (gdb) call debug_rtx (op) (reg:DI 222 [ used+-7 ]) ... And although the comment in widen_operand states that we're generating a paradoxical subreg: ... /* If MODE is no wider than a single word, we return a paradoxical SUBREG. */ if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0); ... it's not because mode == SImode and GET_MODE (op) == DImode. Then validate_subreg triggers the ICE in gen_rtx_SUBREG by returning false here: ... /* For pseudo registers, we want most of the same checks. Namely: If the register no larger than a word, the subreg must be lowpart. If the register is larger than a word, the subreg must be the lowpart of a subword. A subreg does *not* perform arbitrary bit extraction. Given that we've already checked mode/offset alignment, we only have to check subword subregs here. */ if (osize < UNITS_PER_WORD && ! (lra_in_progress && (FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode)))) { enum machine_mode wmode = isize > UNITS_PER_WORD ? word_mode : imode; unsigned int low_off = subreg_lowpart_offset (omode, wmode); if (offset % UNITS_PER_WORD != low_off) return false; } ... For a valid pseudo subreg with outer mode SImode and inner mode DImode we need the offset corresponding to the lowpart, which is 4 for -EB. But since we were trying to generate a paradoxical subreg, the offset is 0. This explains why the assert doesn't trigger with -EL. Attached patch (build and tested for target mips-linux-gnu) prevents the ICE by checking in widen_operand whether the result of the gen_rtx_SUBREG call would indeed be a paradoxical subreg. As a consequence, it handles this case now here: ... /* Otherwise, get an object of MODE, clobber it, and set the low-order part to OP. */ result = gen_reg_rtx (mode); emit_clobber (result); emit_move_insn (gen_lowpart (GET_MODE (op), result), op); return result; ... So the generated code is this: ... (insn 34 33 35 2 (clobber (reg:SI 228)) -1 (nil)) (insn 35 34 36 2 (set (subreg:DI (reg:SI 228) 0) (reg:DI 222 [ usedD.1407+-7 ])) -1 (nil)) (insn 36 35 37 2 (set (reg:SI 229) (xor:SI (reg:SI 228) (const_int 1 [0x1]))) -1 ... which is correct. I've just realized that this is probably a too conservative fix. Using this patch: ... ... we generate this instead: ... (insn 34 33 35 2 (set (reg:SI 228) (xor:SI (subreg:SI (reg:DI 222 [ usedD.1407+-7 ]) 4) (const_int 1 [0x1]))) -1 ... which is similar to what we generate with trunk for -EL. So, is the attached patch ok for trunk? Or should I test the more optimal patch listed above? Or should this be fixed somewhere else? Thanks, - Tom 2013-01-07 Tom de Vries PR target/55876 * optabs.c (optabs.c): Add condition to ensure that subreg will be paradoxical. Index: gcc/optabs.c =================================================================== --- gcc/optabs.c (revision 194898) +++ gcc/optabs.c (working copy) @@ -329,7 +329,8 @@ widen_operand (rtx op, enum machine_mode /* If MODE is no wider than a single word, we return a paradoxical SUBREG. */ - if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) + if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD + && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op))) return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0); /* Otherwise, get an object of MODE, clobber it, and set the low-order