Skip to content

Commit 2aff7f3

Browse files
authored
[mlir][LLVM] Add !invariant.load metadata support to llvm.load (#76754)
Add support for !invariant.load metadata (by way of a unit attribute) to the MLIR representation of llvm.load.
1 parent 460ffcd commit 2aff7f3

File tree

5 files changed

+42
-4
lines changed

5 files changed

+42
-4
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
330330
OptionalAttr<I64Attr>:$alignment,
331331
UnitAttr:$volatile_,
332332
UnitAttr:$nontemporal,
333+
UnitAttr:$invariant,
333334
DefaultValuedAttr<
334335
AtomicOrdering, "AtomicOrdering::not_atomic">:$ordering,
335336
OptionalAttr<StrAttr>:$syncscope);
@@ -364,11 +365,16 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
364365
let assemblyFormat = [{
365366
(`volatile` $volatile_^)? $addr
366367
(`atomic` (`syncscope` `(` $syncscope^ `)`)? $ordering^)?
368+
(`invariant` $invariant^)?
367369
attr-dict `:` qualified(type($addr)) `->` type($res)
368370
}];
369371
string llvmBuilder = [{
370372
auto *inst = builder.CreateLoad($_resultType, $addr, $volatile_);
371373
$res = inst;
374+
if ($invariant) {
375+
llvm::MDNode *metadata = llvm::MDNode::get(inst->getContext(), std::nullopt);
376+
inst->setMetadata(llvm::LLVMContext::MD_invariant_load, metadata);
377+
}
372378
}] # setOrderingCode
373379
# setSyncScopeCode
374380
# setAlignmentCode
@@ -381,13 +387,14 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
381387
$res = $_builder.create<LLVM::LoadOp>($_location, $_resultType, $addr,
382388
alignment, loadInst->isVolatile(),
383389
loadInst->hasMetadata(llvm::LLVMContext::MD_nontemporal),
390+
loadInst->hasMetadata(llvm::LLVMContext::MD_invariant_load),
384391
convertAtomicOrderingFromLLVM(loadInst->getOrdering()),
385392
getLLVMSyncScope(loadInst));
386393
}];
387394
let builders = [
388395
OpBuilder<(ins "Type":$type, "Value":$addr,
389396
CArg<"unsigned", "0">:$alignment, CArg<"bool", "false">:$isVolatile,
390-
CArg<"bool", "false">:$isNonTemporal,
397+
CArg<"bool", "false">:$isNonTemporal, CArg<"bool", "false">:$isInvariant,
391398
CArg<"AtomicOrdering", "AtomicOrdering::not_atomic">:$ordering,
392399
CArg<"StringRef", "StringRef()">:$syncscope)>
393400
];

mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -822,11 +822,11 @@ LogicalResult LoadOp::verify() {
822822

823823
void LoadOp::build(OpBuilder &builder, OperationState &state, Type type,
824824
Value addr, unsigned alignment, bool isVolatile,
825-
bool isNonTemporal, AtomicOrdering ordering,
826-
StringRef syncscope) {
825+
bool isNonTemporal, bool isInvariant,
826+
AtomicOrdering ordering, StringRef syncscope) {
827827
build(builder, state, type, addr,
828828
alignment ? builder.getI64IntegerAttr(alignment) : nullptr, isVolatile,
829-
isNonTemporal, ordering,
829+
isNonTemporal, isInvariant, ordering,
830830
syncscope.empty() ? nullptr : builder.getStringAttr(syncscope),
831831
/*access_groups=*/nullptr,
832832
/*alias_scopes=*/nullptr, /*noalias_scopes=*/nullptr,

mlir/test/Dialect/LLVMIR/roundtrip.mlir

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,13 @@ func.func @cmpxchg(%ptr : !llvm.ptr, %cmp : i32, %new : i32) {
401401
llvm.return
402402
}
403403

404+
// CHECK-LABEL: @invariant_load
405+
func.func @invariant_load(%ptr : !llvm.ptr) -> i32 {
406+
// CHECK: llvm.load %{{.+}} invariant {alignment = 4 : i64} : !llvm.ptr -> i32
407+
%0 = llvm.load %ptr invariant {alignment = 4 : i64} : !llvm.ptr -> i32
408+
func.return %0 : i32
409+
}
410+
404411
llvm.mlir.global external constant @_ZTIi() : !llvm.ptr
405412
llvm.func @bar(!llvm.ptr, !llvm.ptr, !llvm.ptr)
406413
llvm.func @__gxx_personality_v0(...) -> i32

mlir/test/Target/LLVMIR/Import/instructions.ll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,19 @@ define void @load_store(ptr %ptr) {
370370

371371
; // -----
372372

373+
; CHECK-LABEL: @invariant_load
374+
; CHECK-SAME: %[[PTR:[a-zA-Z0-9]+]]
375+
define float @invariant_load(ptr %ptr) {
376+
; CHECK: %[[V:[0-9]+]] = llvm.load %[[PTR]] invariant {alignment = 4 : i64} : !llvm.ptr -> f32
377+
%1 = load float, ptr %ptr, align 4, !invariant.load !0
378+
; CHECK: llvm.return %[[V]]
379+
ret float %1
380+
}
381+
382+
!0 = !{}
383+
384+
; // -----
385+
373386
; CHECK-LABEL: @atomic_load_store
374387
; CHECK-SAME: %[[PTR:[a-zA-Z0-9]+]]
375388
define void @atomic_load_store(ptr %ptr) {

mlir/test/Target/LLVMIR/llvmir.mlir

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,6 +1911,17 @@ llvm.func @nontemporal_store_and_load() {
19111911

19121912
// -----
19131913

1914+
// Check that invariantLoad attribute is exported as metadata node.
1915+
llvm.func @nontemporal_store_and_load(%ptr : !llvm.ptr) -> i32 {
1916+
// CHECK: !invariant.load ![[NODE:[0-9]+]]
1917+
%1 = llvm.load %ptr invariant : !llvm.ptr -> i32
1918+
llvm.return %1 : i32
1919+
}
1920+
1921+
// CHECK: ![[NODE]] = !{}
1922+
1923+
// -----
1924+
19141925
llvm.func @atomic_store_and_load(%ptr : !llvm.ptr) {
19151926
// CHECK: load atomic
19161927
// CHECK-SAME: acquire, align 4

0 commit comments

Comments
 (0)