On Mon, 21 Apr 2014, Richard Henderson wrote:

On 04/21/2014 01:19 PM, Bill Schmidt wrote:
+      if (GET_CODE (trueop0) == VEC_SELECT
+         && GET_MODE (XEXP (trueop0, 0)) == mode)
+       {
+         rtx op0_subop1 = XEXP (trueop0, 1);
+         gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
+         gcc_assert (XVECLEN (trueop1, 0) == GET_MODE_NUNITS (mode));
+
+         /* Apply the outer ordering vector to the inner one.  (The inner
+            ordering vector is expressly permitted to be of a different
+            length than the outer one.)  If the result is { 0, 1, ..., n-1 }
+            then the two VEC_SELECTs cancel.  */
+         for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
+           {
+             rtx x = XVECEXP (trueop1, 0, i);
+             gcc_assert (CONST_INT_P (x));
+             rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
+             gcc_assert (CONST_INT_P (y));

In two places you're asserting that you've got a constant permutation.  Surely
there should be a non-assertion check and graceful exit for either select to be
a variable permutation.

Note that in the case where trueop0 is a CONST_VECTOR, we already check each element of trueop1:

                  gcc_assert (CONST_INT_P (x));

In the case where the result is a scalar, we also have:

          gcc_assert (CONST_INT_P (XVECEXP (trueop1, 0, 0)));

so we will have other issues if something ever creates a variable vec_select. Not that a graceful exit will hurt of course.

--
Marc Glisse

Reply via email to