On Mon, 2018-01-15 at 10:24 +0000, Richard Sandiford wrote: > >> + for (int i = 0; i < midpoint; i++) > >> + { > >> + tree tmp1 = build_int_cst (lhs_type_type, offset + i); > >> + tree tmp2 = build_int_cst (lhs_type_type, offset + n_elts + > i); > >> + CONSTRUCTOR_APPEND_ELT (ctor_elts, NULL_TREE, tmp1); > >> + CONSTRUCTOR_APPEND_ELT (ctor_elts, NULL_TREE, tmp2); > >> + } > >> + tree permute = create_tmp_reg_or_ssa_name (lhs_type); > >> + g = gimple_build_assign (permute, build_constructor (lhs_type, > ctor_elts)); > > > > I think this is no longer canonical GIMPLE (Richard?) > > FWIW, although the recent patches added the option of using wider > permute vectors if the permute vector is constant, it's still OK to > use the original style of permute vectors if that's known to be valid. > In this case it is because we know the indices won't wrap, given the > size of the input vectors.
Ok. > > and given it is also a constant you shouldn't emit a CONSTRUCTOR > here > > but directly construct the appropriate VECTOR_CST. So it looks like > > the mergel/h intrinsics interleave the low or high part of two > > vectors? Right, it is an interleaving of the two vectors. The size and contents vary depending on the type, and though i briefly considered building up a if/else table, this approach was far simpler (and less error prone for me) to code up. i.e. (int, mergel) (permute) D.2885 = {0, 4, 1, 5}; (long long, mergel) (permute) D.2876 = {1, 3}; Thanks -Will