diff --git a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp --- a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp +++ b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp @@ -38,12 +38,60 @@ [&](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) { + llvm::errs() << "passthrough\n"; return LLVM::isCompatibleType(type) ? llvm::Optional(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 { + if (auto pointee = convertType(type.getElementType())) + return LLVM::LLVMPointerType::get(pointee, type.getAddressSpace()); + return llvm::None; + }); + addConversion([&](LLVM::LLVMStructType type) -> llvm::Optional { + // TODO: handle conversion of identified structs, which may be recursive. + if (type.isIdentified()) + return type; + + SmallVector convertedSubtypes; + convertedSubtypes.reserve(type.getBody().size()); + for (Type nested : type.getBody()) { + convertedSubtypes.push_back(convertType(nested)); + if (!convertedSubtypes.back()) + return llvm::None; + } + + return LLVM::LLVMStructType::getLiteral(type.getContext(), + convertedSubtypes, type.isPacked()); + }); + addConversion([&](LLVM::LLVMArrayType type) -> llvm::Optional { + if (auto element = convertType(type.getElementType())) + return LLVM::LLVMArrayType::get(element, type.getNumElements()); + return llvm::None; + }); + addConversion([&](LLVM::LLVMFunctionType type) -> llvm::Optional { + Type convertedResType = convertType(type.getReturnType()); + if (!convertedResType) + return llvm::None; + + SmallVector convertedArgTypes; + convertedArgTypes.reserve(type.getNumParams()); + for (Type t : type.getParams()) { + convertedArgTypes.push_back(convertType(t)); + if (!convertedArgTypes.back()) + 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. diff --git a/mlir/test/lib/Conversion/StandardToLLVM/TestConvertCallOp.cpp b/mlir/test/lib/Conversion/StandardToLLVM/TestConvertCallOp.cpp --- a/mlir/test/lib/Conversion/StandardToLLVM/TestConvertCallOp.cpp +++ b/mlir/test/lib/Conversion/StandardToLLVM/TestConvertCallOp.cpp @@ -52,6 +52,9 @@ typeConverter.addConversion([&](test::TestType type) { return LLVM::LLVMPointerType::get(IntegerType::get(m.getContext(), 8)); }); + typeConverter.addConversion([&](test::SimpleAType type) { + return IntegerType::get(type.getContext(), 42); + }); // Populate patterns. RewritePatternSet patterns(m.getContext());