[clang] [CIR] Proper lowering of atomic sync scope to LLVM (PR #173393)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 23 08:37:25 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Sirui Mu (Lancern)
<details>
<summary>Changes</summary>
This patch sets up a framework to properly lower atomic sync scopes from CIR to LLVM. Since the lowering is target-specific, this patch first upstreams a minimum implementation of the TargetLoweringInfo class. It then adds a virtual function there to handle the lowering of atomic sync scopes in a target-specific way.
---
Full diff: https://github.com/llvm/llvm-project/pull/173393.diff
8 Files Affected:
- (modified) clang/include/clang/CIR/MissingFeatures.h (+1)
- (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt (+1)
- (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp (+13)
- (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h (+4)
- (added) clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp (+25)
- (added) clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h (+31)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+14-6)
- (modified) clang/test/CIR/CodeGen/atomic-scoped.c (+4-4)
``````````diff
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index acfc937a11993..fbfb47070f95f 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -193,6 +193,7 @@ struct MissingFeatures {
// LowerModule handling
static bool lowerModuleCodeGenOpts() { return false; }
static bool lowerModuleLangOpts() { return false; }
+ static bool targetLoweringInfo() { return false; }
// Misc
static bool aarch64SIMDIntrinsics() { return false; }
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt
index 158c42e729536..17941359a5e83 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt
@@ -2,6 +2,7 @@ add_clang_library(MLIRCIRTargetLowering
CIRCXXABI.cpp
LowerModule.cpp
LowerItaniumCXXABI.cpp
+ TargetLoweringInfo.cpp
DEPENDS
clangBasic
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp
index 7576e20ac8f54..e39b764f6a838 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp
@@ -20,6 +20,7 @@
#include "clang/Basic/TargetOptions.h"
#include "clang/CIR/MissingFeatures.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
namespace cir {
@@ -43,6 +44,12 @@ static std::unique_ptr<CIRCXXABI> createCXXABI(LowerModule &lm) {
llvm_unreachable("invalid C++ ABI kind");
}
+static std::unique_ptr<TargetLoweringInfo>
+createTargetLoweringInfo(LowerModule &lm) {
+ assert(!cir::MissingFeatures::targetLoweringInfo());
+ return std::make_unique<TargetLoweringInfo>();
+}
+
LowerModule::LowerModule(clang::LangOptions langOpts,
clang::CodeGenOptions codeGenOpts,
mlir::ModuleOp &module,
@@ -51,6 +58,12 @@ LowerModule::LowerModule(clang::LangOptions langOpts,
: module(module), target(std::move(target)), abi(createCXXABI(*this)),
rewriter(rewriter) {}
+const TargetLoweringInfo &LowerModule::getTargetLoweringInfo() {
+ if (!targetLoweringInfo)
+ targetLoweringInfo = createTargetLoweringInfo(*this);
+ return *targetLoweringInfo;
+}
+
// TODO: not to create it every time
std::unique_ptr<LowerModule>
createLowerModule(mlir::ModuleOp module, mlir::PatternRewriter &rewriter) {
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h
index 440e307f571e9..560bf87c76c11 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h
@@ -15,6 +15,7 @@
#define CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_LOWERMODULE_H
#include "CIRCXXABI.h"
+#include "TargetLoweringInfo.h"
#include "mlir/IR/BuiltinOps.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/LangOptions.h"
@@ -28,6 +29,7 @@ namespace cir {
class LowerModule {
mlir::ModuleOp module;
const std::unique_ptr<clang::TargetInfo> target;
+ std::unique_ptr<TargetLoweringInfo> targetLoweringInfo;
std::unique_ptr<CIRCXXABI> abi;
[[maybe_unused]] mlir::PatternRewriter &rewriter;
@@ -45,6 +47,8 @@ class LowerModule {
CIRCXXABI &getCXXABI() const { return *abi; }
const clang::TargetInfo &getTarget() const { return *target; }
mlir::MLIRContext *getMLIRContext() { return module.getContext(); }
+
+ const TargetLoweringInfo &getTargetLoweringInfo();
};
std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module,
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp
new file mode 100644
index 0000000000000..b9b756077da04
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp
@@ -0,0 +1,25 @@
+//===---- TargetLoweringInfo.cpp - Encapsulate target details ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file partially mimics the TargetCodeGenInfo class from the file
+// clang/lib/CodeGen/TargetInfo.cpp.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TargetLoweringInfo.h"
+
+namespace cir {
+
+TargetLoweringInfo::~TargetLoweringInfo() = default;
+
+std::string
+TargetLoweringInfo::getLLVMSyncScope(cir::SyncScopeKind syncScope) const {
+ return ""; // default sync scope
+}
+
+} // namespace cir
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h
new file mode 100644
index 0000000000000..91e7eb79ec83e
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h
@@ -0,0 +1,31 @@
+//===---- TargetLoweringInfo.h - Encapsulate target details -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file partially mimics the TargetCodeGenInfo class from the file
+// clang/lib/CodeGen/TargetInfo.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_TARGETLOWERINGINFO_H
+#define LLVM_CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_TARGETLOWERINGINFO_H
+
+#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
+#include <string>
+
+namespace cir {
+
+class TargetLoweringInfo {
+public:
+ virtual ~TargetLoweringInfo();
+
+ virtual std::string getLLVMSyncScope(cir::SyncScopeKind syncScope) const;
+};
+
+} // namespace cir
+
+#endif
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 998c93efb768a..1406c12b424c1 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1721,13 +1721,17 @@ mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite(
// TODO: nontemporal.
assert(!cir::MissingFeatures::opLoadStoreNontemporal());
- std::optional<llvm::StringRef> syncScope =
- getLLVMSyncScope(op.getSyncScope());
+
+ std::optional<std::string> llvmSyncScope;
+ if (std::optional<cir::SyncScopeKind> syncScope = op.getSyncScope())
+ llvmSyncScope =
+ lowerMod->getTargetLoweringInfo().getLLVMSyncScope(*syncScope);
+
mlir::LLVM::LoadOp newLoad = mlir::LLVM::LoadOp::create(
rewriter, op->getLoc(), llvmTy, adaptor.getAddr(), alignment,
op.getIsVolatile(), /*isNonTemporal=*/false,
/*isInvariant=*/false, /*isInvariantGroup=*/false, ordering,
- syncScope.value_or(llvm::StringRef()));
+ llvmSyncScope.value_or(std::string()));
// Convert adapted result to its original type if needed.
mlir::Value result =
@@ -1755,13 +1759,17 @@ mlir::LogicalResult CIRToLLVMStoreOpLowering::matchAndRewrite(
// TODO: nontemporal.
assert(!cir::MissingFeatures::opLoadStoreNontemporal());
assert(!cir::MissingFeatures::opLoadStoreTbaa());
- std::optional<llvm::StringRef> syncScope =
- getLLVMSyncScope(op.getSyncScope());
+
+ std::optional<std::string> llvmSyncScope;
+ if (std::optional<cir::SyncScopeKind> syncScope = op.getSyncScope())
+ llvmSyncScope =
+ lowerMod->getTargetLoweringInfo().getLLVMSyncScope(*syncScope);
+
mlir::LLVM::StoreOp storeOp = mlir::LLVM::StoreOp::create(
rewriter, op->getLoc(), value, adaptor.getAddr(), alignment,
op.getIsVolatile(),
/*isNonTemporal=*/false, /*isInvariantGroup=*/false, memorder,
- syncScope.value_or(llvm::StringRef()));
+ llvmSyncScope.value_or(std::string()));
rewriter.replaceOp(op, storeOp);
assert(!cir::MissingFeatures::opLoadStoreTbaa());
return mlir::LogicalResult::success();
diff --git a/clang/test/CIR/CodeGen/atomic-scoped.c b/clang/test/CIR/CodeGen/atomic-scoped.c
index 5b8c868d6c9d6..62d075c21a893 100644
--- a/clang/test/CIR/CodeGen/atomic-scoped.c
+++ b/clang/test/CIR/CodeGen/atomic-scoped.c
@@ -13,7 +13,7 @@ void scoped_atomic_load(int *ptr) {
int x;
__scoped_atomic_load(ptr, &x, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
// CIR: %{{.+}} = cir.load align(4) syncscope(single_thread) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i
- // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} syncscope("singlethread") monotonic, align 4
+ // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4
// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4
__scoped_atomic_load(ptr, &x, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
@@ -30,7 +30,7 @@ void scoped_atomic_load_n(int *ptr) {
int x;
x = __scoped_atomic_load_n(ptr, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
// CIR: %{{.+}} = cir.load align(4) syncscope(single_thread) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i
- // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} syncscope("singlethread") monotonic, align 4
+ // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4
// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4
x = __scoped_atomic_load_n(ptr, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
@@ -46,7 +46,7 @@ void scoped_atomic_store(int *ptr, int value) {
__scoped_atomic_store(ptr, &value, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
// CIR: cir.store align(4) syncscope(single_thread) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>
- // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} syncscope("singlethread") monotonic, align 4
+ // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4
// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4
__scoped_atomic_store(ptr, &value, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
@@ -62,7 +62,7 @@ void scoped_atomic_store_n(int *ptr, int value) {
__scoped_atomic_store_n(ptr, value, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
// CIR: cir.store align(4) syncscope(single_thread) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>
- // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} syncscope("singlethread") monotonic, align 4
+ // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4
// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4
__scoped_atomic_store_n(ptr, value, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
``````````
</details>
https://github.com/llvm/llvm-project/pull/173393
More information about the cfe-commits
mailing list