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

From 02cf87cd1dd27732414b68f3715ce722b00b92cc Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Fri, 14 Nov 2025 13:29:41 +0100
Subject: [PATCH 1/9] Add prefetch builtins

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  4 +--
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    | 30 ++++++++++++++++
 .../test/CIR/CodeGen/X86/prefetchw-builtin.c  | 36 +++++++++++++++++++
 clang/test/CIR/CodeGen/X86/sse-builtins.c     | 18 ++++++++++
 4 files changed, 86 insertions(+), 2 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 2124b1dc62a81..219846ec7a884 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4116,7 +4116,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'.
   }];
@@ -4150,7 +4150,7 @@ def CIR_ObjSizeOp : CIR_Op<"objsize", [Pure]> {
     When the `min` attribute is present, the operation returns the minimum
     guaranteed accessible size. When absent (max mode), it returns the maximum
     possible object size. Corresponds to `llvm.objectsize`'s `min` argument.
-    
+
     The `dynamic` attribute determines if the value should be evaluated at
     runtime. Corresponds to `llvm.objectsize`'s `dynamic` argument.
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index ba160373ec77e..580d8b890b5c7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -20,6 +20,11 @@
 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,
@@ -33,6 +38,28 @@ static mlir::Value emitIntrinsicCallOp(CIRGenFunction &cgf, 
const CallExpr *e,
       .getResult();
 }
 
+static mlir::Value emitPrefetch(CIRGenFunction &cgf, unsigned builtinID,
+                                const CallExpr *e,
+                                mlir::Value &addr, int64_t hint) {
+  CIRGenBuilderTy &builder = cgf.getBuilder();
+  mlir::Location location = cgf.getLoc(e->getExprLoc());
+  mlir::Type voidTy = builder.getVoidTy();
+  mlir::Value address = builder.createPtrBitcast(addr, voidTy);
+  bool isWrite{};
+  int locality{};
+
+  if (builtinID == X86::BI_mm_prefetch) {
+    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 *e) {
   if (builtinID == Builtin::BI__builtin_cpu_is) {
@@ -85,6 +112,9 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
   case X86::BI_mm_sfence:
     return emitIntrinsicCallOp(*this, e, "x86.sse.sfence", voidTy);
   case X86::BI_mm_prefetch:
+  case X86::BI_m_prefetch:
+  case X86::BI_m_prefetchw:
+      return emitPrefetch(*this, builtinID, e, ops[0], 
getIntValueFromConstOp(ops[1]));
   case X86::BI__rdtsc:
   case X86::BI__builtin_ia32_rdtscp:
   case X86::BI__builtin_ia32_lzcnt_u16:
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..fbf7894ba69b2
--- /dev/null
+++ b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c
@@ -0,0 +1,36 @@
+
+// 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(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(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_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(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)
+}
diff --git a/clang/test/CIR/CodeGen/X86/sse-builtins.c 
b/clang/test/CIR/CodeGen/X86/sse-builtins.c
index 3a61018741958..07c586d7c0b8c 100644
--- a/clang/test/CIR/CodeGen/X86/sse-builtins.c
+++ b/clang/test/CIR/CodeGen/X86/sse-builtins.c
@@ -26,3 +26,21 @@ void test_mm_sfence(void) {
   // LLVM: call void @llvm.x86.sse.sfence()
   // OGCG: call void @llvm.x86.sse.sfence()
 }
+
+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)
+}

From 84f845d4c24a27cfc9a818af913c539a62462a3e Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Fri, 14 Nov 2025 15:38:58 +0100
Subject: [PATCH 2/9] Format

---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    |  7 ++++---
 .../test/CIR/CodeGen/X86/prefetchw-builtin.c  | 20 +++++++++----------
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 580d8b890b5c7..3d0dfef12a6c3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -40,15 +40,16 @@ static mlir::Value emitIntrinsicCallOp(CIRGenFunction &cgf, 
const CallExpr *e,
 
 static mlir::Value emitPrefetch(CIRGenFunction &cgf, unsigned builtinID,
                                 const CallExpr *e,
-                                mlir::Value &addr, int64_t hint) {
+                                const SmallVector<mlir::Value> &ops) {
   CIRGenBuilderTy &builder = cgf.getBuilder();
   mlir::Location location = cgf.getLoc(e->getExprLoc());
   mlir::Type voidTy = builder.getVoidTy();
-  mlir::Value address = builder.createPtrBitcast(addr, voidTy);
+  mlir::Value address = builder.createPtrBitcast(ops[0], voidTy);
   bool isWrite{};
   int locality{};
 
   if (builtinID == X86::BI_mm_prefetch) {
+    int hint = getIntValueFromConstOp(ops[1]);
     isWrite = (hint >> 2) & 0x1;
     locality = hint & 0x3;
   } else {
@@ -114,7 +115,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, e, ops[0], 
getIntValueFromConstOp(ops[1]));
+    return emitPrefetch(*this, builtinID, e, ops);
   case X86::BI__rdtsc:
   case X86::BI__builtin_ia32_rdtscp:
   case X86::BI__builtin_ia32_lzcnt_u16:
diff --git a/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c 
b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c
index fbf7894ba69b2..3b04b789b3322 100644
--- a/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c
+++ b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c
@@ -15,16 +15,6 @@
 
 #include <x86intrin.h>
 
-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(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_m_prefetch_w(void *p) {
   // CIR-LABEL: test_m_prefetch_w
   // LLVM-LABEL: test_m_prefetch_w
@@ -34,3 +24,13 @@ void test_m_prefetch_w(void *p) {
   // 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_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(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)
+}

From fd266d4bd99cfffb88c85d58958444df063ffc42 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Sat, 15 Nov 2025 17:15:56 +0100
Subject: [PATCH 3/9] Feedback

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp        | 18 +++++++++++++-----
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp     |  6 +++++-
 clang/lib/CIR/CodeGen/CIRGenFunction.h         |  4 ++--
 clang/test/CIR/CodeGen/X86/prefetchw-builtin.c | 12 ++++++------
 clang/test/CIR/CodeGen/X86/sse-builtins.c      |  9 +++++++++
 5 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 77f19343653db..201759fba0aba 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -540,12 +540,20 @@ 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)) {
+  std::optional<mlir::Value> valueOpt =
+      emitTargetBuiltinExpr(builtinID, e, returnValue);
+  if (valueOpt) {
+    // A builtin was emitted but had no return value.
+    if (*valueOpt == nullptr) {
+      return RValue::get(nullptr);
+    }
+
     switch (evalKind) {
     case cir::TEK_Scalar:
-      if (mlir::isa<cir::VoidType>(v.getType()))
+      if (mlir::isa<cir::VoidType>(valueOpt->getType())) {
         return RValue::get(nullptr);
-      return RValue::get(v);
+      }
+      return RValue::get(*valueOpt);
     case cir::TEK_Aggregate:
       cgm.errorNYI(e->getSourceRange(), "aggregate return value from builtin");
       return getUndefRValue(e->getType());
@@ -561,7 +569,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   return getUndefRValue(e->getType());
 }
 
-static mlir::Value emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
+static std::optional<mlir::Value> emitTargetArchBuiltinExpr(CIRGenFunction 
*cgf,
                                              unsigned builtinID,
                                              const CallExpr *e,
                                              ReturnValueSlot &returnValue,
@@ -616,7 +624,7 @@ static mlir::Value emitTargetArchBuiltinExpr(CIRGenFunction 
*cgf,
   }
 }
 
-mlir::Value
+std::optional<mlir::Value>
 CIRGenFunction::emitTargetBuiltinExpr(unsigned builtinID, const CallExpr *e,
                                       ReturnValueSlot &returnValue) {
   if (getContext().BuiltinInfo.isAuxBuiltinID(builtinID)) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 3d0dfef12a6c3..503ff1b93bc29 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -48,6 +48,10 @@ static mlir::Value emitPrefetch(CIRGenFunction &cgf, 
unsigned builtinID,
   bool isWrite{};
   int locality{};
 
+  assert(builtinID == X86::BI_mm_prefetch ||
+         builtinID == X86::BI_m_prefetchw ||
+         builtinID == X86::BI_m_prefetch && "Expected prefetch builtin");
+
   if (builtinID == X86::BI_mm_prefetch) {
     int hint = getIntValueFromConstOp(ops[1]);
     isWrite = (hint >> 2) & 0x1;
@@ -61,7 +65,7 @@ static mlir::Value emitPrefetch(CIRGenFunction &cgf, unsigned 
builtinID,
   return {};
 }
 
-mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
+std::optional<mlir::Value> CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
                                                const CallExpr *e) {
   if (builtinID == Builtin::BI__builtin_cpu_is) {
     cgm.errorNYI(e->getSourceRange(), "__builtin_cpu_is");
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 00f289bcd1bb2..52d278f5264cf 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1746,7 +1746,7 @@ class CIRGenFunction : public CIRGenTypeCache {
                                      bool buildingTopLevelCase);
   mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s);
 
-  mlir::Value emitTargetBuiltinExpr(unsigned builtinID,
+  std::optional<mlir::Value> emitTargetBuiltinExpr(unsigned builtinID,
                                     const clang::CallExpr *e,
                                     ReturnValueSlot &returnValue);
 
@@ -1788,7 +1788,7 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   mlir::LogicalResult emitWhileStmt(const clang::WhileStmt &s);
 
-  mlir::Value emitX86BuiltinExpr(unsigned builtinID, const CallExpr *e);
+  std::optional<mlir::Value> emitX86BuiltinExpr(unsigned builtinID, const 
CallExpr *e);
 
   /// Given an assignment `*lhs = rhs`, emit a test that checks if \p rhs is
   /// nonnull, if 1\p LHS is marked _Nonnull.
diff --git a/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c 
b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c
index 3b04b789b3322..7d7ce348b8d88 100644
--- a/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c
+++ b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c
@@ -20,9 +20,9 @@ void test_m_prefetch_w(void *p) {
   // LLVM-LABEL: test_m_prefetch_w
   // OGCG-LABEL: test_m_prefetch_w
   return _m_prefetchw(p);
-  // CIR: cir.prefetch write 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)
+  // 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) {
@@ -30,7 +30,7 @@ void test_m_prefetch(void *p) {
   // LLVM-LABEL: test_m_prefetch
   // OGCG-LABEL: test_m_prefetch
   return _m_prefetch(p);
-  // 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)
+  // 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 07c586d7c0b8c..c7e4db46fbfca 100644
--- a/clang/test/CIR/CodeGen/X86/sse-builtins.c
+++ b/clang/test/CIR/CodeGen/X86/sse-builtins.c
@@ -44,3 +44,12 @@ void test_mm_prefetch_local(char const* p) {
   // 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
+  _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 30e68019c087569ee4f6c42a084b308db5acf728 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Sat, 15 Nov 2025 17:16:07 +0100
Subject: [PATCH 4/9] Formatting

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp    | 9 ++++-----
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 7 +++----
 clang/lib/CIR/CodeGen/CIRGenFunction.h     | 9 +++++----
 3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 201759fba0aba..302b8fc65515a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -569,11 +569,10 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   return getUndefRValue(e->getType());
 }
 
-static std::optional<mlir::Value> emitTargetArchBuiltinExpr(CIRGenFunction 
*cgf,
-                                             unsigned builtinID,
-                                             const CallExpr *e,
-                                             ReturnValueSlot &returnValue,
-                                             llvm::Triple::ArchType arch) {
+static std::optional<mlir::Value>
+emitTargetArchBuiltinExpr(CIRGenFunction *cgf, unsigned builtinID,
+                          const CallExpr *e, ReturnValueSlot &returnValue,
+                          llvm::Triple::ArchType arch) {
   // When compiling in HipStdPar mode we have to be conservative in rejecting
   // target specific features in the FE, and defer the possible error to the
   // AcceleratorCodeSelection pass, wherein iff an unsupported target builtin 
is
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 503ff1b93bc29..d28aa3567c999 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -48,8 +48,7 @@ static mlir::Value emitPrefetch(CIRGenFunction &cgf, unsigned 
builtinID,
   bool isWrite{};
   int locality{};
 
-  assert(builtinID == X86::BI_mm_prefetch ||
-         builtinID == X86::BI_m_prefetchw ||
+  assert(builtinID == X86::BI_mm_prefetch || builtinID == X86::BI_m_prefetchw 
||
          builtinID == X86::BI_m_prefetch && "Expected prefetch builtin");
 
   if (builtinID == X86::BI_mm_prefetch) {
@@ -65,8 +64,8 @@ static mlir::Value emitPrefetch(CIRGenFunction &cgf, unsigned 
builtinID,
   return {};
 }
 
-std::optional<mlir::Value> CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
-                                               const CallExpr *e) {
+std::optional<mlir::Value>
+CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *e) {
   if (builtinID == Builtin::BI__builtin_cpu_is) {
     cgm.errorNYI(e->getSourceRange(), "__builtin_cpu_is");
     return {};
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 52d278f5264cf..b1403bd3780ab 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1746,9 +1746,9 @@ class CIRGenFunction : public CIRGenTypeCache {
                                      bool buildingTopLevelCase);
   mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s);
 
-  std::optional<mlir::Value> emitTargetBuiltinExpr(unsigned builtinID,
-                                    const clang::CallExpr *e,
-                                    ReturnValueSlot &returnValue);
+  std::optional<mlir::Value>
+  emitTargetBuiltinExpr(unsigned builtinID, const clang::CallExpr *e,
+                        ReturnValueSlot &returnValue);
 
   /// Given a value and its clang type, returns the value casted to its memory
   /// representation.
@@ -1788,7 +1788,8 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   mlir::LogicalResult emitWhileStmt(const clang::WhileStmt &s);
 
-  std::optional<mlir::Value> emitX86BuiltinExpr(unsigned builtinID, const 
CallExpr *e);
+  std::optional<mlir::Value> emitX86BuiltinExpr(unsigned builtinID,
+                                                const CallExpr *e);
 
   /// Given an assignment `*lhs = rhs`, emit a test that checks if \p rhs is
   /// nonnull, if 1\p LHS is marked _Nonnull.

From e8d557fd45efd0d6782ded597f55b5039ae09ddf Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Mon, 17 Nov 2025 23:39:33 +0100
Subject: [PATCH 5/9] revert formatting changes

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 219846ec7a884..2b53fff4c9e19 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4150,7 +4150,7 @@ def CIR_ObjSizeOp : CIR_Op<"objsize", [Pure]> {
     When the `min` attribute is present, the operation returns the minimum
     guaranteed accessible size. When absent (max mode), it returns the maximum
     possible object size. Corresponds to `llvm.objectsize`'s `min` argument.
-
+    
     The `dynamic` attribute determines if the value should be evaluated at
     runtime. Corresponds to `llvm.objectsize`'s `dynamic` argument.
 

From fd000c83d08a6f1df3fad60dfad0d9c2f09deb0e Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Mon, 17 Nov 2025 23:45:38 +0100
Subject: [PATCH 6/9] revert formatting changes

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 2b53fff4c9e19..2124b1dc62a81 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4116,7 +4116,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'.
   }];

From 34a531d441eceb7992ae0c3f01c365d02a2cef5b Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Mon, 17 Nov 2025 23:46:59 +0100
Subject: [PATCH 7/9] add OGCG label

---
 clang/test/CIR/CodeGen/X86/sse-builtins.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/test/CIR/CodeGen/X86/sse-builtins.c 
b/clang/test/CIR/CodeGen/X86/sse-builtins.c
index c7e4db46fbfca..e8203265f89f3 100644
--- a/clang/test/CIR/CodeGen/X86/sse-builtins.c
+++ b/clang/test/CIR/CodeGen/X86/sse-builtins.c
@@ -30,6 +30,7 @@ void test_mm_sfence(void) {
 void test_mm_prefetch(char const* p) {
   // CIR-LABEL: test_mm_prefetch
   // LLVM-LABEL: test_mm_prefetch
+  // OGCG-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)
@@ -39,6 +40,7 @@ void test_mm_prefetch(char const* p) {
 void test_mm_prefetch_local(char const* p) {
   // CIR-LABEL: test_mm_prefetch_local
   // LLVM-LABEL: test_mm_prefetch_local
+  // OGCG-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)
@@ -48,6 +50,7 @@ void test_mm_prefetch_local(char const* p) {
 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)

From 58af6247576f2c5c8d4bad046f4de69b90f11792 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Wed, 19 Nov 2025 01:55:56 +0100
Subject: [PATCH 8/9] feedback

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 63 +++++++++++++------------
 clang/lib/CIR/CodeGen/CIRGenFunction.h  |  5 +-
 2 files changed, 35 insertions(+), 33 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 302b8fc65515a..c4408405002a0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -540,33 +540,26 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   }
 
   // Now see if we can emit a target-specific builtin.
-  std::optional<mlir::Value> valueOpt =
-      emitTargetBuiltinExpr(builtinID, e, returnValue);
-  if (valueOpt) {
-    // A builtin was emitted but had no return value.
-    if (*valueOpt == nullptr) {
-      return RValue::get(nullptr);
-    }
+  RValue value = emitTargetBuiltinExpr(builtinID, e, returnValue);
 
-    switch (evalKind) {
-    case cir::TEK_Scalar:
-      if (mlir::isa<cir::VoidType>(valueOpt->getType())) {
-        return RValue::get(nullptr);
-      }
-      return RValue::get(*valueOpt);
-    case cir::TEK_Aggregate:
-      cgm.errorNYI(e->getSourceRange(), "aggregate return value from builtin");
-      return getUndefRValue(e->getType());
-    case cir::TEK_Complex:
-      llvm_unreachable("No current target builtin returns complex");
-    }
-    llvm_unreachable("Bad evaluation kind in EmitBuiltinExpr");
+
+  if (value.isScalar()) {
+    if (!value.getValue() || 
mlir::isa<cir::VoidType>(value.getValue().getType()))
+        return RValue::getIgnored();
+
+    return value;
   }
 
-  cgm.errorNYI(e->getSourceRange(),
-               std::string("unimplemented builtin call: ") +
-                   getContext().BuiltinInfo.getName(builtinID));
-  return getUndefRValue(e->getType());
+  if (value.isAggregate()) {
+    cgm.errorNYI(e->getSourceRange(), "aggregate return value from builtin");
+    return getUndefRValue(e->getType());
+  }
+
+  if (value.isComplex()) {
+    llvm_unreachable("No current target builtin returns complex");
+  }
+
+  llvm_unreachable("Bad evaluation kind in EmitBuiltinExpr");
 }
 
 static std::optional<mlir::Value>
@@ -623,18 +616,28 @@ emitTargetArchBuiltinExpr(CIRGenFunction *cgf, unsigned 
builtinID,
   }
 }
 
-std::optional<mlir::Value>
-CIRGenFunction::emitTargetBuiltinExpr(unsigned builtinID, const CallExpr *e,
-                                      ReturnValueSlot &returnValue) {
+RValue CIRGenFunction::emitTargetBuiltinExpr(unsigned builtinID,
+                                             const CallExpr *e,
+                                             ReturnValueSlot &returnValue) {
+  std::optional<mlir::Value> valueOpt;
   if (getContext().BuiltinInfo.isAuxBuiltinID(builtinID)) {
     assert(getContext().getAuxTargetInfo() && "Missing aux target info");
-    return emitTargetArchBuiltinExpr(
+    valueOpt = emitTargetArchBuiltinExpr(
         this, getContext().BuiltinInfo.getAuxBuiltinID(builtinID), e,
         returnValue, getContext().getAuxTargetInfo()->getTriple().getArch());
+  } else {
+    valueOpt = emitTargetArchBuiltinExpr(this, builtinID, e, returnValue,
+                                         getTarget().getTriple().getArch());
+  }
+
+  if (!valueOpt) {
+    cgm.errorNYI(e->getSourceRange(),
+                 std::string("unimplemented builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return getUndefRValue(e->getType());
   }
 
-  return emitTargetArchBuiltinExpr(this, builtinID, e, returnValue,
-                                   getTarget().getTriple().getArch());
+  return RValue::get(*valueOpt);
 }
 
 mlir::Value CIRGenFunction::emitScalarOrConstFoldImmArg(
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index b1403bd3780ab..97be21317d3a6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1746,9 +1746,8 @@ class CIRGenFunction : public CIRGenTypeCache {
                                      bool buildingTopLevelCase);
   mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s);
 
-  std::optional<mlir::Value>
-  emitTargetBuiltinExpr(unsigned builtinID, const clang::CallExpr *e,
-                        ReturnValueSlot &returnValue);
+  RValue emitTargetBuiltinExpr(unsigned builtinID, const clang::CallExpr *e,
+                               ReturnValueSlot &returnValue);
 
   /// Given a value and its clang type, returns the value casted to its memory
   /// representation.

From e8c7671419049c23e01ac01262d80435e9ed0251 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hendrik=20H=C3=BCbner?=
 <[email protected]>
Date: Wed, 19 Nov 2025 16:19:32 +0100
Subject: [PATCH 9/9] Fix merge issue

---
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 81bfac8c9a02d..ad5742aef174a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -100,7 +100,7 @@ static mlir::Value emitVectorFCmp(CIRGenBuilderTy &builder,
 }
 
 std::optional<mlir::Value>
-CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *e) {
+CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
   if (builtinID == Builtin::BI__builtin_cpu_is) {
     cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_is");
     return {};
@@ -153,7 +153,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *e) {
   case X86::BI_mm_prefetch:
   case X86::BI_m_prefetch:
   case X86::BI_m_prefetchw:
-    return emitPrefetch(*this, builtinID, e, ops);
+    return emitPrefetch(*this, builtinID, expr, ops);
   case X86::BI__rdtsc:
   case X86::BI__builtin_ia32_rdtscp:
   case X86::BI__builtin_ia32_lzcnt_u16:

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

Reply via email to