]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: prefetch: fix LRA failing to allocate reg [PR118241] master trunk
authorVineet Gupta <vineetg@rivosinc.com>
Fri, 4 Jul 2025 19:33:51 +0000 (12:33 -0700)
committerVineet Gupta <vineetg@rivosinc.com>
Fri, 4 Jul 2025 23:13:31 +0000 (16:13 -0700)
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>
gcc/config/riscv/riscv.md
gcc/testsuite/gcc.target/riscv/pr118241-b.cc [new file with mode: 0644]

index 893c925b6b9402fd1d673fd26fdf99f384c06262..f5ec0c5170f502a23ca7f526239e73c2cc71e634 100644 (file)
 )
 
 (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 (file)
index 0000000..b2cc73f
--- /dev/null
@@ -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 } } */