diff options
author | PeixinQiao <qiaopeixin@huawei.com> | 2022-05-06 17:10:13 +0300 |
---|---|---|
committer | PeixinQiao <qiaopeixin@huawei.com> | 2022-05-06 17:10:13 +0300 |
commit | ac0f4c8f362e819316ca152315e930f4e6515e9d (patch) | |
tree | aa070da0dc6f860c5d9fcda572bf9508382dfd9f /flang | |
parent | 0863abe3ac47c281fdd35dc87d83c495cf741da0 (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.cpp | 59 | ||||
-rw-r--r-- | flang/test/Fir/alloc.fir | 337 | ||||
-rw-r--r-- | flang/test/Fir/convert-to-llvm.fir | 4 |
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> |