From patchwork Wed Aug 4 20:58:33 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 60895 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 48E2EB70D4 for ; Thu, 5 Aug 2010 06:58:44 +1000 (EST) Received: (qmail 14054 invoked by alias); 4 Aug 2010 20:58:42 -0000 Received: (qmail 14032 invoked by uid 22791); 4 Aug 2010 20:58:41 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, TW_ZJ, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-qy0-f182.google.com (HELO mail-qy0-f182.google.com) (209.85.216.182) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 04 Aug 2010 20:58:36 +0000 Received: by qyk32 with SMTP id 32so5095314qyk.20 for ; Wed, 04 Aug 2010 13:58:34 -0700 (PDT) MIME-Version: 1.0 Received: by 10.224.88.81 with SMTP id z17mr4275918qal.109.1280955514145; Wed, 04 Aug 2010 13:58:34 -0700 (PDT) Received: by 10.229.35.4 with HTTP; Wed, 4 Aug 2010 13:58:33 -0700 (PDT) Date: Wed, 4 Aug 2010 22:58:33 +0200 Message-ID: Subject: [PATCH, rtl]: Do not generate insns with mismatched REG_EQUAL mode for multiword MULT RTXes. From: Uros Bizjak To: gcc-patches@gcc.gnu.org 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 Hello! Currently, multiword MULT RTX, synthesized via alg_shift algorithm, can produce insn with REG_EQUAL note in the wrong mode: ;; D.2028_13 = acc_24 * 10; (insn 51 50 52 920501-6.c:17 (set (reg:DI 107) (reg/v:DI 87 [ acc ])) -1 (nil)) (insn 52 51 53 920501-6.c:17 (set (reg:SI 109) (lshiftrt:SI (subreg:SI (reg:DI 107) 4) (const_int 31 [0x1f]))) -1 (nil)) (insn 53 52 54 920501-6.c:17 (set (subreg:SI (reg:DI 108) 0) (ashift:SI (subreg:SI (reg:DI 107) 0) (const_int 1 [0x1]))) -1 (nil)) (insn 54 53 55 920501-6.c:17 (set (subreg:SI (reg:DI 108) 0) (ior:SI (reg:SI 109) (subreg:SI (reg:DI 108) 0))) -1 (nil)) (insn 55 54 56 920501-6.c:17 (set (subreg:SI (reg:DI 108) 4) (ashift:SI (subreg:SI (reg:DI 107) 4) (const_int 1 [0x1]))) -1 (expr_list:REG_EQUAL (mult:DI (reg/v:DI 87 [ acc ]) (const_int 2 [0x2])) (nil))) (...) The last insn then triggers assert in loop-iv.c, iv_analyze_expr: gcc_assert (GET_MODE (rhs) == mode || GET_MODE (rhs) == VOIDmode); where iv_analyze_expr is called from iv_analyze_def with the RTX from attached REG_EQUAL note: if (!REG_P (reg)) return false; set = single_set (insn); if (!set) return false; if (!REG_P (SET_DEST (set))) return false; gcc_assert (SET_DEST (set) == reg); rhs = find_reg_equal_equiv_note (insn); if (rhs) rhs = XEXP (rhs, 0); else rhs = SET_SRC (set); iv_analyze_expr (insn, rhs, GET_MODE (reg), iv); To avoid mismatched modes, proposed patch introduces dummy move, where REG_EQUAL note can be attached: (insn 55 54 56 920501-6.c:17 (set (subreg:SI (reg:DI 108) 4) (ashift:SI (subreg:SI (reg:DI 107) 4) (const_int 1 [0x1]))) -1 (nil)) (insn 56 55 57 920501-6.c:17 (set (reg:DI 108) (reg:DI 108)) -1 (expr_list:REG_EQUAL (mult:DI (reg/v:DI 87 [ acc ]) (const_int 2 [0x2])) (nil))) This fixes ICE on my private (unreleased) target. I didn't find the testcase that would trigger on FSF targets, but the solutions should be obvious from the above analysis. 2010-08-04 Uros Bizjak * expmed.c (expand_mult_const) : Generate dummy move, so REG_EQUAL note will be attached to the correct insn. Patch was tested on x86_64-pc-linux-gnu. OK for mainline and all release branches? Uros. Index: expmed.c =================================================================== --- expmed.c (revision 162879) +++ expmed.c (working copy) @@ -2907,6 +2907,8 @@ expand_mult_const (enum machine_mode mod accum = expand_shift (LSHIFT_EXPR, mode, accum, build_int_cst (NULL_TREE, log), NULL_RTX, 0); + /* REG_EQUAL note will be attached to following insn. */ + emit_move_insn (accum, accum); val_so_far <<= log; break;