From a35fde2e5c7b8ca3ed57b010d996b0a5a554ee64 Mon Sep 17 00:00:00 2001
From: shrikardongre <shrikardongre@gmail.com>
Date: Sun, 13 Apr 2025 16:08:56 +0530
Subject: [PATCH] _mm_prefetch implementation

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td |  2 ++
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp   | 16 +++++++++++++++-
 clang/test/CIR/CodeGen/X86/builtins-x86.c    |  8 ++++++++
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 23b75e89acaa..ed74fe26b219 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -5304,6 +5304,8 @@ def PrefetchOp : CIR_Op<"prefetch"> {
           IntMaxValue<3>]>:$locality,
         UnitAttr:$isWrite);
 
+  let results = (outs VoidPtr:$result);
+
   let assemblyFormat = [{
     `(` $addr `:` qualified(type($addr)) `)`
         `locality``(` $locality `)`
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 96469248535b..14fc14096004 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -95,7 +95,21 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID,
   default:
     return nullptr;
   case X86::BI_mm_prefetch: {
-    llvm_unreachable("_mm_prefetch NYI");
+    mlir::Location loc = getLoc(E->getExprLoc());
+    auto C = dyn_cast<cir::IntAttr>(
+        cast<cir::ConstantOp>(Ops[1].getDefiningOp()).getValue());
+    auto Locality = mlir::IntegerAttr::get(
+        mlir::IntegerType::get(builder.getContext(), 32), C.getUInt() & 0x3);
+    bool ReadWrite = ((C.getUInt() >> 2) & 0x1) == 1;
+    mlir::UnitAttr isWrite =
+        ReadWrite ? mlir::UnitAttr::get(&getMLIRContext()) : nullptr;
+    mlir::Type voidPtrType =
+        cir::PointerType::get(cir::VoidType::get(&getMLIRContext()));
+    auto CastToVoid = builder.create<cir::CastOp>(
+        loc, voidPtrType, cir::CastKind::bitcast, Ops[0]);
+    auto res =
+        builder.create<cir::PrefetchOp>(loc, CastToVoid, Locality, isWrite);
+    return res->getResult(0);
   }
   case X86::BI_mm_clflush: {
     mlir::Type voidTy = cir::VoidType::get(&getMLIRContext());
diff --git a/clang/test/CIR/CodeGen/X86/builtins-x86.c b/clang/test/CIR/CodeGen/X86/builtins-x86.c
index eeebec717bcd..73b689e6e735 100644
--- a/clang/test/CIR/CodeGen/X86/builtins-x86.c
+++ b/clang/test/CIR/CodeGen/X86/builtins-x86.c
@@ -6,6 +6,14 @@
 // This test mimics clang/test/CodeGen/builtins-x86.c, which eventually
 // CIR shall be able to support fully.
 
+void test_mm_prefetch(char const* p) {
+  // CIR-LABEL: test_mm_prefetch
+  // LLVM-LABEL: test_mm_prefetch
+  _mm_prefetch(p,0);
+  //CIR: {{%.*}}= cir.prefetch({{%.*}} : !cir.ptr<!void>) locality(0) read
+  // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 0, i32 1)
+}
+
 void test_mm_clflush(const void* tmp_vCp) {
   // CIR-LABEL: test_mm_clflush
   // LLVM-LABEL: test_mm_clflush