[Mlir-commits] [mlir] [MLIR][LLVM] Add noundef metadata to llvm.load (PR #228517)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Oct 2 09:46:57 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Arseniy Obolenskiy (aobolensk)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/228517.diff
5 Files Affected:
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+14-3)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+1-1)
- (modified) mlir/test/Dialect/LLVMIR/roundtrip.mlir (+7)
- (modified) mlir/test/Target/LLVMIR/Import/instructions.ll (+13)
- (modified) mlir/test/Target/LLVMIR/llvmir.mlir (+11)
``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 2df02fae26d20e..129d62ab97fea4 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -393,7 +393,8 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
DefaultValuedAttr<
AtomicOrdering, "AtomicOrdering::not_atomic">:$ordering,
OptionalAttr<StrAttr>:$syncscope,
- OptionalAttr<LLVM_DereferenceableAttr>:$dereferenceable);
+ OptionalAttr<LLVM_DereferenceableAttr>:$dereferenceable,
+ UnitAttr:$noundef);
// Append the aliasing related attributes defined in LLVM_MemAccessOpBase.
let arguments = !con(args, aliasAttrs);
let results = (outs LLVM_LoadableType:$res);
@@ -414,6 +415,9 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
// A nontemporal load of a float variable.
%0 = llvm.load %ptr <nontemporal> : !llvm.ptr -> f32
+ // A load of a value that is neither undef nor poison.
+ %0 = llvm.load %ptr noundef : !llvm.ptr -> i32
+
// An atomic load of an integer variable.
%0 = llvm.load %ptr atomic monotonic <alignment = 8>
: !llvm.ptr -> i64
@@ -428,6 +432,7 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
(`invariant` $invariant^)?
(`invariant_group` $invariantGroup^)?
(`dereferenceable` `` $dereferenceable^)?
+ (`noundef` $noundef^)?
prop-dict
attr-dict `:` qualified(type($addr)) `->` type($res)
}];
@@ -440,6 +445,10 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
}
if ($dereferenceable)
moduleTranslation.setDereferenceableMetadata(op, inst);
+ if ($noundef) {
+ llvm::MDNode *metadata = llvm::MDNode::get(inst->getContext(), {});
+ inst->setMetadata(llvm::LLVMContext::MD_noundef, metadata);
+ }
}] # setOrderingCode
# setSyncScopeCode
# setAlignmentCode
@@ -450,13 +459,15 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
string mlirBuilder = [{
auto *loadInst = cast<llvm::LoadInst>(inst);
unsigned alignment = loadInst->getAlign().value();
- $res = LLVM::LoadOp::create($_builder, $_location, $_resultType, $addr,
- alignment, loadInst->isVolatile(),
+ auto loadOp = LLVM::LoadOp::create($_builder, $_location, $_resultType,
+ $addr, alignment, loadInst->isVolatile(),
loadInst->hasMetadata(llvm::LLVMContext::MD_nontemporal),
loadInst->hasMetadata(llvm::LLVMContext::MD_invariant_load),
loadInst->hasMetadata(llvm::LLVMContext::MD_invariant_group),
convertAtomicOrderingFromLLVM(loadInst->getOrdering()),
getLLVMSyncScope(loadInst));
+ loadOp.setNoundef(loadInst->hasMetadata(llvm::LLVMContext::MD_noundef));
+ $res = loadOp;
}];
let builders = [
OpBuilder<(ins "Type":$type, "Value":$addr,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index ff75b5a7dfb2e3..cf08fa3bac9e76 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -933,7 +933,7 @@ void LoadOp::build(OpBuilder &builder, OperationState &state, Type type,
alignment ? builder.getI64IntegerAttr(alignment) : nullptr, isVolatile,
isNonTemporal, isInvariant, isInvariantGroup, ordering,
syncscope.empty() ? nullptr : builder.getStringAttr(syncscope),
- /*dereferenceable=*/nullptr,
+ /*dereferenceable=*/nullptr, /*noundef=*/false,
/*access_groups=*/nullptr,
/*alias_scopes=*/nullptr, /*noalias_scopes=*/nullptr,
/*tbaa=*/nullptr);
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index 6ef571efe5c51b..48d1a12eb43e12 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -598,6 +598,13 @@ func.func @invariant_load(%ptr : !llvm.ptr) -> i32 {
func.return %0 : i32
}
+// CHECK-LABEL: @noundef_load
+func.func @noundef_load(%ptr : !llvm.ptr) -> i32 {
+ // CHECK: llvm.load %{{.+}} noundef <alignment = 4> : !llvm.ptr -> i32
+ %0 = llvm.load %ptr noundef <alignment = 4> : !llvm.ptr -> i32
+ func.return %0 : i32
+}
+
// CHECK-LABEL: @invariant_group_load
func.func @invariant_group_load(%ptr : !llvm.ptr) -> i32 {
// CHECK: llvm.load %{{.+}} invariant_group <alignment = 4> : !llvm.ptr -> i32
diff --git a/mlir/test/Target/LLVMIR/Import/instructions.ll b/mlir/test/Target/LLVMIR/Import/instructions.ll
index 28ab4bc44a40ab..0cdaa667b3dc50 100644
--- a/mlir/test/Target/LLVMIR/Import/instructions.ll
+++ b/mlir/test/Target/LLVMIR/Import/instructions.ll
@@ -375,6 +375,19 @@ define void @load_store(ptr %ptr) {
; // -----
+; CHECK-LABEL: @noundef_load
+; CHECK-SAME: %[[PTR:[a-zA-Z0-9]+]]
+define i32 @noundef_load(ptr %ptr) {
+ ; CHECK: %[[V:[0-9]+]] = llvm.load %[[PTR]] noundef <alignment = 4> : !llvm.ptr -> i32
+ %1 = load i32, ptr %ptr, align 4, !noundef !0
+ ; CHECK: llvm.return %[[V]]
+ ret i32 %1
+}
+
+!0 = !{}
+
+; // -----
+
; CHECK-LABEL: @invariant_load
; CHECK-SAME: %[[PTR:[a-zA-Z0-9]+]]
define float @invariant_load(ptr %ptr) {
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index f29184beb6b4d6..cccf402d8e2ebe 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2135,6 +2135,17 @@ llvm.func @nontemporal_store_and_load(%ptr : !llvm.ptr) -> i32 {
// -----
+// CHECK-LABEL: @noundef_load
+llvm.func @noundef_load(%ptr : !llvm.ptr) -> i32 {
+ // CHECK: load i32, ptr %{{.*}}, align 4, !noundef ![[NODE:[0-9]+]]
+ %0 = llvm.load %ptr noundef : !llvm.ptr -> i32
+ llvm.return %0 : i32
+}
+
+// CHECK: ![[NODE]] = !{}
+
+// -----
+
// Check that invariant group attribute is exported as metadata node.
llvm.func @nontemporal_store_and_load(%ptr : !llvm.ptr) -> i32 {
%val = llvm.mlir.constant(42 : i32) : i32
``````````
</details>
https://github.com/llvm/llvm-project/pull/228517
More information about the Mlir-commits
mailing list