Index: flang/lib/Optimizer/CodeGen/CodeGen.cpp =================================================================== --- flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -317,12 +317,13 @@ mlir::Value size = genConstantIndex(loc, ity, rewriter, 1).getResult(); mlir::Type ty = convertType(alloc.getType()); mlir::Type resultTy = ty; + mlir::Type allocEleTy = alloc.getInType(); + mlir::Type scalarType = fir::unwrapSequenceType(allocEleTy); if (alloc.hasLenParams()) { unsigned end = alloc.numLenParams(); llvm::SmallVector lenParams; for (; i < end; ++i) lenParams.push_back(operands[i]); - mlir::Type scalarType = fir::unwrapSequenceType(alloc.getInType()); if (auto chrTy = scalarType.dyn_cast()) { fir::CharacterType rawCharTy = fir::CharacterType::getUnknownLen( chrTy.getContext(), chrTy.getFKind()); @@ -346,21 +347,25 @@ << scalarType << " with type parameters"; } } - 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. + // Scale the size by constant factors encoded in the array type. + // We do this for char arrays and non-char arrays without a constant + // interior, since those are the only ones that get decayed to a pointer + // to the element type. + if ((allocEleTy.isa() && + scalarType.isa()) || + alloc.hasShapeOperands()) { if (auto seqTy = allocEleTy.dyn_cast()) { - if (!seqTy.hasConstantInterior()) { + if (scalarType.isa() || + !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); + if (constSize != 1) { + mlir::Value constVal{ + genConstantIndex(loc, ity, rewriter, constSize).getResult()}; + size = rewriter.create(loc, ity, size, constVal); + } } } unsigned end = operands.size(); Index: flang/test/Fir/alloc.fir =================================================================== --- flang/test/Fir/alloc.fir +++ flang/test/Fir/alloc.fir @@ -50,6 +50,27 @@ return %a : !fir.ref>> } +// CHECK-LABEL: define i8* @char_array_alloca2( +// CHECK-SAME: i32 %[[l:.*]], i64 %[[e:.*]]) +func @char_array_alloca2(%l: i32, %e : index) -> !fir.ref>> { + // CHECK: %[[lcast:.*]] = sext i32 %[[l]] to i64 + // CHECK: %[[prod:.*]] = mul i64 %[[lcast]], 3 + // CHECK: %[[size:.*]] = mul i64 %[[prod]], %[[e]] + // CHECK: alloca i8, i64 %[[size]] + %a = fir.alloca !fir.array<3x?x!fir.char<1,?>>(%l : i32), %e + return %a : !fir.ref>> +} + +// CHECK-LABEL: define i8* @char_array_alloca3( +// CHECK-SAME: i32 %[[l:.*]]) +func @char_array_alloca3(%l: i32) -> !fir.ref>> { + // CHECK: %[[lcast:.*]] = sext i32 %[[l]] to i64 + // CHECK: %[[size:.*]] = mul i64 %[[lcast]], 9 + // CHECK: alloca i8, i64 %[[size]] + %a = fir.alloca !fir.array<3x3x!fir.char<1,?>>(%l : i32) + return %a : !fir.ref>> +} + // Constant factor of 60 (4*3*5) must be included. // CHECK-LABEL: define i32* @array_with_holes( // CHECK-SAME: i64 %[[a:.*]], i64 %[[b:.*]])