--- /dev/null
+/* { dg-do compile } */
+/* PR tree-optimization/123382 */
+
+#define BS_VEC(type, num) type __attribute__((vector_size(num * sizeof(type))))
+
+typedef BS_VEC(short, 4) v4s;
+void f(int l, v4s *a, bool *b)
+{
+ for(int i =0;i < l; i++)
+ {
+ v4s t = a[i];
+ if (b[i])
+ t = __builtin_shufflevector(t, t, 3,3,2,3);
+ else
+ t = __builtin_shufflevector(t, t, 0,0,2,3);
+ a[i] = t;
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+/* PR tree-optimization/123382 */
+
+#define BS_VEC(type, num) type __attribute__((vector_size(num * sizeof(type))))
+
+typedef BS_VEC(short, 4) v4s;
+void f(int l, v4s *a, bool *b)
+{
+ for(int i =0;i < l; i++)
+ {
+ v4s t = a[i];
+ if (b[i])
+ t = __builtin_shufflevector(t, t, 3,3,2,3);
+ else
+ t = __builtin_shuffle(t, t, t);
+ a[i] = t;
+ }
+}
&& opnum != 0)
return;
+ /* It is not profitability to factor out vec_perm with
+ constant masks (operand 2). The target might not support it
+ and that might be invalid to do as such. Also with constants
+ masks, the number of elements of the mask type does not need
+ to match tne number of elements of other operands and can be
+ arbitrary integral vector type so factoring that out can't work.
+ Note in the case where one mask is a constant and the other is not,
+ the next check for compatiable types will reject the case the
+ constant mask has the incompatible type. */
+ if (arg1_op.code == VEC_PERM_EXPR && opnum == 2
+ && TREE_CODE (new_arg0) == VECTOR_CST
+ && TREE_CODE (new_arg1) == VECTOR_CST)
+ return;
if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1)))
return;