Dmitrij Pochepko <dmitrij.poche...@bell-sw.com> writes: > + unsigned int encoded_nelts = d->perm.encoding ().encoded_nelts (); > + for (unsigned int i = 0; i < encoded_nelts; ++i) > + if (!d->perm[i].is_constant ()) > + return false;
I think it would be better to test this as part of the loop below. > + > + /* to_constant is safe since this routine is specific to Advanced SIMD > + vectors. */ > + nelt = d->perm.length ().to_constant (); > + rtx insv = d->op0; > + > + HOST_WIDE_INT idx = -1; > + > + for (unsigned HOST_WIDE_INT i = 0; i < nelt; i ++) > + { > + if (d->perm[i].to_constant () == (HOST_WIDE_INT) i) > + continue; > + if (idx != -1) > + { > + idx = -1; > + break; > + } > + idx = i; > + } > + > + if (idx == -1) > + { > + insv = d->op1; > + for (unsigned HOST_WIDE_INT i = 0; i < nelt; i ++) > + { > + if (d->perm[i].to_constant () == (HOST_WIDE_INT) (i + nelt)) > + continue; > + if (idx != -1) > + return false; > + idx = i; > + } > + > + if (idx == -1) > + return false; > + } > + > + if (d->testing_p) > + return true; > + > + gcc_assert (idx != -1); > + > + unsigned extractindex = d->perm[idx].to_constant (); > + rtx extractv = d->op0; > + if (extractindex >= nelt) > + { > + extractv = d->op1; > + extractindex -= nelt; > + } > + gcc_assert (extractindex < nelt); > + > + machine_mode inner_mode = GET_MODE_INNER (mode); > + > + enum insn_code inscode = optab_handler (vec_set_optab, mode); > + gcc_assert (inscode != CODE_FOR_nothing); > + enum insn_code iextcode = convert_optab_handler (vec_extract_optab, mode, > + inner_mode); > + gcc_assert (iextcode != CODE_FOR_nothing); > + rtx tempinner = gen_reg_rtx (inner_mode); > + emit_insn (GEN_FCN (iextcode) (tempinner, extractv, GEN_INT > (extractindex))); > + > + rtx temp = gen_reg_rtx (mode); > + emit_move_insn (temp, insv); > + emit_insn (GEN_FCN (inscode) (temp, tempinner, GEN_INT (idx))); > + > + emit_move_insn (d->target, temp); I think it'd be better to generate the target instruction directly. We can do that by replacing: (define_insn "*aarch64_simd_vec_copy_lane<mode>" with: (define_insn "@aarch64_simd_vec_copy_lane<mode>" then using the expand_insn interface to create an instance of code_for_aarch64_simd_vec_copy_lane (mode). > +/* { dg-final { scan-assembler-times "\[ \t\]*ins\[ \t\]+v\[0-9\]+\.s" 4 } } > */ Same comment as the other patch about using {…} regexp quoting. Thanks, Richard