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 <vineetg@rivosinc.com>
)
(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"
--- /dev/null
+/* { 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 } } */