On Mon, Aug 24, 2020 at 6:18 PM Jeff Law <l...@redhat.com> wrote: > > The post-reload splitter introduces the clobber. The wiki > > suggests that approach if most insns clobber REG_CC, perhaps because of > > the missed optimizations you describe below? > If most patterns set/clobber the flags, then yes, it's slightly better to only > expose them after reload. Various passes that directly grub through RTL > rather > than using helpers like single_set will optimize things better.
I think I made it to the next pitfall :-) The cmpelim pass tries to recognize cc-setting variants of insns. Whether or not there is one (i.e. whether or not the insn should be recognized) depends on the "cc" attribute, which depends on which alternative is used. So I did the obvious thing, and put a condition in the define_insn which depends on get_cc_attr (insn). But get_cc_attr() tries to recognize the insn, so we recurse indefinitely and die with a segfault. Things appear to work with a somewhat subtle hack: we recognize that a false positive from the inner recognition isn't harmful, because the outer condition will still catch invalid cases. static int recurse = 0; if (recurse) return gen_rtx_REG (CCmode, REG_CC); // causes the insn to be recognized recurse++; int old_insn_code = INSN_CODE (insn); enum attr_cc cc = get_attr_cc (insn); INSN_CODE (insn) = old_insn_code; recurse--; But surely that's not the right way? Note that whether there is a CC-setting variant depends not just on the "cc" attr, but also on the precise operands for some values of the "cc" attr, which requires hairy C code to figure out. Is it possible to avoid this situation by avoiding constraint alternatives, and defining insns separately for each of them?