diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h index 7cb99d61a686e..ca15b4bc34b29 100644 --- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h +++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h @@ -338,6 +338,7 @@ struct IntrinsicLibrary { mlir::Value genSign(mlir::Type, llvm::ArrayRef); mlir::Value genSind(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genSize(mlir::Type, llvm::ArrayRef); + fir::ExtendedValue genSizeOf(mlir::Type, llvm::ArrayRef); mlir::Value genSpacing(mlir::Type resultType, llvm::ArrayRef args); fir::ExtendedValue genSpread(mlir::Type, llvm::ArrayRef); diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 2f7ace658e475..ca5ab6fcea342 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -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 args) { + assert(args.size() == 1); + mlir::Value box = fir::getBase(args[0]); + mlir::Value eleSize = builder.create(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(loc, eleSize, arraySize); +} + // TAND mlir::Value IntrinsicLibrary::genTand(mlir::Type resultType, llvm::ArrayRef args) { diff --git a/flang/test/Lower/Intrinsics/sizeof.f90 b/flang/test/Lower/Intrinsics/sizeof.f90 new file mode 100644 index 0000000000000..959ca1692b514 --- /dev/null +++ b/flang/test/Lower/Intrinsics/sizeof.f90 @@ -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) -> (!fir.class, !fir.class) +! CHECK: %[[VAL_4:.*]] = fir.box_elesize %[[VAL_3]]#1 : (!fir.class) -> i64 +! CHECK: hlfir.assign %[[VAL_4]] to %{{.*}} : i64, !fir.ref + +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.class>, !fir.class>) +! CHECK: %[[VAL_4:.*]] = fir.box_elesize %[[VAL_3]]#1 : (!fir.class>) -> i64 +! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.class>) -> !fir.box +! CHECK: %[[VAL_9:.*]] = fir.call @_FortranASize(%[[VAL_7]], %{{.*}}, %{{.*}}) fastmath : (!fir.box, !fir.ref, i32) -> i64 +! CHECK: %[[VAL_10:.*]] = arith.muli %[[VAL_4]], %[[VAL_9]] : i64 +! CHECK: hlfir.assign %[[VAL_10]] to %{{.*}} : i64, !fir.ref