diff mbox series

RISC-V: Fix CTZ unnecessary sign extension [PR #106888]

Message ID orzfvvoj5s.fsf@lxoliva.fsfla.org
State New
Headers show
Series RISC-V: Fix CTZ unnecessary sign extension [PR #106888] | expand

Commit Message

Alexandre Oliva Feb. 20, 2024, 4:26 a.m. UTC
This backport for gcc-13 is required for pr90838.c to get the expected
count of andi instructions on riscv64-elf, rather than fail because of
two extra andi insns in functions where it is not necessary.  (On
riscv32-elf, it passes).  Regstrapped on x86_64-linux-gnu, along with
other backports, and tested manually on riscv64-elf.  Ok to install?

From: Raphael Moreira Zinsly <rzinsly@ventanamicro.com>

Changes since v1:
	- Remove subreg from operand 1.

-- >8 --

We were not able to match the CTZ sign extend pattern on RISC-V
because it gets optimized to zero extend and/or to ANDI patterns.
For the ANDI case, combine scrambles the RTL and generates the
extension by using subregs.

gcc/ChangeLog:
	PR target/106888
	* config/riscv/bitmanip.md
	(<bitmanip_optab>disi2): Match with any_extend.
	(<bitmanip_optab>disi2_sext): New pattern to match
	with sign extend using an ANDI instruction.

gcc/testsuite/ChangeLog:
	PR target/106888
	* gcc.target/riscv/pr106888.c: New test.
	* gcc.target/riscv/zbbw.c: Check for ANDI.

(cherry picked from commit 9000da00dd70988f30d43806bae33b22ee6b9904)
---
 gcc/config/riscv/bitmanip.md              |   13 ++++++++++++-
 gcc/testsuite/gcc.target/riscv/pr106888.c |   12 ++++++++++++
 gcc/testsuite/gcc.target/riscv/zbbw.c     |    1 +
 3 files changed, 25 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr106888.c

Comments

Jeff Law Feb. 20, 2024, 6:49 a.m. UTC | #1
On 2/19/24 21:26, Alexandre Oliva wrote:
> This backport for gcc-13 is required for pr90838.c to get the expected
> count of andi instructions on riscv64-elf, rather than fail because of
> two extra andi insns in functions where it is not necessary.  (On
> riscv32-elf, it passes).  Regstrapped on x86_64-linux-gnu, along with
> other backports, and tested manually on riscv64-elf.  Ok to install?
> 
> From: Raphael Moreira Zinsly <rzinsly@ventanamicro.com>
> 
> Changes since v1:
> 	- Remove subreg from operand 1.
> 
> -- >8 --
> 
> We were not able to match the CTZ sign extend pattern on RISC-V
> because it gets optimized to zero extend and/or to ANDI patterns.
> For the ANDI case, combine scrambles the RTL and generates the
> extension by using subregs.
> 
> gcc/ChangeLog:
> 	PR target/106888
> 	* config/riscv/bitmanip.md
> 	(<bitmanip_optab>disi2): Match with any_extend.
> 	(<bitmanip_optab>disi2_sext): New pattern to match
> 	with sign extend using an ANDI instruction.
> 
> gcc/testsuite/ChangeLog:
> 	PR target/106888
> 	* gcc.target/riscv/pr106888.c: New test.
> 	* gcc.target/riscv/zbbw.c: Check for ANDI.
In general, shouldn't backports be focused on correctness issues?  It's 
unclear what the motivation is for backporting this change into gcc-13.

Not objecting, trying understand at this stage.
Jeff
Alexandre Oliva Feb. 20, 2024, 2:21 p.m. UTC | #2
On Feb 20, 2024, Jeff Law <jeffreyalaw@gmail.com> wrote:

> On 2/19/24 21:26, Alexandre Oliva wrote:
>> This backport for gcc-13 is required for pr90838.c to get the expected
>> count of andi instructions on riscv64-elf
.
> In general, shouldn't backports be focused on correctness issues?

*nod*.

> It's unclear what the motivation is for backporting this change into
> gcc-13.

There's this unexpected fail in gcc-13 (pr90838.c), one out of a handful
that we've hit while transitioning our riscv toolchains to gcc-13.

I set out to understand them, I identified the patches that got them to
pass in the trunk, and so I've proposed their backports to fix the fails
in gcc-13.

Surely there are other ways to address each one of the fails.

But even if we choose to just xfail them, or leave them failing noisily,
I've already gone through the process of identifying the fix, so I
figured I might as well share it.
Jeff Law Feb. 23, 2024, 7:14 a.m. UTC | #3
On 2/20/24 07:21, Alexandre Oliva wrote:
> On Feb 20, 2024, Jeff Law <jeffreyalaw@gmail.com> wrote:
> 
>> On 2/19/24 21:26, Alexandre Oliva wrote:
>>> This backport for gcc-13 is required for pr90838.c to get the expected
>>> count of andi instructions on riscv64-elf
> .
>> In general, shouldn't backports be focused on correctness issues?
> 
> *nod*.
> 
>> It's unclear what the motivation is for backporting this change into
>> gcc-13.
> 
> There's this unexpected fail in gcc-13 (pr90838.c), one out of a handful
> that we've hit while transitioning our riscv toolchains to gcc-13.
> 
> I set out to understand them, I identified the patches that got them to
> pass in the trunk, and so I've proposed their backports to fix the fails
> in gcc-13.
> 
> Surely there are other ways to address each one of the fails.
> 
> But even if we choose to just xfail them, or leave them failing noisily,
> I've already gone through the process of identifying the fix, so I
> figured I might as well share it.
Thanks for explaining things.  I had a feeling the motivation might be 
something along those lines.

I'd tend to think we don't want this backported.  It doesn't fix any 
correctness issue and the performance impact is small.  I also don't 
expect gcc-13 is going to be of significant long term interest in the 
RISC-V space as it predates any RVV support.

So this feels like it ought to be left as-is on the gcc-13 branch.

jeff
diff mbox series

Patch

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 7aa591689ba87..cc55ca133c3fe 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -246,13 +246,24 @@  (define_insn "*<bitmanip_optab>si2"
 
 (define_insn "*<bitmanip_optab>disi2"
   [(set (match_operand:DI 0 "register_operand" "=r")
-        (sign_extend:DI
+        (any_extend:DI
           (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r"))))]
   "TARGET_64BIT && TARGET_ZBB"
   "<bitmanip_insn>w\t%0,%1"
   [(set_attr "type" "bitmanip")
    (set_attr "mode" "SI")])
 
+;; A SImode clz_ctz_pcnt may be extended to DImode via subreg.
+(define_insn "*<bitmanip_optab>disi2_sext"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (and:DI (subreg:DI
+          (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")) 0)
+          (match_operand:DI 2 "const_int_operand")))]
+  "TARGET_64BIT && TARGET_ZBB && ((INTVAL (operands[2]) & 0x3f) == 0x3f)"
+  "<bitmanip_insn>w\t%0,%1"
+  [(set_attr "type" "bitmanip")
+   (set_attr "mode" "SI")])
+
 (define_insn "*<bitmanip_optab>di2"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
diff --git a/gcc/testsuite/gcc.target/riscv/pr106888.c b/gcc/testsuite/gcc.target/riscv/pr106888.c
new file mode 100644
index 0000000000000..77fb8e5b79c6b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr106888.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbb -mabi=lp64" } */
+
+int
+ctz (int i)
+{
+  int res = __builtin_ctz (i);
+  return res&0xffff;
+}
+
+/* { dg-final { scan-assembler-times "ctzw" 1 } } */
+/* { dg-final { scan-assembler-not "andi" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zbbw.c b/gcc/testsuite/gcc.target/riscv/zbbw.c
index 709743c3b6807..f7b2b63853f40 100644
--- a/gcc/testsuite/gcc.target/riscv/zbbw.c
+++ b/gcc/testsuite/gcc.target/riscv/zbbw.c
@@ -23,3 +23,4 @@  popcount (int i)
 /* { dg-final { scan-assembler-times "clzw" 1 } } */
 /* { dg-final { scan-assembler-times "ctzw" 1 } } */
 /* { dg-final { scan-assembler-times "cpopw" 1 } } */
+/* { dg-final { scan-assembler-not "andi\t" } } */