> Am 04.01.2026 um 00:49 schrieb Andrew Pinski <[email protected]>:
> 
> 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.

Please adjust the comment to indicate it’s not profitable to do and invalid if 
the target cannot do variable permutes.  The type of the constant permute 
elements is arbitrary, the number of elements have to agree.  So I think if 
this is an ICE then the constant would need adjustment (but as actual vector 
constant it might not be materializable).

That is, complicated to code generate and unlikely to be profitable.

OK otherwise,
Richard 

>    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
> 

Reply via email to