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.

Updated the non-V2 fallback code to produce the same result for zero
inputs as this change does not come at any cost.

This fixes gcc.dg/torture/pr122212.c.

        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/pr127117.c: New test.

Signed-off-by: Michiel Derhaeg <[email protected]>
---
 gcc/config/arc/arc.md                   |  4 +--
 gcc/testsuite/gcc.target/arc/pr127117.c | 34 +++++++++++++++++++++++++
 2 files changed, 36 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 a406f793090..ae8e25e8b13 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -4768,7 +4768,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;
 }
@@ -4813,7 +4813,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/pr127117.c 
b/gcc/testsuite/gcc.target/arc/pr127117.c
new file mode 100644
index 00000000000..976c9941c5d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/pr127117.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mnorm" } */
+
+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.55.0

Reply via email to