The patch optimizes code generation for comparisons of the form
X & C1 == C2. When the bitwise AND mask could fit in a 12-bit immediate
operand of RISC-V "andi" instruction with help of right shifting.
For example, C1 = 0x55500000 and C2 = 0x14500000.
These numbers can be stored using 12 bits, which is advantageous in RISC-V,
since instructions such as ANDI exist. By shifting all used values
by 20 bits to the right, we can make use of the “and immediate” instruction,
thus improving performance.

2024-12-11  Oliver Kozul  <oliver.ko...@rt-rk.com>

      PR target/114087

gcc/ChangeLog:

      * config/riscv/riscv.md (*lui_constraint<ANYI:mode>_lshiftrt): New 
pattern.

gcc/testsuite/ChangeLog:

      * gcc.target/riscv/pr114087-2.c: New test.



CONFIDENTIALITY: The contents of this e-mail are confidential and intended only 
for the above addressee(s). If you are not the intended recipient, or the 
person responsible for delivering it to the intended recipient, copying or 
delivering it to anyone else or using it in any unauthorized manner is 
prohibited and may be unlawful. If you receive this e-mail by mistake, please 
notify the sender and the systems administrator at straym...@rt-rk.com 
immediately.
---
 gcc/config/riscv/riscv.md                   | 25 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr114087-2.c | 11 +++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr114087-2.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 3a4cd1d93a0..310cbd5617e 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -858,6 +858,31 @@
   [(set_attr "type" "arith")
    (set_attr "mode" "SI")])
 
+(define_insn_and_split "*lui_constraint<ANYI:mode>_lshiftrt"
+  [(set (match_operand:ANYI 0 "register_operand" "=r")
+  (plus:ANYI (and:ANYI (match_operand:ANYI 1 "register_operand" "r")
+    (match_operand 2 "const_int_operand"))
+    (match_operand 3 "const_int_operand")))]
+  "!SMALL_OPERAND (INTVAL (operands[2]))
+  && !SMALL_OPERAND (INTVAL (operands[3]))
+  && SMALL_AFTER_COMMON_TRAILING_SHIFT (INTVAL (operands[2]),
+  INTVAL (operands[3]))"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (lshiftrt:X (match_dup 1) (match_dup 4)))
+   (set (match_dup 0) (and:X (match_dup 0) (match_dup 5)))
+   (set (match_dup 0) (plus:X (match_dup 0) (match_dup 6)))]
+  {
+    HOST_WIDE_INT mask = INTVAL (operands[2]);
+    HOST_WIDE_INT val = INTVAL (operands[3]);
+    int trailing_shift = COMMON_TRAILING_ZEROS (mask, val);
+
+    operands[4] = GEN_INT (trailing_shift);
+    operands[5] = GEN_INT (mask >> trailing_shift);
+    operands[6] = GEN_INT (val >> trailing_shift);
+  }
+[(set_attr "type" "arith")])
+
 ;;
 ;;  ....................
 ;;
diff --git a/gcc/testsuite/gcc.target/riscv/pr114087-2.c 
b/gcc/testsuite/gcc.target/riscv/pr114087-2.c
new file mode 100644
index 00000000000..1e158e8b722
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr114087-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+int pred2a(int x) {
+  return ((x & 0x55500000) == 0x14500000);
+}
+
+/* { dg-final { scan-assembler  {srli\s*[a-x0-9]+,\s*[a-x0-9]+,\s*20}} } */
+/* { dg-final { scan-assembler  {andi\s*[a-x0-9]+,\s*[a-x0-9]+,\s*1365}} } */
\ No newline at end of file
-- 
2.43.0

Reply via email to