
…sic_call Original introduced in https://github.com/llvm/llvm-project/pull/128626, reverted in https://github.com/llvm/llvm-project/pull/128973 Reproduced the issue on a shared lib build locally on Linux, moved content around to satisfy both static and shared lib builds. ### Original commit message Currently, the llvm importer can only cover intrinsics that have a first class representation in an MLIR dialect (arm-neon, etc). This PR introduces a fallback mechanism that allow "unregistered" intrinsics to be imported by using the generic `llvm.intrinsic_call` operation. This is useful in several ways: 1. Allows round-trip the LLVM dialect output lowered from other dialects (example: ClangIR) 2. Enables MLIR-linking tools to operate on imported LLVM IR without requiring to add new operations to dozen of different targets. If multiple dialects implement this interface hook, the last one to register is the one converting all unregistered intrinsics. --------- Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
60 lines
2.1 KiB
C++
60 lines
2.1 KiB
C++
//===------------------------------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements methods from LLVMImportInterface.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Target/LLVMIR/LLVMImportInterface.h"
|
|
#include "mlir/Target/LLVMIR/Import.h"
|
|
#include "mlir/Target/LLVMIR/ModuleImport.h"
|
|
|
|
using namespace mlir;
|
|
using namespace mlir::LLVM;
|
|
using namespace mlir::LLVM::detail;
|
|
|
|
LogicalResult mlir::LLVMImportInterface::convertUnregisteredIntrinsic(
|
|
OpBuilder &builder, llvm::CallInst *inst,
|
|
LLVM::ModuleImport &moduleImport) {
|
|
StringRef intrinName = inst->getCalledFunction()->getName();
|
|
|
|
SmallVector<llvm::Value *> args(inst->args());
|
|
ArrayRef<llvm::Value *> llvmOperands(args);
|
|
|
|
SmallVector<llvm::OperandBundleUse> llvmOpBundles;
|
|
llvmOpBundles.reserve(inst->getNumOperandBundles());
|
|
for (unsigned i = 0; i < inst->getNumOperandBundles(); ++i)
|
|
llvmOpBundles.push_back(inst->getOperandBundleAt(i));
|
|
|
|
SmallVector<Value> mlirOperands;
|
|
SmallVector<NamedAttribute> mlirAttrs;
|
|
if (failed(moduleImport.convertIntrinsicArguments(
|
|
llvmOperands, llvmOpBundles, false, {}, {}, mlirOperands, mlirAttrs)))
|
|
return failure();
|
|
|
|
Type results = moduleImport.convertType(inst->getType());
|
|
auto op = builder.create<::mlir::LLVM::CallIntrinsicOp>(
|
|
moduleImport.translateLoc(inst->getDebugLoc()), results,
|
|
StringAttr::get(builder.getContext(), intrinName),
|
|
ValueRange{mlirOperands}, FastmathFlagsAttr{});
|
|
|
|
moduleImport.setFastmathFlagsAttr(inst, op);
|
|
|
|
// Update importer tracking of results.
|
|
unsigned numRes = op.getNumResults();
|
|
if (numRes == 1)
|
|
moduleImport.mapValue(inst) = op.getResult(0);
|
|
else if (numRes == 0)
|
|
moduleImport.mapNoResultOp(inst);
|
|
else
|
|
return op.emitError(
|
|
"expected at most one result from target intrinsic call");
|
|
|
|
return success();
|
|
}
|