> > +Operand 0 is a comparison operator.  Operand 1 and operand 2 are the
> > +first and second operands of the comparison, respectively.  Operand 3
> > +is the @code{code_label} to jump to.
> > +
> > +@cindex @code{cbranch_all@var{mode}4} instruction pattern
> > +@item @samp{cbranch_all@var{mode}4}
> > +Conditional branch instruction combined with a compare instruction on 
> > vectors
> > +where it is required that at all of the elementwise comparisons of the
> > +two input vectors are true.
> 
> See above.
> 
> When I look at the RTL for aarch64 I wonder whether the middle-end
> can still invert a jump (for BB reorder, for example)?  Without
> a cbranch_none expander we have to invert during RTL expansion?
> 

Isn't cbranch_none just cbranch_all x 0? i.e. all value must be zero.
I think all states are expressible with any and all and flipping the branches
so it shouldn't be any more restrictive than cbranch itself is today.

cbranch also only supports eq and ne, so none would be cbranch (eq x 0)

and FTR the RTL generated for AArch64 (Both SVE And Adv.SIMD) will be 
simplified to:

(insn 23 22 24 5 (parallel [
            (set (reg:VNx4BI 128 [ mask_patt_14.15_57 ])
                (unspec:VNx4BI [
                        (reg:VNx4BI 129)
                        (const_int 0 [0x0])
                        (gt:VNx4BI (reg:VNx4SI 114 [ vect__2.11 ])
                            (const_vector:VNx4SI repeat [
                                    (const_int 0 [0])
                                ]))
                    ] UNSPEC_PRED_Z))
            (clobber (reg:CC_NZC 66 cc))
        ]) "cbranch.c":25:10 -1

(jump_insn 27 26 28 5 (set (pc)
        (if_then_else (eq (reg:CC_Z 66 cc)
                (const_int 0 [0]))
            (label_ref 33)
            (pc))) "cbranch.c":25:10 -1
     (int_list:REG_BR_PROB 1014686025 (nil))

The thing is we can't rid of the unspecs as there's concept of masking in RTL 
compares.
We could technically do an AND (and do in some cases) but then you lose the 
predicate
Hint constant in the RTL which tells you whether the mask is known to be all 
true or not.
This hint is crucial to allow for further optimizations.

That said the condition code, branch and compares are fully exposed.

We expand to a larger sequence than I'd like mostly because there's no support
for conditional cbranch optabs, or even conditional vector comparisons. So the 
comparisons
must be generated unpredicated by generating an all true mask, and later 
patterns
merge in the AND.

The new patterns allow us to clean up codegen for Adv.SIMD + SVE (in a single 
loop)
But not pure SVE.  For which I take a different approach to try to avoid 
requiring
a predicated version of these optabs.

I don't want to push my luck, but would you be ok with a conditional version of 
these
optabs too? i.e. cond_cbranch_all and cond_cbranch_all?  This would allow us to
immediately expand to the correct representation for both SVE and Adv.SIMD
without having to rely on various combine patterns and cc-fusion to optimize 
the sequences
later on (which has historically been a bit hit or miss if someone adds a new 
CC pattern).

And the reason for both is that for Adv.SIMD there's no mask at GIMPLE level 
and we have to
make it during expand.

Thanks,
Tamar

Reply via email to