From: Bohan Lei Date: Sat, 11 Oct 2025 16:11:34 +0000 (-0600) Subject: [PR target/119587] RISC-V: xtheadmemidx: Split slli.uw pattern X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9586a3e9060cfcbda62604f515d9974c00adaea;p=thirdparty%2Fgcc.git [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. --- diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index d816f3b86dd..20e82e68df2 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_extendqi2" [(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 00000000000..92b24e311b6 --- /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)); +}