Skip to content

Commit 318b0dd

Browse files
authored
[CIR] Add atomic load and store operations (#153814)
This patch adds support for atomic loads and stores. Specifically, it adds support for the following intrinsic calls: - `__atomic_load` and `__atomic_store`; - `__c11_atomic_load` and `__c11_atomic_store`.
1 parent 2330fd2 commit 318b0dd

File tree

10 files changed

+522
-28
lines changed

10 files changed

+522
-28
lines changed

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
161161
uint64_t alignment = 0) {
162162
mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
163163
assert(!cir::MissingFeatures::opLoadStoreVolatile());
164-
assert(!cir::MissingFeatures::opLoadStoreMemOrder());
165164
return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false,
166-
alignmentAttr);
165+
alignmentAttr, cir::MemOrderAttr{});
167166
}
168167

169168
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -245,8 +244,10 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
245244
}
246245

247246
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
248-
mlir::IntegerAttr align = {}) {
249-
return create<cir::StoreOp>(loc, val, dst, align);
247+
bool isVolatile = false,
248+
mlir::IntegerAttr align = {},
249+
cir::MemOrderAttr order = {}) {
250+
return cir::StoreOp::create(*this, loc, val, dst, align, order);
250251
}
251252

252253
[[nodiscard]] cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule,
@@ -269,7 +270,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
269270
clang::CharUnits alignment) {
270271
mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
271272
auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
272-
return create<cir::LoadOp>(loc, addr, /*isDeref=*/false, alignmentAttr);
273+
return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
274+
alignmentAttr, /*mem_order=*/{});
273275
}
274276

275277
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,20 @@ def CIR_ConstantOp : CIR_Op<"const", [
299299
let hasFolder = 1;
300300
}
301301

302+
//===----------------------------------------------------------------------===//
303+
// C/C++ memory order definitions
304+
//===----------------------------------------------------------------------===//
305+
306+
def CIR_MemOrder : CIR_I32EnumAttr<
307+
"MemOrder", "Memory order according to C++11 memory model", [
308+
I32EnumAttrCase<"Relaxed", 0, "relaxed">,
309+
I32EnumAttrCase<"Consume", 1, "consume">,
310+
I32EnumAttrCase<"Acquire", 2, "acquire">,
311+
I32EnumAttrCase<"Release", 3, "release">,
312+
I32EnumAttrCase<"AcquireRelease", 4, "acq_rel">,
313+
I32EnumAttrCase<"SequentiallyConsistent", 5, "seq_cst">
314+
]>;
315+
302316
//===----------------------------------------------------------------------===//
303317
// AllocaOp
304318
//===----------------------------------------------------------------------===//
@@ -408,13 +422,14 @@ def CIR_LoadOp : CIR_Op<"load", [
408422
let arguments = (ins Arg<CIR_PointerType, "the address to load from",
409423
[MemRead]>:$addr,
410424
UnitAttr:$isDeref,
411-
OptionalAttr<I64Attr>:$alignment
412-
);
425+
OptionalAttr<I64Attr>:$alignment,
426+
OptionalAttr<CIR_MemOrder>:$mem_order);
413427
let results = (outs CIR_AnyType:$result);
414428

415429
let assemblyFormat = [{
416430
(`deref` $isDeref^)?
417431
(`align` `(` $alignment^ `)`)?
432+
(`atomic` `(` $mem_order^ `)`)?
418433
$addr `:` qualified(type($addr)) `,` type($result) attr-dict
419434
}];
420435

@@ -451,10 +466,12 @@ def CIR_StoreOp : CIR_Op<"store", [
451466
let arguments = (ins CIR_AnyType:$value,
452467
Arg<CIR_PointerType, "the address to store the value",
453468
[MemWrite]>:$addr,
454-
OptionalAttr<I64Attr>:$alignment);
469+
OptionalAttr<I64Attr>:$alignment,
470+
OptionalAttr<CIR_MemOrder>:$mem_order);
455471

456472
let assemblyFormat = [{
457473
(`align` `(` $alignment^ `)`)?
474+
(`atomic` `(` $mem_order^ `)`)?
458475
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
459476
}];
460477

clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,18 @@ LLVM_ATTRIBUTE_UNUSED static bool isValidLinkage(GlobalLinkageKind gl) {
113113
isLinkOnceLinkage(gl);
114114
}
115115

116+
bool operator<(cir::MemOrder, cir::MemOrder) = delete;
117+
bool operator>(cir::MemOrder, cir::MemOrder) = delete;
118+
bool operator<=(cir::MemOrder, cir::MemOrder) = delete;
119+
bool operator>=(cir::MemOrder, cir::MemOrder) = delete;
120+
121+
// Validate an integral value which isn't known to fit within the enum's range
122+
// is a valid AtomicOrderingCABI.
123+
template <typename Int> inline bool isValidCIRAtomicOrderingCABI(Int value) {
124+
return static_cast<Int>(cir::MemOrder::Relaxed) <= value &&
125+
value <= static_cast<Int>(cir::MemOrder::SequentiallyConsistent);
126+
}
127+
116128
} // namespace cir
117129

118130
#endif // CLANG_CIR_DIALECT_IR_CIROPSENUMS_H

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ struct MissingFeatures {
4949
static bool opLoadEmitScalarRangeCheck() { return false; }
5050
static bool opLoadBooleanRepresentation() { return false; }
5151
static bool opLoadStoreTbaa() { return false; }
52-
static bool opLoadStoreMemOrder() { return false; }
5352
static bool opLoadStoreVolatile() { return false; }
5453
static bool opLoadStoreAtomic() { return false; }
5554
static bool opLoadStoreObjC() { return false; }
@@ -163,6 +162,8 @@ struct MissingFeatures {
163162
static bool atomicInfoGetAtomicPointer() { return false; }
164163
static bool atomicInfoGetAtomicAddress() { return false; }
165164
static bool atomicUseLibCall() { return false; }
165+
static bool atomicScope() { return false; }
166+
static bool atomicSyncScopeID() { return false; }
166167

167168
// Misc
168169
static bool abiArgInfo() { return false; }

clang/lib/CIR/CodeGen/Address.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ class Address {
6868
return pointerAndKnownNonNull.getPointer() != nullptr;
6969
}
7070

71+
/// Return address with different pointer, but same element type and
72+
/// alignment.
73+
Address withPointer(mlir::Value newPtr) const {
74+
return Address(newPtr, getElementType(), getAlignment());
75+
}
76+
7177
/// Return address with different element type, a bitcast pointer, and
7278
/// the same alignment.
7379
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const;

0 commit comments

Comments
 (0)