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