2424#include " llvm/IR/InlineAsm.h"
2525#include " llvm/IR/Instructions.h"
2626#include " llvm/IR/IntrinsicInst.h"
27+ #include " llvm/IR/IntrinsicsAArch64.h"
28+ #include " llvm/IR/IntrinsicsAMDGPU.h"
29+ #include " llvm/IR/IntrinsicsARM.h"
30+ #include " llvm/IR/IntrinsicsBPF.h"
31+ #include " llvm/IR/IntrinsicsDirectX.h"
32+ #include " llvm/IR/IntrinsicsHexagon.h"
33+ #include " llvm/IR/IntrinsicsLoongArch.h"
34+ #include " llvm/IR/IntrinsicsMips.h"
35+ #include " llvm/IR/IntrinsicsNVPTX.h"
36+ #include " llvm/IR/IntrinsicsPowerPC.h"
37+ #include " llvm/IR/IntrinsicsR600.h"
38+ #include " llvm/IR/IntrinsicsRISCV.h"
39+ #include " llvm/IR/IntrinsicsS390.h"
40+ #include " llvm/IR/IntrinsicsSPIRV.h"
41+ #include " llvm/IR/IntrinsicsVE.h"
42+ #include " llvm/IR/IntrinsicsWebAssembly.h"
43+ #include " llvm/IR/IntrinsicsX86.h"
44+ #include " llvm/IR/IntrinsicsXCore.h"
2745#include " llvm/Support/ModRef.h"
2846
2947using namespace mlir ;
@@ -56,6 +74,105 @@ static ArrayRef<unsigned> getSupportedIntrinsicsImpl() {
5674 return convertibleIntrinsics;
5775}
5876
77+ // / Returns true if the LLVM IR intrinsic is convertible to llvm.intrinsic_call
78+ // / Returns false otherwise.
79+ static bool isConvertibleUnregisteredIntrinsic (llvm::Intrinsic::ID id) {
80+ static const DenseSet<unsigned > convertibleTargetIntrinsics = {
81+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredAArch64LLVMIRIntrinsics.inc"
82+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredAMDGPULLVMIRIntrinsics.inc"
83+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredARMLLVMIRIntrinsics.inc"
84+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredBPFLLVMIRIntrinsics.inc"
85+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredDirectXLLVMIRIntrinsics.inc"
86+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredHexagonLLVMIRIntrinsics.inc"
87+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredLLVMIRIntrinsics.inc"
88+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredLoongArchLLVMIRIntrinsics.inc"
89+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredMipsLLVMIRIntrinsics.inc"
90+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredNVPTXLLVMIRIntrinsics.inc"
91+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredPowerPCLLVMIRIntrinsics.inc"
92+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredR600LLVMIRIntrinsics.inc"
93+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredRISCVLLVMIRIntrinsics.inc"
94+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredS390LLVMIRIntrinsics.inc"
95+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredSPIRVLLVMIRIntrinsics.inc"
96+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredVELLVMIRIntrinsics.inc"
97+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredWebAssemblyLLVMIRIntrinsics.inc"
98+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredX86LLVMIRIntrinsics.inc"
99+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredXCoreLLVMIRIntrinsics.inc"
100+ };
101+ return convertibleTargetIntrinsics.contains (id);
102+ }
103+
104+ // / Returns the list of LLVM IR intrinsic identifiers that are not registered
105+ // / by any dialect but can be convertible to llvm.intrinsic_call operation.
106+ static ArrayRef<unsigned > getUnregisteredIntrinsicsImpl () {
107+ static const SmallVector<unsigned > convertibleTargetIntrinsics = {
108+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredAArch64LLVMIRIntrinsics.inc"
109+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredAMDGPULLVMIRIntrinsics.inc"
110+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredARMLLVMIRIntrinsics.inc"
111+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredBPFLLVMIRIntrinsics.inc"
112+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredDirectXLLVMIRIntrinsics.inc"
113+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredHexagonLLVMIRIntrinsics.inc"
114+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredLLVMIRIntrinsics.inc"
115+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredLoongArchLLVMIRIntrinsics.inc"
116+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredMipsLLVMIRIntrinsics.inc"
117+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredNVPTXLLVMIRIntrinsics.inc"
118+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredPowerPCLLVMIRIntrinsics.inc"
119+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredR600LLVMIRIntrinsics.inc"
120+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredRISCVLLVMIRIntrinsics.inc"
121+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredS390LLVMIRIntrinsics.inc"
122+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredSPIRVLLVMIRIntrinsics.inc"
123+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredVELLVMIRIntrinsics.inc"
124+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredWebAssemblyLLVMIRIntrinsics.inc"
125+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredX86LLVMIRIntrinsics.inc"
126+ #include " mlir/Dialect/LLVMIR/LLVMUnregisteredXCoreLLVMIRIntrinsics.inc"
127+ };
128+ return convertibleTargetIntrinsics;
129+ }
130+
131+ // / Converts the LLVM intrinsic to a generic LLVM intrinsic call using
132+ // / llvm.intrinsic_call. Returns failure otherwise.
133+ static LogicalResult
134+ convertUnregisteredIntrinsicImpl (OpBuilder &odsBuilder, llvm::CallInst *inst,
135+ LLVM::ModuleImport &moduleImport) {
136+ llvm::Intrinsic::ID intrinsicID = inst->getIntrinsicID ();
137+ StringRef intrinName = inst->getCalledFunction ()->getName ();
138+
139+ // Sanity check the intrinsic ID.
140+ assert (isConvertibleUnregisteredIntrinsic (intrinsicID));
141+ SmallVector<llvm::Value *> args (inst->args ());
142+ ArrayRef<llvm::Value *> llvmOperands (args);
143+
144+ SmallVector<llvm::OperandBundleUse> llvmOpBundles;
145+ llvmOpBundles.reserve (inst->getNumOperandBundles ());
146+ for (unsigned i = 0 ; i < inst->getNumOperandBundles (); ++i)
147+ llvmOpBundles.push_back (inst->getOperandBundleAt (i));
148+
149+ SmallVector<Value> mlirOperands;
150+ SmallVector<NamedAttribute> mlirAttrs;
151+ if (failed (moduleImport.convertIntrinsicArguments (
152+ llvmOperands, llvmOpBundles, false , {}, {}, mlirOperands, mlirAttrs)))
153+ return failure ();
154+
155+ mlir::Type results = moduleImport.convertType (inst->getType ());
156+ auto op = odsBuilder.create <::mlir::LLVM::CallIntrinsicOp>(
157+ moduleImport.translateLoc (inst->getDebugLoc ()), results,
158+ StringAttr::get (odsBuilder.getContext (), intrinName),
159+ ValueRange{mlirOperands}, FastmathFlagsAttr{});
160+
161+ moduleImport.setFastmathFlagsAttr (inst, op);
162+
163+ // Update importer tracking of results.
164+ unsigned numRes = op.getNumResults ();
165+ if (numRes == 1 )
166+ moduleImport.mapValue (inst) = op.getResult (0 );
167+ else if (numRes == 0 )
168+ moduleImport.mapNoResultOp (inst);
169+ else
170+ return op.emitError (
171+ " expected at most one result from target intrinsic call" );
172+
173+ return success ();
174+ }
175+
59176// / Converts the LLVM intrinsic to an MLIR LLVM dialect operation if a
60177// / conversion exits. Returns failure otherwise.
61178static LogicalResult convertIntrinsicImpl (OpBuilder &odsBuilder,
@@ -75,6 +192,8 @@ static LogicalResult convertIntrinsicImpl(OpBuilder &odsBuilder,
75192 llvmOpBundles.push_back (inst->getOperandBundleAt (i));
76193
77194#include " mlir/Dialect/LLVMIR/LLVMIntrinsicFromLLVMIRConversions.inc"
195+ } else if (isConvertibleUnregisteredIntrinsic (intrinsicID)) {
196+ return convertUnregisteredIntrinsicImpl (odsBuilder, inst, moduleImport);
78197 }
79198
80199 return failure ();
@@ -422,6 +541,12 @@ class LLVMDialectLLVMIRImportInterface : public LLVMImportDialectInterface {
422541 return getSupportedIntrinsicsImpl ();
423542 }
424543
544+ // / Returns the list of LLVM IR intrinsic identifiers that are unsupported
545+ // / by existing dialects by are convertible to generic llvm.call_intrinsic.
546+ ArrayRef<unsigned > getUnregisteredIntrinsics () const final {
547+ return getUnregisteredIntrinsicsImpl ();
548+ }
549+
425550 // / Returns the list of LLVM IR metadata kinds that are convertible to MLIR
426551 // / LLVM dialect attributes.
427552 ArrayRef<unsigned >
0 commit comments