Skip to content

Commit ed05dcc

Browse files
committed
[flang] MERGE result is polymorphic only if TSOURCE and FSOURCE are polymorphic
16.9.129 point 4: the result is polymorphic if and only if both TSOURCE and FSOURCE are polymorphic. If neither TSOURCE and FSOURCE are polymorphic then the current behavior is preserved. Depends on D145058 Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D145060
1 parent 3eceab9 commit ed05dcc

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3925,14 +3925,29 @@ IntrinsicLibrary::genMerge(mlir::Type,
39253925
mlir::Type type0 = fir::unwrapRefType(tsource.getType());
39263926
bool isCharRslt = fir::isa_char(type0); // result is same as first argument
39273927
mlir::Value mask = builder.createConvert(loc, builder.getI1Type(), rawMask);
3928-
// FSOURCE has the same type as TSOURCE, but they may not have the same MLIR
3929-
// types (one can have dynamic length while the other has constant lengths,
3930-
// or one may be a fir.logical<> while the other is an i1). Insert a cast to
3931-
// fulfill mlir::SelectOp constraint that the MLIR types must be the same.
3932-
mlir::Value fsourceCast =
3933-
builder.createConvert(loc, tsource.getType(), fsource);
3934-
auto rslt =
3935-
builder.create<mlir::arith::SelectOp>(loc, mask, tsource, fsourceCast);
3928+
3929+
// The result is polymorphic if and only if both TSOURCE and FSOURCE are
3930+
// polymorphic. TSOURCE and FSOURCE are required to have the same type
3931+
// (for both declared and dynamic types) so a simple convert op can be
3932+
// used.
3933+
mlir::Value tsourceCast = tsource;
3934+
mlir::Value fsourceCast = fsource;
3935+
if (fir::isPolymorphicType(tsource.getType()) &&
3936+
!fir::isPolymorphicType(fsource.getType())) {
3937+
tsourceCast = builder.createConvert(loc, fsource.getType(), tsource);
3938+
} else if (!fir::isPolymorphicType(tsource.getType()) &&
3939+
fir::isPolymorphicType(fsource.getType())) {
3940+
fsourceCast = builder.createConvert(loc, tsource.getType(), fsource);
3941+
} else {
3942+
// FSOURCE and TSOURCE are not polymorphic.
3943+
// FSOURCE has the same type as TSOURCE, but they may not have the same MLIR
3944+
// types (one can have dynamic length while the other has constant lengths,
3945+
// or one may be a fir.logical<> while the other is an i1). Insert a cast to
3946+
// fulfill mlir::SelectOp constraint that the MLIR types must be the same.
3947+
fsourceCast = builder.createConvert(loc, tsource.getType(), fsource);
3948+
}
3949+
auto rslt = builder.create<mlir::arith::SelectOp>(loc, mask, tsourceCast,
3950+
fsourceCast);
39363951
if (isCharRslt) {
39373952
// Need a CharBoxValue for character results
39383953
const fir::CharBoxValue *charBox = args[0].getCharBox();

flang/test/Lower/polymorphic-temp.f90

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,14 @@ subroutine test_merge_intrinsic2(a, b, i)
215215
call check_scalar(merge(a, b, i==1))
216216
end subroutine
217217

218-
219218
! CHECK-LABEL: func.func @_QMpoly_tmpPtest_merge_intrinsic2(
220219
! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>> {fir.bindc_name = "b"}, %[[I:.*]]: !fir.ref<i32> {fir.bindc_name = "i"}) {
221220
! CHECK: %[[LOAD_A:.*]] = fir.load %[[A]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>>
222221
! CHECK: %[[LOAD_B:.*]] = fir.load %[[B]] : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>>
223222
! CHECK: %[[LOAD_I:.*]] = fir.load %[[I]] : !fir.ref<i32>
224223
! CHECK: %[[C1:.*]] = arith.constant 1 : i32
225224
! CHECK: %[[CMPI:.*]] = arith.cmpi eq, %[[LOAD_I]], %[[C1]] : i32
226-
! CHECK: %[[B_CONV:.*]] = fir.convert %[[LOAD_B]] : (!fir.box<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>) -> !fir.class<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>
227-
! CHECK: %{{.*}} = arith.select %[[CMPI]], %[[LOAD_A]], %[[B_CONV]] : !fir.class<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>
225+
! CHECK: %[[A_CONV:.*]] = fir.convert %[[LOAD_A]] : (!fir.class<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>) -> !fir.box<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>
226+
! CHECK: %{{.*}} = arith.select %[[CMPI]], %[[A_CONV]], %[[LOAD_B]] : !fir.box<!fir.heap<!fir.type<_QMpoly_tmpTp1{a:i32}>>>
228227

229228
end module

0 commit comments

Comments
 (0)