Skip to content

Commit 82f5ee3

Browse files
committed
Adds argument attributes for using LLVM's sret and byval attributes to
the conversion of LLVM IR dialect. These attributes are used in FIR to support the lowering of Fortran using target-specific calling conventions. Add roundtrip tests. Add changes per review comments/concerns. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D94052
1 parent db33f85 commit 82f5ee3

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,22 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
11021102
llvm::AttrBuilder().addAlignmentAttr(llvm::Align(attr.getInt())));
11031103
}
11041104

1105+
if (auto attr = func.getArgAttrOfType<UnitAttr>(argIdx, "llvm.sret")) {
1106+
auto argTy = mlirArg.getType().dyn_cast<LLVM::LLVMType>();
1107+
if (!argTy.isa<LLVM::LLVMPointerType>())
1108+
return func.emitError(
1109+
"llvm.sret attribute attached to LLVM non-pointer argument");
1110+
llvmArg.addAttr(llvm::Attribute::AttrKind::StructRet);
1111+
}
1112+
1113+
if (auto attr = func.getArgAttrOfType<UnitAttr>(argIdx, "llvm.byval")) {
1114+
auto argTy = mlirArg.getType().dyn_cast<LLVM::LLVMType>();
1115+
if (!argTy.isa<LLVM::LLVMPointerType>())
1116+
return func.emitError(
1117+
"llvm.byval attribute attached to LLVM non-pointer argument");
1118+
llvmArg.addAttr(llvm::Attribute::AttrKind::ByVal);
1119+
}
1120+
11051121
valueMapping[mlirArg] = &llvmArg;
11061122
argIdx++;
11071123
}

mlir/test/Dialect/LLVMIR/func.mlir

+10
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ module {
8787
llvm.return
8888
}
8989

90+
// CHECK: llvm.func @byvalattr(%{{.*}}: !llvm.ptr<i32> {llvm.byval})
91+
llvm.func @byvalattr(%arg0: !llvm.ptr<i32> {llvm.byval}) {
92+
llvm.return
93+
}
94+
95+
// CHECK: llvm.func @sretattr(%{{.*}}: !llvm.ptr<i32> {llvm.sret})
96+
llvm.func @sretattr(%arg0: !llvm.ptr<i32> {llvm.sret}) {
97+
llvm.return
98+
}
99+
90100
// CHECK: llvm.func @variadic(...)
91101
llvm.func @variadic(...)
92102

mlir/test/Target/llvmir-invalid.mlir

+13
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ llvm.func @invalid_noalias(%arg0 : !llvm.float {llvm.noalias = true}) -> !llvm.f
1414

1515
// -----
1616

17+
// expected-error @+1 {{llvm.sret attribute attached to LLVM non-pointer argument}}
18+
llvm.func @invalid_noalias(%arg0 : !llvm.float {llvm.sret}) -> !llvm.float {
19+
llvm.return %arg0 : !llvm.float
20+
}
21+
// -----
22+
23+
// expected-error @+1 {{llvm.byval attribute attached to LLVM non-pointer argument}}
24+
llvm.func @invalid_noalias(%arg0 : !llvm.float {llvm.byval}) -> !llvm.float {
25+
llvm.return %arg0 : !llvm.float
26+
}
27+
28+
// -----
29+
1730
// expected-error @+1 {{llvm.align attribute attached to LLVM non-pointer argument}}
1831
llvm.func @invalid_align(%arg0 : !llvm.float {llvm.align = 4}) -> !llvm.float {
1932
llvm.return %arg0 : !llvm.float

0 commit comments

Comments
 (0)