Skip to content

Commit

Permalink
[flang] Load unlimited polymorphic box the same way as other
Browse files Browse the repository at this point in the history
Unlimited polymorphic descriptor have a set size and can be loaded the
same way as polymorphic or monomorphic descriptors. The descriptor
code gen as been set in D138587.
Of course, the data hold by those descriptors have an unknown size
at compile time.

Depends on D141383

Reviewed By: jeanPerier, PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D141390
  • Loading branch information
clementval committed Jan 10, 2023
1 parent 1fbbf92 commit 69bbcdd
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
7 changes: 3 additions & 4 deletions flang/lib/Optimizer/CodeGen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3013,12 +3013,11 @@ struct LoadOpConversion : public FIROpConversion<fir::LoadOp> {
auto inputBoxStorage = adaptor.getOperands()[0];
mlir::Location loc = load.getLoc();
fir::SequenceType seqTy = fir::unwrapUntilSeqType(boxTy);
mlir::Type eleTy = fir::unwrapPassByRefType(boxTy);
// fir.box of assumed rank and polymorphic entities do not have a storage
// fir.box of assumed rank do not have a storage
// size that is know at compile time. The copy needs to be runtime driven
// depending on the actual dynamic rank or type.
if (eleTy.isa<mlir::NoneType>() || (seqTy && seqTy.hasUnknownShape()))
TODO(loc, "loading polymorphic or assumed rank fir.box");
if (seqTy && seqTy.hasUnknownShape())
TODO(loc, "loading or assumed rank fir.box");
mlir::Type boxPtrTy = inputBoxStorage.getType();
auto boxValue = rewriter.create<mlir::LLVM::LoadOp>(
loc, boxPtrTy.cast<mlir::LLVM::LLVMPointerType>().getElementType(),
Expand Down
23 changes: 23 additions & 0 deletions flang/test/Fir/polymorphic.fir
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,27 @@ func.func @_QQmain() {
// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[LOAD]], ptr %[[DESC]]
// CHECK: call void @_QMmod1Psub1(ptr %[[DESC]])

fir.global @_QMmod2Ep : !fir.class<!fir.ptr<none>> {
%0 = fir.zero_bits !fir.ptr<none>
%1 = fir.embox %0 : (!fir.ptr<none>) -> !fir.class<!fir.ptr<none>>
fir.has_value %1 : !fir.class<!fir.ptr<none>>
}
func.func @_QMmod2Pinitp(%arg0: !fir.ref<!fir.class<!fir.ptr<none>>> {fir.bindc_name = "target"}) {
%0 = fir.address_of(@_QMmod2Ep) : !fir.ref<!fir.class<!fir.ptr<none>>>
%1 = fir.load %arg0 : !fir.ref<!fir.class<!fir.ptr<none>>>
%2 = fir.convert %0 : (!fir.ref<!fir.class<!fir.ptr<none>>>) -> !fir.ref<!fir.box<none>>
%3 = fir.convert %1 : (!fir.class<!fir.ptr<none>>) -> !fir.box<none>
%4 = fir.call @_FortranAPointerAssociate(%2, %3) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>) -> none
return
}
func.func private @_FortranAPointerAssociate(!fir.ref<!fir.box<none>>, !fir.box<none>) -> none attributes {fir.runtime}

// CHECK-LABEL: define void @_QMmod2Pinitp(
// CHECK-SAME: ptr %[[ARG0:.*]]) {
// CHECK: %[[ALLOCA_CLASS_NONE:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
// CHECK: %[[LOAD:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[ARG0]]
// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[LOAD]], ptr %[[ALLOCA_CLASS_NONE]]
// CHECK: %{{.*}} = call {} @_FortranAPointerAssociate(ptr @_QMmod2Ep, ptr %[[ALLOCA_CLASS_NONE]])
// CHECK: ret void


0 comments on commit 69bbcdd

Please sign in to comment.