Skip to content

Commit 85f6669

Browse files
authored
[flang] implement sizeof lowering for polymorphic entities (#84498)
For non polymorphic entities, semantics knows the type size and rewrite sizeof to `"cst element size" * size(x)`. Lowering has to deal with the polymorphic case where the type size must be retrieved from the descriptor (note that the lowering implementation would work with any entity, polymorphic on not, it is just not used for the non polymorphic cases).
1 parent 103469b commit 85f6669

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

flang/include/flang/Optimizer/Builder/IntrinsicCall.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ struct IntrinsicLibrary {
338338
mlir::Value genSign(mlir::Type, llvm::ArrayRef<mlir::Value>);
339339
mlir::Value genSind(mlir::Type, llvm::ArrayRef<mlir::Value>);
340340
fir::ExtendedValue genSize(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
341+
fir::ExtendedValue genSizeOf(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
341342
mlir::Value genSpacing(mlir::Type resultType,
342343
llvm::ArrayRef<mlir::Value> args);
343344
fir::ExtendedValue genSpread(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,10 @@ static constexpr IntrinsicHandler handlers[]{
567567
{"dim", asAddr, handleDynamicOptional},
568568
{"kind", asValue}}},
569569
/*isElemental=*/false},
570+
{"sizeof",
571+
&I::genSizeOf,
572+
{{{"a", asBox}}},
573+
/*isElemental=*/false},
570574
{"sleep", &I::genSleep, {{{"seconds", asValue}}}, /*isElemental=*/false},
571575
{"spacing", &I::genSpacing},
572576
{"spread",
@@ -5946,6 +5950,20 @@ IntrinsicLibrary::genSize(mlir::Type resultType,
59465950
.getResults()[0];
59475951
}
59485952

5953+
// SIZEOF
5954+
fir::ExtendedValue
5955+
IntrinsicLibrary::genSizeOf(mlir::Type resultType,
5956+
llvm::ArrayRef<fir::ExtendedValue> args) {
5957+
assert(args.size() == 1);
5958+
mlir::Value box = fir::getBase(args[0]);
5959+
mlir::Value eleSize = builder.create<fir::BoxEleSizeOp>(loc, resultType, box);
5960+
if (!fir::isArray(args[0]))
5961+
return eleSize;
5962+
mlir::Value arraySize = builder.createConvert(
5963+
loc, resultType, fir::runtime::genSize(builder, loc, box));
5964+
return builder.create<mlir::arith::MulIOp>(loc, eleSize, arraySize);
5965+
}
5966+
59495967
// TAND
59505968
mlir::Value IntrinsicLibrary::genTand(mlir::Type resultType,
59515969
llvm::ArrayRef<mlir::Value> args) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
! Test SIZEOF lowering for polymorphic entities.
2+
! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s
3+
4+
integer(8) function test1(x)
5+
class(*) :: x
6+
test1 = sizeof(x)
7+
end function
8+
! CHECK-LABEL: func.func @_QPtest1(
9+
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtest1Ex"} : (!fir.class<none>) -> (!fir.class<none>, !fir.class<none>)
10+
! CHECK: %[[VAL_4:.*]] = fir.box_elesize %[[VAL_3]]#1 : (!fir.class<none>) -> i64
11+
! CHECK: hlfir.assign %[[VAL_4]] to %{{.*}} : i64, !fir.ref<i64>
12+
13+
integer(8) function test2(x)
14+
class(*) :: x(:, :)
15+
test2 = sizeof(x)
16+
end function
17+
! CHECK-LABEL: func.func @_QPtest2(
18+
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtest2Ex"} : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, !fir.class<!fir.array<?x?xnone>>)
19+
! CHECK: %[[VAL_4:.*]] = fir.box_elesize %[[VAL_3]]#1 : (!fir.class<!fir.array<?x?xnone>>) -> i64
20+
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
21+
! CHECK: %[[VAL_9:.*]] = fir.call @_FortranASize(%[[VAL_7]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> i64
22+
! CHECK: %[[VAL_10:.*]] = arith.muli %[[VAL_4]], %[[VAL_9]] : i64
23+
! CHECK: hlfir.assign %[[VAL_10]] to %{{.*}} : i64, !fir.ref<i64>

0 commit comments

Comments
 (0)