Hi,

While changing register costs for AArch64 (patches to follow), the test
gcc.target/aarch64/vect-mult.c fails. This is caused by ree inserting a TI mode 
copy of a DI
register. Since TI mode requires 2 registers, this results in silent corruption 
of the 2nd register.

After split2:

(insn 149 148 147 2 (set (reg:DI 3 x3 [90])
        (reg:DI 2 x2 [90])) vect-mull.c:78 34 {*movdi_aarch64}
     (nil))
(insn 152 127 153 2 (set (reg:TI 32 v0 [90])
        (zero_extend:TI (reg:DI 3 x3 [90]))) vect-mull.c:78 719 
{aarch64_movtilow_di}
     (nil))

Ree transforms this into:

(insn 149 148 157 2 (set (reg:TI 32 v0)
        (zero_extend:TI (reg:DI 2 x2 [90]))) vect-mull.c:78 719 
{aarch64_movtilow_di}
     (nil))
(insn 157 149 147 2 (set (reg:TI 3 x3)
        (reg:TI 32 v0)) vect-mull.c:78 -1
     (nil))

The TI mode in the second instruction means both x3 and x4 are assigned after 
expansion in split4
(rather than just x3 in the original instruction), corrupting x4. The fix is to 
ensure the inserted
copy will set only one register. Also ensure we always call 
get_extended_src_reg() rather than
assume there is always a single extend.

OK for commit?

Wilco

ChangeLog:
2014-09-04  Wilco Dijkstra  <wdijk...@arm.com>

        * gcc/ree.c (combine_reaching_defs):
        Ensure inserted copy writes a single register.

---
 gcc/ree.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/gcc/ree.c b/gcc/ree.c
index 856745f..9aa1e36 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -743,6 +743,12 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, 
ext_state *state)
       if (!SCALAR_INT_MODE_P (GET_MODE (SET_DEST (PATTERN (cand->insn)))))
        return false;
 
+      /* Ensure the destination of the copy is still a single register.  */
+      if (HARD_REGNO_NREGS (
+         REGNO (get_extended_src_reg (SET_SRC (PATTERN (cand->insn)))),
+         GET_MODE (SET_DEST (PATTERN (cand->insn)))) != 1)
+        return false;
+
       /* There's only one reaching def.  */
       rtx def_insn = state->defs_list[0];
 
@@ -792,7 +798,7 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, 
ext_state *state)
       start_sequence ();
       rtx pat = PATTERN (cand->insn);
       rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (pat)),
-                                 REGNO (XEXP (SET_SRC (pat), 0)));
+                                 REGNO (get_extended_src_reg (SET_SRC (pat))));
       rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (pat)),
                                  REGNO (SET_DEST (pat)));
       emit_move_insn (new_dst, new_src);
-- 
1.9.1



Reply via email to