[Mlir-commits] [mlir] c4d8bd1 - [mlir][llvm] Add convergent attribute to llvm.inline_asm. (#221990)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Sep 8 06:48:00 PDT 2026
Author: Benjamin Chetioui
Date: 2026-09-08T15:47:55+02:00
New Revision: c4d8bd10c14a6902da83306270e836ef6fa5bb76
URL: https://github.com/llvm/llvm-project/commit/c4d8bd10c14a6902da83306270e836ef6fa5bb76
DIFF: https://github.com/llvm/llvm-project/commit/c4d8bd10c14a6902da83306270e836ef6fa5bb76.diff
LOG: [mlir][llvm] Add convergent attribute to llvm.inline_asm. (#221990)
Expose LLVM's convergent call-site attribute on the LLVM dialect
inline_asm op. This allows marking an inline asm block as convergent so
that divergence-aware passes do not move it relative to divergent
control flow.
Added:
Modified:
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
mlir/lib/Conversion/AMDGPUToROCDL/AMDGPUToROCDL.cpp
mlir/lib/Conversion/NVGPUToNVVM/NVGPUToNVVM.cpp
mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
mlir/lib/Dialect/X86/Transforms/AVXTranspose.cpp
mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
mlir/lib/Target/LLVMIR/ModuleImport.cpp
mlir/test/Dialect/LLVMIR/roundtrip.mlir
mlir/test/Target/LLVMIR/Import/instructions.ll
mlir/test/Target/LLVMIR/llvmir.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index ceb418ebd2998..9811b93539a9b 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2548,6 +2548,7 @@ def LLVM_InlineAsmOp : LLVM_Op<"inline_asm", [DeclareOpInterfaceMethods<MemoryEf
UnitAttr:$has_side_effects,
UnitAttr:$is_align_stack,
DefaultValuedAttr<TailCallKind, "TailCallKind::None">:$tail_call_kind,
+ UnitAttr:$convergent,
OptionalAttr<
DefaultValuedAttr<AsmATTOrIntel, "AsmDialect::AD_ATT">>:$asm_dialect,
OptionalAttr<ArrayAttr>:$operand_attrs);
@@ -2558,6 +2559,7 @@ def LLVM_InlineAsmOp : LLVM_Op<"inline_asm", [DeclareOpInterfaceMethods<MemoryEf
(`has_side_effects` $has_side_effects^)?
(`is_align_stack` $is_align_stack^)?
(`tail_call_kind` `=` $tail_call_kind^)?
+ (`convergent` $convergent^)?
(`asm_dialect` `=` $asm_dialect^)?
(`operand_attrs` `=` $operand_attrs^)?
attr-dict
diff --git a/mlir/lib/Conversion/AMDGPUToROCDL/AMDGPUToROCDL.cpp b/mlir/lib/Conversion/AMDGPUToROCDL/AMDGPUToROCDL.cpp
index cb7192f651a0d..8aacd032b932a 100644
--- a/mlir/lib/Conversion/AMDGPUToROCDL/AMDGPUToROCDL.cpp
+++ b/mlir/lib/Conversion/AMDGPUToROCDL/AMDGPUToROCDL.cpp
@@ -666,6 +666,7 @@ struct LDSBarrierOpLowering : public ConvertOpToLLVMPattern<LDSBarrierOp> {
/*resultTypes=*/TypeRange(), /*operands=*/ValueRange(),
/*asm_string=*/asmStr, constraints, /*has_side_effects=*/true,
/*is_align_stack=*/false, LLVM::TailCallKind::None,
+ /*convergent=*/false,
/*asm_dialect=*/asmDialectAttr,
/*operand_attrs=*/ArrayAttr());
} else if (chipset.majorVersion < 12) {
diff --git a/mlir/lib/Conversion/NVGPUToNVVM/NVGPUToNVVM.cpp b/mlir/lib/Conversion/NVGPUToNVVM/NVGPUToNVVM.cpp
index 4bc0d3a7a6ebe..7c393e8cf2b66 100644
--- a/mlir/lib/Conversion/NVGPUToNVVM/NVGPUToNVVM.cpp
+++ b/mlir/lib/Conversion/NVGPUToNVVM/NVGPUToNVVM.cpp
@@ -566,6 +566,7 @@ static FailureOr<LLVM::InlineAsmOp> emitMmaSparseSyncOpAsm(
/*has_side_effects=*/true,
/*is_align_stack=*/false,
LLVM::TailCallKind::None,
+ /*convergent=*/false,
/*asm_dialect=*/asmDialectAttr,
/*operand_attrs=*/ArrayAttr());
}
diff --git a/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp b/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
index a8767611adb64..64cec0eadd2cb 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
@@ -505,6 +505,7 @@ LLVM::InlineAsmOp PtxBuilder::build() {
/*constraints=*/registerConstraints.data(),
/*has_side_effects=*/interfaceOp.hasSideEffect(),
/*is_align_stack=*/false, LLVM::TailCallKind::None,
+ /*convergent=*/false,
/*asm_dialect=*/asmDialectAttr,
/*operand_attrs=*/ArrayAttr());
}
diff --git a/mlir/lib/Dialect/X86/Transforms/AVXTranspose.cpp b/mlir/lib/Dialect/X86/Transforms/AVXTranspose.cpp
index bd649a555461f..089de23f3a8ed 100644
--- a/mlir/lib/Dialect/X86/Transforms/AVXTranspose.cpp
+++ b/mlir/lib/Dialect/X86/Transforms/AVXTranspose.cpp
@@ -41,6 +41,7 @@ Value mlir::x86::avx2::inline_asm::mm256BlendPsAsm(ImplicitLocOpBuilder &b,
b, v1.getType(), /*operands=*/asmVals, /*asm_string=*/asmStr,
/*constraints=*/asmCstr, /*has_side_effects=*/false,
/*is_align_stack=*/false, LLVM::TailCallKind::None,
+ /*convergent=*/false,
/*asm_dialect=*/asmDialectAttr,
/*operand_attrs=*/ArrayAttr());
return asmOp.getResult(0);
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 497b24c94811c..0c715da6ba954 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -607,6 +607,8 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
moduleTranslation.lookupValues(inlineAsmOp.getOperands()));
inst->setTailCallKind(convertTailCallKindToLLVM(
inlineAsmOp.getTailCallKindAttr().getTailCallKind()));
+ if (inlineAsmOp.getConvergent())
+ inst->addFnAttr(llvm::Attribute::Convergent);
if (auto maybeOperandAttrs = inlineAsmOp.getOperandAttrs()) {
llvm::AttributeList attrList;
for (const auto &it : llvm::enumerate(*maybeOperandAttrs)) {
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index bc4ca805b9d7b..00fb013f08d5e 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -2551,6 +2551,7 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
builder.getStringAttr(asmI->getConstraintString()),
asmI->hasSideEffects(), asmI->isAlignStack(),
convertTailCallKindFromLLVM(callInst->getTailCallKind()),
+ callInst->hasFnAttr(llvm::Attribute::Convergent),
AsmDialectAttr::get(
mlirModule.getContext(),
convertAsmDialectFromLLVM(asmI->getDialect())),
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index 42581ca2e3d92..a17ee35808ed9 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -721,6 +721,9 @@ llvm.func @useInlineAsm(%arg0: i32) {
// CHECK-NEXT: llvm.inline_asm "foo", "=r,=r,r" {{.*}} : (i32) -> !llvm.struct<(i8, i8)>
%5 = llvm.inline_asm "foo", "=r,=r,r" %arg0 : (i32) -> !llvm.struct<(i8, i8)>
+ // CHECK-NEXT: llvm.inline_asm convergent {{.*}} (i32) -> i8
+ %6 = llvm.inline_asm convergent "bswap $0", "=r,r" %arg0 : (i32) -> i8
+
llvm.return
}
diff --git a/mlir/test/Target/LLVMIR/Import/instructions.ll b/mlir/test/Target/LLVMIR/Import/instructions.ll
index 4116bed6f3489..6665262a035dd 100644
--- a/mlir/test/Target/LLVMIR/Import/instructions.ll
+++ b/mlir/test/Target/LLVMIR/Import/instructions.ll
@@ -555,6 +555,19 @@ define i32 @inlineasm(i32 %arg1) {
; // -----
+; CHECK-LABEL: @inlineasm_convergent
+; CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]
+define i32 @inlineasm_convergent(i32 %arg1) {
+ ; CHECK: %[[RES:.+]] = llvm.inline_asm convergent asm_dialect = att "bswap $0", "=r,r" %[[ARG1]] : (i32) -> i32
+ %1 = call i32 asm "bswap $0", "=r,r"(i32 %arg1) #0
+ ; CHECK: return %[[RES]]
+ ret i32 %1
+}
+
+attributes #0 = { convergent }
+
+; // -----
+
; CHECK-LABEL: @inlineasm2
define void @inlineasm2() {
%p = alloca ptr, align 8
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 9f99bf83dae95..84d892876d36a 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2209,9 +2209,14 @@ llvm.func @useInlineAsm(%arg0: i32, %arg1 : !llvm.ptr) {
// CHECK-NEXT: notail call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}})
%8 = llvm.inline_asm tail_call_kind = <notail> "foo", "=r,=r,r" %arg0 : (i32) -> !llvm.struct<(i8, i8)>
+ // CHECK-NEXT: call i8 asm "foo", "=r,r"(i32 {{.*}}) #[[$CONVERGENT:.*]]
+ %9 = llvm.inline_asm convergent "foo", "=r,r" %arg0 : (i32) -> i8
+
llvm.return
}
+// CHECK: attributes #[[$CONVERGENT]] = { convergent }
+
// -----
// CHECK: @useInlineAsm2(ptr %[[A0:.*]], i64 %[[A1:.*]], ptr %[[A2:.*]], i64 %[[A3:.*]]) {
More information about the Mlir-commits
mailing list