public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: Fix CTZ unnecessary sign extension [PR #106888]
@ 2023-05-04 17:14 Raphael Moreira Zinsly
  2023-05-06 14:57 ` Jeff Law
  0 siblings, 1 reply; 6+ messages in thread
From: Raphael Moreira Zinsly @ 2023-05-04 17:14 UTC (permalink / raw)
  To: gcc-patches; +Cc: jeffreyalaw, vineetg, shihua, Raphael Moreira Zinsly

We were not able to match the CTZ sign extend pattern on RISC-V
because it get 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.
---
 gcc/config/riscv/bitmanip.md              | 14 +++++++++++++-
 gcc/testsuite/gcc.target/riscv/pr106888.c | 12 ++++++++++++
 gcc/testsuite/gcc.target/riscv/zbbw.c     |  1 +
 3 files changed, 26 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr106888.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index a27fc3e34a1..8dc3e85a338 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -246,13 +246,25 @@
 
 (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_insn>")
    (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 (subreg:SI
+             (match_operand:DI 1 "register_operand" "r") 0)) 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 00000000000..77fb8e5b79c
--- /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 709743c3b68..f7b2b63853f 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" } } */
-- 
2.40.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] RISC-V: Fix CTZ unnecessary sign extension [PR #106888]
  2023-05-04 17:14 [PATCH] RISC-V: Fix CTZ unnecessary sign extension [PR #106888] Raphael Moreira Zinsly
@ 2023-05-06 14:57 ` Jeff Law
  0 siblings, 0 replies; 6+ messages in thread
From: Jeff Law @ 2023-05-06 14:57 UTC (permalink / raw)
  To: Raphael Moreira Zinsly, gcc-patches; +Cc: vineetg, shihua



On 5/4/23 11:14, Raphael Moreira Zinsly wrote:
> We were not able to match the CTZ sign extend pattern on RISC-V
> because it get optimized to zero extend and/or to ANDI patterns.
> For the ANDI case, combine scrambles the RTL and generates the
> extension by using subregs.
So to provide a few more details here.

Coming into combine we have:
> (insn 2 4 3 2 (set (reg/v:DI 136 [ i ])
>         (reg:DI 10 a0 [ i ])) "j.c":3:1 179 {*movdi_64bit}
>      (expr_list:REG_DEAD (reg:DI 10 a0 [ i ])
>         (nil)))
> (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)
> (insn 6 3 7 2 (set (reg:SI 137)
>         (ctz:SI (subreg/u:SI (reg/v:DI 136 [ i ]) 0))) "j.c":4:13 345 {*ctzsi2}
>      (expr_list:REG_DEAD (reg/v:DI 136 [ i ])
>         (nil)))
> (insn 7 6 12 2 (set (reg/v:DI 135 [ <retval> ])
>         (sign_extend:DI (reg:SI 137))) "j.c":4:13 116 {extendsidi2}
>      (expr_list:REG_DEAD (reg:SI 137)
>         (nil)))


The first key being we're starting with an SImode CTZ.  So we have an 
extension on the result and the original argument is in DImode, so we 
have a subreg to get the input into SImode.  That allows us to match the 
standard ctzw pattern.

Of course we know the result of the ctz is in the range 0..32 because 
it's an SImode operand. Thus the extension is redundant and we'd like to 
remove it.

Even though insn 7 is a SIGN_EXTEND, combine knows the SImode sign bit 
is always zero.  As a result it'll canonicalize to ZERO_EXTEND (there's 
a larger discussion around that in the context of aarch64 that I'm not 
going to wade into at the moment).

So combine ultimately tries to match this:


