[&](UnrankedMemRefType type) { return convertUnrankedMemRefType(type); });
addConversion([&](VectorType type) { return convertVectorType(type); });
- // LLVM-compatible types are legal, so add a pass-through conversion.
+ // LLVM-compatible types are legal, so add a pass-through conversion. Do this
+ // before the conversions below since conversions are attempted in reverse
+ // order and those should take priority.
addConversion([](Type type) {
return LLVM::isCompatibleType(type) ? llvm::Optional<Type>(type)
: llvm::None;
});
+ // LLVM container types may (recursively) contain other types that must be
+ // converted even when the outer type is compatible.
+ addConversion([&](LLVM::LLVMPointerType type) -> llvm::Optional<Type> {
+ if (auto pointee = convertType(type.getElementType()))
+ return LLVM::LLVMPointerType::get(pointee, type.getAddressSpace());
+ return llvm::None;
+ });
+ addConversion([&](LLVM::LLVMStructType type) -> llvm::Optional<Type> {
+ // TODO: handle conversion of identified structs, which may be recursive.
+ if (type.isIdentified())
+ return type;
+
+ SmallVector<Type> convertedSubtypes;
+ convertedSubtypes.reserve(type.getBody().size());
+ if (failed(convertTypes(type.getBody(), convertedSubtypes)))
+ return llvm::None;
+
+ return LLVM::LLVMStructType::getLiteral(type.getContext(),
+ convertedSubtypes, type.isPacked());
+ });
+ addConversion([&](LLVM::LLVMArrayType type) -> llvm::Optional<Type> {
+ if (auto element = convertType(type.getElementType()))
+ return LLVM::LLVMArrayType::get(element, type.getNumElements());
+ return llvm::None;
+ });
+ addConversion([&](LLVM::LLVMFunctionType type) -> llvm::Optional<Type> {
+ Type convertedResType = convertType(type.getReturnType());
+ if (!convertedResType)
+ return llvm::None;
+
+ SmallVector<Type> convertedArgTypes;
+ convertedArgTypes.reserve(type.getNumParams());
+ if (failed(convertTypes(type.getParams(), convertedArgTypes)))
+ return llvm::None;
+
+ return LLVM::LLVMFunctionType::get(convertedResType, convertedArgTypes,
+ type.isVarArg());
+ });
+
// Materialization for memrefs creates descriptor structs from individual
// values constituting them, when descriptors are used, i.e. more than one
// value represents a memref.
--- /dev/null
+// RUN: mlir-opt -test-convert-call-op %s | FileCheck %s
+
+// CHECK-LABEL: @ptr
+// CHECK: !llvm.ptr<i42>
+func private @ptr() -> !llvm.ptr<!test.smpla>
+
+// CHECK-LABEL: @ptr_ptr()
+// CHECK: !llvm.ptr<ptr<i42>>
+func private @ptr_ptr() -> !llvm.ptr<!llvm.ptr<!test.smpla>>
+
+// CHECK-LABEL: @struct_ptr()
+// CHECK: !llvm.struct<(ptr<i42>)>
+func private @struct_ptr() -> !llvm.struct<(ptr<!test.smpla>)>
+
+// CHECK-LABEL: @named_struct_ptr()
+// CHECK: !llvm.struct<"named", (ptr<!test.smpla>)>
+func private @named_struct_ptr() -> !llvm.struct<"named", (ptr<!test.smpla>)>
+
+// CHECK-LABEL: @array_ptr()
+// CHECK: !llvm.array<10 x ptr<i42>>
+func private @array_ptr() -> !llvm.array<10 x ptr<!test.smpla>>
+
+// CHECK-LABEL: @func()
+// CHECK: !llvm.ptr<func<i42 (i42)>>
+func private @func() -> !llvm.ptr<!llvm.func<!test.smpla (!test.smpla)>>
+
+// TODO: support conversion of recursive types in the conversion infra.
+// CHECK-LABEL: @named_recursive()
+// CHECK: !llvm.struct<"recursive", (ptr<!test.smpla>, ptr<struct<"recursive">>)>
+func private @named_recursive() -> !llvm.struct<"recursive", (ptr<!test.smpla>, ptr<struct<"recursive">>)>
+