Skip to content

Commit e2ebd28

Browse files
committed
[flang] Fixed assumed-type temporary allocation for -frepack-arrays.
After #142609, repacking of assumed-type arrays under -frepack-arrays become broken, because the code tried to pass a `!fir.box` source_box to `fir.embox`, which is not allowed. It might be okay to cast the original box to class for using it in `fir.embox`.
1 parent 093afed commit e2ebd28

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

flang/lib/Optimizer/Builder/MutableBox.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,15 @@ mlir::Value fir::factory::getAndEstablishBoxStorage(
987987
mlir::Value boxStorage = builder.createTemporary(loc, boxTy);
988988
mlir::Value nullAddr =
989989
builder.createNullConstant(loc, boxTy.getBaseAddressType());
990+
if (polymorphicMold && fir::isAssumedType(polymorphicMold.getType())) {
991+
// An assumed-type (!fir.box) entity cannot be used as a mold
992+
// in fir.embox, so we have to represent it as an unlimited
993+
// polymorphic entity (!fir.class).
994+
mlir::Type newMoldType = fir::wrapInClassOrBoxType(
995+
mlir::cast<fir::BaseBoxType>(polymorphicMold.getType()).getEleTy(),
996+
/*isPolymorphic=*/true);
997+
polymorphicMold = builder.createConvert(loc, newMoldType, polymorphicMold);
998+
}
990999
mlir::Value box =
9911000
builder.create<fir::EmboxOp>(loc, boxTy, nullAddr, shape,
9921001
/*emptySlice=*/mlir::Value{},

flang/test/Transforms/lower-repack-arrays.fir

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,3 +1091,81 @@ func.func @_QPtest7_stack(%arg0: !fir.class<!fir.array<?x?xnone>> {fir.bindc_nam
10911091
// CHECK: }
10921092
// CHECK: return
10931093
// CHECK: }
1094+
1095+
// Test assumed type array.
1096+
// The temporary allocation requires creating a fir.box with the mold
1097+
// being the !fir.box<!fir.array<?xnone>>. We have to cast it to
1098+
// !fir.class<!fir.array<?xnone>> to make the fir.embox's source_box
1099+
// operand valid.
1100+
// CHECK-LABEL: func.func @_QPrepack_assumed_type(
1101+
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x"}) {
1102+
// CHECK: %[[VAL_0:.*]] = arith.constant
1103+
// CHECK: %[[VAL_1:.*]] = arith.constant
1104+
// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index
1105+
// CHECK: %[[VAL_3:.*]] = arith.constant false
1106+
// CHECK: %[[VAL_4:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?xnone>>>
1107+
// CHECK: %[[VAL_5:.*]] = fir.dummy_scope : !fir.dscope
1108+
// CHECK: %[[VAL_6:.*]] = fir.is_present %[[ARG0]] : (!fir.box<!fir.array<?xnone>>) -> i1
1109+
// CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_6]] -> (!fir.box<!fir.array<?xnone>>) {
1110+
// CHECK: %[[VAL_8:.*]] = fir.is_contiguous_box %[[ARG0]] whole : (!fir.box<!fir.array<?xnone>>) -> i1
1111+
// CHECK: %[[VAL_9:.*]] = arith.cmpi eq, %[[VAL_8]], %[[VAL_3]] : i1
1112+
// CHECK: %[[VAL_10:.*]] = fir.box_addr %[[ARG0]] : (!fir.box<!fir.array<?xnone>>) -> !fir.ref<!fir.box<!fir.array<?xnone>>>
1113+
// CHECK: %[[VAL_11:.*]] = fir.is_present %[[VAL_10]] : (!fir.ref<!fir.box<!fir.array<?xnone>>>) -> i1
1114+
// CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_11]] : i1
1115+
// CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_12]] weights([0, 1]) -> (!fir.box<!fir.array<?xnone>>) {
1116+
// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_2]] : (!fir.box<!fir.array<?xnone>>, index) -> (index, index, index)
1117+
// CHECK: %[[VAL_15:.*]] = fir.shape %[[VAL_14]]#1 : (index) -> !fir.shape<1>
1118+
// CHECK: %[[VAL_16:.*]] = fir.zero_bits !fir.heap<!fir.array<?xnone>>
1119+
// CHECK: %[[VAL_17:.*]] = fir.convert %[[ARG0]] : (!fir.box<!fir.array<?xnone>>) -> !fir.class<!fir.array<?xnone>>
1120+
// CHECK: %[[VAL_18:.*]] = fir.embox %[[VAL_16]](%[[VAL_15]]) source_box %[[VAL_17]] : (!fir.heap<!fir.array<?xnone>>, !fir.shape<1>, !fir.class<!fir.array<?xnone>>) -> !fir.class<!fir.heap<!fir.array<?xnone>>>
1121+
// CHECK: fir.store %[[VAL_18]] to %[[VAL_4]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>
1122+
// CHECK: %[[VAL_19:.*]] = fir.zero_bits !fir.ref<none>
1123+
// CHECK: %[[VAL_20:.*]] = fir.address_of(@{{_QQcl.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
1124+
// CHECK: %[[VAL_21:.*]] = fir.absent !fir.box<none>
1125+
// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>) -> !fir.ref<!fir.box<none>>
1126+
// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_19]] : (!fir.ref<none>) -> !fir.ref<i64>
1127+
// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_20]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
1128+
// CHECK: %[[VAL_25:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_22]], %[[VAL_23]], %[[VAL_3]], %[[VAL_21]], %[[VAL_24]], %[[VAL_1]]) : (!fir.ref<!fir.box<none>>, !fir.ref<i64>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
1129+
// CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_4]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>
1130+
// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_26]] {uniq_name = ".repacked"} : (!fir.class<!fir.heap<!fir.array<?xnone>>>) -> !fir.class<!fir.heap<!fir.array<?xnone>>>
1131+
// CHECK: %[[VAL_28:.*]] = fir.address_of(@{{_QQcl.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
1132+
// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_27]] : (!fir.class<!fir.heap<!fir.array<?xnone>>>) -> !fir.box<none>
1133+
// CHECK: %[[VAL_30:.*]] = fir.convert %[[ARG0]] : (!fir.box<!fir.array<?xnone>>) -> !fir.box<none>
1134+
// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_28]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
1135+
// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
1136+
// CHECK: %[[VAL_32:.*]] = fir.shift %[[VAL_14]]#0 : (index) -> !fir.shift<1>
1137+
// CHECK: %[[VAL_33:.*]] = fir.rebox %[[VAL_27]](%[[VAL_32]]) : (!fir.class<!fir.heap<!fir.array<?xnone>>>, !fir.shift<1>) -> !fir.box<!fir.array<?xnone>>
1138+
// CHECK: fir.result %[[VAL_33]] : !fir.box<!fir.array<?xnone>>
1139+
// CHECK: } else {
1140+
// CHECK: fir.result %[[ARG0]] : !fir.box<!fir.array<?xnone>>
1141+
// CHECK: }
1142+
// CHECK: fir.result %[[VAL_13]] : !fir.box<!fir.array<?xnone>>
1143+
// CHECK: } else {
1144+
// CHECK: fir.result %[[ARG0]] : !fir.box<!fir.array<?xnone>>
1145+
// CHECK: }
1146+
// CHECK: %[[VAL_34:.*]] = fir.declare %[[VAL_7]] dummy_scope %[[VAL_5]] {uniq_name = "_QFrepack_assumed_typeEx"} : (!fir.box<!fir.array<?xnone>>, !fir.dscope) -> !fir.box<!fir.array<?xnone>>
1147+
// CHECK: %[[VAL_35:.*]] = fir.is_present %[[ARG0]] : (!fir.box<!fir.array<?xnone>>) -> i1
1148+
// CHECK: fir.if %[[VAL_35]] {
1149+
// CHECK: %[[VAL_36:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.array<?xnone>>) -> !fir.heap<!fir.array<?xnone>>
1150+
// CHECK: %[[VAL_37:.*]] = fir.box_addr %[[ARG0]] : (!fir.box<!fir.array<?xnone>>) -> !fir.heap<!fir.array<?xnone>>
1151+
// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_36]] : (!fir.heap<!fir.array<?xnone>>) -> index
1152+
// CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (!fir.heap<!fir.array<?xnone>>) -> index
1153+
// CHECK: %[[VAL_40:.*]] = arith.cmpi ne, %[[VAL_38]], %[[VAL_39]] : index
1154+
// CHECK: fir.if %[[VAL_40]] weights([0, 1]) {
1155+
// CHECK: %[[VAL_41:.*]] = fir.address_of(@_QQclX2b7d3b4eb2a9b0772619a406c28937e5) : !fir.ref<!fir.char<1,{{.*}}>>
1156+
// CHECK: %[[VAL_42:.*]] = fir.convert %[[ARG0]] : (!fir.box<!fir.array<?xnone>>) -> !fir.box<none>
1157+
// CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.array<?xnone>>) -> !fir.box<none>
1158+
// CHECK: %[[VAL_44:.*]] = fir.convert %[[VAL_41]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
1159+
// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_42]], %[[VAL_43]], %[[VAL_44]], %[[VAL_0]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
1160+
// CHECK: fir.freemem %[[VAL_36]] : !fir.heap<!fir.array<?xnone>>
1161+
// CHECK: }
1162+
// CHECK: }
1163+
// CHECK: return
1164+
// CHECK: }
1165+
func.func @_QPrepack_assumed_type(%arg0: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x"}) {
1166+
%0 = fir.dummy_scope : !fir.dscope
1167+
%1 = fir.pack_array %arg0 heap whole : (!fir.box<!fir.array<?xnone>>) -> !fir.box<!fir.array<?xnone>>
1168+
%2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFrepack_assumed_typeEx"} : (!fir.box<!fir.array<?xnone>>, !fir.dscope) -> !fir.box<!fir.array<?xnone>>
1169+
fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?xnone>>
1170+
return
1171+
}

0 commit comments

Comments
 (0)