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. gcc/ChangeLog: * config/riscv/thead.md (*th_memidx_operand): New splitter. gcc/testsuite/ChangeLog: * gcc.target/riscv/xtheadmemidx-bug.c: New test. --- gcc/config/riscv/thead.md | 21 +++++++++++++++++++ .../gcc.target/riscv/xtheadmemidx-bug.c | 13 ++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-bug.c 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 @@ (define_insn "*th_mempair_load_zero_extendsidi2" ;; 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 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)); +} -- 2.46.0