Skip to content

Commit 8b845f0

Browse files
Implement fence builtins
1 parent 2aa5a6d commit 8b845f0

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4845,6 +4845,11 @@ def CIR_AtomicClearOp : CIR_Op<"atomic.clear"> {
48454845
}];
48464846
}
48474847

4848+
def CIR_MemScopeKind : CIR_I32EnumAttr<"MemScopeKind", "memory scope kind", [
4849+
I32EnumAttrCase<"SingleThread", 0, "single_thread">,
4850+
I32EnumAttrCase<"System", 1, "system">
4851+
]>;
4852+
48484853
def CIR_AtomicFence : CIR_Op<"atomic.fence"> {
48494854
let summary = "Atomic thread fence";
48504855
let description = [{

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,28 @@ static RValue emitBuiltinBitOp(CIRGenFunction &cgf, const CallExpr *e,
5858
return RValue::get(result);
5959
}
6060

61+
static mlir::Value makeAtomicFenceValue(CIRGenFunction &cgf,
62+
const CallExpr *expr,
63+
cir::MemScopeKind syncScope) {
64+
auto &builder = cgf.getBuilder();
65+
mlir::Value orderingVal = cgf.emitScalarExpr(expr->getArg(0));
66+
67+
auto constOrdering = orderingVal.getDefiningOp<cir::ConstantOp>();
68+
if (!constOrdering)
69+
llvm_unreachable("NYI: variable ordering not supported");
70+
71+
if (auto constOrderingAttr = constOrdering.getValueAttr<cir::IntAttr>()) {
72+
cir::MemOrder ordering =
73+
static_cast<cir::MemOrder>(constOrderingAttr.getUInt());
74+
75+
cir::AtomicFence::create(
76+
builder, cgf.getLoc(expr->getSourceRange()), ordering,
77+
cir::MemScopeKindAttr::get(&cgf.getMLIRContext(), syncScope));
78+
}
79+
80+
return {};
81+
}
82+
6183
RValue CIRGenFunction::emitRotate(const CallExpr *e, bool isRotateLeft) {
6284
mlir::Value input = emitScalarExpr(e->getArg(0));
6385
mlir::Value amount = emitScalarExpr(e->getArg(1));
@@ -520,6 +542,23 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
520542
cir::PrefetchOp::create(builder, loc, address, locality, isWrite);
521543
return RValue::get(nullptr);
522544
}
545+
case Builtin::BI__c11_atomic_is_lock_free:
546+
llvm_unreachable("BI__c11_atomic_is_lock_free NYI");
547+
case Builtin::BI__atomic_is_lock_free:
548+
llvm_unreachable("BI__atomic_is_lock_free NYI");
549+
case Builtin::BI__atomic_test_and_set:
550+
llvm_unreachable("BI__atomic_test_and_set NYI");
551+
case Builtin::BI__atomic_clear:
552+
llvm_unreachable("BI__atomic_clear NYI");
553+
case Builtin::BI__atomic_thread_fence:
554+
return RValue::get(
555+
makeAtomicFenceValue(*this, e, cir::MemScopeKind::System));
556+
case Builtin::BI__atomic_signal_fence:
557+
return RValue::get(
558+
makeAtomicFenceValue(*this, e, cir::MemScopeKind::SingleThread));
559+
case Builtin::BI__c11_atomic_thread_fence:
560+
case Builtin::BI__c11_atomic_signal_fence:
561+
llvm_unreachable("BI__c11_atomic_thread_fence like NYI");
523562
}
524563

525564
// If this is an alias for a lib function (e.g. __builtin_sin), emit

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,14 @@ getLLVMMemOrder(std::optional<cir::MemOrder> memorder) {
732732
llvm_unreachable("unknown memory order");
733733
}
734734

735+
static std::optional<llvm::StringRef>
736+
getLLVMSyncScope(std::optional<cir::MemScopeKind> syncScope) {
737+
if (syncScope.has_value())
738+
return syncScope.value() == cir::MemScopeKind::SingleThread ? "singlethread"
739+
: "";
740+
return std::nullopt;
741+
}
742+
735743
mlir::LogicalResult CIRToLLVMAtomicCmpXchgOpLowering::matchAndRewrite(
736744
cir::AtomicCmpXchgOp op, OpAdaptor adaptor,
737745
mlir::ConversionPatternRewriter &rewriter) const {
@@ -808,6 +816,19 @@ mlir::LogicalResult CIRToLLVMAtomicClearOpLowering::matchAndRewrite(
808816
return mlir::success();
809817
}
810818

819+
mlir::LogicalResult CIRToLLVMAtomicFenceLowering::matchAndRewrite(
820+
cir::AtomicFence op, OpAdaptor adaptor,
821+
mlir::ConversionPatternRewriter &rewriter) const {
822+
mlir::LLVM::AtomicOrdering llvmOrder = getLLVMMemOrder(adaptor.getOrdering());
823+
824+
auto fence = mlir::LLVM::FenceOp::create(rewriter, op.getLoc(), llvmOrder);
825+
fence.setSyncscope(getLLVMSyncScope(adaptor.getSyncscope()));
826+
827+
rewriter.replaceOp(op, fence);
828+
829+
return mlir::success();
830+
}
831+
811832
static mlir::LLVM::AtomicBinOp
812833
getLLVMAtomicBinOp(cir::AtomicFetchKind k, bool isInt, bool isSignedInt) {
813834
switch (k) {

0 commit comments

Comments
 (0)