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.
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