diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 29dbacfa917..7efd896d364 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -22332,6 +22332,32 @@ aarch64_unzip_vector_init (machine_mode mode, rtx vals, bool even_p) return gen_rtx_PARALLEL (new_mode, vec); } +/* Return true if INSN is a scalar move. */ + +static bool +scalar_move_insn_p (rtx_insn *insn) +{ + rtx set = single_set (insn); + if (!set) + return false; + rtx src = SET_SRC (set); + rtx dest = SET_DEST (set); + return is_a(GET_MODE (dest)) && aarch64_mov_operand_p (src, GET_MODE (src)); +} + +/* Ignore cost for scalar moves from cost of sequence. This function is called + for calculating sequence costs in aarch64_expand_vector_init. */ + +static unsigned +seq_cost_ignore_scalar_moves (rtx_insn *seq, bool speed) +{ + unsigned cost = seq_cost (seq, speed); + for (; seq; seq = NEXT_INSN (seq)) + if (scalar_move_insn_p (seq)) + cost -= insn_cost (seq, speed); + return cost; +} + /* Expand a vector initialization sequence, such that TARGET is initialized to contain VALS. */ @@ -22367,7 +22393,7 @@ aarch64_expand_vector_init (rtx target, rtx vals) halves[i] = gen_rtx_SUBREG (mode, tmp_reg, 0); rtx_insn *rec_seq = get_insns (); end_sequence (); - costs[i] = seq_cost (rec_seq, !optimize_size); + costs[i] = seq_cost_ignore_scalar_moves (rec_seq, !optimize_size); emit_insn (rec_seq); } @@ -22384,7 +22410,7 @@ aarch64_expand_vector_init (rtx target, rtx vals) start_sequence (); aarch64_expand_vector_init_fallback (target, vals); rtx_insn *fallback_seq = get_insns (); - unsigned fallback_seq_cost = seq_cost (fallback_seq, !optimize_size); + unsigned fallback_seq_cost = seq_cost_ignore_scalar_moves (fallback_seq, !optimize_size); end_sequence (); emit_insn (seq_total_cost < fallback_seq_cost ? seq : fallback_seq);