On Mon, May 23, 2022 at 3:06 PM Roger Sayle <ro...@nextmovesoftware.com> wrote:
>
>
> Hi Richard,
> I was wondering what you think of the following patch as a solution to
> PR tree-optimization/96912, i.e. the ability to recognize pblendvb from
> regular code rather than as a target specific builtin?
>
> The obvious point of contention is that the current middle-end philosophy
> around vector expressions is that the middle-end should continually check
> for backend support, whereas I prefer the "old school" view that trees
> are an abstraction and that RTL expansion is the point where these abstract
> operations get converted/lowered into instructions supported by the target.

That's still true for trees aka GENERIC but GIMPLE is more like RTL here.
Note before vector lowering GIMPLE is like GENERIC but after the
"RTL expansion" of vectors is considered done.  I _think_ this was done
to get the opportunity to optimize the lowered code (and maybe cheat
by doing that lowering sub-optimally) given that user-written "generic"
vector code tends to run into limitations.

> [The exceptions being built-in functions, IFN_* etc.] Should tree.texi
> document
> which tree codes can't be used without checking the backend.

I suppose yes, but it's not really "which tree codes" but which
types.  Even for PLUS_EXPR you have to check for target support
when vector types are involved.

Note when being too lazy before vector lowering you could end up
transforming previously supported IL into unsupported and thus
triggering vector lowering to perform elementwise operations, severly
slowing down code which is why you might find checks like
if (target supports new code || target didn't support old code)

> Bootstrapped and regression tested, but this obviously depends upon RTL
> expansion being able to perform the inverse operation/lowering if required.

So the case in question "historically" was a task for RTL combine.  If
we now bring that to GIMPLE we should indeed verify if the target
can efficiently(!) do the operation we like to use.  In this particular
case it would be vec_cond_mask support for the created VEC_COND_EXPR.
We also have to avoid doing this after ISEL.

Note all original types are data types while you need a mask type for
the selector which in turn means you will almost never match
unless you hit the

+(match vector_mask_p
+ VECTOR_CST@0
+ (if (integer_zerop (@0) || integer_all_onesp (@0))))

case?

+(simplify
+ (bit_xor:c (bit_and:c (bit_xor:c @0 @1) (view_convert vector_mask_p@2)) @0)
+ (if (VECTOR_TYPE_P (type)
+      && VECTOR_TYPE_P (TREE_TYPE (@2)))
+  (with { tree masktype = truth_type_for (TREE_TYPE (@2));

I think you want to check the truth_type_for (type) instead, check that
you can V_C_E @2 to it by checking it's a vector mode and the same
as the truth_type mode.

+          tree vecttype = maybe_ne (TYPE_VECTOR_SUBPARTS (masktype),
+                                   TYPE_VECTOR_SUBPARTS (type))
+                         ? unsigned_type_for (masktype)
+                         : type; }
+   (view_convert (vec_cond:vecttype (view_convert:masktype @2)
+                                   (view_convert:vecttype @1)
+                                   (view_convert:vecttype @0))))))

and then have

    (vec_cond (view_convert:masktype @2) @1 @0)

Richard.

>
> 2022-05-23  Roger Sayle  <ro...@nextmovesoftware.com>
>
> gcc/ChangeLog
>         PR tree-optimization/96912
>         * match.pd (vector_mask_p): New predicate to identify vectors
>         where every element must be zero or all ones.
>         (bit_xor (bit_and (bit_xor ...) ...) ...): Recognize a VEC_COND_EXPR
>         expressed as logical vector operations.
>
> gcc/testsuite/ChangeLog
>         PR tree-optimization/96912
>         * gcc.target/i386/pr96912.c: New test case.
>
>
> Thoughts?  How would you solve this PR?  Are there convenience predicates
> for testing whether a target supports vec_cond_expr, vec_duplicate, etc?
>
> Cheers,
> Roger
> --
>

Reply via email to