https://gcc.gnu.org/g:c5ae6aaa9e7ff78d81c5be106e2c12100d3425bc
commit r16-6566-gc5ae6aaa9e7ff78d81c5be106e2c12100d3425bc Author: Andrew Pinski <[email protected]> Date: Sat Jan 3 11:32:02 2026 -0800 vect/ifcvt: Don't factor out VEC_PERM_EXPR with constant masks [PR123382] 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. Changes since v1: * v2: Expand comment on why we should reject this. 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. * gcc.dg/torture/pr123382-2.c: New test. Signed-off-by: Andrew Pinski <[email protected]> Diff: --- gcc/testsuite/gcc.dg/torture/pr123382-1.c | 18 ++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr123382-2.c | 18 ++++++++++++++++++ gcc/tree-if-conv.cc | 13 +++++++++++++ 3 files changed, 49 insertions(+) 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 000000000000..9890f9171dab --- /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/testsuite/gcc.dg/torture/pr123382-2.c b/gcc/testsuite/gcc.dg/torture/pr123382-2.c new file mode 100644 index 000000000000..6d57b519d306 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr123382-2.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_shuffle(t, t, t); + a[i] = t; + } +} diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index 6f258a390761..c8f7b8453d85 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -2284,6 +2284,19 @@ again: && 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;
