Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorPeixinQiao <qiaopeixin@huawei.com>2022-05-06 17:10:13 +0300
committerPeixinQiao <qiaopeixin@huawei.com>2022-05-06 17:10:13 +0300
commitac0f4c8f362e819316ca152315e930f4e6515e9d (patch)
treeaa070da0dc6f860c5d9fcda572bf9508382dfd9f /flang
parent0863abe3ac47c281fdd35dc87d83c495cf741da0 (diff)
[flang] Fix AllocaOp/AllocMemOp type conversion
For arrays without a constant interior or arrays of character with dynamic length arrays, the data types are converted to a pointer to the element type, so the scale size of the constant extents needs to be counted. The previous AllocaOp conversion does not consider the arrays of character with dynamic length arrays, and the previous AllocMemOp conversion does not consider arrays without a constant interior. This fixes them and refactors the code so that it can be shared. Also add the test cases. Reviewed By: Jean Perier Differential Revision: https://reviews.llvm.org/D124766
Diffstat (limited to 'flang')
-rw-r--r--flang/lib/Optimizer/CodeGen/CodeGen.cpp59
-rw-r--r--flang/test/Fir/alloc.fir337
-rw-r--r--flang/test/Fir/convert-to-llvm.fir4
3 files changed, 326 insertions, 74 deletions
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 2cc41382f0d1..edc0b33fa2d0 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -302,6 +302,33 @@ getDependentTypeMemSizeFn(fir::RecordType recTy, fir::AllocaOp op,
return module.lookupSymbol<mlir::LLVM::LLVMFuncOp>(name);
}
+// Compute the alloc scale size (constant factors encoded in the array type).
+// We do this for arrays without a constant interior or arrays of character with
+// dynamic length arrays, since those are the only ones that get decayed to a
+// pointer to the element type.
+template <typename OP>
+static mlir::Value
+genAllocationScaleSize(OP op, mlir::Type ity,
+ mlir::ConversionPatternRewriter &rewriter) {
+ mlir::Location loc = op.getLoc();
+ mlir::Type dataTy = op.getInType();
+ mlir::Type scalarType = fir::unwrapSequenceType(dataTy);
+ auto seqTy = dataTy.dyn_cast<fir::SequenceType>();
+ if ((op.hasShapeOperands() && seqTy && !seqTy.hasConstantInterior()) ||
+ (seqTy && fir::characterWithDynamicLen(scalarType))) {
+ fir::SequenceType::Extent constSize = 1;
+ for (auto extent : seqTy.getShape())
+ if (extent != fir::SequenceType::getUnknownExtent())
+ constSize *= extent;
+ if (constSize != 1) {
+ mlir::Value constVal{
+ genConstantIndex(loc, ity, rewriter, constSize).getResult()};
+ return constVal;
+ }
+ }
+ return nullptr;
+}
+
namespace {
/// convert to LLVM IR dialect `alloca`
struct AllocaOpConversion : public FIROpConversion<fir::AllocaOp> {
@@ -346,23 +373,9 @@ struct AllocaOpConversion : public FIROpConversion<fir::AllocaOp> {
<< scalarType << " with type parameters";
}
}
+ if (auto scaleSize = genAllocationScaleSize(alloc, ity, rewriter))
+ size = rewriter.create<mlir::LLVM::MulOp>(loc, ity, size, scaleSize);
if (alloc.hasShapeOperands()) {
- mlir::Type allocEleTy = fir::unwrapRefType(alloc.getType());
- // Scale the size by constant factors encoded in the array type.
- // We only do this for arrays that don't have a constant interior, since
- // those are the only ones that get decayed to a pointer to the element
- // type.
- if (auto seqTy = allocEleTy.dyn_cast<fir::SequenceType>()) {
- if (!seqTy.hasConstantInterior()) {
- fir::SequenceType::Extent constSize = 1;
- for (auto extent : seqTy.getShape())
- if (extent != fir::SequenceType::getUnknownExtent())
- constSize *= extent;
- mlir::Value constVal{
- genConstantIndex(loc, ity, rewriter, constSize).getResult()};
- size = rewriter.create<mlir::LLVM::MulOp>(loc, ity, size, constVal);
- }
- }
unsigned end = operands.size();
for (; i < end; ++i)
size = rewriter.create<mlir::LLVM::MulOp>(
@@ -1001,18 +1014,8 @@ struct AllocMemOpConversion : public FIROpConversion<fir::AllocMemOp> {
if (fir::isRecordWithTypeParameters(fir::unwrapSequenceType(dataTy)))
TODO(loc, "fir.allocmem codegen of derived type with length parameters");
mlir::Value size = genTypeSizeInBytes(loc, ity, rewriter, ty);
- // !fir.array<NxMx!fir.char<K,?>> sets `size` to the width of !fir.char<K>.
- // So multiply the constant dimensions here.
- if (fir::hasDynamicSize(dataTy))
- if (auto seqTy = dataTy.dyn_cast<fir::SequenceType>())
- if (fir::characterWithDynamicLen(seqTy.getEleTy())) {
- fir::SequenceType::Extent arrSize = 1;
- for (auto d : seqTy.getShape())
- if (d != fir::SequenceType::getUnknownExtent())
- arrSize *= d;
- size = rewriter.create<mlir::LLVM::MulOp>(
- loc, ity, size, genConstantIndex(loc, ity, rewriter, arrSize));
- }
+ if (auto scaleSize = genAllocationScaleSize(heap, ity, rewriter))
+ size = rewriter.create<mlir::LLVM::MulOp>(loc, ity, size, scaleSize);
for (mlir::Value opnd : adaptor.getOperands())
size = rewriter.create<mlir::LLVM::MulOp>(
loc, ity, size, integerCast(loc, rewriter, ity, opnd));
diff --git a/flang/test/Fir/alloc.fir b/flang/test/Fir/alloc.fir
index e18a888e803d..07c97ff0a749 100644
--- a/flang/test/Fir/alloc.fir
+++ b/flang/test/Fir/alloc.fir
@@ -2,82 +2,333 @@
// UNSUPPORTED: system-windows
-// CHECK-LABEL: define i32* @f1()
-func @f1() -> !fir.ref<i32> {
- // CHECK: alloca i32, i64 1
+// CHECK-LABEL: define i32* @alloca_scalar_nonchar()
+// CHECK: alloca i32, i64 1
+func @alloca_scalar_nonchar() -> !fir.ref<i32> {
%1 = fir.alloca i32
return %1 : !fir.ref<i32>
}
-// CHECK-LABEL: define i32* @f2()
-func @f2() -> !fir.ref<i32> {
+// CHECK-LABEL: define i32* @alloca_scalars_nonchar()
+// CHECK: alloca i32, i64 100
+func @alloca_scalars_nonchar() -> !fir.ref<i32> {
%0 = arith.constant 100 : index
- // CHECK: alloca i32, i64 100
%1 = fir.alloca i32, %0
return %1 : !fir.ref<i32>
}
-// CHECK-LABEL: define i32* @f3()
-func @f3() -> !fir.heap<i32> {
- // CHECK: call i8* @malloc(i64 4)
+// CHECK-LABEL: define i32* @allocmem_scalar_nonchar(
+// CHECK: call i8* @malloc(i64 4)
+func @allocmem_scalar_nonchar() -> !fir.heap<i32> {
%1 = fir.allocmem i32
return %1 : !fir.heap<i32>
}
-// CHECK-LABEL: define i32* @f4()
-func @f4() -> !fir.heap<i32> {
+// CHECK-LABEL: define i32* @allocmem_scalars_nonchar(
+// CHECK: call i8* @malloc(i64 400)
+func @allocmem_scalars_nonchar() -> !fir.heap<i32> {
%0 = arith.constant 100 : index
- // CHECK: call i8* @malloc(i64 400)
%1 = fir.allocmem i32, %0
return %1 : !fir.heap<i32>
}
-// CHECK-LABEL: define i32** @f5()
-func @f5() -> !fir.ref<!fir.ptr<!fir.array<?xi32>>> {
- // CHECK: alloca i32*, i64 1
+// CHECK-LABEL: define [10 x i8]* @alloca_scalar_char(
+// CHECK: alloca [10 x i8], i64 1
+func @alloca_scalar_char() -> !fir.ref<!fir.char<1,10>> {
+ %1 = fir.alloca !fir.char<1,10>
+ return %1 : !fir.ref<!fir.char<1,10>>
+}
+
+// CHECK-LABEL: define [10 x i16]* @alloca_scalar_char_kind(
+// CHECK: alloca [10 x i16], i64 1
+func @alloca_scalar_char_kind() -> !fir.ref<!fir.char<2,10>> {
+ %1 = fir.alloca !fir.char<2,10>
+ return %1 : !fir.ref<!fir.char<2,10>>
+}
+
+// CHECK-LABEL: define [10 x i8]* @allocmem_scalar_char(
+// CHECK: call i8* @malloc(i64 ptrtoint ([10 x i8]* getelementptr ([10 x i8], [10 x i8]* null, i64 1) to i64))
+func @allocmem_scalar_char() -> !fir.heap<!fir.char<1,10>> {
+ %1 = fir.allocmem !fir.char<1,10>
+ return %1 : !fir.heap<!fir.char<1,10>>
+}
+
+// CHECK-LABEL: define [10 x i16]* @allocmem_scalar_char_kind(
+// CHECK: call i8* @malloc(i64 ptrtoint ([10 x i16]* getelementptr ([10 x i16], [10 x i16]* null, i64 1) to i64))
+func @allocmem_scalar_char_kind() -> !fir.heap<!fir.char<2,10>> {
+ %1 = fir.allocmem !fir.char<2,10>
+ return %1 : !fir.heap<!fir.char<2,10>>
+}
+
+// CHECK-LABEL: define i8* @alloca_scalar_dynchar(
+// CHECK-SAME: i32 %[[len:.*]])
+// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
+// CHECK: alloca i8, i64 %[[mul1]]
+func @alloca_scalar_dynchar(%l : i32) -> !fir.ref<!fir.char<1,?>> {
+ %1 = fir.alloca !fir.char<1,?>(%l : i32)
+ return %1 : !fir.ref<!fir.char<1,?>>
+}
+
+// CHECK-LABEL: define i16* @alloca_scalar_dynchar_kind(
+// CHECK-SAME: i32 %[[len:.*]])
+// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
+// CHECK: alloca i16, i64 %[[mul1]]
+func @alloca_scalar_dynchar_kind(%l : i32) -> !fir.ref<!fir.char<2,?>> {
+ %1 = fir.alloca !fir.char<2,?>(%l : i32)
+ return %1 : !fir.ref<!fir.char<2,?>>
+}
+
+// CHECK-LABEL: define i8* @allocmem_scalar_dynchar(
+// CHECK-SAME: i32 %[[len:.*]])
+// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
+// CHECK: %[[mul2:.*]] = mul i64 1, %[[mul1]]
+// CHECK: call i8* @malloc(i64 %[[mul2]])
+func @allocmem_scalar_dynchar(%l : i32) -> !fir.heap<!fir.char<1,?>> {
+ %1 = fir.allocmem !fir.char<1,?>(%l : i32)
+ return %1 : !fir.heap<!fir.char<1,?>>
+}
+
+// CHECK-LABEL: define i16* @allocmem_scalar_dynchar_kind(
+// CHECK-SAME: i32 %[[len:.*]])
+// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
+// CHECK: %[[mul2:.*]] = mul i64 2, %[[mul1]]
+// CHECK: call i8* @malloc(i64 %[[mul2]])
+func @allocmem_scalar_dynchar_kind(%l : i32) -> !fir.heap<!fir.char<2,?>>{
+ %1 = fir.allocmem !fir.char<2,?>(%l : i32)
+ return %1 : !fir.heap<!fir.char<2,?>>
+}
+
+// CHECK-LABEL: define i32** @alloca_ptr_to_dynarray_nonchar(
+// CHECK: %1 = alloca i32*, i64 1
+func @alloca_ptr_to_dynarray_nonchar() -> !fir.ref<!fir.ptr<!fir.array<?xi32>>> {
%1 = fir.alloca !fir.ptr<!fir.array<?xi32>>
return %1 : !fir.ref<!fir.ptr<!fir.array<?xi32>>>
}
-// CHECK-LABEL: define i8* @char_array_alloca(
-// CHECK-SAME: i32 %[[l:.*]], i64 %[[e:.*]])
-func @char_array_alloca(%l: i32, %e : index) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>> {
- // CHECK: %[[lcast:.*]] = sext i32 %[[l]] to i64
- // CHECK: %[[prod:.*]] = mul i64 %[[lcast]], %[[e]]
- // CHECK: %[[size:.*]] = mul i64 %[[prod]], %[[e]]
- // CHECK: alloca i8, i64 %[[size]]
- %a = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%l : i32), %e, %e
- return %a : !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK-LABEL: define [3 x [3 x i32]]* @alloca_array_of_nonchar(
+// CHECK: alloca [3 x [3 x i32]], i64 1
+func @alloca_array_of_nonchar() -> !fir.ref<!fir.array<3x3xi32>> {
+ %1 = fir.alloca !fir.array<3x3xi32>
+ return %1 : !fir.ref<!fir.array<3x3xi32>>
+}
+
+// CHECK-LABEL: define [3 x [3 x [10 x i8]]]* @alloca_array_of_char(
+// CHECK: alloca [3 x [3 x [10 x i8]]], i64 1
+func @alloca_array_of_char() -> !fir.ref<!fir.array<3x3x!fir.char<1,10>>> {
+ %1 = fir.alloca !fir.array<3x3x!fir.char<1,10>>
+ return %1 : !fir.ref<!fir.array<3x3x!fir.char<1,10>>>
+}
+
+// CHECK-LABEL: define i8* @alloca_array_of_dynchar(
+// CHECK-SAME: i32 %[[len:.*]])
+// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
+// CHECK: %[[mul2:.*]] = mul i64 %[[mul1]], 9
+// CHECK: alloca i8, i64 %[[mul2]]
+func @alloca_array_of_dynchar(%l: i32) -> !fir.ref<!fir.array<3x3x!fir.char<1,?>>> {
+ %1 = fir.alloca !fir.array<3x3x!fir.char<1,?>>(%l : i32)
+ return %1 : !fir.ref<!fir.array<3x3x!fir.char<1,?>>>
+}
+
+// CHECK-LABEL: define [3 x [3 x i32]]* @allocmem_array_of_nonchar(
+// CHECK: call i8* @malloc(i64 ptrtoint ([3 x [3 x i32]]* getelementptr ([3 x [3 x i32]], [3 x [3 x i32]]* null, i64 1) to i64))
+func @allocmem_array_of_nonchar() -> !fir.heap<!fir.array<3x3xi32>> {
+ %1 = fir.allocmem !fir.array<3x3xi32>
+ return %1 : !fir.heap<!fir.array<3x3xi32>>
+}
+
+// CHECK-LABEL: define [3 x [3 x [10 x i8]]]* @allocmem_array_of_char(
+// CHECK: call i8* @malloc(i64 ptrtoint ([3 x [3 x [10 x i8]]]* getelementptr ([3 x [3 x [10 x i8]]], [3 x [3 x [10 x i8]]]* null, i64 1) to i64))
+func @allocmem_array_of_char() -> !fir.heap<!fir.array<3x3x!fir.char<1,10>>> {
+ %1 = fir.allocmem !fir.array<3x3x!fir.char<1,10>>
+ return %1 : !fir.heap<!fir.array<3x3x!fir.char<1,10>>>
+}
+
+// CHECK-LABEL: define i8* @allocmem_array_of_dynchar(
+// CHECK-SAME: i32 %[[len:.*]])
+// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
+// CHECK: %[[mul2:.*]] = mul i64 9, %[[mul1]]
+// CHECK: call i8* @malloc(i64 %[[mul2]])
+func @allocmem_array_of_dynchar(%l: i32) -> !fir.heap<!fir.array<3x3x!fir.char<1,?>>> {
+ %1 = fir.allocmem !fir.array<3x3x!fir.char<1,?>>(%l : i32)
+ return %1 : !fir.heap<!fir.array<3x3x!fir.char<1,?>>>
+}
+
+// CHECK-LABEL: define [3 x i32]* @alloca_dynarray_of_nonchar(
+// CHECK-SAME: i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
+// CHECK: alloca [3 x i32], i64 %[[prod1]]
+func @alloca_dynarray_of_nonchar(%e: index) -> !fir.ref<!fir.array<3x?xi32>> {
+ %1 = fir.alloca !fir.array<3x?xi32>, %e
+ return %1 : !fir.ref<!fir.array<3x?xi32>>
+}
+
+// CHECK-LABEL: define i32* @alloca_dynarray_of_nonchar2(
+// CHECK-SAME: i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
+// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
+// CHECK: alloca i32, i64 %[[prod2]]
+func @alloca_dynarray_of_nonchar2(%e: index) -> !fir.ref<!fir.array<?x?xi32>> {
+ %1 = fir.alloca !fir.array<?x?xi32>, %e, %e
+ return %1 : !fir.ref<!fir.array<?x?xi32>>
}
-// Constant factor of 60 (4*3*5) must be included.
-// CHECK-LABEL: define i32* @array_with_holes(
+// CHECK-LABEL: define [3 x i32]* @allocmem_dynarray_of_nonchar(
+// CHECK-SAME: i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = mul i64 ptrtoint ([3 x i32]* getelementptr ([3 x i32], [3 x i32]* null, i64 1) to i64), %[[extent]]
+// CHECK: call i8* @malloc(i64 %[[prod1]])
+func @allocmem_dynarray_of_nonchar(%e: index) -> !fir.heap<!fir.array<3x?xi32>> {
+ %1 = fir.allocmem !fir.array<3x?xi32>, %e
+ return %1 : !fir.heap<!fir.array<3x?xi32>>
+}
+
+// CHECK-LABEL: define i32* @allocmem_dynarray_of_nonchar2(
+// CHECK-SAME: i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = mul i64 4, %[[extent]]
+// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
+// CHECK: call i8* @malloc(i64 %[[prod2]])
+func @allocmem_dynarray_of_nonchar2(%e: index) -> !fir.heap<!fir.array<?x?xi32>> {
+ %1 = fir.allocmem !fir.array<?x?xi32>, %e, %e
+ return %1 : !fir.heap<!fir.array<?x?xi32>>
+}
+
+// CHECK-LABEL: define [3 x [10 x i16]]* @alloca_dynarray_of_char(
+// CHECK-SAME: i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
+// CHECK: alloca [3 x [10 x i16]], i64 %[[prod1]]
+func @alloca_dynarray_of_char(%e : index) -> !fir.ref<!fir.array<3x?x!fir.char<2,10>>> {
+ %1 = fir.alloca !fir.array<3x?x!fir.char<2,10>>, %e
+ return %1 : !fir.ref<!fir.array<3x?x!fir.char<2,10>>>
+}
+
+// CHECK-LABEL: define [10 x i16]* @alloca_dynarray_of_char2(
+// CHECK-SAME: i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
+// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
+// CHECK: alloca [10 x i16], i64 %[[prod2]]
+func @alloca_dynarray_of_char2(%e : index) -> !fir.ref<!fir.array<?x?x!fir.char<2,10>>> {
+ %1 = fir.alloca !fir.array<?x?x!fir.char<2,10>>, %e, %e
+ return %1 : !fir.ref<!fir.array<?x?x!fir.char<2,10>>>
+}
+
+// CHECK-LABEL: define [3 x [10 x i16]]* @allocmem_dynarray_of_char(
+// CHECK-SAME: i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = mul i64 ptrtoint ([3 x [10 x i16]]* getelementptr ([3 x [10 x i16]], [3 x [10 x i16]]* null, i64 1) to i64), %[[extent]]
+// CHECK: call i8* @malloc(i64 %[[prod1]])
+func @allocmem_dynarray_of_char(%e : index) -> !fir.heap<!fir.array<3x?x!fir.char<2,10>>> {
+ %1 = fir.allocmem !fir.array<3x?x!fir.char<2,10>>, %e
+ return %1 : !fir.heap<!fir.array<3x?x!fir.char<2,10>>>
+}
+
+// CHECK-LABEL: define [10 x i16]* @allocmem_dynarray_of_char2(
+// CHECK-SAME: i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = mul i64 ptrtoint ([10 x i16]* getelementptr ([10 x i16], [10 x i16]* null, i64 1) to i64), %[[extent]]
+// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
+// CHECK: call i8* @malloc(i64 %[[prod2]])
+func @allocmem_dynarray_of_char2(%e : index) -> !fir.heap<!fir.array<?x?x!fir.char<2,10>>> {
+ %1 = fir.allocmem !fir.array<?x?x!fir.char<2,10>>, %e, %e
+ return %1 : !fir.heap<!fir.array<?x?x!fir.char<2,10>>>
+}
+
+// CHECK-LABEL: define i16* @alloca_dynarray_of_dynchar(
+// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64
+// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], 3
+// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
+// CHECK: alloca i16, i64 %[[prod3]]
+func @alloca_dynarray_of_dynchar(%l: i32, %e : index) -> !fir.ref<!fir.array<3x?x!fir.char<2,?>>> {
+ %1 = fir.alloca !fir.array<3x?x!fir.char<2,?>>(%l : i32), %e
+ return %1 : !fir.ref<!fir.array<3x?x!fir.char<2,?>>>
+}
+
+// CHECK-LABEL: define i16* @alloca_dynarray_of_dynchar2(
+// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64
+// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
+// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
+// CHECK: alloca i16, i64 %[[prod3]]
+func @alloca_dynarray_of_dynchar2(%l: i32, %e : index) -> !fir.ref<!fir.array<?x?x!fir.char<2,?>>> {
+ %1 = fir.alloca !fir.array<?x?x!fir.char<2,?>>(%l : i32), %e, %e
+ return %1 : !fir.ref<!fir.array<?x?x!fir.char<2,?>>>
+}
+
+// CHECK-LABEL: define i16* @allocmem_dynarray_of_dynchar(
+// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
+// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64
+// CHECK: %[[prod2:.*]] = mul i64 6, %[[prod1]]
+// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
+// CHECK: call i8* @malloc(i64 %[[prod3]])
+func @allocmem_dynarray_of_dynchar(%l: i32, %e : index) -> !fir.heap<!fir.array<3x?x!fir.char<2,?>>> {
+ %1 = fir.allocmem !fir.array<3x?x!fir.char<2,?>>(%l : i32), %e
+ return %1 : !fir.heap<!fir.array<3x?x!fir.char<2,?>>>
+}
+
+// CHECK-LABEL: define i16* @allocmem_dynarray_of_dynchar2(
+// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
+// CHECK: %[[a:.*]] = sext i32 %[[len]] to i64
+// CHECK: %[[prod1:.*]] = mul i64 2, %[[a]]
+// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
+// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
+// CHECK: call i8* @malloc(i64 %[[prod3]])
+func @allocmem_dynarray_of_dynchar2(%l: i32, %e : index) -> !fir.heap<!fir.array<?x?x!fir.char<2,?>>> {
+ %1 = fir.allocmem !fir.array<?x?x!fir.char<2,?>>(%l : i32), %e, %e
+ return %1 : !fir.heap<!fir.array<?x?x!fir.char<2,?>>>
+}
+
+// CHECK-LABEL: define i32* @alloca_array_with_holes_nonchar(
// CHECK-SAME: i64 %[[a:.*]], i64 %[[b:.*]])
-func @array_with_holes(%0 : index, %1 : index) -> !fir.ref<!fir.array<4x?x3x?x5xi32>> {
- // CHECK: %[[prod1:.*]] = mul i64 60, %[[a]]
- // CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[b]]
- // CHECK: alloca i32, i64 %[[prod2]]
+// CHECK: %[[prod1:.*]] = mul i64 60, %[[a]]
+// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[b]]
+// CHECK: alloca i32, i64 %[[prod2]]
+func @alloca_array_with_holes_nonchar(%0 : index, %1 : index) -> !fir.ref<!fir.array<4x?x3x?x5xi32>> {
%a = fir.alloca !fir.array<4x?x3x?x5xi32>, %0, %1
return %a : !fir.ref<!fir.array<4x?x3x?x5xi32>>
}
-// CHECK-LABEL: define void @allocmem_array_of_dynchar(
-// CHECK-SAME: i64 %[[arg:.*]])
-// CHECK: %[[mul:.*]] = mul i64 9, %[[arg]]
-// CHECK: %[[malloc:.*]] = call i8* @malloc(i64 %[[mul]])
-// CHECK: ret void
-func @allocmem_array_of_dynchar(%arg0: index) {
- %1 = fir.allocmem !fir.array<3x3x!fir.char<1,?>>(%arg0 : index)
- return
+// CHECK-LABEL: define [10 x i16]* @alloca_array_with_holes_char(
+// CHECK-SAME: i64 %[[e:.*]])
+// CHECK: %[[mul:.*]] = mul i64 12, %[[e]]
+// CHECK: alloca [10 x i16], i64 %[[mul]]
+func @alloca_array_with_holes_char(%e: index) -> !fir.ref<!fir.array<3x?x4x!fir.char<2,10>>> {
+ %1 = fir.alloca !fir.array<3x?x4x!fir.char<2,10>>, %e
+ return %1 : !fir.ref<!fir.array<3x?x4x!fir.char<2,10>>>
+}
+
+// CHECK-LABEL: define i16* @alloca_array_with_holes_dynchar(
+// CHECK-SAME: i64 %[[len:.*]], i64 %[[extent:.*]])
+// CHECK: %[[a:.*]] = mul i64 %[[len]], 12
+// CHECK: %[[b:.*]] = mul i64 %[[a]], %[[extent]]
+// CHECK: alloca i16, i64 %[[b]]
+func @alloca_array_with_holes_dynchar(%arg0: index, %arg1: index) -> !fir.ref<!fir.array<3x?x4x!fir.char<2,?>>> {
+ %1 = fir.alloca !fir.array<3x?x4x!fir.char<2,?>>(%arg0 : index), %arg1
+ return %1 : !fir.ref<!fir.array<3x?x4x!fir.char<2,?>>>
+}
+
+// CHECK-LABEL: define i32* @allocmem_array_with_holes_nonchar(
+// CHECK-SAME: i64 %[[e1:.*]], i64 %[[e2:.*]])
+// CHECK: %[[a:.*]] = mul i64 240, %[[e1]]
+// CHECK: %[[b:.*]] = mul i64 %3, %[[e2]]
+// CHECK: call i8* @malloc(i64 %[[b]])
+func @allocmem_array_with_holes_nonchar(%0 : index, %1 : index) -> !fir.heap<!fir.array<4x?x3x?x5xi32>> {
+ %a = fir.allocmem !fir.array<4x?x3x?x5xi32>, %0, %1
+ return %a : !fir.heap<!fir.array<4x?x3x?x5xi32>>
}
-// CHECK-LABEL: define void @allocmem_dynarray_of_dynchar(
+// CHECK-LABEL: define [10 x i16]* @allocmem_array_with_holes_char(
+// CHECK-SAME: i64 %[[e:.*]])
+// CHECK: %[[mul:.*]] = mul i64 mul (i64 ptrtoint ([10 x i16]* getelementptr ([10 x i16], [10 x i16]* null, i64 1) to i64), i64 12), %[[e]]
+// CHECK: call i8* @malloc(i64 %[[mul]])
+func @allocmem_array_with_holes_char(%e: index) -> !fir.heap<!fir.array<3x?x4x!fir.char<2,10>>> {
+ %1 = fir.allocmem !fir.array<3x?x4x!fir.char<2,10>>, %e
+ return %1 : !fir.heap<!fir.array<3x?x4x!fir.char<2,10>>>
+}
+
+// CHECK-LABEL: define i16* @allocmem_array_with_holes_dynchar(
// CHECK-SAME: i64 %[[len:.*]], i64 %[[extent:.*]])
// CHECK: %[[a:.*]] = mul i64 24, %[[len]]
// CHECK: %[[b:.*]] = mul i64 %[[a]], %[[extent]]
-// CHECK: %[[malloc:.*]] = call i8* @malloc(i64 %[[b]])
-// CHECK: ret void
-func @allocmem_dynarray_of_dynchar(%arg0: index, %arg1: index) {
+// CHECK: call i8* @malloc(i64 %[[b]])
+func @allocmem_array_with_holes_dynchar(%arg0: index, %arg1: index) -> !fir.heap<!fir.array<3x?x4x!fir.char<2,?>>> {
%1 = fir.allocmem !fir.array<3x?x4x!fir.char<2,?>>(%arg0 : index), %arg1
- return
+ return %1 : !fir.heap<!fir.array<3x?x4x!fir.char<2,?>>>
}
+
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 81f38156081b..d022c8a02884 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -230,9 +230,7 @@ func @test_string_with_shape(%len: index, %nelems: index) {
// CHECK-LABEL: llvm.func @test_string_with_shape
// CHECK-SAME: %[[LEN:.*]]: i64, %[[NELEMS:.*]]: i64)
// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[ONE2:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[MUL1:.*]] = llvm.mul %[[ONE]], %[[ONE2]] : i64
-// CHECK: %[[LEN_SIZE:.*]] = llvm.mul %[[MUL1]], %[[LEN]] : i64
+// CHECK: %[[LEN_SIZE:.*]] = llvm.mul %[[ONE]], %[[LEN]] : i64
// CHECK: %[[TOTAL_SIZE:.*]] = llvm.mul %[[LEN_SIZE]], %[[NELEMS]] : i64
// CHECK: %[[MEM:.*]] = llvm.call @malloc(%[[TOTAL_SIZE]])
// CHECK: %[[B1:.*]] = llvm.bitcast %[[MEM]] : !llvm.ptr<i8> to !llvm.ptr<i8>