> Trying 6 -> 7:
>     6: r137:SI=ctz(r139:DI#0)
>       REG_DEAD r139:DI
>     7: r135:DI=sign_extend(r137:SI)
>       REG_DEAD r137:SI
> Successfully matched this instruction:
> (set (reg/v:DI 135 [ <retval> ])
>     (and:DI (subreg:DI (ctz:SI (subreg/u:SI (reg:DI 139) 0)) 0)
>         (const_int 127 [0x7f])))

The inner subreg is (of course) still there and must remain so that we 
can continue to distinguish between an SI and DI mode ctz which generate 
different assembler codes on riscv.

Combine has turned the zero extension into a masking operation.  Of 
course the masking operation has to happen in DImode hence new  subreg 
wrapping the result of the ctz so that it can be used in a DImode operation.






> 
> 	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.
> ---
>   gcc/config/riscv/bitmanip.md              | 14 +++++++++++++-
>   gcc/testsuite/gcc.target/riscv/pr106888.c | 12 ++++++++++++
>   gcc/testsuite/gcc.target/riscv/zbbw.c     |  1 +
>   3 files changed, 26 insertions(+), 1 deletion(-)
>   create mode 100644 gcc/testsuite/gcc.target/riscv/pr106888.c
> 
> diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> index a27fc3e34a1..8dc3e85a338 100644
> --- a/gcc/config/riscv/bitmanip.md
> +++ b/gcc/config/riscv/bitmanip.md
> @@ -246,13 +246,25 @@
>   
>   (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_insn>")
>      (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 (subreg:SI
> +             (match_operand:DI 1 "register_operand" "r") 0)) 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")])
Looking at this again after a few months away, I'm pretty sure we can 
eliminate that explicit (subreg:SI ...)).  Instead just use 
(match_operand:SI ...) just like the existing pattern already did.

So the pattern just needs the (subreg:DI ...) on the result to allow us 
to mask in DImode...  So something like this:

> ;; 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")])


I lightly tested this locally and it seems to work just as well as your 
original, but is slightly simpler and avoids the explicit subreg.

OK with that change.

jeff

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] RISC-V: Fix CTZ unnecessary sign extension [PR #106888]
  2024-02-20 14:21   ` Alexandre Oliva
@ 2024-02-23  7:14     ` Jeff Law
  0 siblings, 0 replies; 6+ messages in thread
From: Jeff Law @ 2024-02-23  7:14 UTC (permalink / raw)
  To: Alexandre Oliva
  Cc: gcc-patches, Kito Cheng, Palmer Dabbelt, Andrew Waterman,
	Jim Wilson, Raphael Moreira Zinsly



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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] RISC-V: Fix CTZ unnecessary sign extension [PR #106888]
  2024-02-20  6:49 ` Jeff Law
@ 2024-02-20 14:21   ` Alexandre Oliva
  2024-02-23  7:14     ` Jeff Law
  0 siblings, 1 reply; 6+ messages in thread
From: Alexandre Oliva @ 2024-02-20 14:21 UTC (permalink / raw)
  To: Jeff Law
  Cc: gcc-patches, Kito Cheng, Palmer Dabbelt, Andrew Waterman,
	Jim Wilson, Raphael Moreira Zinsly

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.

-- 
Alexandre Oliva, happy hacker            https://FSFLA.org/blogs/lxo/
   Free Software Activist                   GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity
Excluding neuro-others for not behaving ""normal"" is *not* inclusive

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] RISC-V: Fix CTZ unnecessary sign extension [PR #106888]
  2024-02-20  4:26 Alexandre Oliva
@ 2024-02-20  6:49 ` Jeff Law
  2024-02-20 14:21   ` Alexandre Oliva
  0 siblings, 1 reply; 6+ messages in thread
From: Jeff Law @ 2024-02-20  6:49 UTC (permalink / raw)
  To: Alexandre Oliva, gcc-patches
  Cc: Kito Cheng, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Raphael Moreira Zinsly



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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] RISC-V: Fix CTZ unnecessary sign extension [PR #106888]
@ 2024-02-20  4:26 Alexandre Oliva
  2024-02-20  6:49 ` Jeff Law
  0 siblings, 1 reply; 6+ messages in thread
From: Alexandre Oliva @ 2024-02-20  4:26 UTC (permalink / raw)
  To: gcc-patches
  Cc: Kito Cheng, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Raphael Moreira Zinsly

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

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" } } */

-- 
Alexandre Oliva, happy hacker            https://FSFLA.org/blogs/lxo/
   Free Software Activist                   GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity
Excluding neuro-others for not behaving ""normal"" is *not* inclusive

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-02-23  7:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-04 17:14 [PATCH] RISC-V: Fix CTZ unnecessary sign extension [PR #106888] Raphael Moreira Zinsly
2023-05-06 14:57 ` Jeff Law
2024-02-20  4:26 Alexandre Oliva
2024-02-20  6:49 ` Jeff Law
2024-02-20 14:21   ` Alexandre Oliva
2024-02-23  7:14     ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).