On Wed, Sep 30, 2026 at 2:28 PM Michiel Derhaeg <[email protected]> wrote: > > From: Michiel Derhaeg <[email protected]> > > CLZ_DEFINED_VALUE_AT_ZERO and CTZ_DEFINED_VALUE_AT_ZERO advertises > clz(0) == 31 && ctz(0) == 31. This is true for ARCv2 but not for > ARCompact. The latter previously produced 32.
The description of the issue is not precise. The ARCv2 uses FLS/FFS instructions, while the ARCv1 uses NORM instruction. Now, no one stops you from using NORM instructions to emulate FLS/FFS, if the situation is required. The actual problem is in the emulation of CTZ/CLZ patterns using the NORM instruction. Please update your problem description. Otherwise it looks good. Thanks, Claudiu > > Updated the non-V2 fallback code to produce the same result for zero > inputs as this change does not come at any cost. > > 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 > > 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 >
