@@ -258,6 +258,70 @@ static SmallVector<unsigned> extractPosition(ArrayRef<int64_t> indices) {
258
258
return position;
259
259
}
260
260
261
+ // / Get the declaration of an overloaded llvm intrinsic. First we get the
262
+ // / overloaded argument types and/or result type from the CallIntrinsicOp, and
263
+ // / then use those to get the correct declaration of the overloaded intrinsic.
264
+ static FailureOr<llvm::Function *>
265
+ getOverloadedDeclaration (CallIntrinsicOp &op, llvm::Intrinsic::ID id,
266
+ llvm::Module *module ,
267
+ LLVM::ModuleTranslation &moduleTranslation) {
268
+ SmallVector<llvm::Type *, 8 > allArgTys;
269
+ for (Type type : op->getOperandTypes ())
270
+ allArgTys.push_back (moduleTranslation.convertType (type));
271
+
272
+ llvm::Type *resTy;
273
+ if (op.getNumResults () == 0 )
274
+ resTy = llvm::Type::getVoidTy (module ->getContext ());
275
+ else
276
+ resTy = moduleTranslation.convertType (op.getResult (0 ).getType ());
277
+
278
+ // ATM we do not support variadic intrinsics.
279
+ llvm::FunctionType *ft = llvm::FunctionType::get (resTy, allArgTys, false );
280
+
281
+ SmallVector<llvm::Intrinsic::IITDescriptor, 8 > table;
282
+ getIntrinsicInfoTableEntries (id, table);
283
+ ArrayRef<llvm::Intrinsic::IITDescriptor> tableRef = table;
284
+
285
+ SmallVector<llvm::Type *, 8 > overloadedArgTys;
286
+ if (llvm::Intrinsic::matchIntrinsicSignature (ft, tableRef,
287
+ overloadedArgTys) !=
288
+ llvm::Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) {
289
+ return op.emitOpError (" intrinsic type is not a match" );
290
+ }
291
+
292
+ ArrayRef<llvm::Type *> overloadedArgTysRef = overloadedArgTys;
293
+ return llvm::Intrinsic::getDeclaration (module , id, overloadedArgTysRef);
294
+ }
295
+
296
+ // / Builder for LLVM_CallIntrinsicOp
297
+ static LogicalResult
298
+ convertCallLLVMIntrinsicOp (CallIntrinsicOp &op, llvm::IRBuilderBase &builder,
299
+ LLVM::ModuleTranslation &moduleTranslation) {
300
+ llvm::Module *module = builder.GetInsertBlock ()->getModule ();
301
+ llvm::Intrinsic::ID id =
302
+ llvm::Function::lookupIntrinsicID (op.getIntrinAttr ());
303
+ if (!id)
304
+ return op.emitOpError ()
305
+ << " couldn't find intrinsic: " << op.getIntrinAttr ();
306
+
307
+ llvm::Function *fn = nullptr ;
308
+ if (llvm::Intrinsic::isOverloaded (id)) {
309
+ auto fnOrFailure =
310
+ getOverloadedDeclaration (op, id, module , moduleTranslation);
311
+ if (failed (fnOrFailure))
312
+ return failure ();
313
+ fn = fnOrFailure.value ();
314
+ } else {
315
+ fn = llvm::Intrinsic::getDeclaration (module , id, {});
316
+ }
317
+
318
+ auto *inst =
319
+ builder.CreateCall (fn, moduleTranslation.lookupValues (op.getOperands ()));
320
+ if (op.getNumResults () == 1 )
321
+ moduleTranslation.mapValue (op->getResults ().front ()) = inst;
322
+ return success ();
323
+ }
324
+
261
325
static LogicalResult
262
326
convertOperationImpl (Operation &opInst, llvm::IRBuilderBase &builder,
263
327
LLVM::ModuleTranslation &moduleTranslation) {
@@ -272,8 +336,8 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
272
336
// Emit function calls. If the "callee" attribute is present, this is a
273
337
// direct function call and we also need to look up the remapped function
274
338
// itself. Otherwise, this is an indirect call and the callee is the first
275
- // operand, look it up as a normal value. Return the llvm::Value representing
276
- // the function result, which may be of llvm::VoidTy type.
339
+ // operand, look it up as a normal value. Return the llvm::Value
340
+ // representing the function result, which may be of llvm::VoidTy type.
277
341
auto convertCall = [&](Operation &op) -> llvm::Value * {
278
342
auto operands = moduleTranslation.lookupValues (op.getOperands ());
279
343
ArrayRef<llvm::Value *> operandsRef (operands);
@@ -404,8 +468,8 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
404
468
return success ();
405
469
}
406
470
407
- // Emit branches. We need to look up the remapped blocks and ignore the block
408
- // arguments that were transformed into PHI nodes.
471
+ // Emit branches. We need to look up the remapped blocks and ignore the
472
+ // block arguments that were transformed into PHI nodes.
409
473
if (auto brOp = dyn_cast<LLVM::BrOp>(opInst)) {
410
474
llvm::BranchInst *branch =
411
475
builder.CreateBr (moduleTranslation.lookupBlock (brOp.getSuccessor ()));
0 commit comments