Looks like a good idea. Marc Glisse <marc.gli...@inria.fr> writes: > For the testsuite, since the patch is not in a particular target, it would > be better to have a generic test (in gcc.dg?), but I don't really know how > to write a generic one, so would a test in gcc.target/i386 that scans > the asm for shuf or perm be ok?
Tree-level vectorisation tests tend to go in gcc.dg/vector, but it's hard to generalise rtl-level transforms like these. An x86-only test sounds good to me FWIW. > Index: simplify-rtx.c > =================================================================== > --- simplify-rtx.c (revision 187228) > +++ simplify-rtx.c (working copy) > @@ -3268,10 +3268,32 @@ simplify_binary_operation_1 (enum rtx_co > > if (GET_MODE (vec) == mode) > return vec; > } > > + /* If we build {a,b} then permute it, build the result directly. */ > + if (XVECLEN (trueop1, 0) == 2 > + && CONST_INT_P (XVECEXP (trueop1, 0, 0)) > + && CONST_INT_P (XVECEXP (trueop1, 0, 1)) > + && GET_CODE (trueop0) == VEC_CONCAT > + && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop0, 1)) > + && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT > + && GET_MODE (XEXP (trueop0, 0)) == mode) > + { > + int offset0 = INTVAL (XVECEXP (trueop1, 0, 0)) % 2; > + int offset1 = INTVAL (XVECEXP (trueop1, 0, 1)) % 2; > + rtx baseop = XEXP (trueop0, 0); > + rtx baseop0 = XEXP (baseop , 0); > + rtx baseop1 = XEXP (baseop , 1); > + baseop0 = avoid_constant_pool_reference (baseop0); > + baseop1 = avoid_constant_pool_reference (baseop1); > + > + return simplify_gen_binary (VEC_CONCAT, mode, > + offset0 ? baseop1 : baseop0, > + offset1 ? baseop1 : baseop0); > + } > + I know you said that generalising it could be done later, and that's fine, but it looks in some ways like it would be easier to go straight for the more general: && GET_CODE (trueop0) == VEC_CONCAT && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT && GET_MODE (XEXP (trueop0, 0)) == mode && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT && GET_MODE (XEXP (trueop0, 1)) == mode) { unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0)); unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1)); rtx op0, op1; gcc_assert (i0 < 4 && i1 < 4); op0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2); op1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2); return simplify_gen_binary (VEC_CONCAT, mode, op0, op1); } (completely untested). avoid_constant_pool_reference shouldn't be called here. Very minor, but this code probably belongs in the else part of the if (!VECTOR_MODE_P (mode)) block. Richard