https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97579

--- Comment #4 from Martin Liška <marxin at gcc dot gnu.org> ---
> 
> Hmm, but get_vcond_mask_icode expects the vector mode first and the
> mask mode second.  But it would be odd if that's the mistake...
> (but the patterns agree as well).
> 
> Now, the code seems to be a bit confused.  We're looking at
> 
> 
>  op0 = op0a tcode op0b;
>  lhs = op0 ? op1 : op2;
> 
> and I assume the check tries to verify we can expand both the
> compare-to-mask and the vcond_mask.  Then we need to query
> 
>           tree op0_type = TREE_TYPE (op0);
>           tree op0a_type = TREE_TYPE (op0a);
>           if (used_vec_cond_exprs >= 2
>               && (get_vcond_mask_icode (mode, TYPE_MODE (op0_type))
>                   != CODE_FOR_nothing)
>               && expand_vec_cmp_expr_p (op0a_type, op0_type, tcode))
>             {
> 
> no?

Yes, the code was really bogus. I understand it now as you and there's patch
for it:

diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index b64e31fc6fe..bba41f84ef1 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -158,15 +158,22 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi,
       gassign *def_stmt = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (op0));
       if (def_stmt)
        {
+         /* We process the following statements:
+            op0 = op0a tcode op0b;
+            lhs = op0 ? op1 : op2;
+
+            where MODE is mode of the LHS.
+         */
          tcode = gimple_assign_rhs_code (def_stmt);
          op0a = gimple_assign_rhs1 (def_stmt);
          op0b = gimple_assign_rhs2 (def_stmt);

+         tree op0_type = TREE_TYPE (op0);
          tree op0a_type = TREE_TYPE (op0a);
          if (used_vec_cond_exprs >= 2
-             && (get_vcond_mask_icode (mode, TYPE_MODE (op0a_type))
+             && (get_vcond_mask_icode (mode, TYPE_MODE (op0_type))
                  != CODE_FOR_nothing)
-             && expand_vec_cmp_expr_p (op0a_type, TREE_TYPE (lhs), tcode))
+             && expand_vec_cmp_expr_p (op0a_type, op0_type, tcode))
            {
              /* Keep the SSA name and use vcond_mask.  */
              tcode = TREE_CODE (op0);


>  That would match
> 
>   if (TREE_CODE_CLASS (tcode) != tcc_comparison)
>     {
>       gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0)));
>       if (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0)))
>           != CODE_FOR_nothing)

Yes, it's expanded as a .VCOND_MASK now.

> 
> Doing that shifts the ICE elsewhere though:
> 
> during GIMPLE pass: isel
> x.c: In function 'calc_rows':
> x.c:22:1: internal compiler error: in gimple_expand_vec_cond_expr, at 
> gimple-isel.cc:204
>    22 | calc_rows() {
>       | ^~~~~~~~~
> 0x17c3bd8 gimple_expand_vec_cond_expr
>         /home/rguenther/src/gcc2/gcc/gimple-isel.cc:202
> 
> Now we face the situation where lhs == HImode but op0a is V16SImode
> so a VEC_COND_EXPR combining masks based on a compare.  That's
> a situation we didn't run into before the VEC_COND_EXPR splitting.

I can confirm that:

mask__258.180_254 = vect_cst__77 != { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 };
mask__581.198_1001 = VEC_COND_EXPR <mask__258.180_254, { 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0 }, mask__649.184_117>;

> 
> Which means we're missing a fallback like
> 
>   if (expand_vec_cmp_expr_p (op0a_type, op0_type, tcode))
>     {
>       expand the comparison to a mask
>       turn the VEC_COND_EXPR into a mask operation,
>         maskr = cmpmask ? maska : maskb;
>       becomes
>         maskr = (maska & cmpmask) | (maskb & ~cmpmask);
>     }
> 
> the alternative is to add vcond_mask patterns for mask value modes
> (I think vternlog can do this in one operation, there may also be
> a mask operation for this).  But that would be an enhancement
> and not require any new fallback code.
> 
> But first double-check the first point I made above.

Reply via email to