diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -1005,21 +1005,30 @@ mlir::Location loc, const fir::ExtendedValue &lhs, const fir::ExtendedValue &rhs) { - auto baseType = fir::unwrapPassByRefType(fir::getBase(lhs).getType()); - auto lhsType = baseType.dyn_cast(); + auto lbaseType = fir::unwrapPassByRefType(fir::getBase(lhs).getType()); + auto lhsType = lbaseType.dyn_cast(); assert(lhsType && "lhs must be a scalar record type"); + auto rbaseType = fir::unwrapPassByRefType(fir::getBase(rhs).getType()); + auto rhsType = rbaseType.dyn_cast(); + assert(rhsType && "rhs must be a scalar record type"); auto fieldIndexType = fir::FieldType::get(lhsType.getContext()); - for (auto [fieldName, fieldType] : lhsType.getTypeList()) { - assert(!fir::hasDynamicSize(fieldType)); - mlir::Value field = builder.create( - loc, fieldIndexType, fieldName, lhsType, fir::getTypeParams(lhs)); - auto fieldRefType = builder.getRefType(fieldType); + for (auto [lhsPair, rhsPair] : + llvm::zip(lhsType.getTypeList(), rhsType.getTypeList())) { + auto &[lFieldName, lFieldTy] = lhsPair; + auto &[rFieldName, rFieldTy] = rhsPair; + assert(!fir::hasDynamicSize(lFieldTy) && !fir::hasDynamicSize(rFieldTy)); + mlir::Value rField = builder.create( + loc, fieldIndexType, rFieldName, rhsType, fir::getTypeParams(rhs)); + auto rFieldRefType = builder.getRefType(rFieldTy); mlir::Value fromCoor = builder.create( - loc, fieldRefType, fir::getBase(rhs), field); + loc, rFieldRefType, fir::getBase(rhs), rField); + mlir::Value field = builder.create( + loc, fieldIndexType, lFieldName, lhsType, fir::getTypeParams(lhs)); + auto fieldRefType = builder.getRefType(lFieldTy); mlir::Value toCoor = builder.create( loc, fieldRefType, fir::getBase(lhs), field); llvm::Optional outerLoop; - if (auto sequenceType = fieldType.dyn_cast()) { + if (auto sequenceType = lFieldTy.dyn_cast()) { // Create loops to assign array components elements by elements. // Note that, since these are components, they either do not overlap, // or are the same and exactly overlap. They also have compile time @@ -1045,14 +1054,14 @@ fromCoor = builder.create(loc, elementRefType, fromCoor, indices); } - auto fieldElementType = fir::unwrapSequenceType(fieldType); - if (fieldElementType.isa()) { - assert(fieldElementType.cast() - .getEleTy() - .isa() && - "allocatable require deep copy"); + if (auto fieldEleTy = fir::unwrapSequenceType(lFieldTy); + fieldEleTy.isa()) { + assert( + fieldEleTy.cast().getEleTy().isa() && + "allocatable members require deep copy"); auto fromPointerValue = builder.create(loc, fromCoor); - builder.create(loc, fromPointerValue, toCoor); + auto castTo = builder.createConvert(loc, fieldEleTy, fromPointerValue); + builder.create(loc, castTo, toCoor); } else { auto from = fir::factory::componentToExtendedValue(builder, loc, fromCoor); diff --git a/flang/test/Lower/allocatable-assignment.f90 b/flang/test/Lower/allocatable-assignment.f90 --- a/flang/test/Lower/allocatable-assignment.f90 +++ b/flang/test/Lower/allocatable-assignment.f90 @@ -249,7 +249,8 @@ ! CHECK: } ! CHECK: %[[VAL_14:.*]] = fir.field_index i, !fir.type<_QMalloc_assignTt{i:i32}> ! CHECK: %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_14]] : (!fir.ref>, !fir.field) -> !fir.ref -! CHECK: %[[VAL_16:.*]] = fir.coordinate_of %[[VAL_7]]#1, %[[VAL_14]] : (!fir.heap>, !fir.field) -> !fir.ref +! CHECK: %[[VAL_14b:.*]] = fir.field_index i, !fir.type<_QMalloc_assignTt{i:i32}> +! CHECK: %[[VAL_16:.*]] = fir.coordinate_of %[[VAL_7]]#1, %[[VAL_14b]] : (!fir.heap>, !fir.field) -> !fir.ref ! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_15]] : !fir.ref ! CHECK: fir.store %[[VAL_17]] to %[[VAL_16]] : !fir.ref> ! CHECK: %[[FIELD:.*]] = fir.field_index i, !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}> ! CHECK: %[[FROM:.*]] = fir.coordinate_of %[[VAL_22]], %[[FIELD]] : (!fir.ref>, !fir.field) -> !fir.ref -! CHECK: %[[TO:.*]] = fir.coordinate_of %[[VAL_0]], %[[FIELD]] : (!fir.ref>, !fir.field) -> !fir.ref +! CHECK: %[[FIELD2:.*]] = fir.field_index i, !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}> +! CHECK: %[[TO:.*]] = fir.coordinate_of %[[VAL_0]], %[[FIELD2]] : (!fir.ref>, !fir.field) -> !fir.ref ! CHECK: %[[VAL:.*]] = fir.load %[[FROM]] : !fir.ref ! CHECK: fir.store %[[VAL]] to %[[TO]] : !fir.ref -! CHECK: %25 = fir.call @_QPelem_func_derived(%[[VAL_0]]) : (!fir.ref>) -> i32 +! CHECK: %{{.*}} = fir.call @_QPelem_func_derived(%[[VAL_0]]) : (!fir.ref>) -> i32 end subroutine end module diff --git a/flang/test/Lower/derived-assignments.f90 b/flang/test/Lower/derived-assignments.f90 --- a/flang/test/Lower/derived-assignments.f90 +++ b/flang/test/Lower/derived-assignments.f90 @@ -13,12 +13,14 @@ ! CHECK-DAG: %[[VAL_1:.*]] = fir.alloca !fir.type<_QFtest1Tt{a:i32,b:i32}> {{{.*}}uniq_name = "_QFtest1Et2"} ! CHECK: %[[VAL_2:.*]] = fir.field_index a, !fir.type<_QFtest1Tt{a:i32,b:i32}> ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref>, !fir.field) -> !fir.ref - ! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref>, !fir.field) -> !fir.ref + ! CHECK: %[[VAL_2b:.*]] = fir.field_index a, !fir.type<_QFtest1Tt{a:i32,b:i32}> + ! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2b]] : (!fir.ref>, !fir.field) -> !fir.ref ! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]] : !fir.ref ! CHECK: fir.store %[[VAL_5]] to %[[VAL_4]] : !fir.ref ! CHECK: %[[VAL_6:.*]] = fir.field_index b, !fir.type<_QFtest1Tt{a:i32,b:i32}> ! CHECK: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_6]] : (!fir.ref>, !fir.field) -> !fir.ref - ! CHECK: %[[VAL_8:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_6]] : (!fir.ref>, !fir.field) -> !fir.ref + ! CHECK: %[[VAL_6b:.*]] = fir.field_index b, !fir.type<_QFtest1Tt{a:i32,b:i32}> + ! CHECK: %[[VAL_8:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_6b]] : (!fir.ref>, !fir.field) -> !fir.ref ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_7]] : !fir.ref ! CHECK: fir.store %[[VAL_9]] to %[[VAL_8]] : !fir.ref t1 = t2 @@ -77,7 +79,8 @@ ! CHECK-DAG: %[[VAL_1:.*]] = fir.alloca !fir.type<_QFtest3Tt{m_c:!fir.char<1,20>,m_i:i32}> {{{.*}}uniq_name = "_QFtest3Et2"} ! CHECK: %[[VAL_2:.*]] = fir.field_index m_c, !fir.type<_QFtest3Tt{m_c:!fir.char<1,20>,m_i:i32}> ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref> - ! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref> + ! CHECK: %[[VAL_2b:.*]] = fir.field_index m_c, !fir.type<_QFtest3Tt{m_c:!fir.char<1,20>,m_i:i32}> + ! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2b]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref> ! CHECK: %[[VAL_5:.*]] = arith.constant 20 : index ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i64 ! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_5]] : (index) -> i64 @@ -88,7 +91,8 @@ ! CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_10]], %[[VAL_11]], %[[VAL_8]], %[[VAL_9]]) : (!fir.ref, !fir.ref, i64, i1) -> () ! CHECK: %[[VAL_12:.*]] = fir.field_index m_i, !fir.type<_QFtest3Tt{m_c:!fir.char<1,20>,m_i:i32}> ! CHECK: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_12]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref - ! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_12]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref + ! CHECK: %[[VAL_12b:.*]] = fir.field_index m_i, !fir.type<_QFtest3Tt{m_c:!fir.char<1,20>,m_i:i32}> + ! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_12b]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_13]] : !fir.ref ! CHECK: fir.store %[[VAL_15]] to %[[VAL_14]] : !fir.ref t1 = t2 @@ -106,7 +110,8 @@ ! CHECK: %[[VAL_2:.*]] = fir.field_index m_x, !fir.type<_QFtest_array_compTt{m_x:!fir.array<10xf32>,m_i:i32}> ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref> - ! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref> + ! CHECK: %[[VAL_2b:.*]] = fir.field_index m_x, !fir.type<_QFtest_array_compTt{m_x:!fir.array<10xf32>,m_i:i32}> + ! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2b]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref> ! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : index ! CHECK: %[[VAL_7:.*]] = arith.constant 9 : index @@ -118,7 +123,8 @@ ! CHECK: } ! CHECK: %[[VAL_12:.*]] = fir.field_index m_i, !fir.type<_QFtest_array_compTt{m_x:!fir.array<10xf32>,m_i:i32}> ! CHECK: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_12]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref - ! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_12]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref + ! CHECK: %[[VAL_12b:.*]] = fir.field_index m_i, !fir.type<_QFtest_array_compTt{m_x:!fir.array<10xf32>,m_i:i32}> + ! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_12b]] : (!fir.ref,m_i:i32}>>, !fir.field) -> !fir.ref ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_13]] : !fir.ref ! CHECK: fir.store %[[VAL_15]] to %[[VAL_14]] : !fir.ref t1 = t2 @@ -135,12 +141,14 @@ ! CHECK: %[[VAL_2:.*]] = fir.field_index ptr, !fir.type<_QFtest_ptr_compTt{ptr:!fir.box>>>,m_i:i32}> ! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref>>>,m_i:i32}>>, !fir.field) -> !fir.ref>>>> - ! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref>>>,m_i:i32}>>, !fir.field) -> !fir.ref>>>> + ! CHECK: %[[VAL_2b:.*]] = fir.field_index ptr, !fir.type<_QFtest_ptr_compTt{ptr:!fir.box>>>,m_i:i32}> + ! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2b]] : (!fir.ref>>>,m_i:i32}>>, !fir.field) -> !fir.ref>>>> ! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]] : !fir.ref>>>> ! CHECK: fir.store %[[VAL_5]] to %[[VAL_4]] : !fir.ref>>>> ! CHECK: %[[VAL_6:.*]] = fir.field_index m_i, !fir.type<_QFtest_ptr_compTt{ptr:!fir.box>>>,m_i:i32}> ! CHECK: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_6]] : (!fir.ref>>>,m_i:i32}>>, !fir.field) -> !fir.ref - ! CHECK: %[[VAL_8:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_6]] : (!fir.ref>>>,m_i:i32}>>, !fir.field) -> !fir.ref + ! CHECK: %[[VAL_6b:.*]] = fir.field_index m_i, !fir.type<_QFtest_ptr_compTt{ptr:!fir.box>>>,m_i:i32}> + ! CHECK: %[[VAL_8:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_6b]] : (!fir.ref>>>,m_i:i32}>>, !fir.field) -> !fir.ref ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_7]] : !fir.ref ! CHECK: fir.store %[[VAL_9]] to %[[VAL_8]] : !fir.ref t1 = t2 diff --git a/flang/test/Lower/structure-constructors.f90 b/flang/test/Lower/structure-constructors.f90 --- a/flang/test/Lower/structure-constructors.f90 +++ b/flang/test/Lower/structure-constructors.f90 @@ -177,12 +177,14 @@ ! CHECK: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_6]] : (!fir.ref}>}>>, !fir.field) -> !fir.ref}>> ! CHECK: %[[VAL_8:.*]] = fir.field_index x, !fir.type<_QMm_struct_ctorTt_array{x:f32,i:!fir.array<5xi32>}> ! CHECK: %[[VAL_9:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_8]] : (!fir.ref}>>, !fir.field) -> !fir.ref - ! CHECK: %[[VAL_10:.*]] = fir.coordinate_of %[[VAL_7]], %[[VAL_8]] : (!fir.ref}>>, !fir.field) -> !fir.ref + ! CHECK: %[[VAL_8b:.*]] = fir.field_index x, !fir.type<_QMm_struct_ctorTt_array{x:f32,i:!fir.array<5xi32>}> + ! CHECK: %[[VAL_10:.*]] = fir.coordinate_of %[[VAL_7]], %[[VAL_8b]] : (!fir.ref}>>, !fir.field) -> !fir.ref ! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref ! CHECK: fir.store %[[VAL_11]] to %[[VAL_10]] : !fir.ref ! CHECK: %[[VAL_12:.*]] = fir.field_index i, !fir.type<_QMm_struct_ctorTt_array{x:f32,i:!fir.array<5xi32>}> ! CHECK: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_12]] : (!fir.ref}>>, !fir.field) -> !fir.ref> - ! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_7]], %[[VAL_12]] : (!fir.ref}>>, !fir.field) -> !fir.ref> + ! CHECK: %[[VAL_12b:.*]] = fir.field_index i, !fir.type<_QMm_struct_ctorTt_array{x:f32,i:!fir.array<5xi32>}> + ! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_7]], %[[VAL_12b]] : (!fir.ref}>>, !fir.field) -> !fir.ref> ! CHECK: %[[VAL_15:.*]] = arith.constant 0 : index ! CHECK: %[[VAL_16:.*]] = arith.constant 1 : index ! CHECK: %[[VAL_17:.*]] = arith.constant 4 : index