This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]