Index: flang/lib/Optimizer/CodeGen/CodeGen.cpp =================================================================== --- flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -302,6 +302,33 @@ return module.lookupSymbol(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 +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(); + 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 { @@ -346,23 +373,9 @@ << scalarType << " with type parameters"; } } + if (auto scaleSize = genAllocationScaleSize(alloc, ity, rewriter)) + size = rewriter.create(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()) { - 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(loc, ity, size, constVal); - } - } unsigned end = operands.size(); for (; i < end; ++i) size = rewriter.create( @@ -1001,18 +1014,8 @@ 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> sets `size` to the width of !fir.char. - // So multiply the constant dimensions here. - if (fir::hasDynamicSize(dataTy)) - if (auto seqTy = dataTy.dyn_cast()) - 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( - loc, ity, size, genConstantIndex(loc, ity, rewriter, arrSize)); - } + if (auto scaleSize = genAllocationScaleSize(heap, ity, rewriter)) + size = rewriter.create(loc, ity, size, scaleSize); for (mlir::Value opnd : adaptor.getOperands()) size = rewriter.create( loc, ity, size, integerCast(loc, rewriter, ity, opnd)); Index: flang/test/Fir/alloc.fir =================================================================== --- flang/test/Fir/alloc.fir +++ flang/test/Fir/alloc.fir @@ -2,82 +2,333 @@ // UNSUPPORTED: system-windows -// CHECK-LABEL: define i32* @f1() -func @f1() -> !fir.ref { - // CHECK: alloca i32, i64 1 +// CHECK-LABEL: define i32* @alloca_scalar_nonchar() +// CHECK: alloca i32, i64 1 +func @alloca_scalar_nonchar() -> !fir.ref { %1 = fir.alloca i32 return %1 : !fir.ref } -// CHECK-LABEL: define i32* @f2() -func @f2() -> !fir.ref { +// CHECK-LABEL: define i32* @alloca_scalars_nonchar() +// CHECK: alloca i32, i64 100 +func @alloca_scalars_nonchar() -> !fir.ref { %0 = arith.constant 100 : index - // CHECK: alloca i32, i64 100 %1 = fir.alloca i32, %0 return %1 : !fir.ref } -// CHECK-LABEL: define i32* @f3() -func @f3() -> !fir.heap { - // 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 { %1 = fir.allocmem i32 return %1 : !fir.heap } -// CHECK-LABEL: define i32* @f4() -func @f4() -> !fir.heap { +// CHECK-LABEL: define i32* @allocmem_scalars_nonchar( +// CHECK: call i8* @malloc(i64 400) +func @allocmem_scalars_nonchar() -> !fir.heap { %0 = arith.constant 100 : index - // CHECK: call i8* @malloc(i64 400) %1 = fir.allocmem i32, %0 return %1 : !fir.heap } -// CHECK-LABEL: define i32** @f5() -func @f5() -> !fir.ref>> { - // 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> { + %1 = fir.alloca !fir.char<1,10> + return %1 : !fir.ref> +} + +// CHECK-LABEL: define [10 x i16]* @alloca_scalar_char_kind( +// CHECK: alloca [10 x i16], i64 1 +func @alloca_scalar_char_kind() -> !fir.ref> { + %1 = fir.alloca !fir.char<2,10> + return %1 : !fir.ref> +} + +// 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> { + %1 = fir.allocmem !fir.char<1,10> + return %1 : !fir.heap> +} + +// 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> { + %1 = fir.allocmem !fir.char<2,10> + return %1 : !fir.heap> +} + +// 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> { + %1 = fir.alloca !fir.char<1,?>(%l : i32) + return %1 : !fir.ref> +} + +// 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> { + %1 = fir.alloca !fir.char<2,?>(%l : i32) + return %1 : !fir.ref> +} + +// 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> { + %1 = fir.allocmem !fir.char<1,?>(%l : i32) + return %1 : !fir.heap> +} + +// 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>{ + %1 = fir.allocmem !fir.char<2,?>(%l : i32) + return %1 : !fir.heap> +} + +// CHECK-LABEL: define i32** @alloca_ptr_to_dynarray_nonchar( +// CHECK: %1 = alloca i32*, i64 1 +func @alloca_ptr_to_dynarray_nonchar() -> !fir.ref>> { %1 = fir.alloca !fir.ptr> return %1 : !fir.ref>> } -// CHECK-LABEL: define i8* @char_array_alloca( -// CHECK-SAME: i32 %[[l:.*]], i64 %[[e:.*]]) -func @char_array_alloca(%l: i32, %e : index) -> !fir.ref>> { - // 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>(%l : i32), %e, %e - return %a : !fir.ref>> +// 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> { + %1 = fir.alloca !fir.array<3x3xi32> + return %1 : !fir.ref> +} + +// 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>> { + %1 = fir.alloca !fir.array<3x3x!fir.char<1,10>> + return %1 : !fir.ref>> +} + +// 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>> { + %1 = fir.alloca !fir.array<3x3x!fir.char<1,?>>(%l : i32) + return %1 : !fir.ref>> +} + +// 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> { + %1 = fir.allocmem !fir.array<3x3xi32> + return %1 : !fir.heap> +} + +// 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>> { + %1 = fir.allocmem !fir.array<3x3x!fir.char<1,10>> + return %1 : !fir.heap>> +} + +// 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>> { + %1 = fir.allocmem !fir.array<3x3x!fir.char<1,?>>(%l : i32) + return %1 : !fir.heap>> +} + +// 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> { + %1 = fir.alloca !fir.array<3x?xi32>, %e + return %1 : !fir.ref> +} + +// 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> { + %1 = fir.alloca !fir.array, %e, %e + return %1 : !fir.ref> } -// 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> { + %1 = fir.allocmem !fir.array<3x?xi32>, %e + return %1 : !fir.heap> +} + +// 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> { + %1 = fir.allocmem !fir.array, %e, %e + return %1 : !fir.heap> +} + +// 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>> { + %1 = fir.alloca !fir.array<3x?x!fir.char<2,10>>, %e + return %1 : !fir.ref>> +} + +// 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>> { + %1 = fir.alloca !fir.array>, %e, %e + return %1 : !fir.ref>> +} + +// 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>> { + %1 = fir.allocmem !fir.array<3x?x!fir.char<2,10>>, %e + return %1 : !fir.heap>> +} + +// 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>> { + %1 = fir.allocmem !fir.array>, %e, %e + return %1 : !fir.heap>> +} + +// 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>> { + %1 = fir.alloca !fir.array<3x?x!fir.char<2,?>>(%l : i32), %e + return %1 : !fir.ref>> +} + +// 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>> { + %1 = fir.alloca !fir.array>(%l : i32), %e, %e + return %1 : !fir.ref>> +} + +// 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>> { + %1 = fir.allocmem !fir.array<3x?x!fir.char<2,?>>(%l : i32), %e + return %1 : !fir.heap>> +} + +// 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>> { + %1 = fir.allocmem !fir.array>(%l : i32), %e, %e + return %1 : !fir.heap>> +} + +// 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> { - // 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> { %a = fir.alloca !fir.array<4x?x3x?x5xi32>, %0, %1 return %a : !fir.ref> } -// 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>> { + %1 = fir.alloca !fir.array<3x?x4x!fir.char<2,10>>, %e + return %1 : !fir.ref>> +} + +// 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>> { + %1 = fir.alloca !fir.array<3x?x4x!fir.char<2,?>>(%arg0 : index), %arg1 + return %1 : !fir.ref>> +} + +// 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> { + %a = fir.allocmem !fir.array<4x?x3x?x5xi32>, %0, %1 + return %a : !fir.heap> } -// 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>> { + %1 = fir.allocmem !fir.array<3x?x4x!fir.char<2,10>>, %e + return %1 : !fir.heap>> +} + +// 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>> { %1 = fir.allocmem !fir.array<3x?x4x!fir.char<2,?>>(%arg0 : index), %arg1 - return + return %1 : !fir.heap>> } + Index: flang/test/Fir/convert-to-llvm.fir =================================================================== --- flang/test/Fir/convert-to-llvm.fir +++ flang/test/Fir/convert-to-llvm.fir @@ -230,9 +230,7 @@ // 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 to !llvm.ptr