This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, rtl]: Do not generate insns with mismatched REG_EQUAL mode for multiword MULT RTXes.
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 4 Aug 2010 22:58:33 +0200
- Subject: [PATCH, rtl]: Do not generate insns with mismatched REG_EQUAL mode for multiword MULT RTXes.
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 <ubizjak@gmail.com>
* expmed.c (expand_mult_const) <case alg_shift>: 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;