aboutsummaryrefslogtreecommitdiff
path: root/mlir/lib/Target/LLVMIR/ModuleImport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mlir/lib/Target/LLVMIR/ModuleImport.cpp')
-rw-r--r--mlir/lib/Target/LLVMIR/ModuleImport.cpp48
1 files changed, 42 insertions, 6 deletions
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index bfda223..c807985 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1031,6 +1031,16 @@ LogicalResult ModuleImport::convertAliases() {
return success();
}
+LogicalResult ModuleImport::convertIFuncs() {
+ for (llvm::GlobalIFunc &ifunc : llvmModule->ifuncs()) {
+ if (failed(convertIFunc(&ifunc))) {
+ return emitError(UnknownLoc::get(context))
+ << "unhandled global ifunc: " << diag(ifunc);
+ }
+ }
+ return success();
+}
+
LogicalResult ModuleImport::convertDataLayout() {
Location loc = mlirModule.getLoc();
DataLayoutImporter dataLayoutImporter(context, llvmModule->getDataLayout());
@@ -1369,6 +1379,21 @@ LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
return success();
}
+LogicalResult ModuleImport::convertIFunc(llvm::GlobalIFunc *ifunc) {
+ OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
+
+ Type type = convertType(ifunc->getValueType());
+ llvm::Constant *resolver = ifunc->getResolver();
+ Type resolverType = convertType(resolver->getType());
+ builder.create<IFuncOp>(mlirModule.getLoc(), ifunc->getName(), type,
+ resolver->getName(), resolverType,
+ convertLinkageFromLLVM(ifunc->getLinkage()),
+ ifunc->isDSOLocal(), ifunc->getAddressSpace(),
+ convertUnnamedAddrFromLLVM(ifunc->getUnnamedAddr()),
+ convertVisibilityFromLLVM(ifunc->getVisibility()));
+ return success();
+}
+
LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
// Insert the global after the last one or at the start of the module.
OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
@@ -1973,8 +1998,9 @@ ModuleImport::convertCallOperands(llvm::CallBase *callInst,
// treated as indirect calls to constant operands that need to be converted.
// Skip the callee operand if it's inline assembly, as it's handled separately
// in InlineAsmOp.
- if (!isa<llvm::Function>(callInst->getCalledOperand()) && !isInlineAsm) {
- FailureOr<Value> called = convertValue(callInst->getCalledOperand());
+ llvm::Value *calleeOperand = callInst->getCalledOperand();
+ if (!isa<llvm::Function, llvm::GlobalIFunc>(calleeOperand) && !isInlineAsm) {
+ FailureOr<Value> called = convertValue(calleeOperand);
if (failed(called))
return failure();
operands.push_back(*called);
@@ -2035,12 +2061,20 @@ ModuleImport::convertFunctionType(llvm::CallBase *callInst,
if (failed(callType))
return failure();
auto *callee = dyn_cast<llvm::Function>(calledOperand);
+
+ llvm::FunctionType *origCalleeType = nullptr;
+ if (callee) {
+ origCalleeType = callee->getFunctionType();
+ } else if (auto *ifunc = dyn_cast<llvm::GlobalIFunc>(calledOperand)) {
+ origCalleeType = cast<llvm::FunctionType>(ifunc->getValueType());
+ }
+
// For indirect calls, return the type of the call itself.
- if (!callee)
+ if (!origCalleeType)
return callType;
FailureOr<LLVMFunctionType> calleeType =
- castOrFailure(convertType(callee->getFunctionType()));
+ castOrFailure(convertType(origCalleeType));
if (failed(calleeType))
return failure();
@@ -2059,8 +2093,8 @@ ModuleImport::convertFunctionType(llvm::CallBase *callInst,
FlatSymbolRefAttr ModuleImport::convertCalleeName(llvm::CallBase *callInst) {
llvm::Value *calledOperand = callInst->getCalledOperand();
- if (auto *callee = dyn_cast<llvm::Function>(calledOperand))
- return SymbolRefAttr::get(context, callee->getName());
+ if (isa<llvm::Function, llvm::GlobalIFunc>(calledOperand))
+ return SymbolRefAttr::get(context, calledOperand->getName());
return {};
}
@@ -3162,6 +3196,8 @@ OwningOpRef<ModuleOp> mlir::translateLLVMIRToModule(
return {};
if (failed(moduleImport.convertAliases()))
return {};
+ if (failed(moduleImport.convertIFuncs()))
+ return {};
moduleImport.convertTargetTriple();
return module;
}