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

Reply via email to