public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [to-be-committed][RISC-V] Improve AND with some constants
@ 2024-05-13 19:18 Jeff Law
  0 siblings, 0 replies; only message in thread
From: Jeff Law @ 2024-05-13 19:18 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 613 bytes --]


If we have an AND with a constant operand and the constant operand 
requires synthesis, then we may be able to generate more efficient code 
than we do now.

Essentially the need for constant synthesis gives us a budget for 
alternative ways to clear bits, which zext.w can do for bits 32..63 
trivially.   So if we clear 32..63  via zext.w, the constant for the 
remaining bits to clear may be simple enough to use with andi or bseti. 
That will save us an instruction.

This has tested in Ventana's CI system as well as my own.  I'll wait for 
the upstream CI tester to report success before committing.

Jeff

[-- Attachment #2: P --]
[-- Type: text/plain, Size: 3025 bytes --]

gcc/
	* config/riscv/bitmanip.md: Add new splitter for AND with
	a constant that masks off bits 32..63 and needs synthesis.

gcc/testsuite/

	* gcc.target/riscv/zba_zbs_and-1.c: New test.

+++ b/gcc/testsuite/gcc.target/riscv/zba_zbs_and-1.c
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 724511b6df3..8769a6b818b 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -843,6 +843,40 @@ (define_insn_and_split "*andi<mode>_extrabit"
 }
 [(set_attr "type" "bitmanip")])
 
+;; If we have the ZBA extension, then we can clear the upper half of a 64
+;; bit object with a zext.w.  So if we have AND where the constant would
+;; require synthesis of two or more instructions, but 32->64 sign extension
+;; of the constant is a simm12, then we can use zext.w+andi.  If the adjusted
+;; constant is a single bit constant, then we can use zext.w+bclri
+;;
+;; With the mvconst_internal pattern claiming a single insn to synthesize
+;; constants, this must be a define_insn_and_split.
+(define_insn_and_split ""
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(and:DI (match_operand:DI 1 "register_operand" "r")
+		(match_operand 2 "const_int_operand" "n")))]
+  "TARGET_64BIT
+   && TARGET_ZBA
+   && !paradoxical_subreg_p (operands[1])
+   /* Only profitable if synthesis takes more than one insn.  */
+   && riscv_const_insns (operands[2]) != 1
+   /* We need the upper half to be zero.  */
+   && (INTVAL (operands[2]) & HOST_WIDE_INT_C (0xffffffff00000000)) == 0
+   /* And the the adjusted constant must either be something we can
+      implement with andi or bclri.  */
+   && ((SMALL_OPERAND (sext_hwi (INTVAL (operands[2]), 32))
+        || (TARGET_ZBS && popcount_hwi (INTVAL (operands[2])) == 31))
+       && INTVAL (operands[2]) != 0x7fffffff)"
+  "#"
+  "&& 1"
+  [(set (match_dup 0) (zero_extend:DI (match_dup 3)))
+   (set (match_dup 0) (and:DI (match_dup 0) (match_dup 2)))]
+  "{
+     operands[3] = gen_lowpart (SImode, operands[1]);
+     operands[2] = GEN_INT (sext_hwi (INTVAL (operands[2]), 32));
+   }"
+  [(set_attr "type" "bitmanip")])
+
 ;; IF_THEN_ELSE: test for 2 bits of opposite polarity
 (define_insn_and_split "*branch<X:mode>_mask_twobits_equals_singlebit"
   [(set (pc)
diff --git a/gcc/testsuite/gcc.target/riscv/zba_zbs_and-1.c b/gcc/testsuite/gcc.target/riscv/zba_zbs_and-1.c
new file mode 100644
index 00000000000..23fd769449e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zba_zbs_and-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zba_zbb_zbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+
+unsigned long long w32mem_1(unsigned long long w32)
+{
+    return w32 & ~(1U << 0);
+}
+
+unsigned long long w32mem_2(unsigned long long w32)
+{
+    return w32 & ~(1U << 30);
+}
+
+unsigned long long w32mem_3(unsigned long long w32)
+{
+    return w32 & ~(1U << 31);
+}
+
+/* If we do synthesis, then we'd see an addi.  */
+/* { dg-final { scan-assembler-not "addi\t" } } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-05-13 19:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-13 19:18 [to-be-committed][RISC-V] Improve AND with some constants 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).