From patchwork Wed Aug 4 20:58:33 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [rtl] : Do not generate insns with mismatched REG_EQUAL mode for multiword MULT RTXes. Date: Wed, 04 Aug 2010 10:58:33 -0000 From: Uros Bizjak X-Patchwork-Id: 60895 Message-Id: To: 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;