On Fri, 21 Mar 2025 at 11:39, Richard Biener <rguent...@suse.de> wrote: > > On Fri, 21 Mar 2025, Richard Earnshaw wrote: > > > If expand_binop_directly fails to add a REG_EQUAL note it tries to > > unwind and restart. But it can unwind too far if expand_binop changed > > some of the operands before calling it. We don't need to unwind that > > far anyway since we should end up taking exactly the same route next > > time, just without a target rtx. > > > > To fix this we remove LAST from the argument list and let the callers > > (all in expand_binop) do their own unwinding if the call fails. > > Instead we unwind just as far as the entry to expand_binop_directly > > and recurse within this function instead of all the way back up. > > This looks good and like a nice cleanup as well. But please give > others more familiar with this code the chance to chime in. >
I was running a bootstrap on arm-linux-gnueabihf with the patch Andrew attached in bugzilla. It passes bootstrap and make check, I think it applies to this patch as well, as it is very similar. Thanks, Christophe > Thanks, > Richard. > > > gcc/ChangeLog: > > > > PR middle-end/117811 > > * optabs.cc (expand_binop_directly): Remove LAST as an argument, > > instead record the last insn on entry. Only delete insns if > > we need to restart and restart by calling ourself, not expand_binop. > > (expand_binop): Update callers to expand_binop_directly. If it > > fails to expand the operation, delete back to LAST. > > > > gcc/testsuite: > > > > PR middle-end/117811 > > * gcc.dg/torture/pr117811.c: New test. > > --- > > gcc/optabs.cc | 24 +++++++++++----------- > > gcc/testsuite/gcc.dg/torture/pr117811.c | 27 +++++++++++++++++++++++++ > > 2 files changed, 39 insertions(+), 12 deletions(-) > > create mode 100644 gcc/testsuite/gcc.dg/torture/pr117811.c > > > > diff --git a/gcc/optabs.cc b/gcc/optabs.cc > > index 36f2e6af8b5..0a14b1eef8a 100644 > > --- a/gcc/optabs.cc > > +++ b/gcc/optabs.cc > > @@ -1369,8 +1369,7 @@ avoid_expensive_constant (machine_mode mode, optab > > binoptab, > > static rtx > > expand_binop_directly (enum insn_code icode, machine_mode mode, optab > > binoptab, > > rtx op0, rtx op1, > > - rtx target, int unsignedp, enum optab_methods methods, > > - rtx_insn *last) > > + rtx target, int unsignedp, enum optab_methods methods) > > { > > machine_mode xmode0 = insn_data[(int) icode].operand[1].mode; > > machine_mode xmode1 = insn_data[(int) icode].operand[2].mode; > > @@ -1380,6 +1379,7 @@ expand_binop_directly (enum insn_code icode, > > machine_mode mode, optab binoptab, > > rtx_insn *pat; > > rtx xop0 = op0, xop1 = op1; > > bool canonicalize_op1 = false; > > + rtx_insn *last = get_last_insn (); > > > > /* If it is a commutative operator and the modes would match > > if we would swap the operands, we can save the conversions. */ > > @@ -1444,10 +1444,7 @@ expand_binop_directly (enum insn_code icode, > > machine_mode mode, optab binoptab, > > tmp_mode = insn_data[(int) icode].operand[0].mode; > > if (VECTOR_MODE_P (mode) > > && maybe_ne (GET_MODE_NUNITS (tmp_mode), 2 * GET_MODE_NUNITS > > (mode))) > > - { > > - delete_insns_since (last); > > - return NULL_RTX; > > - } > > + return NULL_RTX; > > } > > else > > tmp_mode = mode; > > @@ -1467,14 +1464,14 @@ expand_binop_directly (enum insn_code icode, > > machine_mode mode, optab binoptab, > > ops[1].value, ops[2].value, mode0)) > > { > > delete_insns_since (last); > > - return expand_binop (mode, binoptab, op0, op1, NULL_RTX, > > - unsignedp, methods); > > + return expand_binop_directly (icode, mode, binoptab, op0, op1, > > + NULL_RTX, unsignedp, methods); > > } > > > > emit_insn (pat); > > return ops[0].value; > > } > > - delete_insns_since (last); > > + > > return NULL_RTX; > > } > > > > @@ -1543,9 +1540,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx > > op0, rtx op1, > > if (icode != CODE_FOR_nothing) > > { > > temp = expand_binop_directly (icode, mode, binoptab, op0, op1, > > - target, unsignedp, methods, last); > > + target, unsignedp, methods); > > if (temp) > > return temp; > > + delete_insns_since (last); > > } > > } > > > > @@ -1571,9 +1569,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx > > op0, rtx op1, > > NULL_RTX, unsignedp, OPTAB_DIRECT); > > > > temp = expand_binop_directly (icode, int_mode, otheroptab, op0, > > newop1, > > - target, unsignedp, methods, last); > > + target, unsignedp, methods); > > if (temp) > > return temp; > > + delete_insns_since (last); > > } > > > > /* If this is a multiply, see if we can do a widening operation that > > @@ -1637,9 +1636,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx > > op0, rtx op1, > > if (vop1) > > { > > temp = expand_binop_directly (icode, mode, otheroptab, op0, > > vop1, > > - target, unsignedp, methods, last); > > + target, unsignedp, methods); > > if (temp) > > return temp; > > + delete_insns_since (last); > > } > > } > > } > > diff --git a/gcc/testsuite/gcc.dg/torture/pr117811.c > > b/gcc/testsuite/gcc.dg/torture/pr117811.c > > new file mode 100644 > > index 00000000000..13d7e134780 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/torture/pr117811.c > > @@ -0,0 +1,27 @@ > > +/* { dg-do run } */ > > + > > +#include <string.h> > > + > > +typedef int v4 __attribute__((vector_size (4 * sizeof (int)))); > > + > > +void __attribute__((noclone,noinline)) do_shift (v4 *vec, int shift) > > +{ > > + v4 t = *vec; > > + > > + if (shift > 0) > > + { > > + t = t >> shift; > > + } > > + > > + *vec = t; > > +} > > + > > +int main () > > +{ > > + v4 vec = {0x1000000, 0x2000, 0x300, 0x40}; > > + v4 vec2 = {0x100000, 0x200, 0x30, 0x4}; > > + do_shift (&vec, 4); > > + if (memcmp (&vec, &vec2, sizeof (v4)) != 0) > > + __builtin_abort (); > > + return 0; > > +} > > > > -- > Richard Biener <rguent...@suse.de> > SUSE Software Solutions Germany GmbH, > Frankenstrasse 146, 90461 Nuernberg, Germany; > GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)