From patchwork Mon Dec 13 22:59:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 75434 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 6DF1A1007D2 for ; Tue, 14 Dec 2010 10:01:01 +1100 (EST) Received: (qmail 17007 invoked by alias); 13 Dec 2010 23:00:52 -0000 Received: (qmail 16976 invoked by uid 22791); 13 Dec 2010 23:00:48 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, TW_GX, TW_SG, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 13 Dec 2010 23:00:41 +0000 Received: (qmail 27225 invoked from network); 13 Dec 2010 23:00:37 -0000 Received: from unknown (HELO ?84.152.198.60?) (bernds@127.0.0.2) by mail.codesourcery.com with ESMTPA; 13 Dec 2010 23:00:37 -0000 Message-ID: <4D06A565.4030103@codesourcery.com> Date: Mon, 13 Dec 2010 23:59:49 +0100 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101211 Lightning/1.0b3pre Thunderbird/3.1.7 MIME-Version: 1.0 To: GCC Patches Subject: [ARM] Fix an internal error 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 This fixes a crash while compiling a customer testcase (which I don't know yet whether it can be posted) for ARM. Going into combine, we have (insn 166 165 167 20 10208.c:22 (set (reg:CC 24 cc) (compare:CC (reg:SI 141 [ D.2039 ]) (const_int 78 [0x4e]))) (insn 167 166 169 20 10208.c:22 (set (reg:SI 276) (eq:SI (reg:CC 24 cc) (const_int 0 [0x0]))) (insn 169 167 170 20 10208.c:22 (set (reg:CC 24 cc) (compare:CC (reg:SI 141 [ D.2039 ]) (const_int 110 [0x6e]))) (insn 170 169 172 20 10208.c:22 (set (reg:SI 278) (eq:SI (reg:CC 24 cc) (const_int 0 [0x0]))) (insn 172 170 173 20 10208.c:22 (set (reg:SI 279) (ior:SI (reg:SI 276) (reg:SI 278))) (insn 173 172 174 20 10208.c:14 (set (reg/v:SI 136 [ cur_k ]) (and:SI (reg:SI 279) (const_int 255 [0xff]))) (insn 174 173 175 20 10208.c:28 (set (reg:CC 24 cc) (compare:CC (reg/v:SI 136 [ cur_k ]) (const_int 0 [0x0]))) (jump_insn 175 174 192 20 10208.c:28 (set (pc) (if_then_else (le (reg:CC 24 cc) (const_int 0 [0x0])) (label_ref 180) (pc))) All this gets combined so that we finally end up with the following pattern, i3 == insn 174: (set (reg:CC 24 cc) (compare:CC (ior:SI (eq:SI (reg:SI 141 [ D.2039 ]) (const_int 78 [0x4e])) (eq:SI (reg:SI 141 [ D.2039 ]) (const_int 110 [0x6e]))) (const_int 0 [0x0]))) We call arm_select_cc_mode, it returns CC_DEQmode, and we later crash in get_arm_condition_code because we don't expect to see a LE comparison with that mode. Fixed with the following patch. The comment at the top of arm_select_dominance_cc_mode states that "in all cases OP will be EQ or NE", which matches the assert in get_arm_condition_code, but the caller does not ensure it. This looks suspiciously like we have a missed-optimization bug as well, but I did not investigate it. In the following gimple, the compare-and-jump ought to be optimized away. D.2040_26 = D.2039_25 == 110; D.2041_27 = D.2039_25 == 78; D.2042_28 = D.2041_27 | D.2040_26; cur_k_11 = (int) D.2042_28; if (cur_k_11 > 0) goto ; else goto ; Ok? Bernd * config/arm/arm.c (arm_select_cc_mode): Before calling arm_select_dominance_cc_mode for AND or IOR operations, ensure that op is NE or EQ. Index: ../../gcc/trunk-sgxx-4_5/gcc/config/arm/arm.c =================================================================== --- ../../gcc/trunk-sgxx-4_5/gcc/config/arm/arm.c (revision 307695) +++ ../../gcc/trunk-sgxx-4_5/gcc/config/arm/arm.c (working copy) @@ -10686,12 +10686,14 @@ arm_select_cc_mode (enum rtx_code op, rt /* Alternate canonicalizations of the above. These are somewhat cleaner. */ if (GET_CODE (x) == AND + && (op == EQ || op == NE) && COMPARISON_P (XEXP (x, 0)) && COMPARISON_P (XEXP (x, 1))) return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), DOM_CC_X_AND_Y); if (GET_CODE (x) == IOR + && (op == EQ || op == NE) && COMPARISON_P (XEXP (x, 0)) && COMPARISON_P (XEXP (x, 1))) return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),