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