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