VEC_PERM_EXPR is another special case expression where constants can mean
something different from non-constant.
So if we have:
```
if (_5 != 0) goto <bb 4>; else goto <bb 5>;
<bb 4>
t_15 = VEC_PERM_EXPR <t_12, t_12, { 3, 3, 2, 3 }>;
goto <bb 6>; [100.00%]
<bb 5>
t_14 = VEC_PERM_EXPR <t_12, t_12, { 0, 0, 2, 3 }>;
<bb 6>
# t_7 = PHI <t_15(4), t_14(5)>
```
We can't factor out the VEC_PERM_EXPR here since the type
of the vector constant can be different from the type of
the other operands. This is unlike the operand is not a
constant, the mask has to be an integral type which is
similar to the other operands.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/123382
gcc/ChangeLog:
* tree-if-conv.cc: Reject VEC_PERM_EXPR for factoring
if it is the mask and they are constant.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr123382-1.c: New test.
Signed-off-by: Andrew Pinski <[email protected]>
---
gcc/testsuite/gcc.dg/torture/pr123382-1.c | 18 ++++++++++++++++++
gcc/tree-if-conv.cc | 5 +++++
2 files changed, 23 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr123382-1.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr123382-1.c
b/gcc/testsuite/gcc.dg/torture/pr123382-1.c
new file mode 100644
index 00000000000..9890f9171da
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr123382-1.c
@@ -0,0 +1,18 @@
+/* { 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;
+ }
+}
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index 21ffea1544c..17b2d787fa8 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -2252,6 +2252,11 @@ again:
&& opnum != 0)
return;
+ /* VEC_PERM_EXPR can't be factored out for operand 2 (the mask) if both are
constants. */
+ 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;
--
2.43.0