[Mlir-commits] [mlir] [mlir][LLVM] Add invariant load attribute to LLVM's CallIntrinsicOp (PR #223142)

Ayokunle Amodu llvmlistbot at llvm.org
Sat Sep 12 05:13:19 PDT 2026


https://github.com/ayokunle321 created https://github.com/llvm/llvm-project/pull/223142

In LLVM IR, the `llvm.amdgcn.ptr.s.buffer.load` intrinsic has an invariant load metadata attached. LLVMCallIntrinsicOp (an op from the LLVM dialect that maps LLVM IR intrinsic) had no corresponding attribute. This patch therefore adds the invariant attribute to the op.

Assisted by: Claude Opus 5

>From e55ac2df81e4884d2df642ce9053415221fcbc1a Mon Sep 17 00:00:00 2001
From: Ayokunle Amodu <ayokunle321 at gmail.com>
Date: Sat, 12 Sep 2026 13:59:47 +0200
Subject: [PATCH] add invariant attr to call intrinsic op

---
 mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td           |  3 ++-
 .../LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp |  5 +++++
 mlir/test/Target/LLVMIR/llvmir.mlir                   | 11 +++++++++++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 9811b93539a9b..05d3663a796ad 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2666,7 +2666,8 @@ def LLVM_CallIntrinsicOp
                        DenseI32ArrayAttr:$op_bundle_sizes,
                        OptionalAttr<ArrayAttr>:$op_bundle_tags,
                        OptionalAttr<DictArrayAttr>:$arg_attrs,
-                       OptionalAttr<DictArrayAttr>:$res_attrs);
+                       OptionalAttr<DictArrayAttr>:$res_attrs,
+                       UnitAttr:$invariant);
   let results = (outs Optional<LLVM_Type>:$results);
   let llvmBuilder = [{
     return convertCallLLVMIntrinsicOp(op, builder, moduleTranslation);
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 0c715da6ba954..1cd96fd6bf3ba 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -205,6 +205,11 @@ convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder,
   if (failed(moduleTranslation.convertArgAndResultAttrs(op, inst)))
     return failure();
 
+  if (op.getInvariant()) {
+    llvm::MDNode *metadata = llvm::MDNode::get(inst->getContext(), {});
+    inst->setMetadata(llvm::LLVMContext::MD_invariant_load, metadata);
+  }
+
   if (op.getNumResults() == 1)
     moduleTranslation.mapValue(op->getResults().front()) = inst;
   return success();
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 84d892876d36a..8f83c1d1f60ef 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -3486,6 +3486,17 @@ llvm.func @call_intrin_with_opbundle(%arg0 : !llvm.ptr) {
 
 // -----
 
+llvm.func @call_intrin_invariant(%arg0 : !llvm.ptr<8>, %arg1 : i32) -> f32 {
+  %0 = llvm.mlir.constant(0 : i32) : i32
+  %1 = llvm.call_intrinsic "llvm.amdgcn.ptr.s.buffer.load.f32"(%arg0, %arg1, %0) {invariant} : (!llvm.ptr<8>, i32, i32) -> f32
+  llvm.return %1 : f32
+}
+
+// CHECK-LABEL: define float @call_intrin_invariant(
+//      CHECK:   call float @llvm.amdgcn.ptr.s.buffer.load.f32({{.*}}), !invariant.load
+
+// -----
+
 module {
   llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4 : i32>,
                      #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>,



More information about the Mlir-commits mailing list