diff options
Diffstat (limited to 'flang/lib/Optimizer/CodeGen/CodeGen.cpp')
| -rw-r--r-- | flang/lib/Optimizer/CodeGen/CodeGen.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index 1611de9e6389..15fcc09c6219 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -660,6 +660,31 @@ struct ConvertOpConversion : public fir::FIROpConversion<fir::ConvertOp> { auto loc = convert.getLoc(); auto i1Type = mlir::IntegerType::get(convert.getContext(), 1); + if (mlir::isa<fir::RecordType>(toFirTy)) { + // Convert to compatible BIND(C) record type. + // Double check that the record types are compatible (it should have + // already been checked by the verifier). + assert(mlir::cast<fir::RecordType>(fromFirTy).getTypeList() == + mlir::cast<fir::RecordType>(toFirTy).getTypeList() && + "incompatible record types"); + + auto toStTy = mlir::cast<mlir::LLVM::LLVMStructType>(toTy); + mlir::Value val = rewriter.create<mlir::LLVM::UndefOp>(loc, toStTy); + auto indexTypeMap = toStTy.getSubelementIndexMap(); + assert(indexTypeMap.has_value() && "invalid record type"); + + for (auto [attr, type] : indexTypeMap.value()) { + int64_t index = mlir::cast<mlir::IntegerAttr>(attr).getInt(); + auto extVal = + rewriter.create<mlir::LLVM::ExtractValueOp>(loc, op0, index); + val = + rewriter.create<mlir::LLVM::InsertValueOp>(loc, val, extVal, index); + } + + rewriter.replaceOp(convert, val); + return mlir::success(); + } + if (mlir::isa<fir::LogicalType>(fromFirTy) || mlir::isa<fir::LogicalType>(toFirTy)) { // By specification fir::LogicalType value may be any number, |
