On Fri, Nov 3, 2017 at 5:26 PM, Richard Sandiford
<richard.sandif...@linaro.org> wrote:
> This patch allows us to recognise:
>
>     ... = bool1 != bool2 ? x : y
>
> as equivalent to:
>
>     bool tmp = bool1 ^ bool2;
>     ... = tmp ? x : y
>
> For the latter we were already able to find the natural number
> of vector units for tmp based on the types that feed bool1 and
> bool2, whereas with the former we would simply treat bool1 and
> bool2 as vectorised 8-bit values, possibly requiring them to
> be packed and unpacked from their natural width.
>
> This is used by a later SVE patch.

Ok.

I wonder if you can see code generation improvements for
AVX512 as well?  (testcase?)

Thanks,
Richard.

>
> 2017-11-03  Richard Sandiford  <richard.sandif...@linaro.org>
>             Alan Hayward  <alan.hayw...@arm.com>
>             David Sherwood  <david.sherw...@arm.com>
>
> gcc/
>         * tree-vect-patterns.c (vect_recog_mask_conversion_pattern): When
>         handling COND_EXPRs with boolean comparisons, try to find a better
>         basis for the mask type than the boolean itself.
>
> Index: gcc/tree-vect-patterns.c
> ===================================================================
> --- gcc/tree-vect-patterns.c    2017-11-03 12:17:34.392744807 +0000
> +++ gcc/tree-vect-patterns.c    2017-11-03 12:17:36.313554835 +0000
> @@ -3968,15 +3968,43 @@ vect_recog_mask_conversion_pattern (vec<
>             return NULL;
>         }
>        else if (COMPARISON_CLASS_P (rhs1))
> -       rhs1_type = TREE_TYPE (TREE_OPERAND (rhs1, 0));
> +       {
> +         /* Check whether we're comparing scalar booleans and (if so)
> +            whether a better mask type exists than the mask associated
> +            with boolean-sized elements.  This avoids unnecessary packs
> +            and unpacks if the booleans are set from comparisons of
> +            wider types.  E.g. in:
> +
> +              int x1, x2, x3, x4, y1, y1;
> +              ...
> +              bool b1 = (x1 == x2);
> +              bool b2 = (x3 == x4);
> +              ... = b1 == b2 ? y1 : y2;
> +
> +            it is better for b1 and b2 to use the mask type associated
> +            with int elements rather bool (byte) elements.  */
> +         rhs1_type = search_type_for_mask (TREE_OPERAND (rhs1, 0), vinfo);
> +         if (!rhs1_type)
> +           rhs1_type = TREE_TYPE (TREE_OPERAND (rhs1, 0));
> +       }
>        else
>         return NULL;
>
>        vectype2 = get_mask_type_for_scalar_type (rhs1_type);
>
> -      if (!vectype1 || !vectype2
> -         || must_eq (TYPE_VECTOR_SUBPARTS (vectype1),
> -                     TYPE_VECTOR_SUBPARTS (vectype2)))
> +      if (!vectype1 || !vectype2)
> +       return NULL;
> +
> +      /* Continue if a conversion is needed.  Also continue if we have
> +        a comparison whose vector type would normally be different from
> +        VECTYPE2 when considered in isolation.  In that case we'll
> +        replace the comparison with an SSA name (so that we can record
> +        its vector type) and behave as though the comparison was an SSA
> +        name from the outset.  */
> +      if (must_eq (TYPE_VECTOR_SUBPARTS (vectype1),
> +                  TYPE_VECTOR_SUBPARTS (vectype2))
> +         && (TREE_CODE (rhs1) == SSA_NAME
> +             || rhs1_type == TREE_TYPE (TREE_OPERAND (rhs1, 0))))
>         return NULL;
>
>        /* If rhs1 is a comparison we need to move it into a
> @@ -3993,7 +4021,11 @@ vect_recog_mask_conversion_pattern (vec<
>           append_pattern_def_seq (stmt_vinfo, pattern_stmt);
>         }
>
> -      tmp = build_mask_conversion (rhs1, vectype1, stmt_vinfo, vinfo);
> +      if (may_ne (TYPE_VECTOR_SUBPARTS (vectype1),
> +                 TYPE_VECTOR_SUBPARTS (vectype2)))
> +       tmp = build_mask_conversion (rhs1, vectype1, stmt_vinfo, vinfo);
> +      else
> +       tmp = rhs1;
>
>        lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
>        pattern_stmt = gimple_build_assign (lhs, COND_EXPR, tmp,

Reply via email to