https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93122
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Segher Boessenkool from comment #2) > (In reply to Jakub Jelinek from comment #1) > > Created attachment 47581 [details] > > gcc10-pr93122.patch > > > > Untested fix. With additional -fno-asynchronous-unwind-tables, it doesn't > > ICE, but just emit wrong-code, the stack clash protection code expects r12 > > to be r1 + stack offset, but it is not initialized to anything at all. > > The bug seems to be that add<mode>3 expander uses reg_or_add_cint_operand > > predicate for the last operand and if that isn't satisfied, gen_add3_insn > > simply doesn't emit anything. > > Yeah, gen_add3_insn needs to be fixed; it shouldn't silently generate bad > code. I don't think there is anything wrong on gen_add3_insn, like many other expander functions e.g. for optabs that can FAIL (or in this particular case also fail because of unmatched predicates) it signals to the caller a failure through returning NULL and it is up to the caller to handle it. So, rs6000-logue.c could also just gen_add3_insn and if it returns NULL, fall back to what it emits in the else block. > > On top of that, I think we want to use > > add_operand as before too, because otherwise gen_add3_insn can emit multiple > > instructions and in that case we really need to describe the effect to > > dwarf2frame.c properly. > > Does that not happen automatically here? No. First of all, the caller here marks just a single instruction with RTX_FRAME_RELATED_P, so if gen_add3_insn emits e.g. two instructions, it will mark the last instruction that way. That wouldn't be necessarily wrong, but in that case dwarf2cfi.c needs to be able to understand what the instruction does or it needs e.g. REG_FRAME_RELATED_EXPR note (or some other CFI note) that will tell dwarf2cfi.c what the instruction does in a way that it can understand the effects of that for unwind info. So, either we do what the patch does, or e.g. without any predicates try to gen_add3_insn, if it succeeds and returns more than one insn, force REG_FRAME_RELATED_EXPR to the last insn, and if it returns NULL, do what we do ATM in the else block.