As reported on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116372, this change restores bootstrap.
Committing as obvious. --Philipp. On Tue, 20 Aug 2024 at 21:57, Manolis Tsamis <manolis.tsa...@vrull.eu> wrote: > > Now that more operations are allowed for noce_convert_multiple_sets, it is > possible that the same register appears multiple times as target in a > basic block. After noce_convert_multiple_sets_1 is called we potentially > also emit register moves from temporaries back to the original targets. > In some cases where the target registers overlap with the block's condition, > these register moves may overwrite intermediate variables because they're > emitted after the if-converted code. To address this issue we now iterate > backwards and keep track of seen registers when emitting these final register > moves. > > Fix-up for the recent ifcvt commit 72c9b5f4 > > PR rtl-optimization/116372 > PR rtl-optimization/116405 > > gcc/ChangeLog: > > * ifcvt.cc (noce_convert_multiple_sets): Iterate backwards and track > target registers. > > gcc/testsuite/ChangeLog: > > * gcc.dg/pr116372.c: New test. > * gcc.dg/pr116405.c: New test. > > Signed-off-by: Manolis Tsamis <manolis.tsa...@vrull.eu> > --- > > gcc/ifcvt.cc | 22 ++++++++++++++++++---- > gcc/testsuite/gcc.dg/pr116372.c | 13 +++++++++++++ > gcc/testsuite/gcc.dg/pr116405.c | 17 +++++++++++++++++ > 3 files changed, 48 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/pr116372.c > create mode 100644 gcc/testsuite/gcc.dg/pr116405.c > > diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc > index da59c907891..36de036661b 100644 > --- a/gcc/ifcvt.cc > +++ b/gcc/ifcvt.cc > @@ -3515,10 +3515,24 @@ noce_convert_multiple_sets (struct noce_if_info > *if_info) > given an empty BB to convert, and we can't handle that. */ > gcc_assert (!insn_info.is_empty ()); > > - /* Now fixup the assignments. */ > - for (unsigned i = 0; i < insn_info.length (); i++) > - if (insn_info[i]->target != insn_info[i]->temporary) > - noce_emit_move_insn (insn_info[i]->target, insn_info[i]->temporary); > + /* Now fixup the assignments. > + PR116405: Iterate in reverse order and keep track of the targets so that > + a move does not overwrite a subsequent value when multiple instructions > + have the same target. */ > + unsigned i; > + noce_multiple_sets_info *info; > + bitmap set_targets = BITMAP_ALLOC (®_obstack); > + FOR_EACH_VEC_ELT_REVERSE (insn_info, i, info) > + { > + gcc_checking_assert (REG_P (info->target)); > + > + if (info->target != info->temporary > + && !bitmap_bit_p (set_targets, REGNO (info->target))) > + noce_emit_move_insn (info->target, info->temporary); > + > + bitmap_set_bit (set_targets, REGNO (info->target)); > + } > + BITMAP_FREE (set_targets); > > /* Actually emit the sequence if it isn't too expensive. */ > rtx_insn *seq = get_insns (); > diff --git a/gcc/testsuite/gcc.dg/pr116372.c b/gcc/testsuite/gcc.dg/pr116372.c > new file mode 100644 > index 00000000000..e9878ac5042 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr116372.c > @@ -0,0 +1,13 @@ > +/* PR rtl-optimization/116372 */ > +/* { dg-do run } */ > +/* { dg-options "-O1" } */ > +/* { dg-additional-options "-march=z13" { target s390x-*-* } } */ > + > +long x = -0x7fffffff - 1; > +int main (void) > +{ > + long y = x % (-0xf - 1); > + if (-0x7fffffff - 1 + y == x == 0) > + __builtin_abort (); > + return 0; > +} > diff --git a/gcc/testsuite/gcc.dg/pr116405.c b/gcc/testsuite/gcc.dg/pr116405.c > new file mode 100644 > index 00000000000..9223f15a298 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr116405.c > @@ -0,0 +1,17 @@ > +/* PR rtl-optimization/116405 */ > +/* { dg-do run } */ > +/* { dg-options "-O2 -fno-ssa-phiopt -fno-tree-dce" } */ > + > +int printf(const char *, ...); > +int a, b = 2, c = 1; > +unsigned d, e; > +int main() { > + L: > + a = -1 / c; > + d = ~(b && (c && ~e) & b); > + printf("0\n"); > + c = 0; > + if (d != -1) > + goto L; > + return 0; > +} > -- > 2.34.1 >