[flang-commits] [flang] 02f3fec - [flang] Compute type allocation size based on the actual target representation.
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Fri Sep 9 08:48:08 PDT 2022
Author: Slava Zakharin
Date: 2022-09-09T08:39:15-07:00
New Revision: 02f3fec391fa9a612573f6ab5b92db3fbf6f14db
URL: https://github.com/llvm/llvm-project/commit/02f3fec391fa9a612573f6ab5b92db3fbf6f14db
DIFF: https://github.com/llvm/llvm-project/commit/02f3fec391fa9a612573f6ab5b92db3fbf6f14db.diff
LOG: [flang] Compute type allocation size based on the actual target representation.
This change makes sure that we compute the element size and the byte stride
based on the target representation of the element type.
For example, when REAL*10 is mapped to x86_fp80 each element occupies
16 bytes rather than 10 because of the padding.
Note that the size computation method used here actually returns
the distance between two adjacent element of the *same* type in memory
(which is equivalent to llvm::DataLayout::getTypeAllocSize()).
It does not return the number of bytes that may be overwritten
by storing a value of the specified type (e.g. what can be computed
via llvm::DataLayout::getTypeStoreSize(), but not available in
mlir::DataLayout).
Differential Revision: https://reviews.llvm.org/D133508
Added:
Modified:
flang/lib/Optimizer/CodeGen/CodeGen.cpp
flang/test/Fir/alloc.fir
flang/test/Fir/arrexp.fir
flang/test/Fir/box.fir
flang/test/Fir/convert-to-llvm.fir
flang/test/Fir/embox.fir
flang/test/Fir/rebox.fir
flang/test/Lower/forall/character-1.f90
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index b67688c099568..42472d2efc472 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -969,17 +969,40 @@ getMalloc(fir::AllocMemOp op, mlir::ConversionPatternRewriter &rewriter) {
/*isVarArg=*/false));
}
-/// Helper function for generating the LLVM IR that computes the size
-/// in bytes for a derived type.
+/// Helper function for generating the LLVM IR that computes the distance
+/// in bytes between adjacent elements pointed to by a pointer
+/// of type \p ptrTy. The result is returned as a value of \p idxTy integer
+/// type.
static mlir::Value
-computeDerivedTypeSize(mlir::Location loc, mlir::Type ptrTy, mlir::Type idxTy,
+computeElementDistance(mlir::Location loc, mlir::Type ptrTy, mlir::Type idxTy,
mlir::ConversionPatternRewriter &rewriter) {
+ // Note that we cannot use something like
+ // mlir::LLVM::getPrimitiveTypeSizeInBits() for the element type here. For
+ // example, it returns 10 bytes for mlir::Float80Type for targets where it
+ // occupies 16 bytes. Proper solution is probably to use
+ // mlir::DataLayout::getTypeABIAlignment(), but DataLayout is not being set
+ // yet (see llvm-project#57230). For the time being use the '(intptr_t)((type
+ // *)0 + 1)' trick for all types. The generated instructions are optimized
+ // into constant by the first pass of InstCombine, so it should not be a
+ // performance issue.
auto nullPtr = rewriter.create<mlir::LLVM::NullOp>(loc, ptrTy);
auto gep = rewriter.create<mlir::LLVM::GEPOp>(
loc, ptrTy, nullPtr, llvm::ArrayRef<mlir::LLVM::GEPArg>{1});
return rewriter.create<mlir::LLVM::PtrToIntOp>(loc, idxTy, gep);
}
+/// Return value of the stride in bytes between adjacent elements
+/// of LLVM type \p llTy. The result is returned as a value of
+/// \p idxTy integer type.
+static mlir::Value
+genTypeStrideInBytes(mlir::Location loc, mlir::Type idxTy,
+ mlir::ConversionPatternRewriter &rewriter,
+ mlir::Type llTy) {
+ // Create a pointer type and use computeElementDistance().
+ auto ptrTy = mlir::LLVM::LLVMPointerType::get(llTy);
+ return computeElementDistance(loc, ptrTy, idxTy, rewriter);
+}
+
namespace {
/// Lower a `fir.allocmem` instruction into `llvm.call @malloc`
struct AllocMemOpConversion : public FIROpConversion<fir::AllocMemOp> {
@@ -1010,18 +1033,14 @@ struct AllocMemOpConversion : public FIROpConversion<fir::AllocMemOp> {
return mlir::success();
}
- // Compute the (allocation) size of the allocmem type in bytes.
+ /// Compute the allocation size in bytes of the element type of
+ /// \p llTy pointer type. The result is returned as a value of \p idxTy
+ /// integer type.
mlir::Value genTypeSizeInBytes(mlir::Location loc, mlir::Type idxTy,
mlir::ConversionPatternRewriter &rewriter,
mlir::Type llTy) const {
- // Use the primitive size, if available.
auto ptrTy = llTy.dyn_cast<mlir::LLVM::LLVMPointerType>();
- if (auto size =
- mlir::LLVM::getPrimitiveTypeSizeInBits(ptrTy.getElementType()))
- return genConstantIndex(loc, idxTy, rewriter, size / 8);
-
- // Otherwise, generate the GEP trick in LLVM IR to compute the size.
- return computeDerivedTypeSize(loc, ptrTy, idxTy, rewriter);
+ return computeElementDistance(loc, ptrTy, idxTy, rewriter);
}
};
} // namespace
@@ -1127,45 +1146,66 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
std::tuple<mlir::Value, mlir::Value> getSizeAndTypeCode(
mlir::Location loc, mlir::ConversionPatternRewriter &rewriter,
mlir::Type boxEleTy, mlir::ValueRange lenParams = {}) const {
+ auto i64Ty = mlir::IntegerType::get(rewriter.getContext(), 64);
+ auto getKindMap = [&]() -> fir::KindMapping & {
+ return this->lowerTy().getKindMap();
+ };
auto doInteger =
- [&](unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
+ [&](mlir::Type type,
+ unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
int typeCode = fir::integerBitsToTypeCode(width);
- return {this->genConstantOffset(loc, rewriter, width / 8),
- this->genConstantOffset(loc, rewriter, typeCode)};
+ return {
+ genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type)),
+ this->genConstantOffset(loc, rewriter, typeCode)};
};
auto doLogical =
- [&](unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
+ [&](mlir::Type type,
+ unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
int typeCode = fir::logicalBitsToTypeCode(width);
- return {this->genConstantOffset(loc, rewriter, width / 8),
- this->genConstantOffset(loc, rewriter, typeCode)};
+ return {
+ genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type)),
+ this->genConstantOffset(loc, rewriter, typeCode)};
};
- auto doFloat = [&](unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
+ auto doFloat = [&](mlir::Type type,
+ unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
int typeCode = fir::realBitsToTypeCode(width);
- return {this->genConstantOffset(loc, rewriter, width / 8),
- this->genConstantOffset(loc, rewriter, typeCode)};
+ return {
+ genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type)),
+ this->genConstantOffset(loc, rewriter, typeCode)};
};
auto doComplex =
- [&](unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
+ [&](mlir::Type type,
+ unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
auto typeCode = fir::complexBitsToTypeCode(width);
- return {this->genConstantOffset(loc, rewriter, width / 8 * 2),
- this->genConstantOffset(loc, rewriter, typeCode)};
+ return {
+ genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type)),
+ this->genConstantOffset(loc, rewriter, typeCode)};
};
- auto doCharacter =
- [&](unsigned width,
- mlir::Value len) -> std::tuple<mlir::Value, mlir::Value> {
- auto typeCode = fir::characterBitsToTypeCode(width);
+ auto doCharacter = [&](fir::CharacterType type, mlir::ValueRange lenParams)
+ -> std::tuple<mlir::Value, mlir::Value> {
+ unsigned bitWidth = getKindMap().getCharacterBitsize(type.getFKind());
+ auto typeCode = fir::characterBitsToTypeCode(bitWidth);
auto typeCodeVal = this->genConstantOffset(loc, rewriter, typeCode);
- if (width == 8)
- return {len, typeCodeVal};
- auto i64Ty = mlir::IntegerType::get(&this->lowerTy().getContext(), 64);
- auto byteWidth = genConstantIndex(loc, i64Ty, rewriter, width / 8);
- auto len64 = FIROpConversion<OP>::integerCast(loc, rewriter, i64Ty, len);
- auto size =
- rewriter.create<mlir::LLVM::MulOp>(loc, i64Ty, byteWidth, len64);
- return {size, typeCodeVal};
- };
- auto getKindMap = [&]() -> fir::KindMapping & {
- return this->lowerTy().getKindMap();
+
+ bool lengthIsConst = (type.getLen() != fir::CharacterType::unknownLen());
+ mlir::Value eleSize =
+ genTypeStrideInBytes(loc, i64Ty, rewriter, this->convertType(type));
+
+ if (!lengthIsConst) {
+ // If length is constant, then the fir::CharacterType will be
+ // represented as an array of known size of elements having
+ // the corresponding LLVM type. In this case eleSize already
+ // holds correct memory size. If length is not constant, then
+ // the fir::CharacterType will decay to a scalar type,
+ // so we have to multiply it by the non-constant length
+ // to get its size in memory.
+ assert(!lenParams.empty());
+ auto len64 = FIROpConversion<OP>::integerCast(loc, rewriter, i64Ty,
+ lenParams.back());
+ eleSize =
+ rewriter.create<mlir::LLVM::MulOp>(loc, i64Ty, eleSize, len64);
+ }
+ return {eleSize, typeCodeVal};
};
// Pointer-like types.
if (auto eleTy = fir::dyn_cast_ptrEleTy(boxEleTy))
@@ -1173,58 +1213,47 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
// Integer types.
if (fir::isa_integer(boxEleTy)) {
if (auto ty = boxEleTy.dyn_cast<mlir::IntegerType>())
- return doInteger(ty.getWidth());
+ return doInteger(ty, ty.getWidth());
auto ty = boxEleTy.cast<fir::IntegerType>();
- return doInteger(getKindMap().getIntegerBitsize(ty.getFKind()));
+ return doInteger(ty, getKindMap().getIntegerBitsize(ty.getFKind()));
}
// Floating point types.
if (fir::isa_real(boxEleTy)) {
if (auto ty = boxEleTy.dyn_cast<mlir::FloatType>())
- return doFloat(ty.getWidth());
+ return doFloat(ty, ty.getWidth());
auto ty = boxEleTy.cast<fir::RealType>();
- return doFloat(getKindMap().getRealBitsize(ty.getFKind()));
+ return doFloat(ty, getKindMap().getRealBitsize(ty.getFKind()));
}
// Complex types.
if (fir::isa_complex(boxEleTy)) {
if (auto ty = boxEleTy.dyn_cast<mlir::ComplexType>())
return doComplex(
- ty.getElementType().cast<mlir::FloatType>().getWidth());
+ ty, ty.getElementType().cast<mlir::FloatType>().getWidth());
auto ty = boxEleTy.cast<fir::ComplexType>();
- return doComplex(getKindMap().getRealBitsize(ty.getFKind()));
+ return doComplex(ty, getKindMap().getRealBitsize(ty.getFKind()));
}
// Character types.
- if (auto ty = boxEleTy.dyn_cast<fir::CharacterType>()) {
- auto charWidth = getKindMap().getCharacterBitsize(ty.getFKind());
- if (ty.getLen() != fir::CharacterType::unknownLen()) {
- auto len = this->genConstantOffset(loc, rewriter, ty.getLen());
- return doCharacter(charWidth, len);
- }
- assert(!lenParams.empty());
- return doCharacter(charWidth, lenParams.back());
- }
+ if (auto ty = boxEleTy.dyn_cast<fir::CharacterType>())
+ return doCharacter(ty, lenParams);
// Logical type.
if (auto ty = boxEleTy.dyn_cast<fir::LogicalType>())
- return doLogical(getKindMap().getLogicalBitsize(ty.getFKind()));
+ return doLogical(ty, getKindMap().getLogicalBitsize(ty.getFKind()));
// Array types.
if (auto seqTy = boxEleTy.dyn_cast<fir::SequenceType>())
return getSizeAndTypeCode(loc, rewriter, seqTy.getEleTy(), lenParams);
// Derived-type types.
if (boxEleTy.isa<fir::RecordType>()) {
- auto ptrTy = mlir::LLVM::LLVMPointerType::get(
- this->lowerTy().convertType(boxEleTy));
- auto nullPtr = rewriter.create<mlir::LLVM::NullOp>(loc, ptrTy);
- auto gep = rewriter.create<mlir::LLVM::GEPOp>(
- loc, ptrTy, nullPtr, llvm::ArrayRef<mlir::LLVM::GEPArg>{1});
- auto eleSize = rewriter.create<mlir::LLVM::PtrToIntOp>(
- loc, this->lowerTy().indexType(), gep);
+ auto eleSize = genTypeStrideInBytes(loc, i64Ty, rewriter,
+ this->convertType(boxEleTy));
return {eleSize,
this->genConstantOffset(loc, rewriter, fir::derivedToTypeCode())};
}
// Reference type.
if (fir::isa_ref_type(boxEleTy)) {
- // FIXME: use the target pointer size rather than sizeof(void*)
- return {this->genConstantOffset(loc, rewriter, sizeof(void *)),
- this->genConstantOffset(loc, rewriter, CFI_type_cptr)};
+ auto ptrTy = mlir::LLVM::LLVMPointerType::get(
+ mlir::LLVM::LLVMVoidType::get(rewriter.getContext()));
+ mlir::Value size = genTypeStrideInBytes(loc, i64Ty, rewriter, ptrTy);
+ return {size, this->genConstantOffset(loc, rewriter, CFI_type_cptr)};
}
fir::emitFatalError(loc, "unhandled type in fir.box code generation");
}
@@ -1526,14 +1555,7 @@ struct XEmboxOpConversion : public EmboxCommonConversion<fir::cg::XEmboxOp> {
// Adjust the element scaling factor if the element is a dependent type.
if (fir::hasDynamicSize(seqEleTy)) {
if (auto charTy = seqEleTy.dyn_cast<fir::CharacterType>()) {
- assert(xbox.lenParams().size() == 1);
- mlir::LLVM::ConstantOp charSize = genConstantIndex(
- loc, i64Ty, rewriter, lowerTy().characterBitsize(charTy) / 8);
- mlir::Value castedLen =
- integerCast(loc, rewriter, i64Ty, operands[xbox.lenParamOffset()]);
- auto byteOffset =
- rewriter.create<mlir::LLVM::MulOp>(loc, i64Ty, charSize, castedLen);
- prevPtrOff = integerCast(loc, rewriter, i64Ty, byteOffset);
+ prevPtrOff = eleSize;
} else if (seqEleTy.isa<fir::RecordType>()) {
// prevPtrOff = ;
TODO(loc, "generate call to calculate size of PDT");
@@ -1546,14 +1568,14 @@ struct XEmboxOpConversion : public EmboxCommonConversion<fir::cg::XEmboxOp> {
const auto hasSubcomp = !xbox.subcomponent().empty();
const bool hasSubstr = !xbox.substr().empty();
- /// Compute initial element stride that will be use to compute the step in
- /// each dimension.
- mlir::Value prevDimByteStride = integerCast(loc, rewriter, i64Ty, eleSize);
+ // Initial element stride that will be use to compute the step in
+ // each dimension.
+ mlir::Value prevDimByteStride = eleSize;
if (hasSubcomp) {
// We have a subcomponent. The step value needs to be the number of
// bytes per element (which is a derived type).
- auto eleTy = mlir::LLVM::LLVMPointerType::get(convertType(seqEleTy));
- prevDimByteStride = computeDerivedTypeSize(loc, eleTy, i64Ty, rewriter);
+ prevDimByteStride =
+ genTypeStrideInBytes(loc, i64Ty, rewriter, convertType(seqEleTy));
} else if (hasSubstr) {
// We have a substring. The step value needs to be the number of bytes
// per CHARACTER element.
diff --git a/flang/test/Fir/alloc.fir b/flang/test/Fir/alloc.fir
index 668550a65c725..4e6faefa31d71 100644
--- a/flang/test/Fir/alloc.fir
+++ b/flang/test/Fir/alloc.fir
@@ -19,14 +19,14 @@ func.func @alloca_scalars_nonchar() -> !fir.ref<i32> {
}
// CHECK-LABEL: define ptr @allocmem_scalar_nonchar(
-// CHECK: call ptr @malloc(i64 4)
+// CHECK: call ptr @malloc(i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64))
func.func @allocmem_scalar_nonchar() -> !fir.heap<i32> {
%1 = fir.allocmem i32
return %1 : !fir.heap<i32>
}
// CHECK-LABEL: define ptr @allocmem_scalars_nonchar(
-// CHECK: call ptr @malloc(i64 400)
+// CHECK: call ptr @malloc(i64 mul (i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i64 100))
func.func @allocmem_scalars_nonchar() -> !fir.heap<i32> {
%0 = arith.constant 100 : index
%1 = fir.allocmem i32, %0
@@ -82,7 +82,7 @@ func.func @alloca_scalar_dynchar_kind(%l : i32) -> !fir.ref<!fir.char<2,?>> {
// CHECK-LABEL: define ptr @allocmem_scalar_dynchar(
// CHECK-SAME: i32 %[[len:.*]])
// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
-// CHECK: %[[mul2:.*]] = mul i64 1, %[[mul1]]
+// CHECK: %[[mul2:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[mul1]]
// CHECK: call ptr @malloc(i64 %[[mul2]])
func.func @allocmem_scalar_dynchar(%l : i32) -> !fir.heap<!fir.char<1,?>> {
%1 = fir.allocmem !fir.char<1,?>(%l : i32)
@@ -92,7 +92,7 @@ func.func @allocmem_scalar_dynchar(%l : i32) -> !fir.heap<!fir.char<1,?>> {
// CHECK-LABEL: define ptr @allocmem_scalar_dynchar_kind(
// CHECK-SAME: i32 %[[len:.*]])
// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
-// CHECK: %[[mul2:.*]] = mul i64 2, %[[mul1]]
+// CHECK: %[[mul2:.*]] = mul i64 ptrtoint (ptr getelementptr (i16, ptr null, i32 1) to i64), %[[mul1]]
// CHECK: call ptr @malloc(i64 %[[mul2]])
func.func @allocmem_scalar_dynchar_kind(%l : i32) -> !fir.heap<!fir.char<2,?>>{
%1 = fir.allocmem !fir.char<2,?>(%l : i32)
@@ -147,7 +147,7 @@ func.func @allocmem_array_of_char() -> !fir.heap<!fir.array<3x3x!fir.char<1,10>>
// CHECK-LABEL: define ptr @allocmem_array_of_dynchar(
// CHECK-SAME: i32 %[[len:.*]])
// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
-// CHECK: %[[mul2:.*]] = mul i64 9, %[[mul1]]
+// CHECK: %[[mul2:.*]] = mul i64 mul (i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), i64 9), %[[mul1]]
// CHECK: call ptr @malloc(i64 %[[mul2]])
func.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)
@@ -184,7 +184,7 @@ func.func @allocmem_dynarray_of_nonchar(%e: index) -> !fir.heap<!fir.array<3x?xi
// CHECK-LABEL: define ptr @allocmem_dynarray_of_nonchar2(
// CHECK-SAME: i64 %[[extent:.*]])
-// CHECK: %[[prod1:.*]] = mul i64 4, %[[extent]]
+// CHECK: %[[prod1:.*]] = mul i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), %[[extent]]
// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
// CHECK: call ptr @malloc(i64 %[[prod2]])
func.func @allocmem_dynarray_of_nonchar2(%e: index) -> !fir.heap<!fir.array<?x?xi32>> {
@@ -255,7 +255,7 @@ func.func @alloca_dynarray_of_dynchar2(%l: i32, %e : index) -> !fir.ref<!fir.arr
// CHECK-LABEL: define ptr @allocmem_dynarray_of_dynchar(
// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64
-// CHECK: %[[prod2:.*]] = mul i64 6, %[[prod1]]
+// CHECK: %[[prod2:.*]] = mul i64 mul (i64 ptrtoint (ptr getelementptr (i16, ptr null, i32 1) to i64), i64 3), %[[prod1]]
// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
// CHECK: call ptr @malloc(i64 %[[prod3]])
func.func @allocmem_dynarray_of_dynchar(%l: i32, %e : index) -> !fir.heap<!fir.array<3x?x!fir.char<2,?>>> {
@@ -266,7 +266,7 @@ func.func @allocmem_dynarray_of_dynchar(%l: i32, %e : index) -> !fir.heap<!fir.a
// CHECK-LABEL: define ptr @allocmem_dynarray_of_dynchar2(
// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
// CHECK: %[[a:.*]] = sext i32 %[[len]] to i64
-// CHECK: %[[prod1:.*]] = mul i64 2, %[[a]]
+// CHECK: %[[prod1:.*]] = mul i64 ptrtoint (ptr getelementptr (i16, ptr null, i32 1) to i64), %[[a]]
// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
// CHECK: call ptr @malloc(i64 %[[prod3]])
@@ -325,7 +325,7 @@ func.func @allocmem_array_with_holes_char(%e: index) -> !fir.heap<!fir.array<3x?
// CHECK-LABEL: define ptr @allocmem_array_with_holes_dynchar(
// CHECK-SAME: i64 %[[len:.*]], i64 %[[extent:.*]])
-// CHECK: %[[a:.*]] = mul i64 24, %[[len]]
+// CHECK: %[[a:.*]] = mul i64 mul (i64 ptrtoint (ptr getelementptr (i16, ptr null, i32 1) to i64), i64 12), %[[len]]
// CHECK: %[[b:.*]] = mul i64 %[[a]], %[[extent]]
// CHECK: call ptr @malloc(i64 %[[b]])
func.func @allocmem_array_with_holes_dynchar(%arg0: index, %arg1: index) -> !fir.heap<!fir.array<3x?x4x!fir.char<2,?>>> {
diff --git a/flang/test/Fir/arrexp.fir b/flang/test/Fir/arrexp.fir
index 4eb2711c0fd2b..6c769bf25fd38 100644
--- a/flang/test/Fir/arrexp.fir
+++ b/flang/test/Fir/arrexp.fir
@@ -145,7 +145,7 @@ func.func @f6(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: f32) {
// CHECK: %[[EXT_GEP:.*]] = getelementptr {{.*}} %[[A]], i32 0, i32 7, i64 0, i32 1
// CHECK: %[[EXTENT:.*]] = load i64, ptr %[[EXT_GEP]]
- // CHECK: %[[SIZE:.*]] = mul i64 4, %[[EXTENT]]
+ // CHECK: %[[SIZE:.*]] = mul i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), %[[EXTENT]]
// CHECK: %[[MALLOC:.*]] = call ptr @malloc(i64 %[[SIZE]])
%1 = fir.slice %c2, %c10, %c1 : (index, index, index) -> !fir.slice<1>
%2 = fir.array_load %arg0 [%1] : (!fir.box<!fir.array<?xf32>>, !fir.slice<1>) -> !fir.array<?xf32>
diff --git a/flang/test/Fir/box.fir b/flang/test/Fir/box.fir
index d8988102feab3..1a9c9e0496814 100644
--- a/flang/test/Fir/box.fir
+++ b/flang/test/Fir/box.fir
@@ -1,7 +1,7 @@
// RUN: tco -o - %s | FileCheck %s
// Global box initialization (test must come first because llvm globals are emitted first).
-// CHECK-LABEL: @globalx = internal global { ptr, i64, i32, i8, i8, i8, i8 } { ptr null, i64 4, i32 20180515, i8 0, i8 9, i8 2, i8 0 }
+// CHECK-LABEL: @globalx = internal global { ptr, i64, i32, i8, i8, i8, i8 } { ptr null, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20180515, i8 0, i8 9, i8 2, i8 0 }
fir.global internal @globalx : !fir.box<!fir.heap<i32>> {
%c0 = arith.constant 0 : index
%0 = fir.convert %c0 : (index) -> !fir.heap<i32>
@@ -9,7 +9,7 @@ fir.global internal @globalx : !fir.box<!fir.heap<i32>> {
fir.has_value %1 : !fir.box<!fir.heap<i32>>
}
-// CHECK-LABEL: @globaly = internal global { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr null, i64 4, i32 20180515, i8 1, i8 27, i8 2, i8 0,{{.*}}[3 x i64] [i64 1, i64 0, i64 4]
+// CHECK-LABEL: @globaly = internal global { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr null, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 27, i8 2, i8 0,{{.*}}[3 x i64] [i64 1, i64 0, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64)]
fir.global internal @globaly : !fir.box<!fir.heap<!fir.array<?xf32>>> {
%c0 = arith.constant 0 : index
%0 = fir.convert %c0 : (index) -> !fir.heap<!fir.array<?xf32>>
@@ -27,7 +27,7 @@ func.func private @ga(%b : !fir.box<!fir.array<?xf32>>)
// CHECK: (ptr %[[ARG:.*]])
func.func @f(%a : !fir.ref<f32>) {
// CHECK: %[[DESC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8 }
- // CHECK: %[[INS0:.*]] = insertvalue {{.*}} { ptr undef, i64 4, i32 20180515, i8 0, i8 27, i8 0, i8 0 }, ptr %[[ARG]], 0
+ // CHECK: %[[INS0:.*]] = insertvalue {{.*}} { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20180515, i8 0, i8 27, i8 0, i8 0 }, ptr %[[ARG]], 0
// CHECK: store {{.*}} %[[INS0]], {{.*}} %[[DESC]]
%b = fir.embox %a : (!fir.ref<f32>) -> !fir.box<f32>
@@ -44,7 +44,7 @@ func.func @fa(%a : !fir.ref<!fir.array<100xf32>>) {
%c1 = arith.constant 1 : index
%c100 = arith.constant 100 : index
%d = fir.shape %c100 : (index) -> !fir.shape<1>
- // CHECK: %[[INS70:.*]] = insertvalue {{.*}} { ptr undef, i64 4, i32 20180515, i8 1, i8 27, i8 0, i8 0, {{.*}} }, ptr %{{.*}}, 0
+ // CHECK: %[[INS70:.*]] = insertvalue {{.*}} { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 27, i8 0, i8 0, {{.*}} }, ptr %{{.*}}, 0
%b = fir.embox %c(%d) : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
// CHECK: call void @ga(
fir.call @ga(%b) : (!fir.box<!fir.array<?xf32>>) -> ()
@@ -56,7 +56,8 @@ func.func @fa(%a : !fir.ref<!fir.array<100xf32>>) {
// CHECK-LABEL: define void @b1(
// CHECK-SAME: ptr %[[res:.*]], ptr %[[arg0:.*]], i64 %[[arg1:.*]])
func.func @b1(%arg0 : !fir.ref<!fir.char<1,?>>, %arg1 : index) -> !fir.box<!fir.char<1,?>> {
- // CHECK: insertvalue {{.*}} undef, i64 %[[arg1]], 1
+ // CHECK: %[[size:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[arg1]]
+ // CHECK: insertvalue {{.*}} undef, i64 %[[size]], 1
// CHECK: insertvalue {{.*}} i32 20180515, 2
// CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
%x = fir.embox %arg0 typeparams %arg1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
@@ -70,8 +71,8 @@ func.func @b1(%arg0 : !fir.ref<!fir.char<1,?>>, %arg1 : index) -> !fir.box<!fir.
// CHECK-SAME: ptr %[[arg0:.*]], i64 %[[arg1:.*]])
func.func @b2(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,5>>>, %arg1 : index) -> !fir.box<!fir.array<?x!fir.char<1,5>>> {
%1 = fir.shape %arg1 : (index) -> !fir.shape<1>
- // CHECK: insertvalue {{.*}} { ptr undef, i64 5, i32 20180515, i8 1, i8 40, i8 0, i8 0, {{.*}} }, i64 %[[arg1]], 7, 0, 1
- // CHECK: insertvalue {{.*}} %{{.*}}, i64 5, 7, 0, 2
+ // CHECK: insertvalue {{.*}} { ptr undef, i64 ptrtoint (ptr getelementptr ([5 x i8], ptr null, i32 1) to i64), i32 20180515, i8 1, i8 40, i8 0, i8 0, {{.*}} }, i64 %[[arg1]], 7, 0, 1
+ // CHECK: insertvalue {{.*}} %{{.*}}, i64 ptrtoint (ptr getelementptr ([5 x i8], ptr null, i32 1) to i64), 7, 0, 2
// CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
%2 = fir.embox %arg0(%1) : (!fir.ref<!fir.array<?x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
// CHECK: store {{.*}}, ptr %[[res]]
@@ -83,10 +84,11 @@ func.func @b2(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,5>>>, %arg1 : index) ->
// CHECK-SAME: ptr %[[res:.*]], ptr %[[arg0:.*]], i64 %[[arg1:.*]], i64 %[[arg2:.*]])
func.func @b3(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,?>>>, %arg1 : index, %arg2 : index) -> !fir.box<!fir.array<?x!fir.char<1,?>>> {
%1 = fir.shape %arg2 : (index) -> !fir.shape<1>
- // CHECK: insertvalue {{.*}} i64 %[[arg1]], 1
+ // CHECK: %[[size:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[arg1]]
+ // CHECK: insertvalue {{.*}} i64 %[[size]], 1
// CHECK: insertvalue {{.*}} i32 20180515, 2
// CHECK: insertvalue {{.*}} i64 %[[arg2]], 7, 0, 1
- // CHECK: insertvalue {{.*}} i64 %[[arg1]], 7, 0, 2
+ // CHECK: insertvalue {{.*}} i64 %[[size]], 7, 0, 2
// CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
%2 = fir.embox %arg0(%1) typeparams %arg1 : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
// CHECK: store {{.*}}, ptr %[[res]]
@@ -99,10 +101,11 @@ func.func @b3(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,?>>>, %arg1 : index, %ar
func.func @b4(%arg0 : !fir.ref<!fir.array<7x!fir.char<1,?>>>, %arg1 : index) -> !fir.box<!fir.array<7x!fir.char<1,?>>> {
%c_7 = arith.constant 7 : index
%1 = fir.shape %c_7 : (index) -> !fir.shape<1>
- // CHECK: insertvalue {{.*}} i64 %[[arg1]], 1
+ // CHECK: %[[size:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[arg1]]
+ // CHECK: insertvalue {{.*}} i64 %[[size]], 1
// CHECK: insertvalue {{.*}} i32 20180515, 2
// CHECK: insertvalue {{.*}} i64 7, 7, 0, 1
- // CHECK: insertvalue {{.*}} i64 %[[arg1]], 7, 0, 2
+ // CHECK: insertvalue {{.*}} i64 %[[size]], 7, 0, 2
// CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
%x = fir.embox %arg0(%1) typeparams %arg1 : (!fir.ref<!fir.array<7x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<7x!fir.char<1,?>>>
// CHECK: store {{.*}}, ptr %[[res]]
@@ -144,12 +147,12 @@ func.func @box6(%0 : !fir.ref<!fir.array<?x?x?x?xf32>>, %1 : index, %2 : index)
// CHECK: %[[sdp2:.*]] = sdiv i64 %[[dp2]], 2
// CHECK: %[[cmp:.*]] = icmp sgt i64 %[[sdp2]], 0
// CHECK: %[[extent:.*]] = select i1 %[[cmp]], i64 %[[sdp2]], i64 0
- // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } { ptr undef, i64 4, i32 20180515, i8 2, i8 27, i8 0, i8 0, [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 undef, i64 undef], [3 x i64] undef] }, i64 %[[extent]], 7, 0, 1
- // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 800, 7, 0, 2
+ // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20180515, i8 2, i8 27, i8 0, i8 0, [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 undef, i64 undef], [3 x i64] undef] }, i64 %[[extent]], 7, 0, 1
+ // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 mul (i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i64 200), 7, 0, 2
// CHECK: %[[op25:.*]] = add i64 25000, %[[i100p40]]
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 1, 7, 1, 0
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 4, 7, 1, 1
- // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 120000, 7, 1, 2
+ // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 mul (i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i64 30000), 7, 1, 2
// CHECK: %[[op300:.*]] = add i64 300000, %[[op25]]
// CHECK: %[[ptr:.*]] = getelementptr float, ptr %[[ARG0]], i64 %[[op300]]
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, ptr %[[ptr]], 0
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 252d7c669e71e..a7630d7c7353e 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -198,8 +198,10 @@ func.func @test_alloc_and_freemem_one() {
}
// CHECK-LABEL: llvm.func @test_alloc_and_freemem_one() {
-// CHECK-NEXT: [[N:%.*]] = llvm.mlir.constant(4 : i64) : i64
-// CHECK-NEXT: llvm.call @malloc([[N]])
+// CHECK-NEXT: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i32>
+// CHECK-NEXT: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+// CHECK-NEXT: %[[N:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i32> to i64
+// CHECK-NEXT: llvm.call @malloc(%[[N]])
// CHECK: llvm.call @free(%{{.*}})
// CHECK-NEXT: llvm.return
@@ -233,7 +235,9 @@ func.func @test_with_shape(%ncols: index, %nrows: index) {
// CHECK-LABEL: llvm.func @test_with_shape
// CHECK-SAME: %[[NCOLS:.*]]: i64, %[[NROWS:.*]]: i64
-// CHECK: %[[FOUR:.*]] = llvm.mlir.constant(4 : i64) : i64
+// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<f32>
+// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+// CHECK: %[[FOUR:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<f32> to i64
// CHECK: %[[DIM1_SIZE:.*]] = llvm.mul %[[FOUR]], %[[NCOLS]] : i64
// CHECK: %[[TOTAL_SIZE:.*]] = llvm.mul %[[DIM1_SIZE]], %[[NROWS]] : i64
// CHECK: %[[MEM:.*]] = llvm.call @malloc(%[[TOTAL_SIZE]])
@@ -251,7 +255,9 @@ func.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: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i8>
+// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+// CHECK: %[[ONE:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i8> to 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]])
@@ -1502,9 +1508,10 @@ func.func @embox0(%arg0: !fir.ref<!fir.array<100xi32>>) {
// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[C1]] x !llvm.struct<(ptr<array<100 x i32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})> {alignment = 8 : i64} : (i32) -> !llvm.ptr<struct<(ptr<array<100 x i32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>>
// CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<array<100 x i32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>
-// CHECK: %[[ELEM_SIZE:.*]] = llvm.mlir.constant(4 : i32) : i32
+// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i32>
+// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+// CHECK: %[[I64_ELEM_SIZE:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i32> to i64
// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(9 : i32) : i32
-// CHECK: %[[I64_ELEM_SIZE:.*]] = llvm.sext %[[ELEM_SIZE]] : i32 to i64
// CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[I64_ELEM_SIZE]], %[[DESC]][1] : !llvm.struct<(ptr<array<100 x i32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>
// CHECK: %[[CFI_VERSION:.*]] = llvm.mlir.constant(20180515 : i32) : i32
// CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[CFI_VERSION]], %[[DESC0]][2] : !llvm.struct<(ptr<array<100 x i32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>
@@ -1724,9 +1731,10 @@ func.func @xembox0(%arg0: !fir.ref<!fir.array<?xi32>>) {
// CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>
// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
-// CHECK: %[[ELEM_LEN:.*]] = llvm.mlir.constant(4 : i32) : i32
+// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i32>
+// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i32> to i64
// CHECK: %[[TYPE:.*]] = llvm.mlir.constant(9 : i32) : i32
-// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.sext %[[ELEM_LEN]] : i32 to i64
// CHECK: %[[BOX1:.*]] = llvm.insertvalue %[[ELEM_LEN_I64]], %[[BOX0]][1] : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
// CHECK: %[[VERSION:.*]] = llvm.mlir.constant(20180515 : i32) : i32
// CHECK: %[[BOX2:.*]] = llvm.insertvalue %[[VERSION]], %[[BOX1]][2] : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
@@ -1743,7 +1751,6 @@ func.func @xembox0(%arg0: !fir.ref<!fir.array<?xi32>>) {
// CHECK: %[[BOX6:.*]] = llvm.insertvalue %[[F18ADDENDUM_I8]], %[[BOX5]][6] : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.sext %[[ELEM_LEN]] : i32 to i64
// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %[[C0]], %[[C0]] : i64
// CHECK: %[[DIM_OFFSET:.*]] = llvm.mul %[[ADJUSTED_OFFSET]], %[[ONE]] : i64
// CHECK: %[[PTR_OFFSET:.*]] = llvm.add %[[DIM_OFFSET]], %[[ZERO]] : i64
@@ -1773,11 +1780,11 @@ func.func @xembox1(%arg0: !fir.ref<!fir.array<?x!fir.char<1, 10>>>) {
// CHECK-LABEL: llvm.func @xembox1(%{{.*}}: !llvm.ptr<array<10 x i8>>) {
// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[ELEM_LEN:.*]] = llvm.mlir.constant(10 : i32) : i32
-// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.sext %[[ELEM_LEN]] : i32 to i64
+// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<array<10 x i8>>
+// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<array<10 x i8>> to i64
// CHECK: %{{.*}} = llvm.insertvalue %[[ELEM_LEN_I64]], %{{.*}}[1] : !llvm.struct<(ptr<array<10 x i8>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
-// CHECK: %[[PTR_OFFSET:.*]] = llvm.sext %[[ELEM_LEN]] : i32 to i64
-// CHECK: %[[PREV_PTROFF:.*]] = llvm.mul %[[PTR_OFFSET]], %[[C0]] : i64
+// CHECK: %[[PREV_PTROFF:.*]] = llvm.mul %[[ELEM_LEN_I64]], %[[C0]] : i64
// Fortran realistic use case extracted from the following snippet:
//
@@ -1823,9 +1830,10 @@ func.func private @_QPxb(!fir.box<!fir.array<?x?xf64>>)
// CHECK: %[[ARR_SIZE:.*]] = llvm.mul %[[ARR_SIZE_TMP1]], %[[N2]] : i64
// CHECK: %[[ARR:.*]] = llvm.alloca %[[ARR_SIZE]] x f64 {bindc_name = "arr", in_type = !fir.array<?x?xf64>, operand_segment_sizes = array<i32: 0, 2>, uniq_name = "_QFsbEarr"} : (i64) -> !llvm.ptr<f64>
// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<f64>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>
-// CHECK: %[[ELEM_LEN:.*]] = llvm.mlir.constant(8 : i32) : i32
+// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<f64>
+// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<f64> to i64
// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(28 : i32) : i32
-// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.sext %[[ELEM_LEN]] : i32 to i64
// CHECK: %[[BOX1:.*]] = llvm.insertvalue %[[ELEM_LEN_I64]], %[[BOX0]][1] : !llvm.struct<(ptr<f64>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>
// CHECK: %[[VERSION:.*]] = llvm.mlir.constant(20180515 : i32) : i32
// CHECK: %[[BOX2:.*]] = llvm.insertvalue %[[VERSION]], %[[BOX1]][2] : !llvm.struct<(ptr<f64>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>
@@ -1842,7 +1850,6 @@ func.func private @_QPxb(!fir.box<!fir.array<?x?xf64>>)
// CHECK: %[[BOX6:.*]] = llvm.insertvalue %[[F18ADDENDUM_I8]], %[[BOX5]][6] : !llvm.struct<(ptr<f64>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>
// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.sext %[[ELEM_LEN]] : i32 to i64
// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %[[C2]], %[[SH1]] : i64
// CHECK: %[[DIM_OFFSET:.*]] = llvm.mul %[[ADJUSTED_OFFSET]], %[[ONE]] : i64
// CHECK: %[[PTR_OFFSET:.*]] = llvm.add %[[DIM_OFFSET]], %[[ZERO]] : i64
@@ -1902,9 +1909,10 @@ func.func private @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>)
// CHECK: %[[ALLOCA_SIZE_X:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[X:.*]] = llvm.alloca %[[ALLOCA_SIZE_X]] x !llvm.array<20 x struct<"_QFtest_dt_sliceTt", (i32, i32)>> {bindc_name = "x", in_type = !fir.array<20x!fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>>, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFtest_dt_sliceEx"} : (i64) -> !llvm.ptr<array<20 x struct<"_QFtest_dt_sliceTt", (i32, i32)>>>
// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
-// CHECK: %[[ELEM_LEN:.*]] = llvm.mlir.constant(4 : i32) : i32
+// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i32>
+// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i32> to i64
// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(9 : i32) : i32
-// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.sext %[[ELEM_LEN]] : i32 to i64
// CHECK: %[[BOX1:.*]] = llvm.insertvalue %[[ELEM_LEN_I64]], %[[BOX0]][1] : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
// CHECK: %[[VERSION:.*]] = llvm.mlir.constant(20180515 : i32) : i32
// CHECK: %[[BOX2:.*]] = llvm.insertvalue %[[VERSION]], %[[BOX1]][2] : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
@@ -1921,11 +1929,10 @@ func.func private @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>)
// CHECK: %[[BOX6:.*]] = llvm.insertvalue %[[F18ADDENDUM_I8]], %[[BOX5]][6] : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.sext %[[ELEM_LEN]] : i32 to i64
// CHECK: %[[ELE_TYPE:.*]] = llvm.mlir.null : !llvm.ptr<struct<"_QFtest_dt_sliceTt", (i32, i32)>>
// CHECK: %[[GEP_DTYPE_SIZE:.*]] = llvm.getelementptr %[[ELE_TYPE]][1] : (!llvm.ptr<struct<"_QFtest_dt_sliceTt", (i32, i32)>>) -> !llvm.ptr<struct<"_QFtest_dt_sliceTt", (i32, i32)>>
// CHECK: %[[PTRTOINT_DTYPE_SIZE:.*]] = llvm.ptrtoint %[[GEP_DTYPE_SIZE]] : !llvm.ptr<struct<"_QFtest_dt_sliceTt", (i32, i32)>> to i64
-// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %3, %30 : i64
+// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %[[C1]], %[[ONE]] : i64
// CHECK: %[[EXT_SUB:.*]] = llvm.sub %[[C10]], %[[C1]] : i64
// CHECK: %[[EXT_ADD:.*]] = llvm.add %[[EXT_SUB]], %[[C2]] : i64
// CHECK: %[[EXT_SDIV:.*]] = llvm.sdiv %[[EXT_ADD]], %[[C2]] : i64
@@ -2179,9 +2186,10 @@ func.func @test_rebox_1(%arg0: !fir.box<!fir.array<?x?xf32>>) {
//CHECK: %[[SIX:.*]] = llvm.mlir.constant(6 : index) : i64
//CHECK: %[[EIGHTY:.*]] = llvm.mlir.constant(80 : index) : i64
//CHECK: %[[RBOX:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
-//CHECK: %[[ELEM_SIZE:.*]] = llvm.mlir.constant(4 : i32) : i32
+//CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<f32>
+//CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+//CHECK: %[[ELEM_SIZE_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<f32> to i64
//CHECK: %[[FLOAT_TYPE:.*]] = llvm.mlir.constant(27 : i32) : i32
-//CHECK: %[[ELEM_SIZE_I64:.*]] = llvm.sext %[[ELEM_SIZE]] : i32 to i64
//CHECK: %[[RBOX_TMP1:.*]] = llvm.insertvalue %[[ELEM_SIZE_I64]], %[[RBOX]][1] : !llvm.struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
//CHECK: %[[CFI_VERSION:.*]] = llvm.mlir.constant(20180515 : i32) : i32
//CHECK: %[[RBOX_TMP2:.*]] = llvm.insertvalue %[[CFI_VERSION]], %[[RBOX_TMP1]][2] : !llvm.struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
@@ -2251,8 +2259,12 @@ func.func @foo(%arg0: !fir.box<!fir.array<?x!fir.type<t{i:i32,c:!fir.char<1,10>}
//CHECK: %[[RESULT_UB:.*]] = llvm.mlir.constant(60 : i64) : i64
//CHECK: %[[RESULT_STRIDE:.*]] = llvm.mlir.constant(9 : i64) : i64
//CHECK: %[[COMPONENT_OFFSET_1:.*]] = llvm.mlir.constant(1 : i64) : i64
-//CHECK: %[[ELEM_SIZE:.*]] = llvm.mlir.constant(7 : i64) : i64
+//CHECK: %[[ELEM_COUNT:.*]] = llvm.mlir.constant(7 : i64) : i64
//CHECK: %[[TYPE_CHAR:.*]] = llvm.mlir.constant(40 : i32) : i32
+//CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i8>
+//CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
+//CHECK: %[[CHAR_SIZE:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i8> to i64
+//CHECK: %[[ELEM_SIZE:.*]] = llvm.mul %[[CHAR_SIZE]], %[[ELEM_COUNT]]
//CHECK: %[[RBOX_TMP1:.*]] = llvm.insertvalue %[[ELEM_SIZE]], %{{.*}}[1] : !llvm.struct<(ptr<i8>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
//CHECK: %[[RBOX_TMP2:.*]] = llvm.insertvalue %{{.*}}, %[[RBOX_TMP1]][2] : !llvm.struct<(ptr<i8>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
//CHECK: %[[RANK:.*]] = llvm.mlir.constant(1 : i32) : i32
diff --git a/flang/test/Fir/embox.fir b/flang/test/Fir/embox.fir
index 02eba454c47ac..f5e37fbd77d9d 100644
--- a/flang/test/Fir/embox.fir
+++ b/flang/test/Fir/embox.fir
@@ -13,8 +13,8 @@ func.func @_QPtest_slice() {
// CHECK: %[[a2:.*]] = alloca [20 x i32], i64 1, align 4,
// CHECK: %[[a3:.*]] = getelementptr [20 x i32], ptr %[[a2]], i64 0, i64 0,
// CHECK: %[[a4:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
-// CHECK: { ptr undef, i64 4, i32 20180515, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]]
-// CHECK: [i64 1, i64 5, i64 8]] }, ptr %[[a3]], 0,
+// CHECK: { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]]
+// CHECK: [i64 1, i64 5, i64 mul (i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i64 2)]] }, ptr %[[a3]], 0,
// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[a4]], ptr %[[a1]], align 8
// CHECK: call void @_QPtest_callee(ptr %[[a1]]),
%c20 = arith.constant 20 : index
@@ -40,7 +40,7 @@ func.func @_QPtest_dt_slice() {
// CHECK: %[[a3:.*]] = alloca [20 x %_QFtest_dt_sliceTt], i64 1, align 8,
// CHECK: %[[a4:.*]] = getelementptr [20 x %_QFtest_dt_sliceTt], ptr %[[a3]], i64 0, i64 0, i32 0,
// CHECK: %[[a5:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
-// CHECK-SAME: { ptr undef, i64 4, i32 20180515, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]]
+// CHECK-SAME: { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]]
// CHECK-SAME: [i64 1, i64 5, i64 mul
// CHECK-SAME: (i64 ptrtoint (ptr getelementptr (%_QFtest_dt_sliceTt, ptr null, i32 1) to i64), i64 2)]] }
// CHECK-SAME: , ptr %[[a4]], 0
@@ -75,7 +75,7 @@ func.func @emboxSubstring(%arg0: !fir.ref<!fir.array<2x3x!fir.char<1,4>>>) {
%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.array<2x3x!fir.char<1,4>>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: %[[addr:.*]] = getelementptr [3 x [2 x [4 x i8]]], ptr %[[arg0]], 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: insertvalue {[[descriptorType:.*]]} { ptr undef, i64 mul (i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), 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 %[[addr]], 0
@@ -98,7 +98,7 @@ func.func @fir_dev_issue_1416(%arg0: !fir.ref<!fir.array<40x?xf32>>, %low: index
// CHECK: %[[offset:.*]] = add i64 %[[mul]], 0
// CHECK: %[[addr:.*]] = getelementptr [40 x float], ptr %0, i64 %[[offset]], i64 0
// CHECK: %[[box:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
-// CHECK-SAME: { ptr undef, i64 4, i32 20180515, i8 1, i8 27, i8 0, i8 0, [1 x [3 x i64]] [{{.*}} [i64 1, i64 40, i64 4]] }, ptr %[[addr]], 0
+// CHECK-SAME: { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 27, i8 0, i8 0, [1 x [3 x i64]] [{{.*}} [i64 1, i64 40, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64)]] }, ptr %[[addr]], 0
%3 = fir.embox %arg0(%1) [%2] : (!fir.ref<!fir.array<40x?xf32>>, !fir.shapeshift<2>, !fir.slice<2>) -> !fir.box<!fir.array<?xf32>>
fir.call @do_something(%3) : (!fir.box<!fir.array<?xf32>>) -> ()
return
diff --git a/flang/test/Fir/rebox.fir b/flang/test/Fir/rebox.fir
index 5cdf2cd1b4be7..518bfe255cd82 100644
--- a/flang/test/Fir/rebox.fir
+++ b/flang/test/Fir/rebox.fir
@@ -33,7 +33,7 @@ func.func @test_rebox_1(%arg0: !fir.box<!fir.array<?x?xf32>>) {
// CHECK: %[[OFFSET_1:.*]] = mul i64 2, %[[INSTRIDE_1]]
// CHECK: %[[VOIDBASE1:.*]] = getelementptr i8, ptr %[[VOIDBASE0]], i64 %[[OFFSET_1]]
// CHECK: %[[OUTSTRIDE0:.*]] = mul i64 3, %[[INSTRIDE_1]]
- // CHECK: %[[OUTBOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr undef, i64 4, i32 {{.*}}, i8 1, i8 27, i8 0, i8 0, [1 x [3 x i64]] [{{.*}} [i64 1, i64 25, i64 undef]] }, i64 %[[OUTSTRIDE0]], 7, 0, 2
+ // CHECK: %[[OUTBOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 {{.*}}, i8 1, i8 27, i8 0, i8 0, [1 x [3 x i64]] [{{.*}} [i64 1, i64 25, i64 undef]] }, i64 %[[OUTSTRIDE0]], 7, 0, 2
// CHECK: %[[OUTBOX1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[OUTBOX0]], ptr %[[VOIDBASE1]], 0
// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[OUTBOX1]], ptr %[[OUTBOX_ALLOC]], align 8
%2 = fir.rebox %arg0(%1) [%0] : (!fir.box<!fir.array<?x?xf32>>, !fir.shift<2>, !fir.slice<2>) -> !fir.box<!fir.array<?xf32>>
@@ -59,7 +59,8 @@ func.func @test_rebox_2(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
// CHECK: %[[OUTBOX:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }
// CHECK: %[[LEN_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 1
// CHECK: %[[LEN:.*]] = load i64, ptr %[[LEN_GEP]]
- // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } undef, i64 %[[LEN]], 1
+ // CHECK: %[[SIZE:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[LEN]]
+ // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } undef, i64 %[[SIZE]], 1
%1 = fir.rebox %arg0 [%0] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.slice<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
fir.call @bar_rebox_test2(%1) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> ()
@@ -91,7 +92,7 @@ func.func @test_rebox_3(%arg0: !fir.box<!fir.array<?xf32>>) {
// CHECK: %[[INBASE:.*]] = load ptr, ptr %[[INBASE_GEP]]
// CHECK: %[[OUTSTRIDE1:.*]] = mul i64 3, %[[INSTRIDE]]
// CHECK: %[[OUTSTRIDE2:.*]] = mul i64 4, %[[OUTSTRIDE1]]
- // CHECK: %[[OUTBOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } { ptr undef, i64 4, i32 {{.*}}, i8 3, i8 27, i8 0, i8 0, [3 x [3 x i64]] [{{.*}} [i64 2, i64 3, i64 undef], [3 x i64] undef, [3 x i64] undef] }, i64 %[[INSTRIDE]], 7, 0, 2
+ // CHECK: %[[OUTBOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 {{.*}}, i8 3, i8 27, i8 0, i8 0, [3 x [3 x i64]] [{{.*}} [i64 2, i64 3, i64 undef], [3 x i64] undef, [3 x i64] undef] }, i64 %[[INSTRIDE]], 7, 0, 2
// CHECK: %[[OUTBOX1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX0]], i64 3, 7, 1, 0
// CHECK: %[[OUTBOX2:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX1]], i64 4, 7, 1, 1
// CHECK: %[[OUTBOX3:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX2]], i64 %[[OUTSTRIDE1]], 7, 1, 2
@@ -120,7 +121,7 @@ func.func @test_rebox_4(%arg0: !fir.box<!fir.array<?x!fir.char<1,?>>>) {
// CHECK: %[[STRIDE:.*]] = load i64, ptr %[[STRIDE_GEP]]
// CHECK: %[[BASE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INPUT]], i32 0, i32 0
// CHECK: %[[BASE:.*]] = load ptr, ptr %[[BASE_GEP]]
- // CHECK: %[[NEWBOX1:.*]] = insertvalue {{{.*}}} { ptr undef, i64 10, i32 20180515, i8 1, i8 40, i8 1, i8 0, [1 x [3 x i64]] [{{.*}} [i64 1, i64 undef, i64 undef]] }, i64 %[[EXTENT]], 7, 0, 1
+ // CHECK: %[[NEWBOX1:.*]] = insertvalue {{{.*}}} { ptr undef, i64 ptrtoint (ptr getelementptr ([10 x i8], ptr null, i32 1) to i64), i32 20180515, i8 1, i8 40, i8 1, i8 0, [1 x [3 x i64]] [{{.*}} [i64 1, i64 undef, i64 undef]] }, i64 %[[EXTENT]], 7, 0, 1
// CHECK: %[[NEWBOX2:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[NEWBOX1]], i64 %[[STRIDE]], 7, 0, 2
// CHECK: %[[NEWBOX3:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[NEWBOX2]], ptr %[[BASE]], 0
// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[NEWBOX3]], ptr %[[NEWBOX_STORAGE]]
diff --git a/flang/test/Lower/forall/character-1.f90 b/flang/test/Lower/forall/character-1.f90
index 01f1257bb9b86..8ccc09d90be64 100644
--- a/flang/test/Lower/forall/character-1.f90
+++ b/flang/test/Lower/forall/character-1.f90
@@ -23,7 +23,7 @@ end program test
! CHECK: %[[extval:.*]] = load i64, ptr %[[extent]]
! CHECK: %[[elesize:.*]] = getelementptr { {{.*}}, [1 x [3 x i64]] }, ptr %[[arg]], i32 0, i32 1
! CHECK: %[[esval:.*]] = load i64, ptr %[[elesize]]
-! CHECK: %[[mul:.*]] = mul i64 1, %[[esval]]
+! CHECK: %[[mul:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[esval]]
! CHECK: %[[mul2:.*]] = mul i64 %[[mul]], %[[extval]]
! CHECK: %[[buff:.*]] = call ptr @malloc(i64 %[[mul2]])
! CHECK: %[[to:.*]] = getelementptr i8, ptr %[[buff]], i64 %
More information about the flang-commits
mailing list