LGTM, Claudiu
On Fri, Sep 11, 2026 at 2:57 PM Michiel Derhaeg <[email protected]> wrote: > > From: Michiel Derhaeg <[email protected]> > > This is a similar issue as PR120375. > > doloop_end, loop_end, dbnz, flag, and kflag all write the condition > codes without declaring it. Since r16-3301-g724d88900b7a moved > aarch64-cc-fusion into late-combine, GCC exploits that and keeps > condition codes live across these insns, producing wrong code. > > If a loop fails to resolve to a hardware loop, doloop_end and loop_end > fall back to instructions that clobber CC. This needs to be declared on > the pattern itself or it will not be taken into account. This fixes > gcc.c-torture/execute/pr68185.c for ARC60x and ARC700. > > dbnz is wrong in the same way as (do)loop_end but I didn't succeed in > creating a reproducer for it. > > flag and kflag write STATUS32, which holds the condition codes. Since > the cc-fusion move they can cause unintended clobbers too. > > PR target/127191 > > gcc/ChangeLog: > > * config/arc/arc.md (doloop_end): Clobber CC. > (loop_end): Likewise. > (dbnz): Likewise. > (flag): Likewise. > (kflag): Likewise. > > gcc/testsuite/ChangeLog: > > * gcc.target/arc/pr127191-1.c: New test. > * gcc.target/arc/pr127191-2.c: New test. > > Signed-off-by: Michiel Derhaeg <[email protected]> > --- > gcc/config/arc/arc.md | 15 ++++--- > gcc/testsuite/gcc.target/arc/pr127191-1.c | 30 ++++++++++++++ > gcc/testsuite/gcc.target/arc/pr127191-2.c | 50 +++++++++++++++++++++++ > 3 files changed, 90 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/arc/pr127191-1.c > create mode 100644 gcc/testsuite/gcc.target/arc/pr127191-2.c > > diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md > index d080143c45d..a406f793090 100644 > --- a/gcc/config/arc/arc.md > +++ b/gcc/config/arc/arc.md > @@ -4840,7 +4840,8 @@ archs4x, archs4xd" > > (define_insn "flag" > [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")] > - VUNSPEC_ARC_FLAG)] > + VUNSPEC_ARC_FLAG) > + (clobber (reg:CC CC_REG))] > "" > "@ > flag%?\\t%0 > @@ -5311,7 +5312,8 @@ archs4x, archs4xd" > (pc))) > (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))) > (unspec:SI [(const_int 0)] UNSPEC_ARC_LP) > - (clobber (match_dup 2))])] > + (clobber (match_dup 2)) > + (clobber (reg:CC CC_REG))])] > "" > { > if (GET_MODE (operands[0]) != SImode) > @@ -5341,7 +5343,8 @@ archs4x, archs4xd" > (pc))) > (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))) > (unspec:SI [(const_int 0)] UNSPEC_ARC_LP) > - (clobber (match_scratch:SI 2 "=X,&r"))] > + (clobber (match_scratch:SI 2 "=X,&r")) > + (clobber (reg:CC CC_REG))] > "" > "@ > ; ZOL_END, begins @%l1 > @@ -5389,7 +5392,8 @@ archs4x, archs4xd" > (set (match_dup 0) > (plus:SI (match_dup 0) > (const_int -1))) > - (clobber (match_scratch:SI 2 "=X,r"))] > + (clobber (match_scratch:SI 2 "=X,r")) > + (clobber (reg:CC CC_REG))] > "TARGET_DBNZ" > "@ > dbnz%*\\t%0,%l1 > @@ -5812,7 +5816,8 @@ archs4x, archs4xd" > > (define_insn "kflag" > [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")] > - VUNSPEC_ARC_KFLAG)] > + VUNSPEC_ARC_KFLAG) > + (clobber (reg:CC CC_REG))] > "TARGET_V2" > "@ > kflag%?\\t%0 > diff --git a/gcc/testsuite/gcc.target/arc/pr127191-1.c > b/gcc/testsuite/gcc.target/arc/pr127191-1.c > new file mode 100644 > index 00000000000..b79ad2ae3fb > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arc/pr127191-1.c > @@ -0,0 +1,30 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2" } */ > + > +/* Verifies that the potential CC clobber is taken into account when > expanding > + doloop_end but this fails to resolve into a hardware loop. */ > + > +int d = 1, e, f, o, w = 1, q, t; > + > +int > +main (void) > +{ > + int g = 0; > + > + for (; d; d--) > + { > + while (o) > + while (e) > + ; > + > + g = t ? g : w; > + f = g; > + if (g) > + q = 1; > + } > + > + if (q != 1) > + __builtin_abort (); > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.target/arc/pr127191-2.c > b/gcc/testsuite/gcc.target/arc/pr127191-2.c > new file mode 100644 > index 00000000000..d5137af1450 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arc/pr127191-2.c > @@ -0,0 +1,50 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2" } */ > + > +int q, sink; > + > +int __attribute__ ((noipa)) > +flag_clobbers_cc (int a, int b, int *p) > +{ > + int s = a | b; > + > + *p = s; > + __builtin_arc_flag (0); > + if (s == 0) > + q = 1; > + > + return s; > +} > + > +#if defined (__ARCEM__) || defined (__ARCHS__) > +int r; > + > +int __attribute__ ((noipa)) > +kflag_clobbers_cc (int a, int b, int *p) > +{ > + int s = a | b; > + > + *p = s; > + __builtin_arc_kflag (0); > + if (s == 0) > + r = 1; > + > + return s; > +} > +#endif > + > +int > +main (void) > +{ > + flag_clobbers_cc (0, 0, &sink); > + if (q != 1) > + __builtin_abort (); > + > +#if defined (__ARCEM__) || defined (__ARCHS__) > + kflag_clobbers_cc (0, 0, &sink); > + if (r != 1) > + __builtin_abort (); > +#endif > + > + return 0; > +} > -- > 2.54.0 >
