https://github.com/Luhaocong created 
https://github.com/llvm/llvm-project/pull/171094

- Support CIR codegen for follow X86 builtin: `_ReadWriteBarrier` 
`_ReadBarrier` `_WriteBarrier` `__faststorefence`
- CIR dialect operations maybe have no results, no value will return after 
`emitTargetBuiltinExpr` even if it executes successfully. Using 
`std::optional<mlir::Value>` as return type to reslove this problem.

>From 6d8a10d4c9b8df3ea70d3bf326fefb0eac62633c Mon Sep 17 00:00:00 2001
From: Haocong Lu <[email protected]>
Date: Mon, 8 Dec 2025 11:24:15 +0800
Subject: [PATCH] [CIR][X86] Implement lowering for `readwritebarrier` builtins

- Support CIR codegen for follow X86 builtin:
  `_ReadWriteBarrier`
  `_ReadBarrier`
  `_WriteBarrier`
  `__faststorefence`
- CIR dialect operations maybe have no results, no value will return
  after `emitTargetBuiltinExpr` even if it executes successfully.
  Using `std::optional<mlir::Value>` as return type to reslove this
  problem.
---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |   2 +-
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       |  32 +++--
 .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp  | 112 +++++++++---------
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    |  60 +++++++---
 clang/lib/CIR/CodeGen/CIRGenFunction.h        |  24 ++--
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |   4 +-
 .../test/CIR/CodeGen/ms-barriers-intrinsics.c |  82 +++++++++++++
 7 files changed, 216 insertions(+), 100 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/ms-barriers-intrinsics.c

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index fcc7585cf81a5..e39bc31c3eafa 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -5493,7 +5493,7 @@ def CIR_AtomicClearOp : CIR_Op<"atomic.clear"> {
   }];
 }
 
