diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -7236,53 +7236,26 @@ auto &builder = converter.getFirOpBuilder(); mlir::Value boxBase = fir::getBase(box); mlir::Operation *op = boxBase.getDefiningOp(); - auto boxTy = boxBase.getType().dyn_cast(); - mlir::Type boxEleTy = fir::unwrapAllRefAndSeqType(boxTy.getEleTy()); - auto originalRecTy = boxEleTy.dyn_cast(); mlir::Type actualTy = converter.genType(expr); - mlir::Type eleTy = fir::unwrapAllRefAndSeqType(actualTy); - auto parentCompTy = eleTy.dyn_cast(); - assert(parentCompTy && "expecting derived-type"); - - assert((mlir::dyn_cast(op) || - mlir::dyn_cast(op) || - mlir::dyn_cast(op)) && - "expecting fir.embox or fir.rebox or fir.convert operation"); - - if (parentCompTy.getTypeList().empty()) - TODO(loc, "parent component with no component"); - - // Creating a slice with a path to the first component of the parent component - // of the extended type. - auto firstComponent = parentCompTy.getTypeList().front(); - auto fieldTy = fir::FieldType::get(boxTy.getContext()); - auto field = builder.create( - loc, fieldTy, firstComponent.first, originalRecTy, - /*typeParams=*/mlir::ValueRange{}); - - if (auto convert = mlir::dyn_cast(op)) { - auto rebox = builder.create(loc, fir::BoxType::get(actualTy), - convert.getValue(), mlir::Value{}, - mlir::Value{}); - return fir::substBase(box, fir::getBase(rebox)); - } + if (auto embox = mlir::dyn_cast(op)) { - mlir::Value slice = createSliceForParentComp(builder, loc, embox, box, - field, expr.Rank() > 0); auto newBox = builder.create( loc, fir::BoxType::get(actualTy), embox.getMemref(), embox.getShape(), - slice, embox.getTypeparams()); - return fir::substBase(box, fir::getBase(newBox)); + embox.getSlice(), embox.getTypeparams()); + return fir::substBase(box, newBox); } if (auto rebox = mlir::dyn_cast(op)) { - mlir::Value slice = createSliceForParentComp(builder, loc, rebox, box, - field, expr.Rank() > 0); - auto newBox = - builder.create(loc, fir::BoxType::get(actualTy), - rebox.getBox(), rebox.getShape(), slice); - return fir::substBase(box, fir::getBase(newBox)); - } - return box; + auto newBox = builder.create(loc, fir::BoxType::get(actualTy), + rebox.getBox(), rebox.getShape(), + rebox.getSlice()); + return fir::substBase(box, newBox); + } + + mlir::Value empty; + mlir::ValueRange emptyRange; + return builder.create(loc, fir::BoxType::get(actualTy), boxBase, + /*shape=*/empty, + /*slice=*/empty); } fir::ExtendedValue Fortran::lower::createBoxValue( diff --git a/flang/test/Lower/parent-component.f90 b/flang/test/Lower/parent-component.f90 --- a/flang/test/Lower/parent-component.f90 +++ b/flang/test/Lower/parent-component.f90 @@ -51,8 +51,7 @@ ! CHECK: %[[ADD:.*]] = arith.addi %[[C1]], %[[C2]] : index ! CHECK: %[[UB:.*]] = arith.subi %[[ADD]], %[[C1]] : index ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]] : (index) -> !fir.shape<1> - ! CHECK: %[[FIELD:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> - ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[UB]], %[[STRIDE]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1> + ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[UB]], %[[STRIDE]] : (index, index, index) -> !fir.slice<1> ! CHECK: %[[BOX:.*]] = fir.embox %[[Y]](%[[SHAPE]]) [%[[SLICE]]] : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box>> ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box>>) -> !fir.box ! CHECK: %[[IS_CONTIGOUS:.*]] = fir.call @_FortranAIsContiguous(%[[BOX_NONE]]) {{.*}}: (!fir.box) -> i1 @@ -69,8 +68,7 @@ ! CHECK: %[[ADD:.*]] = arith.addi %[[C1]], %[[C2]] : index ! CHECK: %[[UB:.*]] = arith.subi %[[ADD]], %[[C1]] : index ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]] : (index) -> !fir.shape<1> - ! CHECK: %[[FIELD:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> - ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[UB]], %[[STRIDE]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1> + ! CHECK: %[[SLICE:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.slice<1> ! CHECK: %[[BOX:.*]] = fir.embox %[[Y]](%[[SHAPE]]) [%[[SLICE]]] : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box>> ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box>>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[BOX_NONE]]) {{.*}}: (!fir.ref, !fir.box) -> i1 @@ -84,12 +82,7 @@ ! CHECK: %[[Y:.*]] = fir.address_of(@_QFFinit_no_sliceEy) : !fir.ref>> ! CHECK: %[[C2:.*]] = arith.constant 2 : index ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]] : (index) -> !fir.shape<1> - ! CHECK: %[[FIELD:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> - ! CHECK: %[[C0:.*]] = arith.constant 0 : index - ! CHECK: %[[BOX_DIM:.*]]:3 = fir.box_dims %{{.*}}, %[[C0]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[C1:.*]] = arith.constant 1 : index - ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIM]]#1, %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1> - ! CHECK: %[[BOX:.*]] = fir.embox %[[Y]](%[[SHAPE]]) [%[[SLICE]]] : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box>> + ! CHECK: %[[BOX:.*]] = fir.embox %[[Y]](%[[SHAPE]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box>>) -> !fir.box ! CHECK: %[[IS_CONTIGOUS:.*]] = fir.call @_FortranAIsContiguous(%[[BOX_NONE]]) {{.*}}: (!fir.box) -> i1 ! CHECK: %[[TEMP:.*]] = fir.if %[[IS_CONTIGOUS]] -> (!fir.heap>>) { @@ -100,12 +93,7 @@ ! CHECK-LABEL: %{{.*}} = fir.call @_FortranAioBeginExternalListOutput(%{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (i32, !fir.ref, i32) -> !fir.ref ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]] : (index) -> !fir.shape<1> - ! CHECK: %[[FIELD:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> - ! CHECK: %[[C0:.*]] = arith.constant 0 : index - ! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %{{.*}}, %[[C0]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[C1:.*]] = arith.constant 1 : index - ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1> - ! CHECK: %[[BOX:.*]] = fir.embox %[[Y]](%[[SHAPE]]) [%[[SLICE]]] : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box>> + ! CHECK: %[[BOX:.*]] = fir.embox %[[Y]](%[[SHAPE]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box>>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[BOX_NONE]]) {{.*}}: (!fir.ref, !fir.box) -> i1 @@ -127,14 +115,7 @@ ! CHECK: %[[LOAD_EXT0:.*]] = fir.load %[[EXT0]] : !fir.ref ! CHECK: %[[MEM:.*]] = fir.load %[[ALLOC]] : !fir.ref>>> ! CHECK: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[LOAD_LB0]], %[[LOAD_EXT0]] : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[FIELD:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> - ! CHECK: %[[C0:.*]] = arith.constant 0 : index - ! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %{{.*}}, %[[C0]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[C1:.*]] = arith.constant 1 : index - ! CHECK: %[[BOUND_OFFSET:.*]] = arith.subi %[[LOAD_LB0]], %[[C1]] : index - ! CHECK: %[[UB:.*]] = arith.addi %[[BOX_DIMS]]#1, %[[BOUND_OFFSET]] : index - ! CHECK: %[[SLICE:.*]] = fir.slice %[[LOAD_LB0]], %[[UB]], %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1> - ! CHECK: %[[BOX:.*]] = fir.embox %[[MEM]](%[[SHAPE_SHIFT]]) [%[[SLICE]]] : (!fir.heap>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box>> + ! CHECK: %[[BOX:.*]] = fir.embox %[[MEM]](%[[SHAPE_SHIFT]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.box>> ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box>>) -> !fir.box ! CHECK: %[[IS_CONTIGOUS:.*]] = fir.call @_FortranAIsContiguous(%[[BOX_NONE]]) {{.*}}: (!fir.box) -> i1 ! CHECK: %[[TEMP:.*]] = fir.if %[[IS_CONTIGOUS]] -> (!fir.heap>>) { @@ -148,14 +129,7 @@ ! CHECK: %[[LOAD_EXT0:.*]] = fir.load %[[EXT0]] : !fir.ref ! CHECK: %[[LOAD_ALLOC:.*]] = fir.load %[[ALLOC]] : !fir.ref>>> ! CHECK: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[LOAD_LB0]], %[[LOAD_EXT0]] : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[FIELD:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> - ! CHECK: %[[C0:.*]] = arith.constant 0 : index - ! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %{{.*}}, %[[C0]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[C1:.*]] = arith.constant 1 : index - ! CHECK: %[[BOUND_OFFSET:.*]] = arith.subi %[[LOAD_LB0]], %[[C1]] : index - ! CHECK: %[[UB:.*]] = arith.addi %[[BOX_DIMS]]#1, %[[BOUND_OFFSET]] : index - ! CHECK: %[[SLICE:.*]] = fir.slice %[[LOAD_LB0]], %[[UB]], %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1> - ! CHECK: %[[BOX:.*]] = fir.embox %[[LOAD_ALLOC]](%[[SHAPE_SHIFT]]) [%[[SLICE]]] : (!fir.heap>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box>> + ! CHECK: %[[BOX:.*]] = fir.embox %[[LOAD_ALLOC]](%[[SHAPE_SHIFT]]) : (!fir.heap>>, !fir.shapeshift<1>) -> !fir.box>> ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box>>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[BOX_NONE]]) {{.*}}: (!fir.ref, !fir.box) -> i1 @@ -182,21 +156,9 @@ ! CHECK-LABEL: func.func @_QFPinit_assumed( ! CHECK-SAME: %[[ARG0:.*]]: !fir.box> - ! CHECK: %[[BOX:.*]] = fir.rebox %[[ARG0]] : (!fir.box>>) -> !fir.box>> - ! CHECK: %[[FIELD:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> - ! CHECK: %[[C0:.*]] = arith.constant 0 : index - ! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[BOX]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[C1:.*]] = arith.constant 1 : index - ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1> - ! CHECK: %{{.*}} = fir.rebox %[[ARG0]] [%[[SLICE]]] : (!fir.box>>, !fir.slice<1>) -> !fir.box>> + ! CHECK: %[[BOX:.*]] = fir.rebox %[[ARG0]] : (!fir.box>>) -> !fir.box>> - ! CHECK: %[[BOX:.*]] = fir.rebox %[[ARG0]] : (!fir.box>>) -> !fir.box>> - ! CHECK: %[[FIELD:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> - ! CHECK: %[[C0:.*]] = arith.constant 0 : index - ! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[BOX]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) - ! CHECK: %[[C1:.*]] = arith.constant 1 : index - ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD]] : (index, index, index, !fir.field) -> !fir.slice<1> - ! CHECK: %[[REBOX:.*]] = fir.rebox %arg0 [%[[SLICE]]] : (!fir.box>>, !fir.slice<1>) -> !fir.box>> + ! CHECK: %[[REBOX:.*]] = fir.rebox %[[ARG0]] : (!fir.box>>) -> !fir.box>> ! CHECK: %[[REBOX_CAST:.*]] = fir.convert %[[REBOX]] : (!fir.box>>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[REBOX_CAST]]) {{.*}}: (!fir.ref, !fir.box) -> i1 @@ -211,7 +173,6 @@ ! CHECK: %[[FIELD_C:.*]] = fir.field_index c, !fir.type<_QFTz{k:i32,c:!fir.type<_QFTc{a:i32,b:i32}>}> ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]] : (index) -> !fir.shape<1> ! CHECK: %[[C1:.*]] = arith.constant 1 : index - ! CHECK: %[[FIELD_A:.*]] = fir.field_index a, !fir.type<_QFTc{a:i32,b:i32}> - ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[C2]], %[[C1]] path %[[FIELD_C]], %[[FIELD_A]] : (index, index, index, !fir.field, !fir.field) -> !fir.slice<1> + ! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[C2]], %[[C1]] path %[[FIELD_C]] : (index, index, index, !fir.field) -> !fir.slice<1> ! CHECK: %{{.*}} = fir.embox %[[ALLOCA]](%[[SHAPE]]) [%[[SLICE]]] : (!fir.ref}>>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box>> end diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -1019,7 +1019,8 @@ ! CHECK: %[[LOAD_S:.*]] = fir.load %[[S]] : !fir.ref>>> ! CHECK: fir.select_type %[[LOAD_S]] : !fir.class>> [#fir.type_is>, ^bb1, unit, ^bb2] ! CHECK: ^bb1: -! CHECK: %[[REBOX_P1:.*]] = fir.rebox %[[LOAD_S]] : (!fir.class>>) -> !fir.box> +! CHECK: %[[CONV_S:.*]] = fir.convert %[[LOAD_S]] : (!fir.class>>) -> !fir.box>> +! CHECK: %[[REBOX_P1:.*]] = fir.rebox %[[CONV_S]] : (!fir.box>>) -> !fir.box> ! CHECK: %[[LOAD_P:.*]] = fir.load %[[P]] : !fir.ref>>> ! CHECK: %[[LHS_CONV:.*]] = fir.convert %[[REBOX_P1]] : (!fir.box>) -> !fir.ref> ! CHECK: %[[RHS_CONV:.*]] = fir.convert %[[LOAD_P]] : (!fir.class>>) -> !fir.box