mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 03:56:06 +00:00
[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).
This commit is contained in:
parent
103469b5f7
commit
85f6669de5
@ -338,6 +338,7 @@ struct IntrinsicLibrary {
|
||||
mlir::Value genSign(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
mlir::Value genSind(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
fir::ExtendedValue genSize(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
fir::ExtendedValue genSizeOf(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
mlir::Value genSpacing(mlir::Type resultType,
|
||||
llvm::ArrayRef<mlir::Value> args);
|
||||
fir::ExtendedValue genSpread(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
|
@ -567,6 +567,10 @@ static constexpr IntrinsicHandler handlers[]{
|
||||
{"dim", asAddr, handleDynamicOptional},
|
||||
{"kind", asValue}}},
|
||||
/*isElemental=*/false},
|
||||
{"sizeof",
|
||||
&I::genSizeOf,
|
||||
{{{"a", asBox}}},
|
||||
/*isElemental=*/false},
|
||||
{"sleep", &I::genSleep, {{{"seconds", asValue}}}, /*isElemental=*/false},
|
||||
{"spacing", &I::genSpacing},
|
||||
{"spread",
|
||||
@ -5946,6 +5950,20 @@ IntrinsicLibrary::genSize(mlir::Type resultType,
|
||||
.getResults()[0];
|
||||
}
|
||||
|
||||
// SIZEOF
|
||||
fir::ExtendedValue
|
||||
IntrinsicLibrary::genSizeOf(mlir::Type resultType,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
assert(args.size() == 1);
|
||||
mlir::Value box = fir::getBase(args[0]);
|
||||
mlir::Value eleSize = builder.create<fir::BoxEleSizeOp>(loc, resultType, box);
|
||||
if (!fir::isArray(args[0]))
|
||||
return eleSize;
|
||||
mlir::Value arraySize = builder.createConvert(
|
||||
loc, resultType, fir::runtime::genSize(builder, loc, box));
|
||||
return builder.create<mlir::arith::MulIOp>(loc, eleSize, arraySize);
|
||||
}
|
||||
|
||||
// TAND
|
||||
mlir::Value IntrinsicLibrary::genTand(mlir::Type resultType,
|
||||
llvm::ArrayRef<mlir::Value> args) {
|
||||
|
23
flang/test/Lower/Intrinsics/sizeof.f90
Normal file
23
flang/test/Lower/Intrinsics/sizeof.f90
Normal file
@ -0,0 +1,23 @@
|
||||
! Test SIZEOF lowering for polymorphic entities.
|
||||
! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s
|
||||
|
||||
integer(8) function test1(x)
|
||||
class(*) :: x
|
||||
test1 = sizeof(x)
|
||||
end function
|
||||
! CHECK-LABEL: func.func @_QPtest1(
|
||||
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtest1Ex"} : (!fir.class<none>) -> (!fir.class<none>, !fir.class<none>)
|
||||
! CHECK: %[[VAL_4:.*]] = fir.box_elesize %[[VAL_3]]#1 : (!fir.class<none>) -> i64
|
||||
! CHECK: hlfir.assign %[[VAL_4]] to %{{.*}} : i64, !fir.ref<i64>
|
||||
|
||||
integer(8) function test2(x)
|
||||
class(*) :: x(:, :)
|
||||
test2 = sizeof(x)
|
||||
end function
|
||||
! CHECK-LABEL: func.func @_QPtest2(
|
||||
! 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>>)
|
||||
! CHECK: %[[VAL_4:.*]] = fir.box_elesize %[[VAL_3]]#1 : (!fir.class<!fir.array<?x?xnone>>) -> i64
|
||||
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
|
||||
! CHECK: %[[VAL_9:.*]] = fir.call @_FortranASize(%[[VAL_7]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> i64
|
||||
! CHECK: %[[VAL_10:.*]] = arith.muli %[[VAL_4]], %[[VAL_9]] : i64
|
||||
! CHECK: hlfir.assign %[[VAL_10]] to %{{.*}} : i64, !fir.ref<i64>
|
Loading…
x
Reference in New Issue
Block a user