On Tue, Aug 27, 2024 at 7:53 PM Georg-Johann Lay <a...@gjlay.de> wrote:
>
> Am 27.08.24 um 17:28 schrieb Jeff Law:
> >
> > On 8/26/24 1:15 PM, Georg-Johann Lay wrote:
> >
> >> What the avr-ifelse pass does is try to replace 2 cbranch insns with
> >> one compare insn and two branches.  It runs after reload and just prior
> >> to .split2 (split_after_reload).  It must run after reload because
> >> REG_CC comes into existence in .split2.  For example, the last case
> >> belongs to transforming
> >>
> >>     if (x == (unsigned) -1) goto A;
> >>     if (x == (unsigned) -2) goto B;
> >>
> >> to
> >>
> >>     REG_CC = x compare (unsigned) -2;
> >>     if (REG_CC >  0) goto A;
> >>     if (REG_CC == 0) goto B;
> > Hmm.  I'd envisioned doing this in gimple, but as your example shows,
> > it's not suitable for gimple (it's an extra expression evaluation).
>
> Max be something like starship operator for integer mode would help?
>
> All the situations are effectively sship situation, but a sship
> detection in gimple could do even more:
>
> char fun (char x)
> {
>      if (x > '0') return 10;
>      return x == '0';
> }
>
> The .optimized tree dump reads something like:
>
> char fun (char x)
> {
>    _Bool _1;
>    char _2;
>    char _4;
>
>    <bb 2> [local count: 1073741824]:
>    if (x_3(D) > 48)
>      goto <bb 4>; [21.72%]
>    else
>      goto <bb 3>; [78.28%]
>
>    <bb 3> [local count: 840525096]:
>    _1 = x_3(D) == 48;
>    _4 = (char) _1;
>
>    <bb 4> [local count: 1073741824]:
>    # _2 = PHI <10(2), _4(3)>
>
>    return _2;
> }
>
> The problem with this is that the code gets expanded like:
>
>     cbranch
>     REG = const ;; clobbers CC
>     cbranch
>
> With a spaceship insn, the backend could avoid that, though it
> is unclear to me to which rtl this should be expanded.
> JUMP_INSNs can only have one JUMP_LABEL (though I recently learned
> that JUMP_INSN can have more than one label when they are registered
> as insn notes, but I never tried that.)
>
> For example, a spaceship insn could provide operands like
>
> $0, $1: The ops for the <=> comparison
> $2: label_ref for <
> $3: label_ref for =
> $4: label_ref for >
>
> Or more general, provide set rtxes as $2, $4, $4 like pc=pc for the
> fallthrough case, (set reg:QI 1) etc. so that jumps can be avoided.

For GIMPLE I'm not sure a separate abstraction for condition codes is
helpful - in the end we have to map to what the targets can do.  Note
GIMPLE is also a bit constrained on the number of outputs of a
statement, so setting CC as side-effect of say an add isn't currently
representable.  Instead you'd have to do like risc-v and have
result = a + b; result_cc = a +cc b; thus separate value and CC
computation.  On RTL we've settled to CC-modes but I think the
semantics of those are purely target specific - the spaceship
idea would produce sth like a "CCallofstarship mode" on GIMPLE
but how this can be expanded to RTL would be implemented on
each target?

Richard.

> Johann
>
>
> >> (As an aside, this will be transformed further down the line to
> >>
> >>     REG_CC = x compare (unsigned) -2;
> >>     if (REG_CC == 0) goto B;
> >>     if (REG_CC >= 0) goto A;
> >>
> >> in order to avoid GTU.)
> >>
> >>> None of the code really looks AVR specific, so is there a good reason
> >>> why we're not doing this in one of the target independent passes?
> >>
> >> That target-independent pass would be compare-elim, which avr does
> >> not use.  Some of the reasons why not using compare-elim I tried to
> >> get across in the review for PR115830:
> > It feels like it'd fit in RTL jump optimizations, well outside
> > compare-elim.  Though that may still be too high level.  So yea, let's
> > keep it AVR specific.
> >
> >
> > Jeff

Reply via email to