[Mlir-commits] [mlir] 9265f92 - [mlir][ABI] Add writable, dead_on_unwind, dead_on_return, nofpclass param attrs to LLVM dialect (#188374)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Apr 6 09:26:16 PDT 2026


Author: adams381
Date: 2026-04-06T11:26:11-05:00
New Revision: 9265f9284c1306d30f5e63efaec805b308fe0457

URL: https://github.com/llvm/llvm-project/commit/9265f9284c1306d30f5e63efaec805b308fe0457
DIFF: https://github.com/llvm/llvm-project/commit/9265f9284c1306d30f5e63efaec805b308fe0457.diff

LOG: [mlir][ABI] Add writable, dead_on_unwind, dead_on_return, nofpclass param attrs to LLVM dialect (#188374)

The MLIR LLVM dialect is missing support for several parameter
attributes that
exist in LLVM IR: `writable`, `dead_on_unwind`, `dead_on_return`, and
`nofpclass`. This adds them to the kind-to-name mapping in
`AttrKindDetail.h`
and the corresponding name accessors in `LLVMDialect.td`.

The existing generic conversion infrastructure in `ModuleTranslation`
and
`ModuleImport` picks them up automatically — `writable` and
`dead_on_unwind`
round-trip as `UnitAttr`, while `dead_on_return` and `nofpclass`
round-trip as
`IntegerAttr`.

CIR needs these to match classic codegen's ABI output (sret gets
`writable
dead_on_unwind`, indirect args get `dead_on_return`, fast-math FP args
get
`nofpclass`).

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
    mlir/lib/Target/LLVMIR/AttrKindDetail.h
    mlir/test/Target/LLVMIR/Import/function-attributes.ll
    mlir/test/Target/LLVMIR/llvmir.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
index d2d71318a6118..01a3c8e9a1bde 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
@@ -62,7 +62,11 @@ def LLVM_Dialect : Dialect {
     static StringRef getSExtAttrName() { return "llvm.signext"; }
     static StringRef getStackAlignmentAttrName() { return "llvm.alignstack"; }
     static StringRef getStructRetAttrName() { return "llvm.sret"; }
+    static StringRef getWritableAttrName() { return "llvm.writable"; }
     static StringRef getWriteOnlyAttrName() { return "llvm.writeonly"; }
+    static StringRef getDeadOnUnwindAttrName() { return "llvm.dead_on_unwind"; }
+    static StringRef getDeadOnReturnAttrName() { return "llvm.dead_on_return"; }
+    static StringRef getNoFPClassAttrName() { return "llvm.nofpclass"; }
     static StringRef getZExtAttrName() { return "llvm.zeroext"; }
     static StringRef getOpBundleSizesAttrName() { return "op_bundle_sizes"; }
     static StringRef getOpBundleTagsAttrName() { return "op_bundle_tags"; }

diff  --git a/mlir/lib/Target/LLVMIR/AttrKindDetail.h b/mlir/lib/Target/LLVMIR/AttrKindDetail.h
index 051ed1edc4fd1..02b1360a6c77b 100644
--- a/mlir/lib/Target/LLVMIR/AttrKindDetail.h
+++ b/mlir/lib/Target/LLVMIR/AttrKindDetail.h
@@ -56,8 +56,15 @@ getAttrKindToNameMapping() {
        LLVMDialect::getStackAlignmentAttrName()},
       {llvm::Attribute::AttrKind::StructRet,
        LLVMDialect::getStructRetAttrName()},
+      {llvm::Attribute::AttrKind::Writable, LLVMDialect::getWritableAttrName()},
       {llvm::Attribute::AttrKind::WriteOnly,
        LLVMDialect::getWriteOnlyAttrName()},
+      {llvm::Attribute::AttrKind::DeadOnUnwind,
+       LLVMDialect::getDeadOnUnwindAttrName()},
+      {llvm::Attribute::AttrKind::DeadOnReturn,
+       LLVMDialect::getDeadOnReturnAttrName()},
+      {llvm::Attribute::AttrKind::NoFPClass,
+       LLVMDialect::getNoFPClassAttrName()},
       {llvm::Attribute::AttrKind::ZExt, LLVMDialect::getZExtAttrName()}};
   return kindNamePairs;
 }

diff  --git a/mlir/test/Target/LLVMIR/Import/function-attributes.ll b/mlir/test/Target/LLVMIR/Import/function-attributes.ll
index 6d057f4e11f75..5d664519e100c 100644
--- a/mlir/test/Target/LLVMIR/Import/function-attributes.ll
+++ b/mlir/test/Target/LLVMIR/Import/function-attributes.ll
@@ -53,7 +53,10 @@ attributes #0 = { readnone }
 ; CHECK-SAME:  !llvm.ptr {llvm.preallocated = f64}
 ; CHECK-SAME:  !llvm.ptr {llvm.returned}
 ; CHECK-SAME:  !llvm.ptr {llvm.alignstack = 32 : i64}
