Skip to content

Commit dc553ce

Browse files
committed
[mlir] LLVM import: handle function-typed constants
The current implementation of the LLVM-to-MLIR translation could not handle functions used as constant values in instructions. The handling is added trivially as `llvm.mlir.constant` can define constants of function type using SymbolRef attributes, which works even for functions that have not been declared yet.
1 parent 936483f commit dc553ce

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ Attribute Importer::getConstantAsAttr(llvm::Constant *value) {
209209
else if (c->getType()->isFloatingPointTy())
210210
return b.getFloatAttr(FloatType::getF32(context), c->getValueAPF());
211211
}
212+
if (auto *f = dyn_cast<llvm::Function>(value))
213+
return b.getSymbolRefAttr(f->getName());
212214
return Attribute();
213215
}
214216

mlir/test/Target/import.ll

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,4 +208,40 @@ define void @FPArithmetic(float %a, float %b, double %c, double %d) {
208208
; CHECK: %[[a13:[0-9]+]] = llvm.frem %arg2, %arg3 : !llvm.double
209209
%11 = frem double %c, %d
210210
ret void
211-
}
211+
}
212+
213+
;
214+
; Functions as constants.
215+
;
216+
217+
; Calling the function that has not been defined yet.
218+
; CHECK-LABEL: @precaller
219+
define i32 @precaller() {
220+
%1 = alloca i32 ()*
221+
; CHECK: %[[func:.*]] = llvm.mlir.constant(@callee) : !llvm<"i32 ()*">
222+
; CHECK: llvm.store %[[func]], %[[loc:.*]]
223+
store i32 ()* @callee, i32 ()** %1
224+
; CHECK: %[[indir:.*]] = llvm.load %[[loc]]
225+
%2 = load i32 ()*, i32 ()** %1
226+
; CHECK: llvm.call %[[indir]]()
227+
%3 = call i32 %2()
228+
ret i32 %3
229+
}
230+
231+
define i32 @callee() {
232+
ret i32 42
233+
}
234+
235+
; Calling the function that has been defined.
236+
; CHECK-LABEL: @postcaller
237+
define i32 @postcaller() {
238+
%1 = alloca i32 ()*
239+
; CHECK: %[[func:.*]] = llvm.mlir.constant(@callee) : !llvm<"i32 ()*">
240+
; CHECK: llvm.store %[[func]], %[[loc:.*]]
241+
store i32 ()* @callee, i32 ()** %1
242+
; CHECK: %[[indir:.*]] = llvm.load %[[loc]]
243+
%2 = load i32 ()*, i32 ()** %1
244+
; CHECK: llvm.call %[[indir]]()
245+
%3 = call i32 %2()
246+
ret i32 %3
247+
}

0 commit comments

Comments
 (0)