https://gcc.gnu.org/g:87cf04d4709ca6f3a6da37fa560018ac5a18d60a

commit 87cf04d4709ca6f3a6da37fa560018ac5a18d60a
Author: Bohan Lei <[email protected]>
Date:   Sat Oct 11 10:11:34 2025 -0600

    [PR target/119587] RISC-V: xtheadmemidx: Split slli.uw pattern
    
    The combine pass can generate an index like (and:DI (mult:DI (reg:DI)
    (const_int scale)) (const_int mask)) when XTheadMemIdx is available.
    LRA may pull it out, and thus a splitter is needed when Zba is not
    available.
    
    A similar splitter were introduced when XTheadMemIdx support was added,
    but removed in commit 31c3c5d.  The new splitter in this new patch is
    based on the removed one.
    
            PR target/119587
    gcc/ChangeLog:
    
            * config/riscv/thead.md (*th_memidx_operand): New splitter.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/xtheadmemidx-bug.c: New test.
    
    (cherry picked from commit c9586a3e9060cfcbda62604f515d9974c00adaea)

Diff:
---
 gcc/config/riscv/thead.md                         | 21 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadmemidx-bug.c | 13 +++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index d816f3b86dde..20e82e68df2a 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -458,6 +458,27 @@
 
 ;; XTheadMemIdx
 
+;; Help reload to add a displacement for the base register.
+;; In the case `zext(*(uN*))(base+((rN<<1)&0x1fffffffe))` LRA splits
+;; off two new instructions: a) `new_base = base + disp`, and
+;; b) `index = (rN<<1)&0x1fffffffe`.  The index calculation has no
+;; corresponding instruction pattern and needs this insn_and_split
+;; to recover.
+
+(define_insn_and_split "*th_memidx_operand"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
+                          (match_operand:QI 2 "imm123_operand" "Ds3"))
+               (match_operand 3 "const_int_operand" "n")))]
+  "TARGET_64BIT && TARGET_XTHEADMEMIDX && (lra_in_progress || reload_completed)
+   && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
+  "#"
+  "&& !TARGET_ZBA && reload_completed"
+  [(set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 1) 0)))
+   (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
+  ""
+  [(set_attr "type" "bitmanip")])
+
 (define_insn "*th_memidx_zero_extendqi<SUPERQI:mode>2"
   [(set (match_operand:SUPERQI 0 "register_operand" "=r,r,r,r,r,r")
        (zero_extend:SUPERQI
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx-bug.c 
b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-bug.c
new file mode 100644
index 000000000000..92b24e311b60
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx-bug.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx" } */
+
+int a;
+int **b;
+
+void
+c ()
+{
+  int **e = &b[(unsigned)(long)&a];
+  __asm__ ("" : "+A"(*e));
+}

Reply via email to