diff --git a/lib/Conversion/LLHDToLLVM/CMakeLists.txt b/lib/Conversion/LLHDToLLVM/CMakeLists.txt index ddeae50e4a..2069542b70 100644 --- a/lib/Conversion/LLHDToLLVM/CMakeLists.txt +++ b/lib/Conversion/LLHDToLLVM/CMakeLists.txt @@ -15,4 +15,5 @@ add_circt_conversion_library(CIRCTLLHDToLLVM MLIRStandardToLLVM MLIRVector MLIRTransforms + MLIRReconcileUnrealizedCasts ) diff --git a/lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp b/lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp index 9e4705f12f..3a7ca99a65 100644 --- a/lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp +++ b/lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp @@ -19,6 +19,7 @@ #include "circt/Support/LLVM.h" #include "mlir/Conversion/LLVMCommon/ConversionTarget.h" #include "mlir/Conversion/LLVMCommon/Pattern.h" +#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h" #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h" #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" @@ -290,20 +291,23 @@ static void persistValue(LLVM::LLVMDialect *dialect, Location loc, rewriter.setInsertionPointAfter(persist.getDefiningOp()); } + Value convPersist = converter->materializeTargetConversion( + rewriter, loc, converter->convertType(persist.getType()), {persist}); + auto gep0 = gepPersistenceState(dialect, loc, rewriter, elemTy, i, state); Value toStore; if (auto ptr = persist.getType().dyn_cast()) { // Unwrap the pointer and store it's value. auto elemTy = converter->convertType(ptr.getUnderlyingType()); - toStore = rewriter.create(loc, elemTy, persist); + toStore = rewriter.create(loc, elemTy, convPersist); } else if (persist.getType().isa()) { // Unwrap and store the signal struct. - toStore = - rewriter.create(loc, getLLVMSigType(dialect), persist); + toStore = rewriter.create(loc, getLLVMSigType(dialect), + convPersist); } else { // Store the value directly. - toStore = persist; + toStore = convPersist; } rewriter.create(loc, toStore, gep0); @@ -313,6 +317,7 @@ static void persistValue(LLVM::LLVMDialect *dialect, Location loc, for (auto &use : llvm::make_early_inc_range(persist.getUses())) { auto user = use.getOwner(); if (persist.getType().isa() && user != toStore.getDefiningOp() && + user != convPersist.getDefiningOp() && persist.getParentBlock() == user->getBlock()) { // Redirect uses of the pointer in the same block to the pointer in the // persistence state. This ensures that stores and loads all operate on @@ -1247,6 +1252,9 @@ struct InstOpConversion : public ConvertToLLVMPattern { // operand (assmued to be a constant/array op) auto defOp = op.init().getDefiningOp(); auto initDef = recursiveCloneInit(initBuilder, defOp)->getResult(0); + Value initDefCast = typeConverter->materializeTargetConversion( + initBuilder, initDef.getLoc(), + typeConverter->convertType(initDef.getType()), initDef); // Compute the required space to malloc. auto oneC = initBuilder.create( @@ -1274,7 +1282,8 @@ struct InstOpConversion : public ConvertToLLVMPattern { // Store the initial value. auto bitcast = initBuilder.create( op.getLoc(), LLVM::LLVMPointerType::get(underlyingTy), mall); - initBuilder.create(op.getLoc(), initDef, bitcast); + + initBuilder.create(op.getLoc(), initDefCast, bitcast); // Get the amount of bytes required to represent an integer underlying // type. Use the whole size of the type if not an integer. @@ -1634,11 +1643,11 @@ struct DrvOpConversion : public ConvertToLLVMPattern { rewriter.setInsertionPointToStart(drvBlock); } + Type valTy = typeConverter->convertType(transformed.value().getType()); auto oneConst = rewriter.create( op->getLoc(), i32Ty, rewriter.getI32IntegerAttr(1)); auto alloca = rewriter.create( - op->getLoc(), LLVM::LLVMPointerType::get(transformed.value().getType()), - oneConst, 4); + op->getLoc(), LLVM::LLVMPointerType::get(valTy), oneConst, 4); rewriter.create(op->getLoc(), transformed.value(), alloca); auto bc = rewriter.create(op->getLoc(), i8PtrTy, alloca); @@ -2381,7 +2390,8 @@ struct DynExtractSliceOpConversion : public ConvertToLLVMPattern { if (auto arrTy = extsOp.result().getType().dyn_cast()) { auto elemTy = typeConverter->convertType(arrTy.getElementType()); auto llvmArrTy = typeConverter->convertType(arrTy); - auto targetTy = transformed.target().getType(); + auto targetTy = + typeConverter->convertType(transformed.target().getType()); auto zeroC = rewriter.create( op->getLoc(), i64Ty, rewriter.getI64IntegerAttr(0)); @@ -2741,12 +2751,12 @@ struct VarOpConversion : ConvertToLLVMPattern { VarOpAdaptor transformed(operands); auto i32Ty = IntegerType::get(rewriter.getContext(), 32); + Type initTy = typeConverter->convertType(transformed.init().getType()); auto oneC = rewriter.create( op->getLoc(), i32Ty, rewriter.getI32IntegerAttr(1)); auto alloca = rewriter.create( - op->getLoc(), LLVM::LLVMPointerType::get(transformed.init().getType()), - oneC, 4); + op->getLoc(), LLVM::LLVMPointerType::get(initTy), oneC, 4); rewriter.create(op->getLoc(), transformed.init(), alloca); rewriter.replaceOp(op, alloca.getResult()); return success(); @@ -2881,6 +2891,14 @@ void LLHDToLLVMLoweringPass::runOnOperation() { target.addLegalDialect(); target.addLegalOp(); + + // Apply a full conversion to remove unrealized conversion casts. + if (failed(applyFullConversion(getOperation(), target, std::move(patterns)))) + signalPassFailure(); + + patterns.clear(); + + mlir::populateReconcileUnrealizedCastsPatterns(patterns); target.addIllegalOp(); // Apply the full conversion. diff --git a/llvm b/llvm index f4726e7238..704a395693 160000 --- a/llvm +++ b/llvm @@ -1 +1 @@ -Subproject commit f4726e72386d4107f427f3b4825bdfb92d0d1a1e +Subproject commit 704a39569346401e96a6a3978ddc490dfa828ccc