https://github.com/HendrikHuebner updated 
https://github.com/llvm/llvm-project/pull/168051

From 67c3c53a0a2ea68492639cccd120eaba59e1678e Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Tue, 25 Nov 2025 14:07:48 +0100
Subject: [PATCH 1/3] feedback

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  2 +-
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       | 22 +++++------
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    | 39 +++++++++++++++++++
 .../test/CIR/CodeGen/X86/prefetchw-builtin.c  | 35 +++++++++++++++++
 clang/test/CIR/CodeGen/X86/sse-builtins.c     | 28 +++++++++++++
 5 files changed, 113 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/X86/prefetchw-builtin.c

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index a19c4f951fff9..eb0ab81c26be0 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4431,7 +4431,7 @@ def CIR_PrefetchOp : CIR_Op<"prefetch"> {
     $locality is a temporal locality specifier ranging from (0) - no locality,
     to (3) - extremely local, keep in cache. If $locality is not present, the
     default value is 3.
-    
+
     $isWrite specifies whether the prefetch is for a 'read' or 'write'. If
     $isWrite is not specified, it means that prefetch is prepared for 'read'.
   }];
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index d220fdf4dc8a7..f5c26b2d8507c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1258,10 +1258,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
 
   // Now see if we can emit a target-specific builtin.
   if (mlir::Value v = emitTargetBuiltinExpr(builtinID, e, returnValue)) {
+    if (mlir::isa<cir::VoidType>(v.getType()))
+      return RValue::get(nullptr);
+
     switch (evalKind) {
     case cir::TEK_Scalar:
-      if (mlir::isa<cir::VoidType>(v.getType()))
-        return RValue::get(nullptr);
       return RValue::get(v);
     case cir::TEK_Aggregate:
       cgm.errorNYI(e->getSourceRange(), "aggregate return value from builtin");
@@ -1272,9 +1273,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     llvm_unreachable("Bad evaluation kind in EmitBuiltinExpr");
   }
 
-  cgm.errorNYI(e->getSourceRange(),
-               std::string("unimplemented builtin call: ") +
-                   getContext().BuiltinInfo.getName(builtinID));
   return getUndefRValue(e->getType());
 }
 
@@ -1303,9 +1301,7 @@ static mlir::Value 
emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
   case llvm::Triple::aarch64_be:
   case llvm::Triple::bpfeb:
   case llvm::Triple::bpfel:
-    // These are actually NYI, but that will be reported by emitBuiltinExpr.
-    // At this point, we don't even know that the builtin is target-specific.
-    return nullptr;
+    break;
 
   case llvm::Triple::x86:
   case llvm::Triple::x86_64:
@@ -1325,12 +1321,14 @@ static mlir::Value 
emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
   case llvm::Triple::hexagon:
   case llvm::Triple::riscv32:
   case llvm::Triple::riscv64:
-    // These are actually NYI, but that will be reported by emitBuiltinExpr.
-    // At this point, we don't even know that the builtin is target-specific.
-    return {};
   default:
-    return {};
+    break;
   }
+
+  cgf->cgm.errorNYI(e->getSourceRange(),
+                "target-specific builtin not implemented on this architecture: 
 " +
+                    cgf->getContext().BuiltinInfo.getName(builtinID));
+  return {};
 }
 
 mlir::Value
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 978fee7dbec9d..40bccce010b85 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -16,10 +16,16 @@
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/CIR/MissingFeatures.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 
 using namespace clang;
 using namespace clang::CIRGen;
 
