https://github.com/bruteforceboy updated 
https://github.com/llvm/llvm-project/pull/178260

>From de1e6d1d08d5dd6d3346e7399abd728594e73f0a Mon Sep 17 00:00:00 2001
From: bruteforceboy <[email protected]>
Date: Tue, 27 Jan 2026 18:26:08 +0100
Subject: [PATCH 1/2] [CIR] Upstream ClearCacheOp support for
 __builtin___clear_cache

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 20 +++++++++++
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       | 10 +++++-
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 13 ++++++++
 clang/test/CIR/CodeGen/clear-cache.c          | 33 +++++++++++++++++++
 4 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CIR/CodeGen/clear-cache.c

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index a6de91b2eda01..c310372844af7 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -5111,6 +5111,26 @@ def CIR_PrefetchOp : CIR_Op<"prefetch"> {
     }];
 }
 
+//===----------------------------------------------------------------------===//
+// ClearCacheOp
+//===----------------------------------------------------------------------===//
+
+def CIR_ClearCacheOp : CIR_Op<"clear_cache", [
+  AllTypesMatch<["begin", "end"]>
+]> {
+  let summary = "clear cache operation";
+  let description = [{
+    CIR representation for `__builtin___clear_cache`.
+  }];
+
+  let arguments = (ins CIR_VoidPtrType:$begin, CIR_VoidPtrType:$end);
+  let assemblyFormat = [{
+    $begin `:` qualified(type($begin)) `,`
+    $end `,`
+    attr-dict
+  }];
+}
+
 
//===----------------------------------------------------------------------===//
 // ObjSizeOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 88d37d56fcd78..c505359271c49 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1080,8 +1080,16 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   }
   case Builtin::BI__builtin_readcyclecounter:
   case Builtin::BI__builtin_readsteadycounter:
-  case Builtin::BI__builtin___clear_cache:
     return errorBuiltinNYI(*this, e, builtinID);
+  case Builtin::BI__builtin___clear_cache: {
+    mlir::Type voidTy = cir::VoidType::get(&getMLIRContext());
+    mlir::Value begin =
+        builder.createPtrBitcast(emitScalarExpr(e->getArg(0)), voidTy);
+    mlir::Value end =
+        builder.createPtrBitcast(emitScalarExpr(e->getArg(1)), voidTy);
+    cir::ClearCacheOp::create(builder, getLoc(e->getSourceRange()), begin, 
end);
+    return RValue::get(nullptr);
+  }
   case Builtin::BI__builtin_trap:
     emitTrap(loc, /*createNewBlock=*/true);
     return RValue::getIgnored();
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 4877508b1c3da..d1b6f2a0cd7f7 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1713,6 +1713,19 @@ mlir::LogicalResult 
CIRToLLVMFrameAddrOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
+mlir::LogicalResult CIRToLLVMClearCacheOpLowering::matchAndRewrite(
+    cir::ClearCacheOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  auto begin = adaptor.getBegin();
+  auto end = adaptor.getEnd();
+  auto intrinNameAttr =
+      mlir::StringAttr::get(op.getContext(), "llvm.clear_cache");
+  rewriter.replaceOpWithNewOp<mlir::LLVM::CallIntrinsicOp>(
+      op, mlir::Type{}, intrinNameAttr, mlir::ValueRange{begin, end});
+
+  return mlir::success();
+}
+
 mlir::LogicalResult CIRToLLVMAddrOfReturnAddrOpLowering::matchAndRewrite(
     cir::AddrOfReturnAddrOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/test/CIR/CodeGen/clear-cache.c 
b/clang/test/CIR/CodeGen/clear-cache.c
new file mode 100644
index 0000000000000..2dd84a98a4583
--- /dev/null
+++ b/clang/test/CIR/CodeGen/clear-cache.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
+
+char buffer[32] = "This is a largely unused buffer";
+
+// __builtin___clear_cache always maps to @llvm.clear_cache, but what
+// each back-end produces is different, and this is tested in LLVM
+
+// CIR-LABEL: main
+// CIR:  %[[VAL_1:.*]] = cir.get_global @buffer : !cir.ptr<!cir.array<!s8i x 
32>>
+// CIR:  %[[VAL_2:.*]] = cir.cast array_to_ptrdecay %[[VAL_1]] : 
!cir.ptr<!cir.array<!s8i x 32>> -> !cir.ptr<!s8i>
+// CIR:  %[[VAL_3:.*]] = cir.cast bitcast %[[VAL_2]] : !cir.ptr<!s8i> -> 
!cir.ptr<!void>
+// CIR:  %[[VAL_4:.*]] = cir.get_global @buffer : !cir.ptr<!cir.array<!s8i x 
32>>
+// CIR:  %[[VAL_5:.*]] = cir.cast array_to_ptrdecay %[[VAL_4]] : 
!cir.ptr<!cir.array<!s8i x 32>>
+// CIR:  %[[VAL_6:.*]] = cir.const #cir.int<32> : !s32i
+// CIR:  %[[VAL_7:.*]] = cir.ptr_stride %[[VAL_5]], %[[VAL_6]] : 
(!cir.ptr<!s8i>, !s32i) -> !cir.ptr<!s8i>
+// CIR:  %[[VAL_8:.*]] = cir.cast bitcast %[[VAL_7]] : !cir.ptr<!s8i> -> 
!cir.ptr<!void>
+// CIR:  cir.clear_cache %[[VAL_3]] : !cir.ptr<!void>, %[[VAL_8]]
+
+// LLVM-LABEL: main
+// LLVM:  call void @llvm.clear_cache(ptr @buffer, ptr getelementptr inbounds 
nuw (i8, ptr @buffer, i64 32))
+
+// OGCG-LABEL: main
+// OGCG:  call void @llvm.clear_cache(ptr @buffer, ptr getelementptr inbounds 
(i8, ptr @buffer, i64 32))
+
+int main(void) {
+  __builtin___clear_cache(buffer, buffer+32);
+  return 0;
+}

>From 3f5447f5e867c48cc195054c23b072854853921d Mon Sep 17 00:00:00 2001
From: bruteforceboy <[email protected]>
Date: Tue, 27 Jan 2026 18:45:42 +0100
Subject: [PATCH 2/2] format nit

---
 clang/test/CIR/CodeGen/clear-cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CIR/CodeGen/clear-cache.c 
b/clang/test/CIR/CodeGen/clear-cache.c
index 2dd84a98a4583..2443fdb40f774 100644
--- a/clang/test/CIR/CodeGen/clear-cache.c
+++ b/clang/test/CIR/CodeGen/clear-cache.c
@@ -28,6 +28,6 @@ char buffer[32] = "This is a largely unused buffer";
 // OGCG:  call void @llvm.clear_cache(ptr @buffer, ptr getelementptr inbounds 
(i8, ptr @buffer, i64 32))
 
 int main(void) {
-  __builtin___clear_cache(buffer, buffer+32);
+  __builtin___clear_cache(buffer, buffer + 32);
   return 0;
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to