https://gcc.gnu.org/g:e8be9b1c419d1b59a6f5fe5f166c43bfea27ec0e

commit e8be9b1c419d1b59a6f5fe5f166c43bfea27ec0e
Author: Monk Chiang <monk.chi...@sifive.com>
Date:   Thu Jul 6 14:05:17 2023 +0800

    RISC-V: Implement locality for __builtin_prefetch
    
    The patch add the Zihintntl instructions in the prefetch pattern.
    Zicbop has prefetch instructions. Zihintntl has NTL instructions.
    Insert NTL instructions before prefetch instruction, if target
    has Zihintntl extension.
    
    gcc/ChangeLog:
    
            * config/riscv/riscv.cc (riscv_print_operand): Add 'L' letter
            to print zihintntl instructions string.
            * config/riscv/riscv.md (prefetch): Add zihintntl instructions.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/prefetch-zicbop.c: New test.
            * gcc.target/riscv/prefetch-zihintntl.c: New test.
    
    (cherry picked from commit bf26413fc4081dfd18b915580b35bdb71481327e)

Diff:
---
 gcc/config/riscv/riscv.cc                          | 22 ++++++++++++++++++++++
 gcc/config/riscv/riscv.md                          | 10 +++++++---
 gcc/testsuite/gcc.target/riscv/prefetch-zicbop.c   | 20 ++++++++++++++++++++
 .../gcc.target/riscv/prefetch-zihintntl.c          | 20 ++++++++++++++++++++
 4 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index d4553aacee96..9bedefa74c35 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6488,6 +6488,7 @@ riscv_asm_output_opcode (FILE *asm_out_file, const char 
*p)
    'A' Print the atomic operation suffix for memory model OP.
    'I' Print the LR suffix for memory model OP.
    'J' Print the SC suffix for memory model OP.
+   'L' Print a non-temporal locality hints instruction.
    'z' Print x0 if OP is zero, otherwise print OP normally.
    'i' Print i if the operand is not a register.
    'S' Print shift-index of single-bit mask OP.
@@ -6682,6 +6683,27 @@ riscv_print_operand (FILE *file, rtx op, int letter)
       break;
     }
 
+    case 'L':
+      {
+       const char *ntl_hint = NULL;
+       switch (INTVAL (op))
+         {
+         case 0:
+           ntl_hint = "ntl.all";
+           break;
+         case 1:
+           ntl_hint = "ntl.pall";
+           break;
+         case 2:
+           ntl_hint = "ntl.p1";
+           break;
+         }
+
+      if (ntl_hint)
+       asm_fprintf (file, "%s\n\t", ntl_hint);
+      break;
+      }
+
     case 'i':
       if (code != REG)
         fputs ("i", file);
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 379015c60de8..46c46039c33a 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -4113,12 +4113,16 @@
 {
   switch (INTVAL (operands[1]))
   {
-    case 0: return "prefetch.r\t%a0";
-    case 1: return "prefetch.w\t%a0";
+    case 0: return TARGET_ZIHINTNTL ? "%L2prefetch.r\t%a0" : "prefetch.r\t%a0";
+    case 1: return TARGET_ZIHINTNTL ? "%L2prefetch.w\t%a0" : "prefetch.w\t%a0";
     default: gcc_unreachable ();
   }
 }
-  [(set_attr "type" "store")])
+  [(set_attr "type" "store")
+   (set (attr "length") (if_then_else (and (match_test "TARGET_ZIHINTNTL")
+                                          (match_test "IN_RANGE (INTVAL 
(operands[2]), 0, 2)"))
+                                     (const_string "8")
+                                     (const_string "4")))])
 
 (define_insn "riscv_prefetchi_<mode>"
   [(unspec_volatile:X [(match_operand:X 0 "address_operand" "r")
diff --git a/gcc/testsuite/gcc.target/riscv/prefetch-zicbop.c 
b/gcc/testsuite/gcc.target/riscv/prefetch-zicbop.c
new file mode 100644
index 000000000000..0faa120f1f79
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/prefetch-zicbop.c
@@ -0,0 +1,20 @@
+/* { dg-do compile target { { rv64-*-*}}} */
+/* { dg-options "-march=rv64gc_zicbop -mabi=lp64" } */
+
+void foo (char *p)
+{
+  __builtin_prefetch (p, 0, 0);
+  __builtin_prefetch (p, 0, 1);
+  __builtin_prefetch (p, 0, 2);
+  __builtin_prefetch (p, 0, 3);
+  __builtin_prefetch (p, 1, 0);
+  __builtin_prefetch (p, 1, 1);
+  __builtin_prefetch (p, 1, 2);
+  __builtin_prefetch (p, 1, 3);
+}
+
+/* { dg-final { scan-assembler-not "ntl.all\t" } } */
+/* { dg-final { scan-assembler-not "ntl.pall\t" } } */
+/* { dg-final { scan-assembler-not "ntl.p1\t" } } */
+/* { dg-final { scan-assembler-times "prefetch.r" 4 } } */
+/* { dg-final { scan-assembler-times "prefetch.w" 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/prefetch-zihintntl.c 
b/gcc/testsuite/gcc.target/riscv/prefetch-zihintntl.c
new file mode 100644
index 000000000000..78a3afe68333
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/prefetch-zihintntl.c
@@ -0,0 +1,20 @@
+/* { dg-do compile target { { rv64-*-*}}} */
+/* { dg-options "-march=rv64gc_zicbop_zihintntl -mabi=lp64" } */
+
+void foo (char *p)
+{
+  __builtin_prefetch (p, 0, 0);
+  __builtin_prefetch (p, 0, 1);
+  __builtin_prefetch (p, 0, 2);
+  __builtin_prefetch (p, 0, 3);
+  __builtin_prefetch (p, 1, 0);
+  __builtin_prefetch (p, 1, 1);
+  __builtin_prefetch (p, 1, 2);
+  __builtin_prefetch (p, 1, 3);
+}
+
+/* { dg-final { scan-assembler-times "ntl.all" 2 } } */
+/* { dg-final { scan-assembler-times "ntl.pall" 2 } } */
+/* { dg-final { scan-assembler-times "ntl.p1" 2 } } */
+/* { dg-final { scan-assembler-times "prefetch.r" 4 } } */
+/* { dg-final { scan-assembler-times "prefetch.w" 4 } } */

Reply via email to