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

From 539eebe34fb2184e20525078df8f6413b66625ce Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Mon, 10 Nov 2025 23:04:51 +0100
Subject: [PATCH 1/5] [CIR] Upstream X86 builtin _mm_prefetch and _mm_clflush

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 45 ++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    | 60 +++++++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp    | 22 +++++++
 clang/lib/CIR/CodeGen/CIRGenFunction.h        |  4 ++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 14 +++++
 clang/test/CIR/CodeGen/X86/sse-builtins.c     | 23 +++++++
 clang/test/CIR/CodeGen/X86/sse2-builtins.c    | 23 +++++++
 7 files changed, 191 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/X86/sse-builtins.c
 create mode 100644 clang/test/CIR/CodeGen/X86/sse2-builtins.c

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 16258513239d9..902b1fa64fb5b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -413,6 +413,18 @@ def CIR_ConstantOp : CIR_Op<"const", [
 
     template <typename T>
     T getValueAttr() { return mlir::dyn_cast<T>(getValue()); }
+
+    llvm::APInt getIntValue() {
+      if (const auto intAttr = getValueAttr<cir::IntAttr>())
+        return intAttr.getValue();
+      llvm_unreachable("Expected an IntAttr in ConstantOp");
+    }
+
+    bool getBoolValue() {
+      if (const auto boolAttr = getValueAttr<cir::BoolAttr>())
+        return boolAttr.getValue();
+      llvm_unreachable("Expected a BoolAttr in ConstantOp");
+    }
   }];
 
   let hasFolder = 1;
