[clang] [llvm] [llvm][clang] Add intrinsic support for cbo.zero instruction (Zicboz ISA extension) (PR #164822)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 23 09:01:42 PDT 2025


https://github.com/t-baydyusenov updated https://github.com/llvm/llvm-project/pull/164822

>From a6a9b13a71af54331807170913602d1936f08ce3 Mon Sep 17 00:00:00 2001
From: "t.baydyusenov" <t.baydyusenov at syntacore.com>
Date: Wed, 22 Oct 2025 14:44:05 +0000
Subject: [PATCH] [llvm][clang] Add intrinsic support for cbo.zero instruction
 (Zicboz ISA extension)

---
 clang/include/clang/Basic/BuiltinsRISCV.td    |  7 +++++
 clang/lib/CodeGen/TargetBuiltins/RISCV.cpp    |  6 ++++
 clang/lib/Headers/CMakeLists.txt              |  1 +
 clang/lib/Headers/riscv_cmo.h                 | 28 +++++++++++++++++++
 .../riscv-zicbo-intrinsics/cbo-zero-invalid.c | 12 ++++++++
 .../riscv-zicbo-intrinsics/cbo-zero-valid.c   | 13 +++++++++
 llvm/include/llvm/IR/IntrinsicsRISCV.td       | 11 ++++++--
 llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td  |  1 +
 8 files changed, 77 insertions(+), 2 deletions(-)
 create mode 100644 clang/lib/Headers/riscv_cmo.h
 create mode 100644 clang/test/CodeGen/RISCV/riscv-zicbo-intrinsics/cbo-zero-invalid.c
 create mode 100644 clang/test/CodeGen/RISCV/riscv-zicbo-intrinsics/cbo-zero-valid.c

diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td b/clang/include/clang/Basic/BuiltinsRISCV.td
index 2dad5ede2d64b..91a2fea8a8a03 100644
--- a/clang/include/clang/Basic/BuiltinsRISCV.td
+++ b/clang/include/clang/Basic/BuiltinsRISCV.td
@@ -153,6 +153,13 @@ def ntl_store : RISCVBuiltin<"void(...)">;
 let Features = "zihintpause", Attributes = [NoThrow] in
 def pause : RISCVBuiltin<"void()">;
 
+//===----------------------------------------------------------------------===//
+// Zicboz extension.
+//===----------------------------------------------------------------------===//
+let Features = "zicboz" in {
+def cbo_zero : RISCVBuiltin<"void(void *)">;
+} // Features = "zicboz"
+
 //===----------------------------------------------------------------------===//
 // XCV extensions.
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
index 920d28561fc2a..acf04fe0ec2a2 100644
--- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
@@ -1296,6 +1296,12 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
     return Builder.CreateCall(Fn, {});
   }
 
