https://github.com/Lancern updated https://github.com/llvm/llvm-project/pull/179245
>From 2451ea73592be43663dd75426f785e4055d09857 Mon Sep 17 00:00:00 2001 From: Sirui Mu <[email protected]> Date: Mon, 2 Feb 2026 22:28:57 +0800 Subject: [PATCH] [CIR][NFC] Add TargetLowering pass This patch adds TargetLowering pass to the CIR pipeline. This new pass does not perform any heavy transformations yet -- for now it only converts sync scopes attached to load and store operations according to the target info, which was done in the LLVM lowering pass. Related to #175968 . --- clang/include/clang/CIR/Dialect/Passes.h | 2 + clang/include/clang/CIR/Dialect/Passes.td | 63 ++++++++++++++++- .../lib/CIR/Dialect/Transforms/CMakeLists.txt | 1 + .../CIR/Dialect/Transforms/CXXABILowering.cpp | 25 +++---- .../CIR/Dialect/Transforms/TargetLowering.cpp | 68 +++++++++++++++++++ .../Transforms/TargetLowering/LowerModule.cpp | 18 ++--- .../Transforms/TargetLowering/LowerModule.h | 8 +-- .../TargetLowering/TargetLoweringInfo.cpp | 7 +- .../TargetLowering/TargetLoweringInfo.h | 4 +- clang/lib/CIR/Lowering/CIRPasses.cpp | 1 + .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 26 ++----- clang/test/CIR/CodeGen/atomic-scoped.c | 20 ++++-- 12 files changed, 183 insertions(+), 60 deletions(-) create mode 100644 clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp diff --git a/clang/include/clang/CIR/Dialect/Passes.h b/clang/include/clang/CIR/Dialect/Passes.h index 98eaf884347ed..161f365bb1402 100644 --- a/clang/include/clang/CIR/Dialect/Passes.h +++ b/clang/include/clang/CIR/Dialect/Passes.h @@ -18,12 +18,14 @@ namespace clang { class ASTContext; } + namespace mlir { std::unique_ptr<Pass> createCIRCanonicalizePass(); std::unique_ptr<Pass> createCIRFlattenCFGPass(); std::unique_ptr<Pass> createCIRSimplifyPass(); std::unique_ptr<Pass> createCXXABILoweringPass(); +std::unique_ptr<Pass> createTargetLoweringPass(); std::unique_ptr<Pass> createHoistAllocasPass(); std::unique_ptr<Pass> createLoweringPreparePass(); std::unique_ptr<Pass> createLoweringPreparePass(clang::ASTContext *astCtx); diff --git a/clang/include/clang/CIR/Dialect/Passes.td b/clang/include/clang/CIR/Dialect/Passes.td index 48c409fa83cee..c5b7c34ea849e 100644 --- a/clang/include/clang/CIR/Dialect/Passes.td +++ b/clang/include/clang/CIR/Dialect/Passes.td @@ -83,15 +83,72 @@ def GotoSolver : Pass<"cir-goto-solver"> { } def CXXABILowering : Pass<"cir-cxxabi-lowering", "mlir::ModuleOp"> { - let summary = "Lower abstract C++ operations to target-specific ABI form"; + let summary = "Lower CIR according to C++ ABI requirements"; let description = [{ - This pass lowers high-level operations that represent C++ constructs in a - target-independent way to concrete, target specific operations. + This pass lowers CIR operations and types that represent high-level C/C++ + constructs to a more fundamental form according to the target ABI + requirements. + + See the description of the `TargetLowering` pass for the difference between + this pass and the `TargetLowering` pass. }]; let constructor = "mlir::createCXXABILoweringPass()"; let dependentDialects = ["cir::CIRDialect"]; } +def TargetLowering : Pass<"cir-target-lowering", "mlir::ModuleOp"> { + let summary = "Lower CIR to a target-specific form"; + let description = [{ + This pass lowers CIR operations from a target-agnostic form to a + target-specific form without considering ABI requirements. + + CIR has three passes in its lowering pipeline that transform input CIR + according to target-specific requirements, scheduled in the pipeline by the + following order: + + 1. The `TargetLowering` pass. + 2. The `CXXABILowering` pass. + 3. The `CallConvLowering` pass (not implemented yet). + + The `TargetLowering` pass acts more like a legalization pass. It ensures + every operation in CIR conforms to the target's constraints. An example + would be the handling of synchronization scopes of atomic operations. The + x86 family of targets only support a system-wide synchronization scope, thus + any atomic operations with a different synchronization scope would be + transformed to use the system-wide scope in this pass. + + The `CXXABILowering` pass and the (not yet implemented) `CallConvLowering` + pass transform the CIR according to the target's ABI requirements. The + former handles all ABI-related lowering except for calling convention + handling, which is handled specifically in the latter. Example + transformations that the `CXXABILowering` pass could make include: + + - Replace C/C++ types that have an ABI-defined layout with more + fundamental types corresponding to the ABI requirements. For example, + the layout of the pointer-to-data-member type in C++ is ABI-defined, + thus the `CXXABILowering` pass would expand all occurrences of this type + according to the ABI requirements. With a typical target ABI, it will be + replaced by the `ptrdiff_t` type since this is the type most ABIs use + for the layout of the pointer-to-data-member type. + - Replace CIR operations that have ABI-dependent implementations with more + fundamental operations. For example, the `dynamic_cast` operator in C++ + is implemented in an ABI-dependent way, typically by calling into a + library function provided by the implementation. The `CXXABILowering` + pass would thus replace all `cir.dyn_cast` operations with corresponding + library function calls. + + The `CallConvLowering` pass is dedicated to handle calling conventions. It + rewrites function signatures according to calling convention requirements, + and updates function body and call sites accordingly. For example, when + passing a large struct by value in C/C++, most ABIs require passing a + pointer to a copy of the struct instead. Thus, the `CallConvLowering` pass + would rewrite function signatures that take a value of a large struct type + to take a pointer to the struct type instead, and update the function body + and the call sites accordingly. + }]; + let constructor = "mlir::createTargetLoweringPass()"; + let dependentDialects = ["cir::CIRDialect"]; +} def LoweringPrepare : Pass<"cir-lowering-prepare"> { let summary = "Lower to more fine-grained CIR operations before lowering to " diff --git a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt index 34d95a92c3bfe..1ace2d8634b40 100644 --- a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt +++ b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt @@ -4,6 +4,7 @@ add_clang_library(MLIRCIRTransforms CIRCanonicalize.cpp CIRSimplify.cpp CXXABILowering.cpp + TargetLowering.cpp FlattenCFG.cpp HoistAllocas.cpp LoweringPrepare.cpp diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp index f0e473a6574c7..cc6a6544a529a 100644 --- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp @@ -453,21 +453,18 @@ populateCXXABIConversionTarget(mlir::ConversionTarget &target, //===----------------------------------------------------------------------===// void CXXABILoweringPass::runOnOperation() { - auto module = mlir::cast<mlir::ModuleOp>(getOperation()); - mlir::MLIRContext *ctx = module.getContext(); - - // If the triple is not present, e.g. CIR modules parsed from text, we - // cannot init LowerModule properly. - assert(!cir::MissingFeatures::makeTripleAlwaysPresent()); - // If no target triple is available, skip the ABI lowering pass. - if (!module->hasAttr(cir::CIRDialect::getTripleAttrName())) + auto mod = mlir::cast<mlir::ModuleOp>(getOperation()); + mlir::MLIRContext *ctx = mod.getContext(); + + std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule(mod); + // If lower module is not available, skip the ABI lowering pass. + if (!lowerModule) { + mod.emitWarning("Cannot create a CIR lower module, skipping the ") + << getName() << " pass"; return; + } - mlir::PatternRewriter rewriter(ctx); - std::unique_ptr<cir::LowerModule> lowerModule = - cir::createLowerModule(module, rewriter); - - mlir::DataLayout dataLayout(module); + mlir::DataLayout dataLayout(mod); mlir::TypeConverter typeConverter; prepareCXXABITypeConverter(typeConverter, dataLayout, *lowerModule); @@ -483,7 +480,7 @@ void CXXABILoweringPass::runOnOperation() { mlir::ConversionTarget target(*ctx); populateCXXABIConversionTarget(target, typeConverter); - if (failed(mlir::applyPartialConversion(module, target, std::move(patterns)))) + if (failed(mlir::applyPartialConversion(mod, target, std::move(patterns)))) signalPassFailure(); } diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp new file mode 100644 index 0000000000000..656f29dab4e92 --- /dev/null +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp @@ -0,0 +1,68 @@ +//===- TargetLowering.cpp -------------------------------------------------===// +// +// 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 implements the cir-target-lowering pass. +// +//===----------------------------------------------------------------------===// + +#include "TargetLowering/LowerModule.h" + +#include "mlir/Support/LLVM.h" +#include "clang/CIR/Dialect/Passes.h" +#include "llvm/ADT/TypeSwitch.h" + +using namespace mlir; +using namespace cir; + +namespace mlir { +#define GEN_PASS_DEF_TARGETLOWERING +#include "clang/CIR/Dialect/Passes.h.inc" +} // namespace mlir + +namespace { + +struct TargetLoweringPass + : public impl::TargetLoweringBase<TargetLoweringPass> { + TargetLoweringPass() = default; + void runOnOperation() override; +}; + +} // namespace + +static void convertSyncScopeIfPresent(mlir::Operation *op, + cir::LowerModule &lowerModule) { + auto syncScopeAttr = + mlir::cast_if_present<cir::SyncScopeKindAttr>(op->getAttr("sync_scope")); + if (syncScopeAttr) { + cir::SyncScopeKind convertedSyncScope = + lowerModule.getTargetLoweringInfo().convertSyncScope( + syncScopeAttr.getValue()); + op->setAttr("sync_scope", cir::SyncScopeKindAttr::get(op->getContext(), + convertedSyncScope)); + } +} + +void TargetLoweringPass::runOnOperation() { + auto mod = mlir::cast<mlir::ModuleOp>(getOperation()); + std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule(mod); + // If lower module is not available, skip the target lowering pass. + if (!lowerModule) { + mod.emitWarning("Cannot create a CIR lower module, skipping the ") + << getName() << " pass"; + return; + } + + mod->walk([&](mlir::Operation *op) { + if (mlir::isa<cir::LoadOp, cir::StoreOp>(op)) + convertSyncScopeIfPresent(op, *lowerModule); + }); +} + +std::unique_ptr<Pass> mlir::createTargetLoweringPass() { + return std::make_unique<TargetLoweringPass>(); +} diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index e39b764f6a838..f2398e3105578 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -14,7 +14,6 @@ #include "LowerModule.h" #include "CIRCXXABI.h" #include "mlir/IR/BuiltinAttributes.h" -#include "mlir/IR/PatternMatch.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" @@ -53,10 +52,8 @@ createTargetLoweringInfo(LowerModule &lm) { LowerModule::LowerModule(clang::LangOptions langOpts, clang::CodeGenOptions codeGenOpts, mlir::ModuleOp &module, - std::unique_ptr<clang::TargetInfo> target, - mlir::PatternRewriter &rewriter) - : module(module), target(std::move(target)), abi(createCXXABI(*this)), - rewriter(rewriter) {} + std::unique_ptr<clang::TargetInfo> target) + : module(module), target(std::move(target)), abi(createCXXABI(*this)) {} const TargetLoweringInfo &LowerModule::getTargetLoweringInfo() { if (!targetLoweringInfo) @@ -65,8 +62,13 @@ const TargetLoweringInfo &LowerModule::getTargetLoweringInfo() { } // TODO: not to create it every time -std::unique_ptr<LowerModule> -createLowerModule(mlir::ModuleOp module, mlir::PatternRewriter &rewriter) { +std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module) { + // If the triple is not present, e.g. CIR modules parsed from text, we + // cannot init LowerModule properly. + assert(!cir::MissingFeatures::makeTripleAlwaysPresent()); + if (!module->hasAttr(cir::CIRDialect::getTripleAttrName())) + return nullptr; + // Fetch target information. llvm::Triple triple(mlir::cast<mlir::StringAttr>( module->getAttr(cir::CIRDialect::getTripleAttrName())) @@ -94,7 +96,7 @@ createLowerModule(mlir::ModuleOp module, mlir::PatternRewriter &rewriter) { return std::make_unique<LowerModule>(std::move(langOpts), std::move(codeGenOpts), module, - std::move(targetInfo), rewriter); + std::move(targetInfo)); } } // namespace cir diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h index 560bf87c76c11..ab3a648683279 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h @@ -31,12 +31,11 @@ class LowerModule { const std::unique_ptr<clang::TargetInfo> target; std::unique_ptr<TargetLoweringInfo> targetLoweringInfo; std::unique_ptr<CIRCXXABI> abi; - [[maybe_unused]] mlir::PatternRewriter &rewriter; public: LowerModule(clang::LangOptions langOpts, clang::CodeGenOptions codeGenOpts, - mlir::ModuleOp &module, std::unique_ptr<clang::TargetInfo> target, - mlir::PatternRewriter &rewriter); + mlir::ModuleOp &module, + std::unique_ptr<clang::TargetInfo> target); ~LowerModule() = default; clang::TargetCXXABI::Kind getCXXABIKind() const { @@ -51,8 +50,7 @@ class LowerModule { const TargetLoweringInfo &getTargetLoweringInfo(); }; -std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module, - mlir::PatternRewriter &rewriter); +std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module); } // namespace cir diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp index b9b756077da04..5ecdb8d587552 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp @@ -17,9 +17,10 @@ namespace cir { TargetLoweringInfo::~TargetLoweringInfo() = default; -std::string -TargetLoweringInfo::getLLVMSyncScope(cir::SyncScopeKind syncScope) const { - return ""; // default sync scope +cir::SyncScopeKind +TargetLoweringInfo::convertSyncScope(cir::SyncScopeKind syncScope) const { + // By default, targets don't deal with sync scopes other than system scope. + return cir::SyncScopeKind::System; } } // namespace cir diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h index 91e7eb79ec83e..760c3b0b7cc5e 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h @@ -15,7 +15,6 @@ #define LLVM_CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_TARGETLOWERINGINFO_H #include "clang/CIR/Dialect/IR/CIROpsEnums.h" -#include <string> namespace cir { @@ -23,7 +22,8 @@ class TargetLoweringInfo { public: virtual ~TargetLoweringInfo(); - virtual std::string getLLVMSyncScope(cir::SyncScopeKind syncScope) const; + virtual cir::SyncScopeKind + convertSyncScope(cir::SyncScopeKind syncScope) const; }; } // namespace cir diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp index 72348ff6287b4..589c2c524c305 100644 --- a/clang/lib/CIR/Lowering/CIRPasses.cpp +++ b/clang/lib/CIR/Lowering/CIRPasses.cpp @@ -31,6 +31,7 @@ mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule, if (enableCIRSimplify) pm.addPass(mlir::createCIRSimplifyPass()); + pm.addPass(mlir::createTargetLoweringPass()); pm.addPass(mlir::createCXXABILoweringPass()); pm.addPass(mlir::createLoweringPreparePass(&astContext)); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 0e50d9c595564..c11b0eb9dd1d0 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1777,10 +1777,8 @@ mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite( // TODO: nontemporal. assert(!cir::MissingFeatures::opLoadStoreNontemporal()); - std::optional<std::string> llvmSyncScope; - if (std::optional<cir::SyncScopeKind> syncScope = op.getSyncScope()) - llvmSyncScope = - lowerMod->getTargetLoweringInfo().getLLVMSyncScope(*syncScope); + std::optional<llvm::StringRef> llvmSyncScope = + getLLVMSyncScope(op.getSyncScope()); mlir::LLVM::LoadOp newLoad = mlir::LLVM::LoadOp::create( rewriter, op->getLoc(), llvmTy, adaptor.getAddr(), alignment, @@ -1815,10 +1813,8 @@ mlir::LogicalResult CIRToLLVMStoreOpLowering::matchAndRewrite( assert(!cir::MissingFeatures::opLoadStoreNontemporal()); assert(!cir::MissingFeatures::opLoadStoreTbaa()); - std::optional<std::string> llvmSyncScope; - if (std::optional<cir::SyncScopeKind> syncScope = op.getSyncScope()) - llvmSyncScope = - lowerMod->getTargetLoweringInfo().getLLVMSyncScope(*syncScope); + std::optional<llvm::StringRef> llvmSyncScope = + getLLVMSyncScope(op.getSyncScope()); mlir::LLVM::StoreOp storeOp = mlir::LLVM::StoreOp::create( rewriter, op->getLoc(), value, adaptor.getAddr(), alignment, @@ -3019,17 +3015,6 @@ mlir::LogicalResult CIRToLLVMSelectOpLowering::matchAndRewrite( return mlir::success(); } -std::unique_ptr<cir::LowerModule> prepareLowerModule(mlir::ModuleOp module) { - mlir::PatternRewriter rewriter{module->getContext()}; - // If the triple is not present, e.g. CIR modules parsed from text, we - // cannot init LowerModule properly. This happens in some lowering tests, - // but it should not happen in real compilation. - assert(!cir::MissingFeatures::makeTripleAlwaysPresent()); - if (!module->hasAttr(cir::CIRDialect::getTripleAttrName())) - return {}; - return cir::createLowerModule(module, rewriter); -} - static void prepareTypeConverter(mlir::LLVMTypeConverter &converter, mlir::DataLayout &dataLayout, cir::LowerModule *lowerModule) { @@ -3330,7 +3315,8 @@ void ConvertCIRToLLVMPass::runOnOperation() { mlir::ModuleOp module = getOperation(); mlir::DataLayout dl(module); mlir::LLVMTypeConverter converter(&getContext()); - std::unique_ptr<cir::LowerModule> lowerModule = prepareLowerModule(module); + std::unique_ptr<cir::LowerModule> lowerModule = + cir::createLowerModule(module); prepareTypeConverter(converter, dl, lowerModule.get()); /// Tracks the state required to lower CIR `LabelOp` and `BlockAddressOp`. diff --git a/clang/test/CIR/CodeGen/atomic-scoped.c b/clang/test/CIR/CodeGen/atomic-scoped.c index 62d075c21a893..4a81288c5bbd6 100644 --- a/clang/test/CIR/CodeGen/atomic-scoped.c +++ b/clang/test/CIR/CodeGen/atomic-scoped.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir -mmlir --mlir-print-ir-before=cir-target-lowering %s -o %t.cir 2>%t-before-target-lowering.cir +// RUN: FileCheck --input-file=%t-before-target-lowering.cir %s --check-prefixes=CIR-BEFORE-TL // RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll // RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM @@ -6,17 +7,20 @@ // RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG void scoped_atomic_load(int *ptr) { + // CIR-BEFORE-TL-LABEL: @scoped_atomic_load // CIR-LABEL: @scoped_atomic_load // LLVM-LABEL: @scoped_atomic_load // OGCG-LABEL: @scoped_atomic_load 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 + // CIR-BEFORE-TL: %{{.+}} = cir.load align(4) syncscope(single_thread) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i + // CIR: %{{.+}} = cir.load align(4) syncscope(system) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i // 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); + // CIR-BEFORE-TL: %{{.+}} = cir.load align(4) syncscope(system) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i // CIR: %{{.+}} = cir.load align(4) syncscope(system) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4 // OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4 @@ -29,11 +33,13 @@ 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 + // CIR-BEFORE-TL: %{{.+}} = cir.load align(4) syncscope(single_thread) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i + // CIR: %{{.+}} = cir.load align(4) syncscope(system) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i // 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); + // CIR-BEFORE-TL: %{{.+}} = cir.load align(4) syncscope(system) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i // CIR: %{{.+}} = cir.load align(4) syncscope(system) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4 // OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4 @@ -45,11 +51,13 @@ void scoped_atomic_store(int *ptr, int value) { // OGCG-LABEL: @scoped_atomic_store __scoped_atomic_store(ptr, &value, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE); - // CIR: cir.store align(4) syncscope(single_thread) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> + // CIR-BEFORE-TL: cir.store align(4) syncscope(single_thread) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> + // CIR: cir.store align(4) syncscope(system) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> // 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); + // CIR-BEFORE-TL: cir.store align(4) syncscope(system) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> // CIR: cir.store align(4) syncscope(system) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4 // OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4 @@ -61,11 +69,13 @@ void scoped_atomic_store_n(int *ptr, int value) { // OGCG-LABEL: @scoped_atomic_store_n __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> + // CIR-BEFORE-TL: cir.store align(4) syncscope(single_thread) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> + // CIR: cir.store align(4) syncscope(system) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> // 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); + // CIR-BEFORE-TL: cir.store align(4) syncscope(system) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> // CIR: cir.store align(4) syncscope(system) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4 // OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
