return false;
}
-static mlir::Type unwrapElementType(mlir::Type type) {
- if (mlir::Type ty = fir::dyn_cast_ptrOrBoxEleTy(type))
- type = ty;
- if (auto seqType = type.dyn_cast<fir::SequenceType>())
- type = seqType.getEleTy();
- return type;
-}
-
fir::ExtendedValue Fortran::lower::genExtAddrInInitializer(
Fortran::lower::AbstractConverter &converter, mlir::Location loc,
const Fortran::lower::SomeExpr &addr) {
}
}
- mlir::Value box;
+ mlir::Value targetBox;
+ mlir::Value targetShift;
if (initialTarget.Rank() > 0) {
- box = fir::getBase(Fortran::lower::createSomeArrayBox(
- converter, initialTarget, globalOpSymMap, stmtCtx));
+ auto target = Fortran::lower::createSomeArrayBox(converter, initialTarget,
+ globalOpSymMap, stmtCtx);
+ targetBox = fir::getBase(target);
+ targetShift = builder.createShape(loc, target);
} else {
fir::ExtendedValue addr = Fortran::lower::createInitializerAddress(
loc, converter, initialTarget, globalOpSymMap, stmtCtx);
- box = builder.createBox(loc, addr);
+ targetBox = builder.createBox(loc, addr);
+ // Nothing to do for targetShift, the target is a scalar.
}
- // box is a fir.box<T>, not a fir.box<fir.ptr<T>> as it should to be used
- // for pointers. A fir.convert should not be used here, because it would
- // not actually set the pointer attribute in the descriptor.
- // In a normal context, fir.rebox would be used to set the pointer attribute
- // while copying the projection from another fir.box. But fir.rebox cannot be
- // used in initializer because its current codegen expects that the input
- // fir.box is in memory, which is not the case in initializers.
- // So, just replace the fir.embox that created addr with one with
- // fir.box<fir.ptr<T>> result type.
- // Note that the descriptor cannot have been created with fir.rebox because
- // the initial-data-target cannot be a fir.box itself (it cannot be
- // assumed-shape, deferred-shape, or polymorphic as per C765). However the
- // case where the initial data target is a derived type with length parameters
- // will most likely be a bit trickier, hence the TODO above.
-
- mlir::Operation *op = box.getDefiningOp();
- if (!op || !mlir::isa<fir::EmboxOp>(*op))
- fir::emitFatalError(
- loc, "fir.box must be created with embox in global initializers");
- mlir::Type targetEleTy = unwrapElementType(box.getType());
- if (!fir::isa_char(targetEleTy))
- return builder.create<fir::EmboxOp>(loc, boxType, op->getOperands(),
- op->getAttrs());
-
- // Handle the character case length particularities: embox takes a length
- // value argument when the result type has unknown length, but not when the
- // result type has constant length. The type of the initial target must be
- // constant length, but the one of the pointer may not be. In this case, a
- // length operand must be added.
- auto targetLen = targetEleTy.cast<fir::CharacterType>().getLen();
- auto ptrLen = unwrapElementType(boxType).cast<fir::CharacterType>().getLen();
- if (ptrLen == targetLen)
- // Nothing to do
- return builder.create<fir::EmboxOp>(loc, boxType, op->getOperands(),
- op->getAttrs());
- auto embox = mlir::cast<fir::EmboxOp>(*op);
- auto ptrType = boxType.cast<fir::BoxType>().getEleTy();
- mlir::Value memref = builder.createConvert(loc, ptrType, embox.getMemref());
- if (targetLen == fir::CharacterType::unknownLen())
- // Drop the length argument.
- return builder.create<fir::EmboxOp>(loc, boxType, memref, embox.getShape(),
- embox.getSlice());
- // targetLen is constant and ptrLen is unknown. Add a length argument.
- mlir::Value targetLenValue =
- builder.createIntegerConstant(loc, builder.getIndexType(), targetLen);
- return builder.create<fir::EmboxOp>(loc, boxType, memref, embox.getShape(),
- embox.getSlice(),
- mlir::ValueRange{targetLenValue});
+ // The targetBox is a fir.box<T>, not a fir.box<fir.ptr<T>> as it should for
+ // pointers (this matters to get the POINTER attribute correctly inside the
+ // initial value of the descriptor).
+ // Create a fir.rebox to set the attribute correctly, and use targetShift
+ // to preserve the target lower bounds if any.
+ return builder.create<fir::ReboxOp>(loc, boxType, targetBox, targetShift,
+ /*slice=*/mlir::Value{});
}
static mlir::Value genDefaultInitializerValue(
mlir::Value getValueFromBox(mlir::Location loc, mlir::Value box,
mlir::Type resultTy,
mlir::ConversionPatternRewriter &rewriter,
- unsigned boxValue) const {
- auto pty = mlir::LLVM::LLVMPointerType::get(resultTy);
- auto p = rewriter.create<mlir::LLVM::GEPOp>(
- loc, pty, box,
- llvm::ArrayRef<mlir::LLVM::GEPArg>{
- 0, static_cast<std::int32_t>(boxValue)});
- return rewriter.create<mlir::LLVM::LoadOp>(loc, resultTy, p);
+ int boxValue) const {
+ if (box.getType().isa<mlir::LLVM::LLVMPointerType>()) {
+ auto pty = mlir::LLVM::LLVMPointerType::get(resultTy);
+ auto p = rewriter.create<mlir::LLVM::GEPOp>(
+ loc, pty, box, llvm::ArrayRef<mlir::LLVM::GEPArg>{0, boxValue});
+ return rewriter.create<mlir::LLVM::LoadOp>(loc, resultTy, p);
+ }
+ return rewriter.create<mlir::LLVM::ExtractValueOp>(loc, box, boxValue);
}
/// Method to construct code sequence to get the triple for dimension `dim`
getDimsFromBox(mlir::Location loc, llvm::ArrayRef<mlir::Type> retTys,
mlir::Value box, mlir::Value dim,
mlir::ConversionPatternRewriter &rewriter) const {
- mlir::LLVM::LoadOp l0 =
- loadFromOffset(loc, box, 0, kDimsPosInBox, dim, 0, retTys[0], rewriter);
- mlir::LLVM::LoadOp l1 =
- loadFromOffset(loc, box, 0, kDimsPosInBox, dim, 1, retTys[1], rewriter);
- mlir::LLVM::LoadOp l2 =
- loadFromOffset(loc, box, 0, kDimsPosInBox, dim, 2, retTys[2], rewriter);
- return {l0.getResult(), l1.getResult(), l2.getResult()};
- }
-
- mlir::LLVM::LoadOp
- loadFromOffset(mlir::Location loc, mlir::Value a, int32_t c0, int32_t cDims,
- mlir::Value dim, int off, mlir::Type ty,
+ mlir::Value l0 = loadDimFieldFromBox(loc, box, dim, 0, retTys[0], rewriter);
+ mlir::Value l1 = loadDimFieldFromBox(loc, box, dim, 1, retTys[1], rewriter);
+ mlir::Value l2 = loadDimFieldFromBox(loc, box, dim, 2, retTys[2], rewriter);
+ return {l0, l1, l2};
+ }
+
+ llvm::SmallVector<mlir::Value, 3>
+ getDimsFromBox(mlir::Location loc, llvm::ArrayRef<mlir::Type> retTys,
+ mlir::Value box, int dim,
mlir::ConversionPatternRewriter &rewriter) const {
+ mlir::Value l0 = getDimFieldFromBox(loc, box, dim, 0, retTys[0], rewriter);
+ mlir::Value l1 = getDimFieldFromBox(loc, box, dim, 1, retTys[1], rewriter);
+ mlir::Value l2 = getDimFieldFromBox(loc, box, dim, 2, retTys[2], rewriter);
+ return {l0, l1, l2};
+ }
+
+ mlir::Value
+ loadDimFieldFromBox(mlir::Location loc, mlir::Value box, mlir::Value dim,
+ int off, mlir::Type ty,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ assert(box.getType().isa<mlir::LLVM::LLVMPointerType>() &&
+ "descriptor inquiry with runtime dim can only be done on descriptor "
+ "in memory");
auto pty = mlir::LLVM::LLVMPointerType::get(ty);
- mlir::LLVM::GEPOp p = genGEP(loc, pty, rewriter, a, c0, cDims, dim, off);
+ mlir::LLVM::GEPOp p = genGEP(loc, pty, rewriter, box, 0,
+ static_cast<int>(kDimsPosInBox), dim, off);
return rewriter.create<mlir::LLVM::LoadOp>(loc, ty, p);
}
mlir::Value
- loadStrideFromBox(mlir::Location loc, mlir::Value box, unsigned dim,
- mlir::ConversionPatternRewriter &rewriter) const {
+ getDimFieldFromBox(mlir::Location loc, mlir::Value box, int dim, int off,
+ mlir::Type ty,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ if (box.getType().isa<mlir::LLVM::LLVMPointerType>()) {
+ auto pty = mlir::LLVM::LLVMPointerType::get(ty);
+ mlir::LLVM::GEPOp p = genGEP(loc, pty, rewriter, box, 0,
+ static_cast<int>(kDimsPosInBox), dim, off);
+ return rewriter.create<mlir::LLVM::LoadOp>(loc, ty, p);
+ }
+ return rewriter.create<mlir::LLVM::ExtractValueOp>(
+ loc, box, llvm::ArrayRef<std::int64_t>{kDimsPosInBox, dim, off});
+ }
+
+ mlir::Value
+ getStrideFromBox(mlir::Location loc, mlir::Value box, unsigned dim,
+ mlir::ConversionPatternRewriter &rewriter) const {
auto idxTy = lowerTy().indexType();
- auto dimValue = genConstantIndex(loc, idxTy, rewriter, dim);
- return loadFromOffset(loc, box, 0, kDimsPosInBox, dimValue, kDimStridePos,
- idxTy, rewriter);
+ return getDimFieldFromBox(loc, box, dim, kDimStridePos, idxTy, rewriter);
}
/// Read base address from a fir.box. Returned address has type ty.
mlir::Value
- loadBaseAddrFromBox(mlir::Location loc, mlir::Type ty, mlir::Value box,
- mlir::ConversionPatternRewriter &rewriter) const {
- auto pty = mlir::LLVM::LLVMPointerType::get(ty);
- mlir::LLVM::GEPOp p = genGEP(loc, pty, rewriter, box, 0,
- static_cast<std::int32_t>(kAddrPosInBox));
- return rewriter.create<mlir::LLVM::LoadOp>(loc, ty, p);
+ getBaseAddrFromBox(mlir::Location loc, mlir::Type ty, mlir::Value box,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ return getValueFromBox(loc, box, ty, rewriter, kAddrPosInBox);
}
mlir::Value
- loadElementSizeFromBox(mlir::Location loc, mlir::Type ty, mlir::Value box,
- mlir::ConversionPatternRewriter &rewriter) const {
- auto pty = mlir::LLVM::LLVMPointerType::get(ty);
- mlir::LLVM::GEPOp p = genGEP(loc, pty, rewriter, box, 0,
- static_cast<std::int32_t>(kElemLenPosInBox));
- return rewriter.create<mlir::LLVM::LoadOp>(loc, ty, p);
+ getElementSizeFromBox(mlir::Location loc, mlir::Type ty, mlir::Value box,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ return getValueFromBox(loc, box, ty, rewriter, kElemLenPosInBox);
}
// Get the element type given an LLVM type that is of the form
mlir::ConversionPatternRewriter &rewriter) const {
unsigned typeDescFieldId = getTypeDescFieldId(ty);
mlir::Type tdescType = lowerTy().convertTypeDescType(rewriter.getContext());
- auto pty = mlir::LLVM::LLVMPointerType::get(tdescType);
- mlir::LLVM::GEPOp p = genGEP(loc, pty, rewriter, box, 0,
- static_cast<std::int32_t>(typeDescFieldId));
- return rewriter.create<mlir::LLVM::LoadOp>(loc, tdescType, p);
+ return getValueFromBox(loc, box, tdescType, rewriter, typeDescFieldId);
}
// Load the attribute from the \p box and perform a check against \p maskValue
auto loc = boxaddr.getLoc();
mlir::Type ty = convertType(boxaddr.getType());
if (auto argty = boxaddr.getVal().getType().dyn_cast<fir::BaseBoxType>()) {
- rewriter.replaceOp(boxaddr, loadBaseAddrFromBox(loc, ty, a, rewriter));
+ rewriter.replaceOp(boxaddr, getBaseAddrFromBox(loc, ty, a, rewriter));
} else {
rewriter.replaceOpWithNewOp<mlir::LLVM::ExtractValueOp>(boxaddr, a, 0);
}
if (auto *gepOp = loadOp.getAddr().getDefiningOp()) {
if (auto gep = mlir::dyn_cast<mlir::LLVM::GEPOp>(gepOp)) {
mlir::Type idxTy = this->lowerTy().indexType();
- eleSize = this->loadElementSizeFromBox(loc, idxTy, gep.getBase(),
- rewriter);
+ eleSize = this->getElementSizeFromBox(loc, idxTy, gep.getBase(),
+ rewriter);
cfiTy = this->getValueFromBox(loc, gep.getBase(), cfiTy.getType(),
rewriter, kTypePosInBox);
}
if (fir::isPolymorphicType(boxTy) &&
fir::isPolymorphicType(box.getBox().getType())) {
mlir::Type idxTy = this->lowerTy().indexType();
- eleSize = this->loadElementSizeFromBox(loc, idxTy, loweredBox, rewriter);
+ eleSize = this->getElementSizeFromBox(loc, idxTy, loweredBox, rewriter);
cfiTy = this->getValueFromBox(loc, loweredBox, cfiTy.getType(), rewriter,
kTypePosInBox);
typeDesc = this->loadTypeDescAddress(loc, box.getBox().getType(),
xbox.getSubcomponent().size());
}
+ static bool isInGlobalOp(mlir::ConversionPatternRewriter &rewriter) {
+ auto *thisBlock = rewriter.getInsertionBlock();
+ return thisBlock &&
+ mlir::isa<mlir::LLVM::GlobalOp>(thisBlock->getParentOp());
+ }
+
/// If the embox is not in a globalOp body, allocate storage for the box;
/// store the value inside and return the generated alloca. Return the input
/// value otherwise.
mlir::Value
placeInMemoryIfNotGlobalInit(mlir::ConversionPatternRewriter &rewriter,
mlir::Location loc, mlir::Value boxValue) const {
- auto *thisBlock = rewriter.getInsertionBlock();
- if (thisBlock && mlir::isa<mlir::LLVM::GlobalOp>(thisBlock->getParentOp()))
+ if (isInGlobalOp(rewriter))
return boxValue;
auto boxPtrTy = mlir::LLVM::LLVMPointerType::get(boxValue.getType());
auto alloca =
mlir::Value loweredBox = adaptor.getOperands()[0];
mlir::ValueRange operands = adaptor.getOperands();
+ // Inside a fir.global, the input box was produced as an llvm.struct<>
+ // because objects cannot be handled in memory inside a fir.global body that
+ // must be constant foldable. However, the type translation are not
+ // contextual, so the fir.box<T> type of the operation that produced the
+ // fir.box was translated to an llvm.ptr<llvm.struct<>> and the MLIR pass
+ // manager inserted a builtin.unrealized_conversion_cast that was inserted
+ // and needs to be removed here.
+ if (isInGlobalOp(rewriter))
+ if (auto unrealizedCast =
+ loweredBox.getDefiningOp<mlir::UnrealizedConversionCastOp>())
+ loweredBox = unrealizedCast.getInputs()[0];
+
// Create new descriptor and fill its non-shape related data.
llvm::SmallVector<mlir::Value, 2> lenParams;
mlir::Type inputEleTy = getInputEleTy(rebox);
if (auto charTy = inputEleTy.dyn_cast<fir::CharacterType>()) {
- mlir::Value len =
- loadElementSizeFromBox(loc, idxTy, loweredBox, rewriter);
+ mlir::Value len = getElementSizeFromBox(loc, idxTy, loweredBox, rewriter);
if (charTy.getFKind() != 1) {
mlir::Value width =
genConstantIndex(loc, idxTy, rewriter, charTy.getFKind());
llvm::SmallVector<mlir::Value> inputExtents;
llvm::SmallVector<mlir::Value> inputStrides;
const unsigned inputRank = rebox.getRank();
- for (unsigned i = 0; i < inputRank; ++i) {
- mlir::Value dim = genConstantIndex(loc, idxTy, rewriter, i);
+ for (unsigned dim = 0; dim < inputRank; ++dim) {
llvm::SmallVector<mlir::Value, 3> dimInfo =
getDimsFromBox(loc, {idxTy, idxTy, idxTy}, loweredBox, dim, rewriter);
inputExtents.emplace_back(dimInfo[1]);
mlir::Type baseTy = getBaseAddrTypeFromBox(loweredBox.getType());
mlir::Value baseAddr =
- loadBaseAddrFromBox(loc, baseTy, loweredBox, rewriter);
+ getBaseAddrFromBox(loc, baseTy, loweredBox, rewriter);
if (!rebox.getSlice().empty() || !rebox.getSubcomponent().empty())
return sliceBox(rebox, dest, baseAddr, inputExtents, inputStrides,
// that was just computed.
if (baseIsBoxed) {
// Use stride in bytes from the descriptor.
- mlir::Value stride = loadStrideFromBox(loc, operands[0], i, rewriter);
+ mlir::Value stride = getStrideFromBox(loc, operands[0], i, rewriter);
auto sc = rewriter.create<mlir::LLVM::MulOp>(loc, idxTy, diff, stride);
offset = rewriter.create<mlir::LLVM::AddOp>(loc, idxTy, sc, offset);
} else {
// Working with byte offsets. The base address is read from the fir.box.
// and need to be casted to i8* to do the pointer arithmetic.
mlir::Type baseTy = getBaseAddrTypeFromBox(operands[0].getType());
- mlir::Value base =
- loadBaseAddrFromBox(loc, baseTy, operands[0], rewriter);
+ mlir::Value base = getBaseAddrFromBox(loc, baseTy, operands[0], rewriter);
mlir::Type voidPtrTy = getVoidPtrType();
base = rewriter.create<mlir::LLVM::BitcastOp>(loc, voidPtrTy, base);
llvm::SmallVector<mlir::LLVM::GEPArg> args{offset};
// 2.4. TODO: Either document or disable any other case that the following
// implementation might convert.
mlir::Value resultAddr =
- loadBaseAddrFromBox(loc, getBaseAddrTypeFromBox(boxBaseAddr.getType()),
- boxBaseAddr, rewriter);
+ getBaseAddrFromBox(loc, getBaseAddrTypeFromBox(boxBaseAddr.getType()),
+ boxBaseAddr, rewriter);
// Component Type
auto cpnTy = fir::dyn_cast_ptrOrBoxEleTy(boxObjTy);
mlir::Type voidPtrTy = ::getVoidPtrType(coor.getContext());
for (unsigned index = i, lastIndex = i + arrTy.getDimension();
index < lastIndex; ++index) {
mlir::Value stride =
- loadStrideFromBox(loc, operands[0], index - i, rewriter);
+ getStrideFromBox(loc, operands[0], index - i, rewriter);
auto sc = rewriter.create<mlir::LLVM::MulOp>(loc, idxTy,
operands[index], stride);
off = rewriter.create<mlir::LLVM::AddOp>(loc, idxTy, sc, off);
return inputs[0];
});
// Similar FIXME workaround here (needed for compare.fir/select-type.fir
- // tests).
+ // as well as rebox-global.fir tests). This is needed to cope with the
+ // the fact that codegen does not lower some operation results to the LLVM
+ // type produced by this LLVMTypeConverter. For instance, inside FIR
+ // globals, fir.box are lowered to llvm.struct, while the fir.box type
+ // conversion translates it into an llvm.ptr<llvm.struct<>> because
+ // descriptors are manipulated in memory outside of global initializers
+ // where this is not possible. Hence, MLIR inserts
+ // builtin.unrealized_conversion_cast after the translation of operations
+ // producing fir.box in fir.global codegen. addSourceMaterialization and
+ // addTargetMaterialization allow ignoring these ops and removing them
+ // after codegen assuming the type discrepencies are intended (like for
+ // fir.box inside globals).
addTargetMaterialization(
[&](mlir::OpBuilder &builder, mlir::Type resultType,
mlir::ValueRange inputs,
// CHECK-LABEL: define double @array_coor_box_value
// CHECK: %[[t3:.*]] = sub i64 %{{.*}}, 1
// CHECK: %[[t4:.*]] = mul i64 %[[t3]], 1
-// CHECK: %[[t5:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %{{.*}}, i32 0, i32 7, i64 0, i32 2
+// CHECK: %[[t5:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %{{.*}}, i32 0, i32 7, i32 0, i32 2
// CHECK: %[[t6:.*]] = load i64, ptr %[[t5]]
// CHECK: %[[t7:.*]] = mul i64 %[[t4]], %[[t6]]
// CHECK: %[[t8:.*]] = add i64 %[[t7]], 0
%3 = fir.array_load %arg1 : (!fir.box<!fir.array<?xf32>>) -> !fir.array<?xf32>
// CHECK: icmp sgt
%4 = fir.do_loop %arg3 = %c0 to %1 step %c1 iter_args(%arg4 = %2) -> (!fir.array<?xf32>) {
- // CHECK: %[[B_STRIDE_GEP:.*]] = getelementptr {{.*}}, ptr %[[B]], i32 0, i32 7, i64 0, i32 2
+ // CHECK: %[[B_STRIDE_GEP:.*]] = getelementptr {{.*}}, ptr %[[B]], i32 0, i32 7, i32 0, i32 2
// CHECK: %[[B_STRIDE:.*]] = load i64, ptr %[[B_STRIDE_GEP]]
// CHECK: %[[B_DIM_OFFSET:.*]] = mul i64 %{{.*}}, %[[B_STRIDE]]
// CHECK: %[[B_OFFSET:.*]] = add i64 %[[B_DIM_OFFSET]], 0
%c4 = arith.constant 4 : index
%c100 = arith.constant 100 : index
%0 = fir.shift %c4 : (index) -> !fir.shift<1>
- // CHECK: %[[STRIDE_GEP:.*]] = getelementptr {{.*}}, ptr %[[Y]], i32 0, i32 7, i64 0, i32 2
+ // CHECK: %[[STRIDE_GEP:.*]] = getelementptr {{.*}}, ptr %[[Y]], i32 0, i32 7, i32 0, i32 2
// CHECK: %[[STRIDE:.*]] = load i64, ptr %[[STRIDE_GEP]]
// CHECK: mul i64 96, %[[STRIDE]]
%1 = fir.array_coor %arg1(%0) %c100 : (!fir.box<!fir.array<?xf32>>, !fir.shift<1>, index) -> !fir.ref<f32>
// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] : i64
// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] : i64
-// CHECK: %[[DIMOFFSET:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[GEPSTRIDE:.*]] = llvm.getelementptr %[[ARG0]][0, 7, %[[DIMOFFSET]], 2] : (!llvm.ptr<struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>, i64) -> !llvm.ptr<i64>
+// CHECK: %[[GEPSTRIDE:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr<struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>) -> !llvm.ptr<i64>
// CHECK: %[[LOADEDSTRIDE:.*]] = llvm.load %[[GEPSTRIDE]] : !llvm.ptr<i64>
// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[LOADEDSTRIDE]] : i64
// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] : i64
//CHECK: %[[ADDENDUM:.*]] = llvm.mlir.constant(0 : i32) : i32
//CHECK: %[[ADDENDUM_I8:.*]] = llvm.trunc %[[ADDENDUM]] : i32 to i8
//CHECK: %[[RBOX_TMP6:.*]] = llvm.insertvalue %[[ADDENDUM_I8]], %[[RBOX_TMP5]][6] : !llvm.struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
-//CHECK: %[[DIM1:.*]] = llvm.mlir.constant(0 : i64) : i64
-//CHECK: %[[DIM1_STRIDE_REF:.*]] = llvm.getelementptr %[[ARG0]][0, 7, %[[DIM1]], 2] : (!llvm.ptr<struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>, i64) -> !llvm.ptr<i64>
+//CHECK: %[[DIM1_STRIDE_REF:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr<struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>) -> !llvm.ptr<i64>
//CHECK: %[[DIM1_STRIDE:.*]] = llvm.load %[[DIM1_STRIDE_REF]] : !llvm.ptr<i64>
-//CHECK: %[[DIM2:.*]] = llvm.mlir.constant(1 : i64) : i64
-//CHECK: %[[DIM2_STRIDE_REF:.*]] = llvm.getelementptr %[[ARG0]][0, 7, %[[DIM2]], 2] : (!llvm.ptr<struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>, i64) -> !llvm.ptr<i64>
+//CHECK: %[[DIM2_STRIDE_REF:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 1, 2] : (!llvm.ptr<struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>) -> !llvm.ptr<i64>
//CHECK: %[[DIM2_STRIDE:.*]] = llvm.load %[[DIM2_STRIDE_REF]] : !llvm.ptr<i64>
//CHECK: %[[SOURCE_ARRAY_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr<struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>) -> !llvm.ptr<ptr<f32>>
//CHECK: %[[SOURCE_ARRAY:.*]] = llvm.load %[[SOURCE_ARRAY_PTR]] : !llvm.ptr<ptr<f32>>
//CHECK: %[[ADDENDUM:.*]] = llvm.mlir.constant(0 : i32) : i32
//CHECK: %[[ADDENDUM_I8:.*]] = llvm.trunc %[[ADDENDUM]] : i32 to i8
//CHECK: %[[RBOX_TMP6:.*]] = llvm.insertvalue %[[ADDENDUM_I8]], %[[RBOX_TMP5]][6] : !llvm.struct<(ptr<i8>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
-//CHECK: %[[DIM1:.*]] = llvm.mlir.constant(0 : i64) : i64
-//CHECK: %[[SRC_STRIDE_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 7, %[[DIM1]], 2] : (!llvm.ptr<struct<(ptr<struct<"t", (i32, array<10 x i8>)>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)>>, i64) -> !llvm.ptr<i64>
+//CHECK: %[[SRC_STRIDE_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr<struct<(ptr<struct<"t", (i32, array<10 x i8>)>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)>>) -> !llvm.ptr<i64>
//CHECK: %[[SRC_STRIDE:.*]] = llvm.load %[[SRC_STRIDE_PTR]] : !llvm.ptr<i64>
//CHECK: %[[SRC_ARRAY_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr<struct<(ptr<struct<"t", (i32, array<10 x i8>)>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)>>) -> !llvm.ptr<ptr<struct<"t", (i32, array<10 x i8>)>>>
//CHECK: %[[SRC_ARRAY:.*]] = llvm.load %[[SRC_ARRAY_PTR]] : !llvm.ptr<ptr<struct<"t", (i32, array<10 x i8>)>>>
// CHECK-NEXT: %[[ARRAY_OBJECT:.*]] = llvm.load %[[ARRAY_ADDR]] : !llvm.ptr<ptr<array<10 x f32>>>
// CHECK-NEXT: %[[OFFSET_INIT:.*]] = llvm.mlir.constant(0 : i64) : i64
// Index of the 1st CFI_dim_t object (corresonds the the 1st dimension)
-// CHECK-NEXT: %[[DIM_1_IDX:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, %[[DIM_1_IDX]], 2] : (!llvm.ptr<struct<(ptr<array<10 x f32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>, i64) -> !llvm.ptr<i64>
+// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr<struct<(ptr<array<10 x f32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>) -> !llvm.ptr<i64>
// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_1_MEM_STRIDE_ADDR]] : !llvm.ptr<i64>
// CHECK-NEXT: %[[BYTE_OFFSET:.*]] = llvm.mul %[[COORDINATE]], %[[DIM_1_MEM_STRIDE_VAL]] : i64
// CHECK-NEXT: %[[SUBOJECT_OFFSET:.*]] = llvm.add %[[BYTE_OFFSET]], %[[OFFSET_INIT]] : i64
// CHECK-NEXT: %[[ARRAY_OBJECT:.*]] = llvm.load %[[ARRAY_ADDR]] : !llvm.ptr<ptr<f32>>
// CHECK-NEXT: %[[OFFSET_INIT:.*]] = llvm.mlir.constant(0 : i64) : i64
// Index of the 1st CFI_dim_t object (corresonds the the 1st dimension)
-// CHECK-NEXT: %[[DIM_1_IDX:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, %[[DIM_1_IDX]], 2] : (!llvm.ptr<struct<(ptr<f32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>, i64) -> !llvm.ptr<i64>
+// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr<struct<(ptr<f32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>) -> !llvm.ptr<i64>
// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_1_MEM_STRIDE_ADDR]] : !llvm.ptr<i64>
// CHECK-NEXT: %[[BYTE_OFFSET:.*]] = llvm.mul %[[COORDINATE]], %[[DIM_1_MEM_STRIDE_VAL]] : i64
// CHECK-NEXT: %[[SUBOJECT_OFFSET:.*]] = llvm.add %[[BYTE_OFFSET]], %[[OFFSET_INIT]] : i64
// CHECK-NEXT: %[[ARRAY_OBJECT:.*]] = llvm.load %[[ARRAY_ADDR]] : !llvm.ptr<ptr<array<10 x array<10 x f32>>>>
// CHECK-NEXT: %[[OFFSET_INIT:.*]] = llvm.mlir.constant(0 : i64) : i64
// Index of the 1st CFI_dim_t object (corresonds the the 1st dimension)
-// CHECK-NEXT: %[[DIM_1_IDX:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, %[[DIM_1_IDX]], 2] : (!llvm.ptr<struct<(ptr<array<10 x array<10 x f32>>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>>, i64) -> !llvm.ptr<i64>
+// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr<struct<(ptr<array<10 x array<10 x f32>>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>>) -> !llvm.ptr<i64>
// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_1_MEM_STRIDE_ADDR]] : !llvm.ptr<i64>
// CHECK-NEXT: %[[BYTE_OFFSET_1:.*]] = llvm.mul %[[COORDINATE_1]], %[[DIM_1_MEM_STRIDE_VAL]] : i64
// CHECK-NEXT: %[[SUBOBJECT_OFFSET_1:.*]] = llvm.add %[[BYTE_OFFSET]], %[[OFFSET_INIT]] : i64
// Index of the 1st CFI_dim_t object (corresonds the the 2nd dimension)
-// CHECK-NEXT: %[[DIM_2_IDX:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK-NEXT: %[[DIM_2_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, %[[DIM_2_IDX]], 2] : (!llvm.ptr<struct<(ptr<array<10 x array<10 x f32>>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>>, i64) -> !llvm.ptr<i64>
+// CHECK-NEXT: %[[DIM_2_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 1, 2] : (!llvm.ptr<struct<(ptr<array<10 x array<10 x f32>>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>>) -> !llvm.ptr<i64>
// CHECK-NEXT: %[[DIM_2_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_2_MEM_STRIDE_ADDR]] : !llvm.ptr<i64>
// CHECK-NEXT: %[[BYTE_OFFSET_2:.*]] = llvm.mul %[[COORDINATE_2]], %[[DIM_2_MEM_STRIDE_VAL]] : i64
// CHECK-NEXT: %[[SUBOBJECT_OFFSET_2:.*]] = llvm.add %[[BYTE_OFFSET_2]], %[[SUBOBJECT_OFFSET_1]] : i64
// CHECK: %[[VAL_6:.*]] = llvm.getelementptr %[[BOX]]{{\[}}0, 0] : (!llvm.ptr<struct<(ptr<array<10 x struct<"derived_3", (f32, f32)>>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)>>) -> !llvm.ptr<ptr<array<10 x struct<"derived_3", (f32, f32)>>>>
// CHECK: %[[ARRAY:.*]] = llvm.load %[[VAL_6]] : !llvm.ptr<ptr<array<10 x struct<"derived_3", (f32, f32)>>>>
// CHECK: %[[VAL_8:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[DIM_IDX:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[VAL_13:.*]] = llvm.getelementptr %[[BOX]][0, 7, %[[DIM_IDX]], 2] : (!llvm.ptr<struct<(ptr<array<10 x struct<"derived_3", (f32, f32)>>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)>>, i64) -> !llvm.ptr<i64>
+// CHECK: %[[VAL_13:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr<struct<(ptr<array<10 x struct<"derived_3", (f32, f32)>>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)>>) -> !llvm.ptr<i64>
// CHECK: %[[VAL_14:.*]] = llvm.load %[[VAL_13]] : !llvm.ptr<i64>
// CHECK: %[[VAL_15:.*]] = llvm.mul %[[COORDINATE_1]], %[[VAL_14]] : i64
// CHECK: %[[OFFSET:.*]] = llvm.add %[[VAL_15]], %[[VAL_8]] : i64
func.func @foo6(%box : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1>>>>, %i : i64 , %res : !fir.ref<!fir.char<1>>) {
// CHECK: %[[addr_gep:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[box]], i32 0, i32 0
// CHECK: %[[addr:.*]] = load ptr, ptr %[[addr_gep]]
- // CHECK: %[[stride_gep:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[box]], i32 0, i32 7, i64 0, i32 2
+ // CHECK: %[[stride_gep:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[box]], i32 0, i32 7, i32 0, i32 2
// CHECK: %[[stride:.*]] = load i64, ptr %[[stride_gep]]
// CHECK: %[[mul:.*]] = mul i64 %{{.*}}, %[[stride]]
// CHECK: %[[offset:.*]] = add i64 %[[mul]], 0
--- /dev/null
+// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
+
+fir.global @x target : i32
+
+fir.global @p : !fir.box<!fir.ptr<i32>> {
+ %0 = fir.address_of(@x) : !fir.ref<i32>
+ %1 = fir.embox %0 : (!fir.ref<i32>) -> !fir.box<i32>
+ %2 = fir.rebox %1 : (!fir.box<i32>) -> !fir.box<!fir.ptr<i32>>
+ fir.has_value %2 : !fir.box<!fir.ptr<i32>>
+}
+// CHECK: @p = global { ptr, i64, i32, i8, i8, i8, i8 } { ptr @x, {{.*}}, i32 {{.*}}, i8 0, i8 9, i8 1, i8 0 }
// Only test the computation of the base address offset computation accounting for the substring
// CHECK: %[[VAL_4:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[VAL_30:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL_37:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}0, 0] : (!llvm.ptr<[[char20_descriptor_t]]>)>>) -> !llvm.ptr<ptr<array<20 x i8>>>
// CHECK: %[[VAL_38:.*]] = llvm.load %[[VAL_37]] : !llvm.ptr<ptr<array<20 x i8>>>
+// CHECK: %[[VAL_30:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL_39:.*]] = llvm.bitcast %[[VAL_38]] : !llvm.ptr<array<20 x i8>> to !llvm.ptr<array<20 x i8>>
// CHECK: %[[VAL_40:.*]] = llvm.getelementptr %[[VAL_39]]{{\[}}%[[VAL_30]], %[[VAL_4]]] : (!llvm.ptr<array<20 x i8>>, i64, i64) -> !llvm.ptr<i8>
// CHECK: llvm.bitcast %[[VAL_40]] : !llvm.ptr<i8> to !llvm.ptr<i8>
// Only test the computation of the base address offset computation accounting for the substring of the component
// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(1 : i32) : i32
-// CHECK: %[[VAL_21:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL_30:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}0, 0] : (!llvm.ptr<[[struct_t_descriptor:.*]]>) -> !llvm.ptr<ptr<[[struct_t]]>>
// CHECK: %[[VAL_31:.*]] = llvm.load %[[VAL_30]] : !llvm.ptr<ptr<[[struct_t]]>>
+// CHECK: %[[VAL_21:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL_32:.*]] = llvm.bitcast %[[VAL_31]] : !llvm.ptr<[[struct_t]]> to !llvm.ptr<[[struct_t]]>
// CHECK: %[[VAL_33:.*]] = llvm.getelementptr %[[VAL_32]]{{\[}}%[[VAL_21]], 1, %[[VAL_4]]] : (!llvm.ptr<[[struct_t]]>, i64, i64) -> !llvm.ptr<i8>
// CHECK: llvm.bitcast %[[VAL_33]] : !llvm.ptr<i8> to !llvm.ptr<i8>
%0 = fir.slice %c5, %undef, %undef, %c6, %c80, %c3 : (index, index, index, index, index, index) -> !fir.slice<2>
%1 = fir.shift %c3, %c4 : (index, index) -> !fir.shift<2>
- // CHECK: %[[INSTRIDE_0_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i64 0, i32 2
+ // CHECK: %[[INSTRIDE_0_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i32 0, i32 2
// CHECK: %[[INSTRIDE_0:.]] = load i64, ptr %[[INSTRIDE_0_GEP]]
- // CHECK: %[[INSTRIDE_1_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i64 1, i32 2
+ // CHECK: %[[INSTRIDE_1_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i32 1, i32 2
// CHECK: %[[INSTRIDE_1:.*]] = load i64, ptr %[[INSTRIDE_1_GEP]]
// CHECK: %[[INBASE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 0
// CHECK: %[[INBASE:.*]] = load ptr, ptr %[[INBASE_GEP]]
%c4 = arith.constant 4 : index
%c5 = arith.constant 5 : index
%1 = fir.shape_shift %c2, %c3, %c3, %c4, %c4, %c5 : (index, index, index, index, index, index) -> !fir.shapeshift<3>
- // CHECK: %[[INSTRIDE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i64 0, i32 2
+ // CHECK: %[[INSTRIDE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i32 0, i32 2
// CHECK: %[[INSTRIDE:.*]] = load i64, ptr %[[INSTRIDE_GEP]]
// CHECK: %[[INBASE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 0
// CHECK: %[[INBASE:.*]] = load ptr, ptr %[[INBASE_GEP]]
// CHECK-SAME: ptr %[[INPUT:.*]])
func.func @test_rebox_4(%arg0: !fir.box<!fir.array<?x!fir.char<1,?>>>) {
// CHECK: %[[NEWBOX_STORAGE:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
- // CHECK: %[[EXTENT_GEP:.*]] = getelementptr {{{.*}}}, ptr %[[INPUT]], i32 0, i32 7, i64 0, i32 1
+ // CHECK: %[[EXTENT_GEP:.*]] = getelementptr {{{.*}}}, ptr %[[INPUT]], i32 0, i32 7, i32 0, i32 1
// CHECK: %[[EXTENT:.*]] = load i64, ptr %[[EXTENT_GEP]]
- // CHECK: %[[STRIDE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INPUT]], i32 0, i32 7, i64 0, i32 2
+ // CHECK: %[[STRIDE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INPUT]], i32 0, i32 7, i32 0, i32 2
// 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: %[[VAL_19:.*]] = fir.insert_value %[[VAL_17]], %[[VAL_18]], ["j", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, i32) -> !fir.type<_QMtinitTt1{{.*}}>
! CHECK: %[[VAL_20:.*]] = fir.address_of(@_QMtinitEziel) : !fir.ref<!fir.array<100xf32>>
! CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
- ! CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
- ! CHECK: %[[VAL_23:.*]] = fir.insert_value %[[VAL_19]], %[[VAL_22]], ["x", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.type<_QMtinitTt1{{.*}}>
+ ! CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<100xf32>>
+ ! CHECK: %[[VAL_22_B:.*]] = fir.rebox %[[VAL_22]] : (!fir.box<!fir.array<100xf32>>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: %[[VAL_23:.*]] = fir.insert_value %[[VAL_19]], %[[VAL_22_B]], ["x", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.type<_QMtinitTt1{{.*}}>
! CHECK: %[[VAL_24:.*]] = fir.zero_bits !fir.ptr<!fir.array<?xf32>>
! CHECK: %[[VAL_25:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_24]](%[[VAL_25]]) : (!fir.ptr<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
! CHECK-DAG: %[[undef:.*]] = fir.undefined
! CHECK-DAG: %[[fld:.*]] = fir.field_index p
! CHECK-DAG: %[[target:.*]] = fir.address_of(@_QMpcompEreal_target)
- ! CHECK: %[[box:.*]] = fir.embox %[[target]] : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>
- ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[box]], ["p", !fir.type<_QMpcompTreal_p0{p:!fir.box<!fir.ptr<f32>>}>] :
+ ! CHECK: %[[box:.*]] = fir.embox %[[target]] : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<f32>) -> !fir.box<!fir.ptr<f32>>
+ ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[rebox]], ["p", !fir.type<_QMpcompTreal_p0{p:!fir.box<!fir.ptr<f32>>}>] :
! CHECK: fir.has_value %[[insert]]
type(real_p0) :: arp0 = real_p0(real_target)
! CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_19:.*]] = fir.slice %[[VAL_7]], %[[VAL_11]], %[[VAL_9]] : (index, index, index) -> !fir.slice<1>
! CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_2]](%[[VAL_18]]) {{\[}}%[[VAL_19]]] : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<9xf32>>
-! CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_2]](%[[VAL_18]]) {{\[}}%[[VAL_19]]] : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+! CHECK: %[[VAL_21:.*]] = fir.rebox %[[VAL_20]] : (!fir.box<!fir.array<9xf32>>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
! CHECK: %[[VAL_22:.*]] = fir.insert_value %[[VAL_0]], %[[VAL_21]], ["p", !fir.type<_QMpcompTreal_p1{p:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>] : (!fir.type<_QMpcompTreal_p1{p:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>, !fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.type<_QMpcompTreal_p1{p:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
! CHECK: fir.has_value %[[VAL_22]] : !fir.type<_QMpcompTreal_p1{p:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
! CHECK: }
! CHECK-DAG: %[[undef:.*]] = fir.undefined
! CHECK-DAG: %[[fld:.*]] = fir.field_index p
! CHECK-DAG: %[[target:.*]] = fir.address_of(@_QMpcompEchar_target)
- ! CHECK: %[[box:.*]] = fir.embox %[[target]] : (!fir.ref<!fir.char<1,10>>) -> !fir.box<!fir.ptr<!fir.char<1,10>>>
- ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[box]], ["p", !fir.type<_QMpcompTcst_char_p0{p:!fir.box<!fir.ptr<!fir.char<1,10>>>}>] :
+ ! CHECK: %[[box:.*]] = fir.embox %[[target]] : (!fir.ref<!fir.char<1,10>>) -> !fir.box<!fir.char<1,10>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.char<1,10>>) -> !fir.box<!fir.ptr<!fir.char<1,10>>>
+ ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[rebox]], ["p", !fir.type<_QMpcompTcst_char_p0{p:!fir.box<!fir.ptr<!fir.char<1,10>>>}>] :
! CHECK: fir.has_value %[[insert]]
type(cst_char_p0) :: ccp0 = cst_char_p0(char_target)
! CHECK-DAG: %[[undef:.*]] = fir.undefined
! CHECK-DAG: %[[fld:.*]] = fir.field_index p
! CHECK-DAG: %[[target:.*]] = fir.address_of(@_QMpcompEchar_array_target)
- ! CHECK-DAG: %[[cast:.*]] = fir.convert %[[target]] : (!fir.ref<!fir.array<100x!fir.char<1,10>>>) -> !fir.ptr<!fir.array<?x!fir.char<1,?>>>
! CHECK-DAG: %[[shape:.*]] = fir.shape %c100{{.*}}
- ! CHECK-DAG: %[[box:.*]] = fir.embox %[[cast]](%[[shape]]) typeparams %c10{{.*}} : (!fir.ptr<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
- ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[box]], ["p", !fir.type<_QMpcompTdef_char_p1{p:!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>}>] :
+ ! CHECK-DAG: %[[box:.*]] = fir.embox %[[target]](%[[shape]]) : (!fir.ref<!fir.array<100x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.array<100x!fir.char<1,10>>>
+ ! CHECK-DAG: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.array<100x!fir.char<1,10>>>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
+ ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[rebox]], ["p", !fir.type<_QMpcompTdef_char_p1{p:!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>}>] :
! CHECK: fir.has_value %[[insert]]
type(def_char_p1) :: dcp1 = def_char_p1(char_array_target)
end module
! CHECK-LABEL: fir.global @_QBa : tuple<!fir.box<!fir.ptr<f32>>>
! CHECK: %[[undef:.*]] = fir.undefined tuple<!fir.box<!fir.ptr<f32>>>
! CHECK: %[[b:.*]] = fir.address_of(@_QEb) : !fir.ref<f32>
- ! CHECK: %[[box:.*]] = fir.embox %[[b]] : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>
- ! CHECK: %[[a:.*]] = fir.insert_value %[[undef]], %[[box]], [0 : index] : (tuple<!fir.box<!fir.ptr<f32>>>, !fir.box<!fir.ptr<f32>>) -> tuple<!fir.box<!fir.ptr<f32>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[b]] : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<f32>) -> !fir.box<!fir.ptr<f32>>
+ ! CHECK: %[[a:.*]] = fir.insert_value %[[undef]], %[[rebox]], [0 : index] : (tuple<!fir.box<!fir.ptr<f32>>>, !fir.box<!fir.ptr<f32>>) -> tuple<!fir.box<!fir.ptr<f32>>>
! CHECK: fir.has_value %[[a]] : tuple<!fir.box<!fir.ptr<f32>>>
end block data
! CHECK: %[[byteView:.*]] = fir.convert %[[snakeAddr:.*]] : (!fir.ref<tuple<!fir.box<!fir.ptr<i32>>, i32>>) -> !fir.ref<!fir.array<?xi8>>
! CHECK: %[[coor:.*]] = fir.coordinate_of %[[byteView]], %c24{{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
! CHECK: %[[bAddr:.*]] = fir.convert %[[coor]] : (!fir.ref<i8>) -> !fir.ref<i32>
- ! CHECK: %[[box:.*]] = fir.embox %[[bAddr]] : (!fir.ref<i32>) -> !fir.box<!fir.ptr<i32>>
- ! CHECK: %[[tuple1:.*]] = fir.insert_value %[[tuple0]], %[[box]], [0 : index] : (tuple<!fir.box<!fir.ptr<i32>>, i32>, !fir.box<!fir.ptr<i32>>) -> tuple<!fir.box<!fir.ptr<i32>>, i32>
+ ! CHECK: %[[box:.*]] = fir.embox %[[bAddr]] : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<i32>) -> !fir.box<!fir.ptr<i32>>
+ ! CHECK: %[[tuple1:.*]] = fir.insert_value %[[tuple0]], %[[rebox]], [0 : index] : (tuple<!fir.box<!fir.ptr<i32>>, i32>, !fir.box<!fir.ptr<i32>>) -> tuple<!fir.box<!fir.ptr<i32>>, i32>
! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple1]], %c42{{.*}}, [1 : index] : (tuple<!fir.box<!fir.ptr<i32>>, i32>, i32) -> tuple<!fir.box<!fir.ptr<i32>>, i32>
! CHECK: fir.has_value %[[tuple2]] : tuple<!fir.box<!fir.ptr<i32>>, i32>
end block data
! CHECK-LABEL: fir.global @_QMsome_modEp : !fir.box<!fir.ptr<!fir.array<?xf32>>> {
! CHECK: %[[x:.*]] = fir.address_of(@_QMsome_modEx) : !fir.ref<!fir.array<100xf32>>
! CHECK: %[[shape:.*]] = fir.shape %c100{{.*}} : (index) -> !fir.shape<1>
- ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<100xf32>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.array<100xf32>>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>
end module
! Test initial data target in a common block
! CHECK: %[[yRaw:.*]] = fir.coordinate_of %[[com]], %c400{{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
! CHECK: %[[y:.*]] = fir.convert %[[yRaw]] : (!fir.ref<i8>) -> !fir.ref<!fir.array<200xf32>>
! CHECK: %[[shape:.*]] = fir.shape_shift %c10{{.*}}, %c200{{.*}} : (index, index) -> !fir.shapeshift<1>
- ! CHECK: %[[box:.*]] = fir.embox %[[y]](%[[shape]]) : (!fir.ref<!fir.array<200xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[y]](%[[shape]]) : (!fir.ref<!fir.array<200xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<200xf32>>
+ ! CHECK: %[[shift:.*]] = fir.shift %c10{{.*}} : (index) -> !fir.shift<1>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]](%[[shift]]) : (!fir.box<!fir.array<200xf32>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>
end module
real, pointer :: p => x
! CHECK-LABEL: fir.global internal @_QFscalarEp : !fir.box<!fir.ptr<f32>>
! CHECK: %[[x:.*]] = fir.address_of(@_QFscalarEx) : !fir.ref<f32>
- ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<f32>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<f32>) -> !fir.box<!fir.ptr<f32>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<f32>>
end subroutine
subroutine scalar_char()
character(:), pointer :: p => x
! CHECK-LABEL: fir.global internal @_QFscalar_charEp : !fir.box<!fir.ptr<!fir.char<1,?>>>
! CHECK: %[[x:.*]] = fir.address_of(@_QFscalar_charEx) : !fir.ref<!fir.char<1,10>>
- ! CHECK: %[[xCast:.*]] = fir.convert %[[x]] : (!fir.ref<!fir.char<1,10>>) -> !fir.ptr<!fir.char<1,?>>
- ! CHECK: %[[box:.*]] = fir.embox %[[xCast]] typeparams %c10{{.*}} : (!fir.ptr<!fir.char<1,?>>, index) -> !fir.box<!fir.ptr<!fir.char<1,?>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.char<1,?>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.char<1,10>>) -> !fir.box<!fir.char<1,10>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.char<1,10>>) -> !fir.box<!fir.ptr<!fir.char<1,?>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.char<1,?>>>
end subroutine
subroutine scalar_char_2()
character(10), pointer :: p => x
! CHECK-LABEL: fir.global internal @_QFscalar_char_2Ep : !fir.box<!fir.ptr<!fir.char<1,10>>>
! CHECK: %[[x:.*]] = fir.address_of(@_QFscalar_char_2Ex) : !fir.ref<!fir.char<1,10>>
- ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.char<1,10>>) -> !fir.box<!fir.ptr<!fir.char<1,10>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.char<1,10>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.char<1,10>>) -> !fir.box<!fir.char<1,10>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.char<1,10>>) -> !fir.box<!fir.ptr<!fir.char<1,10>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.char<1,10>>>
end subroutine
subroutine scalar_derived()
type(t), pointer :: p => x
! CHECK-LABEL: fir.global internal @_QFscalar_derivedEp : !fir.box<!fir.ptr<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>>
! CHECK: %[[x:.*]] = fir.address_of(@_QFscalar_derivedEx) : !fir.ref<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>
- ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>) -> !fir.box<!fir.ptr<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>) -> !fir.box<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>) -> !fir.box<!fir.ptr<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.type<_QFscalar_derivedTt{x:f32,i:i32}>>>
end subroutine
subroutine scalar_null()
! CHECK-LABEL: fir.global internal @_QFarrayEp : !fir.box<!fir.ptr<!fir.array<?xf32>>>
! CHECK: %[[x:.*]] = fir.address_of(@_QFarrayEx) : !fir.ref<!fir.array<100xf32>>
! CHECK: %[[shape:.*]] = fir.shape %c100{{.*}} : (index) -> !fir.shape<1>
- ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<100xf32>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.array<100xf32>>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>
end subroutine
subroutine array_char()
! CHECK-LABEL: fir.global internal @_QFarray_charEp : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
! CHECK: %[[x:.*]] = fir.address_of(@_QFarray_charEx) : !fir.ref<!fir.array<20x!fir.char<1,10>>>
! CHECK: %[[shape:.*]] = fir.shape %c20{{.*}} : (index) -> !fir.shape<1>
- ! CHECK: %[[xCast:.*]] = fir.convert %[[x]] : (!fir.ref<!fir.array<20x!fir.char<1,10>>>) -> !fir.ptr<!fir.array<?x!fir.char<1,?>>>
- ! CHECK: %[[box:.*]] = fir.embox %[[xCast]](%[[shape]]) typeparams %c10{{.*}} : (!fir.ptr<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<20x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.array<20x!fir.char<1,10>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.array<20x!fir.char<1,10>>>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
end subroutine
subroutine array_char_2()
! CHECK-LABEL: fir.global internal @_QFarray_char_2Ep : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>
! CHECK: %[[x:.*]] = fir.address_of(@_QFarray_char_2Ex) : !fir.ref<!fir.array<20x!fir.char<1,10>>>
! CHECK: %[[shape:.*]] = fir.shape %c20{{.*}} : (index) -> !fir.shape<1>
- ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<20x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<20x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.array<20x!fir.char<1,10>>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.array<20x!fir.char<1,10>>>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>
end subroutine
subroutine array_derived()
! CHECK-LABEL: fir.global internal @_QFarray_derivedEp : !fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>>
! CHECK: %[[x:.*]] = fir.address_of(@_QFarray_derivedEx) : !fir.ref<!fir.array<100x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>
! CHECK: %[[shape:.*]] = fir.shape %c100{{.*}} : (index) -> !fir.shape<1>
- ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<100x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<100x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<100x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.array<100x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFarray_derivedTt{x:f32,i:i32}>>>>
end subroutine
subroutine array_null()
! CHECK: %[[lb:.*]] = fir.convert %c4 : (index) -> i64
! CHECK: %[[idx:.*]] = arith.subi %c50{{.*}}, %[[lb]] : i64
! CHECK: %[[elt:.*]] = fir.coordinate_of %[[x]], %[[idx]] : (!fir.ref<!fir.array<97xf32>>, i64) -> !fir.ref<f32>
- ! CHECK: %[[box:.*]] = fir.embox %[[elt]] : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<f32>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[elt]] : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<f32>) -> !fir.box<!fir.ptr<f32>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<f32>>
end subroutine
subroutine scalar_char_ref()
! CHECK: %[[eltCast:.*]] = fir.convert %[[elt:.*]] : (!fir.ref<!fir.char<1,20>>) -> !fir.ref<!fir.array<20x!fir.char<1>>>
! CHECK: %[[coor:.*]] = fir.coordinate_of %[[eltCast]], %{{.*}} : (!fir.ref<!fir.array<20x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
! CHECK: %[[substring:.*]] = fir.convert %[[coor]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
- ! CHECK: %[[substringCast:.*]] = fir.convert %[[substring]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ptr<!fir.char<1,10>>
- ! CHECK: %[[box:.*]] = fir.embox %[[substringCast]] : (!fir.ptr<!fir.char<1,10>>) -> !fir.box<!fir.ptr<!fir.char<1,10>>>
- ! CHECK: fir.has_value %[[box]] : !fir.box<!fir.ptr<!fir.char<1,10>>>
+ ! CHECK: %[[box:.*]] = fir.embox %[[substring]] typeparams %{{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<!fir.ptr<!fir.char<1,10>>>
+ ! CHECK: fir.has_value %[[rebox]] : !fir.box<!fir.ptr<!fir.char<1,10>>>
end subroutine
! -----------------------------------------------------------------------------
! CHECK: %[[VAL_23:.*]] = fir.shape_shift %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]] : (index, index, index, index) -> !fir.shapeshift<2>
! CHECK: %[[VAL_24:.*]] = fir.slice %[[VAL_7]], %[[VAL_8]], %[[VAL_8]], %[[VAL_12]], %[[VAL_16]], %[[VAL_14]] : (i64, index, index, index, index, index) -> !fir.slice<2>
! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_0]](%[[VAL_23]]) {{\[}}%[[VAL_24]]] : (!fir.ref<!fir.array<100x100xf32>>, !fir.shapeshift<2>, !fir.slice<2>) -> !fir.box<!fir.array<41xf32>>
-! CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_0]](%[[VAL_23]]) {{\[}}%[[VAL_24]]] : (!fir.ref<!fir.array<100x100xf32>>, !fir.shapeshift<2>, !fir.slice<2>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+! CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_25]] : (!fir.box<!fir.array<41xf32>>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
! CHECK: fir.has_value %[[VAL_26]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>
! CHECK: }