+  // Zicboz
+  case RISCV::BI__builtin_riscv_cbo_zero:
+    ID = Intrinsic::riscv_cbo_zero;
+    IntrinsicTypes = {Int8PtrTy};
+    break;
+
   // XCValu
   case RISCV::BI__builtin_riscv_cv_alu_addN:
     ID = Intrinsic::riscv_cv_alu_addN;
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 32a6be88abc20..dcad17e8f5979 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -125,6 +125,7 @@ set(ppc_htm_files
 
 set(riscv_files
   riscv_bitmanip.h
+  riscv_cmo.h
   riscv_corev_alu.h
   riscv_crypto.h
   riscv_nds.h
diff --git a/clang/lib/Headers/riscv_cmo.h b/clang/lib/Headers/riscv_cmo.h
new file mode 100644
index 0000000000000..92bf5115b4a76
--- /dev/null
+++ b/clang/lib/Headers/riscv_cmo.h
@@ -0,0 +1,28 @@
+/*===---- riscv_cmo.h - RISC-V CMO intrinsics ----------------------------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __RISCV_CMO_H
+#define __RISCV_CMO_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__riscv_zicboz)
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__riscv_cbo_zero(void *__x) {
+  return __builtin_riscv_cbo_zero(__x);
+}
+#endif // defined(__riscv_zicboz)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // define __RISCV_CMO_H
diff --git a/clang/test/CodeGen/RISCV/riscv-zicbo-intrinsics/cbo-zero-invalid.c b/clang/test/CodeGen/RISCV/riscv-zicbo-intrinsics/cbo-zero-invalid.c
new file mode 100644
index 0000000000000..358c005e6fdd3
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-zicbo-intrinsics/cbo-zero-invalid.c
@@ -0,0 +1,12 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 -target-feature +zicboz \
+// RUN:   -Wall -Wno-unused -Werror -fsyntax-only -verify %s
+
+#include <riscv_cmo.h>
+
+void test(void *x) {
+	__riscv_cbo_zero(x, 0); // expected-error{{too many arguments to function call, expected single argument '__x', have 2 arguments}} expected-note at riscv_cmo.h:* {{'__riscv_cbo_zero' declared here}}
+	int res = __riscv_cbo_zero(x); // expected-error{{initializing 'int' with an expression of incompatible type 'void'}}
+	__riscv_cbo_zero(42); // expected-error{{incompatible integer to pointer conversion passing 'int' to parameter of type 'void *'}} expected-note at riscv_cmo.h:* {{passing argument to parameter '__x' here}}
+}
+
diff --git a/clang/test/CodeGen/RISCV/riscv-zicbo-intrinsics/cbo-zero-valid.c b/clang/test/CodeGen/RISCV/riscv-zicbo-intrinsics/cbo-zero-valid.c
new file mode 100644
index 0000000000000..a73e4eabd850f
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-zicbo-intrinsics/cbo-zero-valid.c
@@ -0,0 +1,13 @@
+
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 -target-feature +zicboz -O2 -S -o - %s | FileCheck %s
+
+#include <riscv_cmo.h>
+
+void test(void *x) {
+// CHECK-LABEL: test:
+// CHECK:       cbo.zero (a0)
+// CHECK:       ret
+  __riscv_cbo_zero(x);
+}
+
diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td
index 77fcc46ea5a89..1a62608cea61e 100644
--- a/llvm/include/llvm/IR/IntrinsicsRISCV.td
+++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td
@@ -1953,13 +1953,20 @@ let TargetPrefix = "riscv" in {
 } // TargetPrefix = "riscv"
 
 
-// Zihintpause extensions
 //===----------------------------------------------------------------------===//
+// Zihintpause extensions
 let TargetPrefix = "riscv" in
 def int_riscv_pause : DefaultAttrsIntrinsic<[], [], [IntrNoMem, IntrHasSideEffects]>;
 
-// Vendor extensions
 //===----------------------------------------------------------------------===//
+// Cache Management
+let TargetPrefix = "riscv" in {
+// Zicboz
+def int_riscv_cbo_zero : Intrinsic<[], [llvm_anyptr_ty], [IntrWriteMem]>;
+} // TargetPrefix = "riscv"
+
+//===----------------------------------------------------------------------===//
+// Vendor extensions
 include "llvm/IR/IntrinsicsRISCVXTHead.td"
 include "llvm/IR/IntrinsicsRISCVXsf.td"
 include "llvm/IR/IntrinsicsRISCVXCV.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td
index 3ddcb1d615dbb..cea2a90ba0675 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td
@@ -56,6 +56,7 @@ def CBO_INVAL : CBO_r<0b000000000000, "cbo.inval">, Sched<[]>;
 
 let Predicates = [HasStdExtZicboz] in {
 def CBO_ZERO : CBO_r<0b000000000100, "cbo.zero">, Sched<[]>;
+def : Pat<(int_riscv_cbo_zero GPR:$rs1), (CBO_ZERO GPR:$rs1)>;
 } // Predicates = [HasStdExtZicboz]
 
 let Predicates = [HasStdExtZicbop, NoVendorXMIPSCBOP] in {



More information about the llvm-commits mailing list