@@ -2579,6 +2591,39 @@ def CIR_FuncOp : CIR_Op<"func", [
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// LLVMIntrinsicCallOp
+//===----------------------------------------------------------------------===//
+
+def CIR_LLVMIntrinsicCallOp : CIR_Op<"llvm.intrinsic"> {
+  let summary = "Call to llvm intrinsic functions that is not defined in CIR";
+  let description = [{
+    `cir.llvm.intrinsic` operation represents a call-like expression which has
+    return type and arguments that maps directly to a llvm intrinsic.
+    It only records intrinsic `intrinsic_name`.
+  }];
+
+  let results = (outs Optional<CIR_AnyType>:$result);
+  let arguments = (ins
+                   StrAttr:$intrinsic_name, Variadic<CIR_AnyType>:$arg_ops);
+
+  let skipDefaultBuilders = 1;
+
+  let assemblyFormat = [{
+    $intrinsic_name $arg_ops `:` functional-type($arg_ops, $result) attr-dict
+  }];
+
+  let builders = [
+    OpBuilder<(ins "mlir::StringAttr":$intrinsic_name, "mlir::Type":$resType,
+              CArg<"mlir::ValueRange", "{}">:$operands), [{
+      $_state.addAttribute("intrinsic_name", intrinsic_name);
+      $_state.addOperands(operands);
+      if (resType)
+        $_state.addTypes(resType);
+    }]>,
+  ];
+}
+
 
//===----------------------------------------------------------------------===//
 // CallOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 0198a9d4eb192..2f02dd0319cd0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -21,6 +21,49 @@
 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();
+}
+
+static mlir::Value emitClFlush(CIRGenFunction& cgf,
+                               const CallExpr* e,
+                               mlir::Value& op) {
+    mlir::Type voidTy = cir::VoidType::get(&cgf.getMLIRContext());
+    mlir::Location location = cgf.getLoc(e->getExprLoc());
+    return cgf.getBuilder()
+        .create<cir::LLVMIntrinsicCallOp>(
+            location, cgf.getBuilder().getStringAttr("x86.sse2.clflush"),
+            voidTy, op)
+        .getResult();
+}
+
+static mlir::Value emitPrefetch(CIRGenFunction& cgf,
+                                const CallExpr* e,
+                                mlir::Value& addr,
+                                int64_t hint) {
+  CIRGenBuilderTy& builder = cgf.getBuilder();
+  mlir::Type voidTy = cir::VoidType::get(&cgf.getMLIRContext());
+  mlir::Type sInt32Ty = cir::IntType::get(&cgf.getMLIRContext(), 32, true);
+  mlir::Value address = builder.createPtrBitcast(addr, voidTy);
+  mlir::Location location = cgf.getLoc(e->getExprLoc());
+  mlir::Value rw =
+      cir::ConstantOp::create(builder, location,
+                              cir::IntAttr::get(sInt32Ty, (hint >> 2) & 0x1));
+  mlir::Value locality =
+      cir::ConstantOp::create(builder, location,
+                              cir::IntAttr::get(sInt32Ty, hint & 0x3));
+  mlir::Value data = cir::ConstantOp::create(builder, location,
+                                             cir::IntAttr::get(sInt32Ty, 1));
+
+  return cir::LLVMIntrinsicCallOp::create(
+             builder, location,
+             builder.getStringAttr("prefetch"), voidTy,
+             mlir::ValueRange{address, rw, locality, data})
+      .getResult();
+}
+
+
 mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
                                                const CallExpr *e) {
   if (builtinID == Builtin::BI__builtin_cpu_is) {
@@ -43,11 +86,28 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
   // Find out if any arguments are required to be integer constant expressions.
   assert(!cir::MissingFeatures::handleBuiltinICEArguments());
 
+  // The operands of the builtin call
+  llvm::SmallVector<mlir::Value, 4> ops;
+
+  // `ICEArguments` is a bitmap indicating whether the argument at the i-th bit
+  // is required to be a constant integer expression.
+  unsigned ICEArguments = 0;
+  ASTContext::GetBuiltinTypeError error;
+  getContext().GetBuiltinType(builtinID, error, &ICEArguments);
+  assert(error == ASTContext::GE_None && "Error while getting builtin type.");
+
+  const unsigned numArgs = e->getNumArgs();
+  for (unsigned i = 0; i != numArgs; i++) {
+    ops.push_back(emitScalarOrConstFoldImmArg(ICEArguments, i, e));
+  }
+
   switch (builtinID) {
   default:
     return {};
   case X86::BI_mm_prefetch:
+    return emitPrefetch(*this, e, ops[0], getIntValueFromConstOp(ops[1]));
   case X86::BI_mm_clflush:
+    return emitClFlush(*this, e, ops[0]);
   case X86::BI_mm_lfence:
   case X86::BI_mm_pause:
   case X86::BI_mm_mfence:
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 5eba5ba6c3df1..236f487afd9ba 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1430,6 +1430,28 @@ mlir::Value CIRGenFunction::emitPromotedScalarExpr(const 
Expr *e,
   return ScalarExprEmitter(*this, builder).Visit(const_cast<Expr *>(e));
 }
 
+mlir::Value CIRGenFunction::emitScalarOrConstFoldImmArg(unsigned ICEArguments,
+                                                        unsigned index,
+                                                        const CallExpr *e) {
+  mlir::Value arg{};
+
+  // The bit at the specified index indicates whether the argument is required
+  // to be a constant integer expression.
+  bool isArgRequiredToBeConstant = (ICEArguments & (1 << index));
+
+  if (!isArgRequiredToBeConstant) {
+    arg = emitScalarExpr(e->getArg(index));
+  } else {
+    // If this is required to be a constant, constant fold it so that we
+    // know that the generated intrinsic gets a ConstantInt.
+    std::optional<llvm::APSInt> result =
+        e->getArg(index)->getIntegerConstantExpr(getContext());
+    assert(result && "Expected argument to be a constant");
+    arg = builder.getConstInt(getLoc(e->getSourceRange()), *result);
+  }
+  return arg;
+}
+
 [[maybe_unused]] static bool mustVisitNullValue(const Expr *e) {
   // If a null pointer expression's type is the C++0x nullptr_t and
   // the expression is not a simple literal, it must be evaluated
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index f879e580989f7..0ce8714b23e82 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1529,6 +1529,10 @@ class CIRGenFunction : public CIRGenTypeCache {
   mlir::Value emitScalarExpr(const clang::Expr *e,
                              bool ignoreResultAssign = false);
 
+  mlir::Value emitScalarOrConstFoldImmArg(unsigned ICEArguments,
+                                          unsigned index,
+                                          const CallExpr *e);
+
   mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv,
                                       cir::UnaryOpKind kind, bool isPre);
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index b4afed7019417..f4379b402fe13 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -320,6 +320,20 @@ static mlir::LLVM::CallIntrinsicOp 
replaceOpWithCallLLVMIntrinsicOp(
   return callIntrinOp;
 }
 
+mlir::LogicalResult CIRToLLVMLLVMIntrinsicCallOpLowering::matchAndRewrite(
+    cir::LLVMIntrinsicCallOp op,
+    OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  mlir::Type llvmResTy =
+      getTypeConverter()->convertType(op->getResultTypes()[0]);
+  if (!llvmResTy)
+    return op.emitError("expected LLVM result type");
+  StringRef name = op.getIntrinsicName();
+  replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm." + name, llvmResTy,
+                                   adaptor.getOperands());
+  return mlir::success();
+}
+
 /// IntAttr visitor.
 mlir::Value CIRAttrToValue::visitCirAttr(cir::IntAttr intAttr) {
   mlir::Location loc = parentOp->getLoc();
diff --git a/clang/test/CIR/CodeGen/X86/sse-builtins.c 
b/clang/test/CIR/CodeGen/X86/sse-builtins.c
new file mode 100644
index 0000000000000..4dd141168ba66
--- /dev/null
+++ b/clang/test/CIR/CodeGen/X86/sse-builtins.c
@@ -0,0 +1,23 @@
+// 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
+
+// This test mimics clang/test/CodeGen/X86/sse-builtins.c, which eventually
+// CIR shall be able to support fully.
+
+#include <immintrin.h>
+
+
+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)
+}
diff --git a/clang/test/CIR/CodeGen/X86/sse2-builtins.c 
b/clang/test/CIR/CodeGen/X86/sse2-builtins.c
new file mode 100644
index 0000000000000..0c275fa089262
--- /dev/null
+++ b/clang/test/CIR/CodeGen/X86/sse2-builtins.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse2 -fclangir -emit-cir -o 
%t.cir -Wall -Werror
+// RUN: FileCheck --check-prefixes=CIR-CHECK --input-file=%t.cir %s
+// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse2 -fno-signed-char -fclangir 
-emit-cir -o %t.cir -Wall -Werror
+// RUN: FileCheck --check-prefixes=CIR-CHECK --input-file=%t.cir %s
+
+// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse2 -fclangir -emit-llvm -o 
%t.ll -Wall -Werror
+// RUN: FileCheck --check-prefixes=LLVM-CHECK --input-file=%t.ll %s
+// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s 
-triple=x86_64-unknown-linux -target-feature +sse2 -fno-signed-char -fclangir 
-emit-llvm -o %t.ll -Wall -Werror
+// RUN: FileCheck --check-prefixes=LLVM-CHECK --input-file=%t.ll %s
+
+// This test mimics clang/test/CodeGen/X86/sse2-builtins.c, which eventually
+// CIR shall be able to support fully.
+
+#include <immintrin.h>
+
+
+void test_mm_clflush(void* A) {
+  // CIR-LABEL: test_mm_clflush
+  // LLVM-LABEL: teh
+  _mm_clflush(A);
+  // CIR-CHECK: {{%.*}} = cir.llvm.intrinsic "x86.sse2.clflush" {{%.*}} : 
(!cir.ptr<!void>) -> !void
+  // LLVM-CHECK: call void @llvm.x86.sse2.clflush(ptr {{%.*}})
+}

From de4743272c246c35ddcc3123a2ecfdd5a5d4a938 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Mon, 10 Nov 2025 23:18:23 +0100
Subject: [PATCH 2/5] fix warning

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

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 2f02dd0319cd0..0c168d86ccde5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -31,11 +31,10 @@ static mlir::Value emitClFlush(CIRGenFunction& cgf,
                                mlir::Value& op) {
     mlir::Type voidTy = cir::VoidType::get(&cgf.getMLIRContext());
     mlir::Location location = cgf.getLoc(e->getExprLoc());
-    return cgf.getBuilder()
-        .create<cir::LLVMIntrinsicCallOp>(
-            location, cgf.getBuilder().getStringAttr("x86.sse2.clflush"),
-            voidTy, op)
-        .getResult();
+    return cir::LLVMIntrinsicCallOp::create(
+          cgf.getBuilder(), location, 
+          cgf.getBuilder().getStringAttr("x86.sse2.clflush"), voidTy, op)
+      .getResult();
 }
 
 static mlir::Value emitPrefetch(CIRGenFunction& cgf,

From 26d8914b8c9ee4e01ea8fa55464e8ab0cb17225f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hendrik=20H=C3=BCbner?=
 <[email protected]>
Date: Tue, 11 Nov 2025 11:56:49 +0100
Subject: [PATCH 3/5] Update clang/include/clang/CIR/Dialect/IR/CIROps.td

Co-authored-by: Andy Kaylor <[email protected]>
---
 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 902b1fa64fb5b..d40466610fc13 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2595,7 +2595,7 @@ def CIR_FuncOp : CIR_Op<"func", [
 // LLVMIntrinsicCallOp
 
//===----------------------------------------------------------------------===//
 
-def CIR_LLVMIntrinsicCallOp : CIR_Op<"llvm.intrinsic"> {
+def CIR_LLVMIntrinsicCallOp : CIR_Op<"call_llvm_intrinsic"> {
   let summary = "Call to llvm intrinsic functions that is not defined in CIR";
   let description = [{
     `cir.llvm.intrinsic` operation represents a call-like expression which has

From 93c0ded976ab0c45df326bec9c3c3aa517e4133e Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Tue, 11 Nov 2025 12:50:22 +0100
Subject: [PATCH 4/5] feedback

---
 clang/include/clang/CIR/MissingFeatures.h     |  1 +
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    | 49 +++++++------------
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 14 +++++-
 clang/test/CIR/CodeGen/X86/sse2-builtins.c    |  2 +-
 4 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index af1ffffcf54c0..460bd69f69c35 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -271,6 +271,7 @@ struct MissingFeatures {
   static bool insertBuiltinUnpredictable() { return false; }
   static bool instrumentation() { return false; }
   static bool intrinsics() { return false; }
+  static bool intrinsicElementTypeSupport() {return false; }
   static bool isMemcpyEquivalentSpecialMember() { return false; }
   static bool isTrivialCtorOrDtor() { return false; }
   static bool lambdaCaptures() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 0c168d86ccde5..546fef7ccb1a0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -26,43 +26,32 @@ static int64_t getIntValueFromConstOp(mlir::Value val) {
   return val.getDefiningOp<cir::ConstantOp>().getIntValue().getSExtValue();
 }
 
-static mlir::Value emitClFlush(CIRGenFunction& cgf,
-                               const CallExpr* e,
-                               mlir::Value& op) {
-    mlir::Type voidTy = cir::VoidType::get(&cgf.getMLIRContext());
-    mlir::Location location = cgf.getLoc(e->getExprLoc());
-    return cir::LLVMIntrinsicCallOp::create(
-          cgf.getBuilder(), location, 
-          cgf.getBuilder().getStringAttr("x86.sse2.clflush"), voidTy, op)
+static mlir::Value emitClFlush(CIRGenFunction &cgf, const CallExpr *e,
+                               mlir::Value &op) {
+  mlir::Type voidTy = cir::VoidType::get(&cgf.getMLIRContext());
+  mlir::Location location = cgf.getLoc(e->getExprLoc());
+  return cir::LLVMIntrinsicCallOp::create(
+             cgf.getBuilder(), location,
+             cgf.getBuilder().getStringAttr("x86.sse2.clflush"), voidTy, op)
       .getResult();
 }
 
-static mlir::Value emitPrefetch(CIRGenFunction& cgf,
-                                const CallExpr* e,
-                                mlir::Value& addr,
-                                int64_t hint) {
-  CIRGenBuilderTy& builder = cgf.getBuilder();
-  mlir::Type voidTy = cir::VoidType::get(&cgf.getMLIRContext());
-  mlir::Type sInt32Ty = cir::IntType::get(&cgf.getMLIRContext(), 32, true);
-  mlir::Value address = builder.createPtrBitcast(addr, voidTy);
+static mlir::Value emitPrefetch(CIRGenFunction &cgf, const CallExpr *e,
+                                mlir::Value &addr, int64_t hint) {
+  CIRGenBuilderTy &builder = cgf.getBuilder();
   mlir::Location location = cgf.getLoc(e->getExprLoc());
-  mlir::Value rw =
-      cir::ConstantOp::create(builder, location,
-                              cir::IntAttr::get(sInt32Ty, (hint >> 2) & 0x1));
-  mlir::Value locality =
-      cir::ConstantOp::create(builder, location,
-                              cir::IntAttr::get(sInt32Ty, hint & 0x3));
-  mlir::Value data = cir::ConstantOp::create(builder, location,
-                                             cir::IntAttr::get(sInt32Ty, 1));
+  mlir::Type voidTy = builder.getVoidTy();
+  mlir::Value address = builder.createPtrBitcast(addr, voidTy);
+  mlir::Value rw = builder.getSignedInt(location, (hint >> 2) & 0x1, 32);
+  mlir::Value locality = builder.getSignedInt(location, hint & 0x3, 32);
+  mlir::Value data = builder.getSignedInt(location, 1, 32);
 
   return cir::LLVMIntrinsicCallOp::create(
-             builder, location,
-             builder.getStringAttr("prefetch"), voidTy,
+             builder, location, builder.getStringAttr("prefetch"), voidTy,
              mlir::ValueRange{address, rw, locality, data})
       .getResult();
 }
 
-
 mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
                                                const CallExpr *e) {
   if (builtinID == Builtin::BI__builtin_cpu_is) {
@@ -90,14 +79,14 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
 
   // `ICEArguments` is a bitmap indicating whether the argument at the i-th bit
   // is required to be a constant integer expression.
-  unsigned ICEArguments = 0;
+  unsigned iceArguments = 0;
   ASTContext::GetBuiltinTypeError error;
-  getContext().GetBuiltinType(builtinID, error, &ICEArguments);
+  getContext().GetBuiltinType(builtinID, error, &iceArguments);
   assert(error == ASTContext::GE_None && "Error while getting builtin type.");
 
   const unsigned numArgs = e->getNumArgs();
   for (unsigned i = 0; i != numArgs; i++) {
-    ops.push_back(emitScalarOrConstFoldImmArg(ICEArguments, i, e));
+    ops.push_back(emitScalarOrConstFoldImmArg(iceArguments, i, e));
   }
 
   switch (builtinID) {
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index f4379b402fe13..db00dff582401 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -321,14 +321,24 @@ static mlir::LLVM::CallIntrinsicOp 
replaceOpWithCallLLVMIntrinsicOp(
 }
 
 mlir::LogicalResult CIRToLLVMLLVMIntrinsicCallOpLowering::matchAndRewrite(
-    cir::LLVMIntrinsicCallOp op,
-    OpAdaptor adaptor,
+    cir::LLVMIntrinsicCallOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
   mlir::Type llvmResTy =
       getTypeConverter()->convertType(op->getResultTypes()[0]);
   if (!llvmResTy)
     return op.emitError("expected LLVM result type");
   StringRef name = op.getIntrinsicName();
+  
+  // Some LLVM intrinsics require ElementType attribute to be attached to
+  // the argument of pointer type. That prevents us from generating LLVM IR
+  // because from LLVM dialect, we have LLVM IR like the below which fails
+  // LLVM IR verification.
+  // %3 = call i64 @llvm.aarch64.ldxr.p0(ptr %2)
+  // The expected LLVM IR should be like
+  // %3 = call i64 @llvm.aarch64.ldxr.p0(ptr elementtype(i32) %2)
+  // TODO(cir): MLIR LLVM dialect should handle this part as CIR has no way
+  // to set LLVM IR attribute.
+  assert(!cir::MissingFeatures::intrinsicElementTypeSupport());
   replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm." + name, llvmResTy,
                                    adaptor.getOperands());
   return mlir::success();
diff --git a/clang/test/CIR/CodeGen/X86/sse2-builtins.c 
b/clang/test/CIR/CodeGen/X86/sse2-builtins.c
index 0c275fa089262..c74597e1735b6 100644
--- a/clang/test/CIR/CodeGen/X86/sse2-builtins.c
+++ b/clang/test/CIR/CodeGen/X86/sse2-builtins.c
@@ -18,6 +18,6 @@ void test_mm_clflush(void* A) {
   // CIR-LABEL: test_mm_clflush
   // LLVM-LABEL: teh
   _mm_clflush(A);
-  // CIR-CHECK: {{%.*}} = cir.llvm.intrinsic "x86.sse2.clflush" {{%.*}} : 
(!cir.ptr<!void>) -> !void
+  // CIR-CHECK: {{%.*}} = cir.call_llvm_intrinsic "x86.sse2.clflush" {{%.*}} : 
(!cir.ptr<!void>) -> !void
   // LLVM-CHECK: call void @llvm.x86.sse2.clflush(ptr {{%.*}})
 }

From 9eb51990ae153968e7856dad51c1fb39242f84a6 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Tue, 11 Nov 2025 12:54:05 +0100
Subject: [PATCH 5/5] formatting

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

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index d40466610fc13..2124b1dc62a81 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2598,7 +2598,7 @@ def CIR_FuncOp : CIR_Op<"func", [
 def CIR_LLVMIntrinsicCallOp : CIR_Op<"call_llvm_intrinsic"> {
   let summary = "Call to llvm intrinsic functions that is not defined in CIR";
   let description = [{
-    `cir.llvm.intrinsic` operation represents a call-like expression which has
+    `cir.call_llvm_intrinsic` operation represents a call-like expression 
which has
     return type and arguments that maps directly to a llvm intrinsic.
     It only records intrinsic `intrinsic_name`.
   }];
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 236f487afd9ba..bb64b2ba710f1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1430,14 +1430,14 @@ mlir::Value 
CIRGenFunction::emitPromotedScalarExpr(const Expr *e,
   return ScalarExprEmitter(*this, builder).Visit(const_cast<Expr *>(e));
 }
 
-mlir::Value CIRGenFunction::emitScalarOrConstFoldImmArg(unsigned ICEArguments,
+mlir::Value CIRGenFunction::emitScalarOrConstFoldImmArg(unsigned iceArguments,
                                                         unsigned index,
                                                         const CallExpr *e) {
   mlir::Value arg{};
 
   // The bit at the specified index indicates whether the argument is required
   // to be a constant integer expression.
-  bool isArgRequiredToBeConstant = (ICEArguments & (1 << index));
+  bool isArgRequiredToBeConstant = (iceArguments & (1 << index));
 
   if (!isArgRequiredToBeConstant) {
     arg = emitScalarExpr(e->getArg(index));
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 0ce8714b23e82..885b6d69bd806 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1529,8 +1529,7 @@ class CIRGenFunction : public CIRGenTypeCache {
   mlir::Value emitScalarExpr(const clang::Expr *e,
                              bool ignoreResultAssign = false);
 
-  mlir::Value emitScalarOrConstFoldImmArg(unsigned ICEArguments,
-                                          unsigned index,
+  mlir::Value emitScalarOrConstFoldImmArg(unsigned iceArguments, unsigned 
index,
                                           const CallExpr *e);
 
   mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv,

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

Reply via email to