-def CIR_AtomicFence : CIR_Op<"atomic.fence"> {
+def CIR_AtomicFenceOp : CIR_Op<"atomic.fence"> {
   let summary = "Atomic thread fence";
   let description = [{
     C/C++ Atomic thread fence synchronization primitive. Implements the builtin
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 16c006df6853e..87408fdae80d8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -80,7 +80,7 @@ static mlir::Value makeAtomicFenceValue(CIRGenFunction &cgf,
 
   auto ordering = static_cast<cir::MemOrder>(constOrderingAttr.getUInt());
 
-  cir::AtomicFence::create(
+  cir::AtomicFenceOp::create(
       builder, cgf.getLoc(expr->getSourceRange()), ordering,
       cir::SyncScopeKindAttr::get(&cgf.getMLIRContext(), syncScope));
 
@@ -1352,7 +1352,14 @@ 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 (std::optional<mlir::Value> rst =
+          emitTargetBuiltinExpr(builtinID, e, returnValue)) {
+    mlir::Value v = rst.value();
+    // CIR dialect operations maybe have no results, no value will return
+    // even if it executes successfully.
+    if (!v)
+      return RValue::get(nullptr);
+
     switch (evalKind) {
     case cir::TEK_Scalar:
       if (mlir::isa<cir::VoidType>(v.getType()))
@@ -1373,11 +1380,10 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   return getUndefRValue(e->getType());
 }
 
-static 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
@@ -1386,7 +1392,7 @@ static mlir::Value 
emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
   // EmitStdParUnsupportedBuiltin.
   if (cgf->getLangOpts().HIPStdPar && cgf->getLangOpts().CUDAIsDevice &&
       arch != cgf->getTarget().getTriple().getArch())
-    return {};
+    return std::nullopt;
 
   switch (arch) {
   case llvm::Triple::arm:
@@ -1395,7 +1401,7 @@ static mlir::Value 
emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
   case llvm::Triple::thumbeb:
     // 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;
+    return std::nullopt;
   case llvm::Triple::aarch64:
   case llvm::Triple::aarch64_32:
   case llvm::Triple::aarch64_be:
@@ -1404,7 +1410,7 @@ static mlir::Value 
emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
   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;
+    return std::nullopt;
 
   case llvm::Triple::x86:
   case llvm::Triple::x86_64:
@@ -1426,13 +1432,13 @@ static mlir::Value 
emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
   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 {};
+    return std::nullopt;
   default:
-    return {};
+    return std::nullopt;
   }
 }
 
-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/CIRGenBuiltinAArch64.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
index 5a9ae59ca253a..bfd16c78e369f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
@@ -30,21 +30,22 @@ using namespace clang;
 using namespace clang::CIRGen;
 using namespace llvm;
 
-mlir::Value CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID,
-                                                      const CallExpr *expr) {
+std::optional<mlir::Value>
+CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID,
+                                          const CallExpr *expr) {
   if (builtinID >= SVE::BI__builtin_sve_reinterpret_s8_s8 &&
       builtinID <= SVE::BI__builtin_sve_reinterpret_f64_f64_x4) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   assert(!cir::MissingFeatures::aarch64SVEIntrinsics());
 
   switch (builtinID) {
   default:
-    return {};
+    return std::nullopt;
 
   case SVE::BI__builtin_sve_svreinterpret_b:
   case SVE::BI__builtin_sve_svreinterpret_c:
@@ -163,20 +164,21 @@ mlir::Value 
CIRGenFunction::emitAArch64SVEBuiltinExpr(unsigned builtinID,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   // Unreachable: All cases in the switch above return.
 }
 
-mlir::Value CIRGenFunction::emitAArch64SMEBuiltinExpr(unsigned builtinID,
-                                                      const CallExpr *expr) {
+std::optional<mlir::Value>
+CIRGenFunction::emitAArch64SMEBuiltinExpr(unsigned builtinID,
+                                          const CallExpr *expr) {
   assert(!cir::MissingFeatures::aarch64SMEIntrinsics());
 
   cgm.errorNYI(expr->getSourceRange(),
                std::string("unimplemented AArch64 builtin call: ") +
                    getContext().BuiltinInfo.getName(builtinID));
-  return {};
+  return std::nullopt;
 }
 
 // Some intrinsics are equivalent for codegen.
@@ -574,7 +576,7 @@ static const std::pair<unsigned, unsigned> 
neonEquivalentIntrinsicMap[] = {
      NEON::BI__builtin_neon_vstl1q_lane_s64},
 };
 
-mlir::Value
+std::optional<mlir::Value>
 CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr 
*expr,
                                        ReturnValueSlot returnValue,
                                        llvm::Triple::ArchType arch) {
@@ -590,7 +592,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   switch (builtinID) {
@@ -610,34 +612,34 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_trap) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_get_sme_state) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_rbit) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
   if (builtinID == clang::AArch64::BI__builtin_arm_rbit64) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_clz ||
@@ -645,20 +647,20 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_cls) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
   if (builtinID == clang::AArch64::BI__builtin_arm_cls64) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_rint32zf ||
@@ -666,7 +668,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_rint64zf ||
@@ -674,7 +676,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_rint32xf ||
@@ -682,7 +684,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_rint64xf ||
@@ -690,14 +692,14 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_jcvt) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_ld64b ||
@@ -707,7 +709,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_rndr ||
@@ -715,14 +717,14 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__clear_cache) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if ((builtinID == clang::AArch64::BI__builtin_arm_ldrex ||
@@ -731,14 +733,14 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
   if (builtinID == clang::AArch64::BI__builtin_arm_ldrex ||
       builtinID == clang::AArch64::BI__builtin_arm_ldaex) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if ((builtinID == clang::AArch64::BI__builtin_arm_strex ||
@@ -747,7 +749,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_strex ||
@@ -755,35 +757,35 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__getReg) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__break) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_clrex) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI_ReadWriteBarrier) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   // CRC32
@@ -819,7 +821,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   // Memory Operations (MOPS)
@@ -827,7 +829,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   // Memory Tagging Extensions (MTE) Intrinsics
@@ -857,7 +859,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_arm_rsr ||
@@ -871,7 +873,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI_ReadStatusReg ||
@@ -880,21 +882,21 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI_AddressOfReturnAddress) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__builtin_sponentry) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == clang::AArch64::BI__mulh ||
@@ -902,7 +904,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == AArch64::BI__writex18byte ||
@@ -912,7 +914,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == AArch64::BI__readx18byte ||
@@ -922,7 +924,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == AArch64::BI__addx18byte ||
@@ -936,7 +938,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == AArch64::BI_CopyDoubleFromInt64 ||
@@ -946,7 +948,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == AArch64::BI_CountLeadingOnes ||
@@ -956,7 +958,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == AArch64::BI_CountLeadingSigns ||
@@ -964,7 +966,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, 
const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == AArch64::BI_CountOneBits ||
@@ -972,28 +974,28 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == AArch64::BI__prefetch) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == AArch64::BI__hlt) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   if (builtinID == NEON::BI__builtin_neon_vcvth_bf16_f32) {
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   // Handle MSVC intrinsics before argument evaluation to prevent double
@@ -1199,7 +1201,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   // Not all intrinsics handled by the common case work for AArch64 yet, so 
only
@@ -1210,7 +1212,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
 
   switch (builtinID) {
   default:
-    return {};
+    return std::nullopt;
   case NEON::BI__builtin_neon_vbsl_v:
   case NEON::BI__builtin_neon_vbslq_v:
   case NEON::BI__builtin_neon_vfma_lane_v:
@@ -1576,7 +1578,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 
   // Unreachable: All cases in the switch above return.
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 1c1ef4da20b0d..d3d026fa7da5c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -370,19 +370,19 @@ static mlir::Value emitX86vpcom(CIRGenBuilderTy &builder, 
mlir::Location loc,
   return builder.createVecCompare(loc, pred, op0, op1);
 }
 
-mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
-                                               const CallExpr *expr) {
+std::optional<mlir::Value>
+CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
   if (builtinID == Builtin::BI__builtin_cpu_is) {
     cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_is");
-    return {};
+    return std::nullopt;
   }
   if (builtinID == Builtin::BI__builtin_cpu_supports) {
     cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_supports");
-    return {};
+    return std::nullopt;
   }
   if (builtinID == Builtin::BI__builtin_cpu_init) {
     cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_init");
-    return {};
+    return std::nullopt;
   }
 
   // Handle MSVC intrinsics before argument evaluation to prevent double
@@ -410,7 +410,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
 
   switch (builtinID) {
   default:
-    return {};
+    return std::nullopt;
   case X86::BI_mm_clflush:
     return emitIntrinsicCallOp(builder, getLoc(expr->getExprLoc()),
                                "x86.sse2.clflush", voidTy, ops[0]);
@@ -432,7 +432,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented X86 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
   case X86::BI__builtin_ia32_lzcnt_u16:
   case X86::BI__builtin_ia32_lzcnt_u32:
@@ -751,7 +751,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented X86 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   case X86::BI__builtin_ia32_gather3div2df:
   case X86::BI__builtin_ia32_gather3div2di:
   case X86::BI__builtin_ia32_gather3div4df:
@@ -1018,7 +1018,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented X86 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   case X86::BI__builtin_ia32_pshuflw:
   case X86::BI__builtin_ia32_pshuflw256:
   case X86::BI__builtin_ia32_pshuflw512:
@@ -1093,7 +1093,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented X86 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   case X86::BI__builtin_ia32_kshiftliqi:
   case X86::BI__builtin_ia32_kshiftlihi:
   case X86::BI__builtin_ia32_kshiftlisi:
@@ -1217,7 +1217,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented X86 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   case X86::BI__builtin_ia32_vpcomb:
   case X86::BI__builtin_ia32_vpcomw:
   case X86::BI__builtin_ia32_vpcomd:
@@ -1353,7 +1353,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented X86 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   case X86::BI__builtin_ia32_pmuludq128:
   case X86::BI__builtin_ia32_pmuludq256:
   case X86::BI__builtin_ia32_pmuludq512: {
@@ -1467,7 +1467,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented X86 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   case X86::BI__builtin_ia32_cmpnltps:
   case X86::BI__builtin_ia32_cmpnltpd:
     return emitVectorFCmp(builder, ops, getLoc(expr->getExprLoc()),
@@ -1523,13 +1523,37 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
   case X86::BI__mulh:
   case X86::BI__umulh:
   case X86::BI_mul128:
-  case X86::BI_umul128:
-  case X86::BI__faststorefence:
+  case X86::BI_umul128: {
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented X86 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return std::nullopt;
+  }
+  case X86::BI__faststorefence: {
+    cir::AtomicFenceOp::create(
+        builder, getLoc(expr->getExprLoc()),
+        cir::MemOrder::SequentiallyConsistent,
+        cir::SyncScopeKindAttr::get(&getMLIRContext(),
+                                    cir::SyncScopeKind::System));
+    return mlir::Value{};
+  }
   case X86::BI__shiftleft128:
-  case X86::BI__shiftright128:
+  case X86::BI__shiftright128: {
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented X86 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return std::nullopt;
+  }
   case X86::BI_ReadWriteBarrier:
   case X86::BI_ReadBarrier:
-  case X86::BI_WriteBarrier:
+  case X86::BI_WriteBarrier: {
+    cir::AtomicFenceOp::create(
+        builder, getLoc(expr->getExprLoc()),
+        cir::MemOrder::SequentiallyConsistent,
+        cir::SyncScopeKindAttr::get(&getMLIRContext(),
+                                    cir::SyncScopeKind::SingleThread));
+    return mlir::Value{};
+  }
   case X86::BI_AddressOfReturnAddress:
   case X86::BI__stosb:
   case X86::BI__ud2:
@@ -1562,6 +1586,6 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned 
builtinID,
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented X86 builtin call: ") +
                      getContext().BuiltinInfo.getName(builtinID));
-    return {};
+    return std::nullopt;
   }
 }
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 0df812bcfb94e..6690f86acff15 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1248,13 +1248,14 @@ class CIRGenFunction : public CIRGenTypeCache {
   /// CIR emit functions
   /// ----------------------
 public:
-  mlir::Value emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr,
-                                     ReturnValueSlot returnValue,
-                                     llvm::Triple::ArchType arch);
-  mlir::Value emitAArch64SMEBuiltinExpr(unsigned builtinID,
-                                        const CallExpr *expr);
-  mlir::Value emitAArch64SVEBuiltinExpr(unsigned builtinID,
-                                        const CallExpr *expr);
+  std::optional<mlir::Value>
+  emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr,
+                         ReturnValueSlot returnValue,
+                         llvm::Triple::ArchType arch);
+  std::optional<mlir::Value> emitAArch64SMEBuiltinExpr(unsigned builtinID,
+                                                       const CallExpr *expr);
+  std::optional<mlir::Value> emitAArch64SVEBuiltinExpr(unsigned builtinID,
+                                                       const CallExpr *expr);
 
   mlir::Value emitAlignmentAssumption(mlir::Value ptrValue, QualType ty,
                                       SourceLocation loc,
@@ -1814,9 +1815,9 @@ class CIRGenFunction : public CIRGenTypeCache {
                                      bool buildingTopLevelCase);
   mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s);
 
-  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.
@@ -1856,7 +1857,8 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   mlir::LogicalResult emitWhileStmt(const clang::WhileStmt &s);
 
-  mlir::Value emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr);
+  std::optional<mlir::Value> emitX86BuiltinExpr(unsigned builtinID,
+                                                const CallExpr *expr);
 
   /// 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/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 97bd3cf850daa..c8b395b1feb93 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -860,8 +860,8 @@ mlir::LogicalResult 
CIRToLLVMAtomicClearOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
-mlir::LogicalResult CIRToLLVMAtomicFenceLowering::matchAndRewrite(
-    cir::AtomicFence op, OpAdaptor adaptor,
+mlir::LogicalResult CIRToLLVMAtomicFenceOpLowering::matchAndRewrite(
+    cir::AtomicFenceOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
   mlir::LLVM::AtomicOrdering llvmOrder = 
getLLVMMemOrder(adaptor.getOrdering());
 
diff --git a/clang/test/CIR/CodeGen/ms-barriers-intrinsics.c 
b/clang/test/CIR/CodeGen/ms-barriers-intrinsics.c
new file mode 100644
index 0000000000000..f316307ec35d2
--- /dev/null
+++ b/clang/test/CIR/CodeGen/ms-barriers-intrinsics.c
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -Wno-implicit-function-declaration 
-fclangir -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefixes=CIR,CIR-X86 --input-file=%t.cir %s
+// RUN: %clang_cc1 -x c++ -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -Wno-implicit-function-declaration 
-fclangir -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefixes=CIR,CIR-X86 --input-file=%t.cir %s
+
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -Wno-implicit-function-declaration 
-fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --check-prefixes=LLVM,LLVM-X86 --input-file=%t.ll %s
+// RUN: %clang_cc1 -x c++ -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -Wno-implicit-function-declaration 
-fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --check-prefixes=LLVM,LLVM-X86 --input-file=%t.ll %s
+
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -emit-llvm -Wall -Werror %s -o - \
+// RUN:   | FileCheck %s --check-prefixes=OGCG,OGCG-X86
+// RUN: %clang_cc1 -x c++ -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -emit-llvm -Wall -Werror %s -o - \
+// RUN:   | FileCheck %s --check-prefixes=OGCG,OGCG-X86
+
+// This test copies clang/test/CodeGen/ms-barriers-intrinsics.c.
+
+void _ReadWriteBarrier(void);
+void _ReadBarrier(void);
+void _WriteBarrier(void);
+void __faststorefence(void);
+
+void test_ReadWriteBarrier(void) { _ReadWriteBarrier(); }
+// CIR-LABEL: test_ReadWriteBarrier
+// CIR:  cir.atomic.fence syncscope(single_thread) seq_cst
+// CIR:  cir.return
+
+// LLVM-LABEL: test_ReadWriteBarrier
+// LLVM: fence syncscope("singlethread") seq_cst
+// LLVM: ret void
+
+// OGCG-LABEL: test_ReadWriteBarrier
+// OGCG: fence syncscope("singlethread") seq_cst
+// OGCG: ret void
+
+void test_ReadBarrier(void) { _ReadBarrier(); }
+// CIR-LABEL: test_ReadBarrier
+// CIR:  cir.atomic.fence syncscope(single_thread) seq_cst
+// CIR:  cir.return
+
+// LLVM-LABEL: test_ReadBarrier
+// LLVM: fence syncscope("singlethread") seq_cst
+// LLVM: ret void
+
+// OGCG-LABEL: test_ReadBarrier
+// OGCG: fence syncscope("singlethread") seq_cst
+// OGCG: ret void
+
+void test_WriteBarrier(void) { _WriteBarrier(); }
+// CIR-LABEL: test_WriteBarrier
+// CIR:  cir.atomic.fence syncscope(single_thread) seq_cst
+// CIR:  cir.return
+
+// LLVM-LABEL: test_WriteBarrier
+// LLVM: fence syncscope("singlethread") seq_cst
+// LLVM: ret void
+
+// OGCG-LABEL: test_WriteBarrier
+// OGCG: fence syncscope("singlethread") seq_cst
+// OGCG: ret void
+
+#if defined(__x86_64__)
+void test__faststorefence(void) { __faststorefence(); }
+// CIR-X86-LABEL: test__faststorefence
+// CIR-X86:  cir.atomic.fence syncscope(system) seq_cst
+// CIR-X86:  cir.return
+
+// LLVM-X86-LABEL: test__faststorefence
+// LLVM-X86: fence seq_cst
+// LLVM-X86: ret void
+
+// OGCG-X86-LABEL: test__faststorefence
+// OGCG-X86: fence seq_cst
+// OGCG-X86: ret void
+#endif
+

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

Reply via email to