LGTM, Claudiu
On Tue, Oct 6, 2026 at 10:50 AM Michiel Derhaeg <[email protected]> wrote: > > From: Michiel Derhaeg <[email protected]> > > CLZ_DEFINED_VALUE_AT_ZERO and CTZ_DEFINED_VALUE_AT_ZERO advertise > clz(0) == 31 and ctz(0) == 31. When clzsi2 and ctzsi2 expand to the > ARCv2 fls and ffs instructions that holds. > > Both patterns can also be emulated with norm, which currently happens > for ARCompact, in that case it returns 32 for a zero operand. > > Correct the two emulation patterns. In *arc_clzsi2 only increment > the norm result when the operand is strictly positive, which leaves a > zero operand at norm's own result of 31. In arc_ctzsi2 produce 31 > instead of 32 on the negative-flag path that a zero operand takes. > > PR target/127117 > > gcc/ChangeLog: > > * config/arc/arc.md (*arc_clzsi2): Produce 31 rather than 32 for > a zero operand. > (arc_ctzsi2): Likewise. > > gcc/testsuite/ChangeLog: > > * gcc.target/arc/arc.exp (check_effective_target_norm): New. > * gcc.target/arc/pr127117.c: New test. > > Co-authored-by: Luis Silva <[email protected]> > Signed-off-by: Michiel Derhaeg <[email protected]> > --- > Changes since v1: > Luis fixed the test by replacing -mnorm with dg-require-effective-target norm > Changes since v2: > Improved commit message. > > gcc/config/arc/arc.md | 4 +-- > gcc/testsuite/gcc.target/arc/arc.exp | 9 +++++++ > gcc/testsuite/gcc.target/arc/pr127117.c | 35 +++++++++++++++++++++++++ > 3 files changed, 46 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/arc/pr127117.c > > diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md > index b4b4a6a3e8e..ef1c0846f9f 100644 > --- a/gcc/config/arc/arc.md > +++ b/gcc/config/arc/arc.md > @@ -4600,7 +4600,7 @@ archs4x, archs4xd" > emit_insn > (gen_rtx_COND_EXEC > (VOIDmode, > - gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx), > + gen_rtx_GT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx), > gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1)))); > DONE; > } > @@ -4645,7 +4645,7 @@ archs4x, archs4xd" > (gen_rtx_COND_EXEC > (VOIDmode, > gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx), > - gen_rtx_SET (operands[0], GEN_INT (32)))); > + gen_rtx_SET (operands[0], GEN_INT (31)))); > emit_insn > (gen_rtx_COND_EXEC > (VOIDmode, > diff --git a/gcc/testsuite/gcc.target/arc/arc.exp > b/gcc/testsuite/gcc.target/arc/arc.exp > index e50db2b6478..34e210b068b 100644 > --- a/gcc/testsuite/gcc.target/arc/arc.exp > +++ b/gcc/testsuite/gcc.target/arc/arc.exp > @@ -94,6 +94,15 @@ proc check_effective_target_barrelshifter { } { > }] > } > > +# Return 1 if norm is enabled by default. > +proc check_effective_target_norm { } { > + return [check_no_compiler_messages norm_default assembly { > + #if !defined(__ARC_NORM__) > + #error No default norm instruction > + #endif > + }] > +} > + > #return 1 if we have code density option on. > proc check_effective_target_codedensity { } { > return [check_no_compiler_messages codedensity assembly { > diff --git a/gcc/testsuite/gcc.target/arc/pr127117.c > b/gcc/testsuite/gcc.target/arc/pr127117.c > new file mode 100644 > index 00000000000..56dd4bbff28 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arc/pr127117.c > @@ -0,0 +1,35 @@ > +/* { dg-do run } */ > +/* { dg-require-effective-target norm } */ > +/* { dg-options "-O2" } */ > + > +unsigned __attribute__ ((noipa)) > +clz (unsigned x) > +{ > + return __builtin_clz (x); > +} > + > +unsigned __attribute__ ((noipa)) > +ctz (unsigned x) > +{ > + return __builtin_ctz (x); > +} > + > +int > +main (void) > +{ > + unsigned msb, lsb; > + > + if (clz (0) != 31 || ctz (0) != 31) > + __builtin_abort (); > + > + for (msb = 0; msb < 32; msb++) > + for (lsb = 0; lsb <= msb; lsb++) > + { > + unsigned v = (1u << msb) | (1u << lsb); > + > + if (clz (v) != 31 - msb || ctz (v) != lsb) > + __builtin_abort (); > + } > + > + return 0; > +} > -- > 2.47.3 >
