diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -1064,6 +1064,15 @@ /*isVarArg=*/false)); } +static unsigned getDimension(mlir::LLVM::LLVMArrayType ty) { + unsigned result = 1; + for (auto eleTy = ty.getElementType().dyn_cast(); + eleTy; + eleTy = eleTy.getElementType().dyn_cast()) + ++result; + return result; +} + namespace { /// Lower a `fir.freemem` instruction into `llvm.call @free` struct FreeMemOpConversion : public FIROpConversion { @@ -1383,9 +1392,15 @@ llvm::SmallVector gepOperands; auto baseType = base.getType().cast().getElementType(); - if (baseType.isa()) { + if (auto arrayType = baseType.dyn_cast()) { + // FIXME: The baseType should be the array element type here, meaning + // there should at most be one dimension (constant length characters are + // lowered to LLVM as an array of length one characters.). However, using + // the character type in the GEP does not lead to correct GEPs when llvm + // opaque pointers are enabled. auto idxTy = this->lowerTy().indexType(); - gepOperands.push_back(genConstantIndex(loc, idxTy, rewriter, 0)); + gepOperands.append(getDimension(arrayType), + genConstantIndex(loc, idxTy, rewriter, 0)); gepOperands.push_back(lowerBound); } else { gepOperands.push_back(lowerBound); @@ -1928,15 +1943,6 @@ } private: - static unsigned getDimension(mlir::LLVM::LLVMArrayType ty) { - unsigned result = 1; - for (auto eleTy = ty.getElementType().dyn_cast(); - eleTy; - eleTy = eleTy.getElementType().dyn_cast()) - ++result; - return result; - } - static mlir::Type getArrayElementType(mlir::LLVM::LLVMArrayType ty) { auto eleTy = ty.getElementType(); while (auto arrTy = eleTy.dyn_cast()) diff --git a/flang/test/Fir/embox.fir b/flang/test/Fir/embox.fir --- a/flang/test/Fir/embox.fir +++ b/flang/test/Fir/embox.fir @@ -75,7 +75,7 @@ %1 = fir.slice %c1, %c2, %c1, %c1, %c3, %c1 substr %c1_i64, %c2_i64 : (index, index, index, index, index, index, i64, i64) -> !fir.slice<2> %2 = fir.embox %arg0(%0) [%1] : (!fir.ref>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box>> // CHECK: %[[addr:.*]] = getelementptr [3 x [2 x [4 x i8]]], ptr %[[arg0]], i64 0, i64 0, i64 0 - // CHECK: %[[substringAddr:.*]] = getelementptr {{.*}}, ptr %[[addr]], i64 0, i64 1 + // CHECK: %[[substringAddr:.*]] = getelementptr {{.*}}, ptr %[[addr]], i64 0, i64 0, i64 0, i64 1 // CHECK: insertvalue {[[descriptorType:.*]]} { ptr undef, i64 2, i32 20180515, i8 2, i8 40, i8 0, i8 0, // CHECK-SAME: [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 2, i64 4], [3 x i64] [i64 1, i64 3, i64 8]] }, // CHECK-SAME: ptr %[[substringAddr]], 0