prefetch was recently fixed/tightened (with Q reg constraint) to only support right address patterns (REG or REG+D with lower 5 bits clear). However in some cases that's too restrictive for LRA and it fails to allocate a reg resulting in following ICE...
| gcc/testsuite/gcc.target/riscv/pr118241-b.cc:31:19: error: unable to generate reloads for: | 31 | void m() { a.l(); } | | ^ |(insn 26 25 27 7 (prefetch (mem/f:DI (plus:DI (reg/f:DI 143 [ _5 ]) | (const_int 56 [0x38])) [5 _5->batch[6]+0 S8 A64]) | (const_int 0 [0]) | (const_int 3 [0x3])) "gcc/testsuite/gcc.target/riscv/pr118241-b.cc":18:29 498 {prefetch} | (expr_list:REG_DEAD (reg/f:DI 142 [ _5->batch[6] ]) | (nil))) |during RTL pass: reload Fix that by providing a fallback alternative register constraint to reload the address. PR target/118241 gcc/ChangeLog: * config/riscv/riscv.md (prefetch): Add alternative "r". gcc/testsuite/ChangeLog: * gcc.target/riscv/pr118241-b.cc: New test. Signed-off-by: Vineet Gupta <vine...@rivosinc.com> --- gcc/config/riscv/riscv.md | 2 +- gcc/testsuite/gcc.target/riscv/pr118241-b.cc | 33 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/riscv/pr118241-b.cc diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 893c925b6b94..f5ec0c5170f5 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -4402,7 +4402,7 @@ (define_insn "riscv_zero_<mode>" ) (define_insn "prefetch" - [(prefetch (match_operand 0 "prefetch_operand" "Q") + [(prefetch (match_operand 0 "prefetch_operand" "Qr") (match_operand 1 "imm5_operand" "i") (match_operand 2 "const_int_operand" "n"))] "TARGET_ZICBOP" diff --git a/gcc/testsuite/gcc.target/riscv/pr118241-b.cc b/gcc/testsuite/gcc.target/riscv/pr118241-b.cc new file mode 100644 index 000000000000..b2cc73faa3a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr118241-b.cc @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64imafdc_zba_zbb_zbs_zicbom_zicbop -mabi=lp64d" } */ + +/* Reduced from libsanitizer::asan_allocator. */ + +enum a { c }; +class d; +struct e { + long count; + void *batch[]; +}; +template <typename> class f { +public: + void g() { + if (e *b = h->i()) + for (; b->count;) + if (6 < b->count) + __builtin_prefetch(b->batch[6]); + } + d *h; +}; +class d { +public: + e *i(); +}; +struct j { + f<int> k; + j(a); + void l() { k.g(); } +} a(c); +void m() { a.l(); } + +/* { dg-final { scan-assembler-times "prefetch.r\t0\\(\[a-x0-9\]+\\)" 1 } } */ -- 2.43.0