+/// Get integer from a mlir::Value that is an int constant or a constant op.
+static int64_t getIntValueFromConstOp(mlir::Value val) {
+  return val.getDefiningOp<cir::ConstantOp>().getIntValue().getSExtValue();
+}
+
 template <typename... Operands>
 static mlir::Value emitIntrinsicCallOp(CIRGenFunction &cgf, const CallExpr *e,
                                        const std::string &str,
@@ -68,6 +74,33 @@ static mlir::Value emitVectorFCmp(CIRGenBuilderTy &builder,
   return bitCast;
 }
 
+static mlir::Value emitPrefetch(CIRGenFunction &cgf, unsigned builtinID,
+                                const CallExpr *e,
+                                const llvm::SmallVector<mlir::Value> &ops) {
+
+  assert(builtinID == X86::BI_mm_prefetch || builtinID == X86::BI_m_prefetchw 
||
+         builtinID == X86::BI_m_prefetch && "Expected prefetch builtin");
+  CIRGenBuilderTy &builder = cgf.getBuilder();
+  mlir::Location location = cgf.getLoc(e->getExprLoc());
+  mlir::Type voidTy = builder.getVoidTy();
+  mlir::Value addr = ops[0];
+  mlir::Value address = builder.createPtrBitcast(addr, voidTy);
+  bool isWrite{};
+  int locality{};
+
+  if (builtinID == X86::BI_mm_prefetch) {
+    int64_t hint = getIntValueFromConstOp(ops[1]);
+    isWrite = (hint >> 2) & 0x1;
+    locality = hint & 0x3;
+  } else {
+    isWrite = (builtinID == X86::BI_m_prefetchw);
+    locality = 0x3;
+  }
+
+  cir::PrefetchOp::create(builder, location, address, locality, isWrite);
+  return {};
+}
+
 mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
                                                const CallExpr *expr) {
   if (builtinID == Builtin::BI__builtin_cpu_is) {
@@ -108,6 +141,9 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
 
   switch (builtinID) {
   default:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented X86 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
     return {};
   case X86::BI_mm_clflush:
     return emitIntrinsicCallOp(*this, expr, "x86.sse2.clflush", voidTy, 
ops[0]);
@@ -120,6 +156,9 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
   case X86::BI_mm_sfence:
     return emitIntrinsicCallOp(*this, expr, "x86.sse.sfence", voidTy);
   case X86::BI_mm_prefetch:
+  case X86::BI_m_prefetch:
+  case X86::BI_m_prefetchw:
+      return emitPrefetch(*this, builtinID, expr, ops);
   case X86::BI__rdtsc:
   case X86::BI__builtin_ia32_rdtscp: {
     cgm.errorNYI(expr->getSourceRange(),
diff --git a/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c 
b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c
new file mode 100644
index 0000000000000..78c6b26b5c2a6
--- /dev/null
+++ b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse -fclangir -emit-cir -o %t.cir 
-Wall -Werror
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse -fclangir -emit-llvm -o %t.ll 
-Wall -Werror
+// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s
+
+// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse -fno-signed-char -fclangir 
-emit-cir -o %t.cir -Wall -Werror
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse -fclangir -emit-llvm -o %t.ll 
-Wall -Werror
+// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s
+
+// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse -emit-llvm -o - -Wall -Werror 
| FileCheck %s -check-prefix=OGCG
+// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse -emit-llvm -o - -Wall -Werror 
| FileCheck %s -check-prefix=OGCG
+
+
+#include <x86intrin.h>
+
+void test_m_prefetch_w(void *p) {
+  // CIR-LABEL: test_m_prefetch_w
+  // LLVM-LABEL: test_m_prefetch_w
+  // OGCG-LABEL: test_m_prefetch_w
+  return _m_prefetchw(p);
+  // CIR: cir.prefetch write locality(3) %{{.*}} : !cir.ptr<!void>
+  // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1)
+  // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1)
+}
+
+void test_m_prefetch(void *p) {
+  // CIR-LABEL: test_m_prefetch
+  // LLVM-LABEL: test_m_prefetch
+  // OGCG-LABEL: test_m_prefetch
+  return _m_prefetch(p);
+  // CIR: cir.prefetch read locality(3) %{{.*}} : !cir.ptr<!void>
+  // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1)
+  // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1)
+}
diff --git a/clang/test/CIR/CodeGen/X86/sse-builtins.c 
b/clang/test/CIR/CodeGen/X86/sse-builtins.c
index c893859b297cc..543dd64cc5ad8 100644
--- a/clang/test/CIR/CodeGen/X86/sse-builtins.c
+++ b/clang/test/CIR/CodeGen/X86/sse-builtins.c
@@ -71,3 +71,31 @@ __m128 test_mm_undefined_ps(void) {
   // OGCG: ret <4 x float> zeroinitializer
   return _mm_undefined_ps();
 }
+
+void test_mm_prefetch(char const* p) {
+  // CIR-LABEL: test_mm_prefetch
+  // LLVM-LABEL: test_mm_prefetch
+  _mm_prefetch(p, 0);
+  // CIR: cir.prefetch read locality(0) %{{.*}} : !cir.ptr<!void>
+  // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 0, i32 1)
+  // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 0, i32 1)
+}
+
+void test_mm_prefetch_local(char const* p) {
+  // CIR-LABEL: test_mm_prefetch_local
+  // LLVM-LABEL: test_mm_prefetch_local
+  _mm_prefetch(p, 3);
+  // CIR: cir.prefetch read locality(3) %{{.*}} : !cir.ptr<!void>
+  // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1)
+  // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1)
+}
+
+void test_mm_prefetch_write(char const* p) {
+  // CIR-LABEL: test_mm_prefetch_write
+  // LLVM-LABEL: test_mm_prefetch_write
+  // OGCG-LABEL: test_mm_prefetch_write
+  _mm_prefetch(p, 7);
+  // CIR: cir.prefetch write locality(3) %{{.*}} : !cir.ptr<!void>
+  // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1)
+  // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1)
+}

From c9229fa1a1a78b558abd85ba0f173fb0b12bbd3b Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Tue, 25 Nov 2025 14:07:58 +0100
Subject: [PATCH 2/3] fmt

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp    | 7 ++++---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 4 ++--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index f5c26b2d8507c..40750b049d7d9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1325,9 +1325,10 @@ static mlir::Value 
emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
     break;
   }
 
-  cgf->cgm.errorNYI(e->getSourceRange(),
-                "target-specific builtin not implemented on this architecture: 
 " +
-                    cgf->getContext().BuiltinInfo.getName(builtinID));
+  cgf->cgm.errorNYI(
+      e->getSourceRange(),
+      "target-specific builtin not implemented on this architecture:  " +
+          cgf->getContext().BuiltinInfo.getName(builtinID));
   return {};
 }
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 40bccce010b85..febcfac822d6b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -13,10 +13,10 @@
 
 #include "CIRGenFunction.h"
 #include "CIRGenModule.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/CIR/MissingFeatures.h"
-#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 
 using namespace clang;
 using namespace clang::CIRGen;
@@ -158,7 +158,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
   case X86::BI_mm_prefetch:
   case X86::BI_m_prefetch:
   case X86::BI_m_prefetchw:
-      return emitPrefetch(*this, builtinID, expr, ops);
+    return emitPrefetch(*this, builtinID, expr, ops);
   case X86::BI__rdtsc:
   case X86::BI__builtin_ia32_rdtscp: {
     cgm.errorNYI(expr->getSourceRange(),

From 8ed31b5729e0852ff35b4cc1b86b732acc46eb40 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Tue, 25 Nov 2025 14:11:17 +0100
Subject: [PATCH 3/3] fix

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 +-
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp      | 5 ++---
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index eb0ab81c26be0..a19c4f951fff9 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4431,7 +4431,7 @@ def CIR_PrefetchOp : CIR_Op<"prefetch"> {
     $locality is a temporal locality specifier ranging from (0) - no locality,
     to (3) - extremely local, keep in cache. If $locality is not present, the
     default value is 3.
-
+    
     $isWrite specifies whether the prefetch is for a 'read' or 'write'. If
     $isWrite is not specified, it means that prefetch is prepared for 'read'.
   }];
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 40750b049d7d9..56006f40274ec 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1258,11 +1258,10 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
 
   // Now see if we can emit a target-specific builtin.
   if (mlir::Value v = emitTargetBuiltinExpr(builtinID, e, returnValue)) {
-    if (mlir::isa<cir::VoidType>(v.getType()))
-      return RValue::get(nullptr);
-
     switch (evalKind) {
     case cir::TEK_Scalar:
+      if (mlir::isa<cir::VoidType>(v.getType()))
+        return RValue::get(nullptr);
       return RValue::get(v);
     case cir::TEK_Aggregate:
       cgm.errorNYI(e->getSourceRange(), "aggregate return value from builtin");

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

Reply via email to