-; CHECK-SAME:  !llvm.ptr {llvm.writeonly}
+; CHECK-SAME:  !llvm.ptr {llvm.writable, llvm.writeonly}
+; CHECK-SAME:  !llvm.ptr {llvm.dead_on_unwind}
+; CHECK-SAME:  !llvm.ptr {llvm.dead_on_return = 8 : i64}
+; CHECK-SAME:  f32 {llvm.nofpclass = 519 : i64}
 ; CHECK-SAME:  i64 {llvm.range = #llvm.constant_range<i64, 0, 4097>}
 define ptr @func_arg_attrs(
     ptr byval(i64) %arg0,
@@ -73,8 +76,11 @@ define ptr @func_arg_attrs(
     ptr preallocated(double) %arg16,
     ptr returned %arg17,
     ptr alignstack(32) %arg18,
-    ptr writeonly %arg19,
-    i64 range(i64 0, 4097) %arg20) {
+    ptr writable writeonly %arg19,
+    ptr dead_on_unwind %arg20,
+    ptr dead_on_return(8) %arg21,
+    float nofpclass(nan inf) %arg22,
+    i64 range(i64 0, 4097) %arg23) {
   ret ptr %arg17
 }
 
@@ -134,6 +140,12 @@ declare noundef ptr @func_res_attr_noundef()
 
 ; // -----
 
+; CHECK-LABEL: @func_res_attr_nofpclass
+; CHECK-SAME:  (f32 {llvm.nofpclass = 519 : i64})
+declare nofpclass(nan inf) float @func_res_attr_nofpclass()
+
+; // -----
+
 ; CHECK-LABEL: @func_res_attr_dereferenceable
 ; CHECK-SAME:  !llvm.ptr {llvm.dereferenceable = 42 : i64}
 declare dereferenceable(42) ptr @func_res_attr_dereferenceable()

diff  --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 4ac3776d87c8e..6882de8ed446c 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -1227,6 +1227,41 @@ llvm.func @alignstackattr_decl(!llvm.ptr {llvm.alignstack = 32 : i64})
 // CHECK-LABEL: declare void @writeonlyattr_decl(ptr writeonly)
 llvm.func @writeonlyattr_decl(!llvm.ptr {llvm.writeonly})
 
+// CHECK-LABEL: define void @writableattr(ptr writable %
+llvm.func @writableattr(%arg0: !llvm.ptr {llvm.writable}) {
+  llvm.return
+}
+
+// CHECK-LABEL: declare void @writableattr_decl(ptr writable)
+llvm.func @writableattr_decl(!llvm.ptr {llvm.writable})
+
+// CHECK-LABEL: define void @deadonunwindattr(ptr dead_on_unwind %
+llvm.func @deadonunwindattr(%arg0: !llvm.ptr {llvm.dead_on_unwind}) {
+  llvm.return
+}
+
+// CHECK-LABEL: declare void @deadonunwindattr_decl(ptr dead_on_unwind)
+llvm.func @deadonunwindattr_decl(!llvm.ptr {llvm.dead_on_unwind})
+
+// CHECK-LABEL: define void @deadonreturnattr(ptr dead_on_return(8) %
+llvm.func @deadonreturnattr(%arg0: !llvm.ptr {llvm.dead_on_return = 8 : i64}) {
+  llvm.return
+}
+
+// CHECK-LABEL: declare void @deadonreturnattr_decl(ptr dead_on_return(8))
+llvm.func @deadonreturnattr_decl(!llvm.ptr {llvm.dead_on_return = 8 : i64})
+
+// CHECK-LABEL: define void @nofpclassattr(float nofpclass(nan inf) %
+llvm.func @nofpclassattr(%arg0: f32 {llvm.nofpclass = 519 : i64}) {
+  llvm.return
+}
+
+// CHECK-LABEL: declare void @nofpclassattr_decl(float nofpclass(nan inf))
+llvm.func @nofpclassattr_decl(f32 {llvm.nofpclass = 519 : i64})
+
+// CHECK-LABEL: declare nofpclass(nan inf) float @nofpclassattr_ret_decl()
+llvm.func @nofpclassattr_ret_decl() -> (f32 {llvm.nofpclass = 519 : i64})
+
 // CHECK-LABEL: declare align 4 ptr @alignattr_ret_decl()
 llvm.func @alignattr_ret_decl() -> (!llvm.ptr {llvm.align = 4})
 


        


More information about the Mlir-commits mailing list