diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index bc579a0eeb435..084221f3840d6 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -160,14 +160,6 @@ hasDerivedTypeWithLengthParameters(const Fortran::semantics::Symbol &sym) { 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()) - type = seqType.getEleTy(); - return type; -} - fir::ExtendedValue Fortran::lower::genExtAddrInInitializer( Fortran::lower::AbstractConverter &converter, mlir::Location loc, const Fortran::lower::SomeExpr &addr) { @@ -254,63 +246,26 @@ mlir::Value Fortran::lower::genInitialDataTarget( } } - 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, not a fir.box> 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> 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(*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(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().getLen(); - auto ptrLen = unwrapElementType(boxType).cast().getLen(); - if (ptrLen == targetLen) - // Nothing to do - return builder.create(loc, boxType, op->getOperands(), - op->getAttrs()); - auto embox = mlir::cast(*op); - auto ptrType = boxType.cast().getEleTy(); - mlir::Value memref = builder.createConvert(loc, ptrType, embox.getMemref()); - if (targetLen == fir::CharacterType::unknownLen()) - // Drop the length argument. - return builder.create(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(loc, boxType, memref, embox.getShape(), - embox.getSlice(), - mlir::ValueRange{targetLenValue}); + // The targetBox is a fir.box, not a fir.box> 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(loc, boxType, targetBox, targetShift, + /*slice=*/mlir::Value{}); } static mlir::Value genDefaultInitializerValue( diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index 5ca04cbcc633e..16af6e0234fe6 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -163,13 +163,14 @@ class FIROpConversion : public mlir::ConvertOpToLLVMPattern { 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( - loc, pty, box, - llvm::ArrayRef{ - 0, static_cast(boxValue)}); - return rewriter.create(loc, resultTy, p); + int boxValue) const { + if (box.getType().isa()) { + auto pty = mlir::LLVM::LLVMPointerType::get(resultTy); + auto p = rewriter.create( + loc, pty, box, llvm::ArrayRef{0, boxValue}); + return rewriter.create(loc, resultTy, p); + } + return rewriter.create(loc, box, boxValue); } /// Method to construct code sequence to get the triple for dimension `dim` @@ -178,50 +179,67 @@ class FIROpConversion : public mlir::ConvertOpToLLVMPattern { getDimsFromBox(mlir::Location loc, llvm::ArrayRef 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 + getDimsFromBox(mlir::Location loc, llvm::ArrayRef 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() && + "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(kDimsPosInBox), dim, off); return rewriter.create(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()) { + auto pty = mlir::LLVM::LLVMPointerType::get(ty); + mlir::LLVM::GEPOp p = genGEP(loc, pty, rewriter, box, 0, + static_cast(kDimsPosInBox), dim, off); + return rewriter.create(loc, ty, p); + } + return rewriter.create( + loc, box, llvm::ArrayRef{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(kAddrPosInBox)); - return rewriter.create(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(kElemLenPosInBox)); - return rewriter.create(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 @@ -258,10 +276,7 @@ class FIROpConversion : public mlir::ConvertOpToLLVMPattern { 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(typeDescFieldId)); - return rewriter.create(loc, tdescType, p); + return getValueFromBox(loc, box, tdescType, rewriter, typeDescFieldId); } // Load the attribute from the \p box and perform a check against \p maskValue @@ -482,7 +497,7 @@ struct BoxAddrOpConversion : public FIROpConversion { auto loc = boxaddr.getLoc(); mlir::Type ty = convertType(boxaddr.getType()); if (auto argty = boxaddr.getVal().getType().dyn_cast()) { - rewriter.replaceOp(boxaddr, loadBaseAddrFromBox(loc, ty, a, rewriter)); + rewriter.replaceOp(boxaddr, getBaseAddrFromBox(loc, ty, a, rewriter)); } else { rewriter.replaceOpWithNewOp(boxaddr, a, 0); } @@ -1578,8 +1593,8 @@ struct EmboxCommonConversion : public FIROpConversion { if (auto *gepOp = loadOp.getAddr().getDefiningOp()) { if (auto gep = mlir::dyn_cast(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); } @@ -1614,7 +1629,7 @@ struct EmboxCommonConversion : public FIROpConversion { 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(), @@ -1708,14 +1723,19 @@ struct EmboxCommonConversion : public FIROpConversion { xbox.getSubcomponent().size()); } + static bool isInGlobalOp(mlir::ConversionPatternRewriter &rewriter) { + auto *thisBlock = rewriter.getInsertionBlock(); + return thisBlock && + mlir::isa(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(thisBlock->getParentOp())) + if (isInGlobalOp(rewriter)) return boxValue; auto boxPtrTy = mlir::LLVM::LLVMPointerType::get(boxValue.getType()); auto alloca = @@ -1964,12 +1984,23 @@ struct XReboxOpConversion : public EmboxCommonConversion { 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 type of the operation that produced the + // fir.box was translated to an llvm.ptr> 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()) + loweredBox = unrealizedCast.getInputs()[0]; + // Create new descriptor and fill its non-shape related data. llvm::SmallVector lenParams; mlir::Type inputEleTy = getInputEleTy(rebox); if (auto charTy = inputEleTy.dyn_cast()) { - 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()); @@ -1996,8 +2027,7 @@ struct XReboxOpConversion : public EmboxCommonConversion { llvm::SmallVector inputExtents; llvm::SmallVector 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 dimInfo = getDimsFromBox(loc, {idxTy, idxTy, idxTy}, loweredBox, dim, rewriter); inputExtents.emplace_back(dimInfo[1]); @@ -2006,7 +2036,7 @@ struct XReboxOpConversion : public EmboxCommonConversion { 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, @@ -2413,7 +2443,7 @@ struct XArrayCoorOpConversion // 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(loc, idxTy, diff, stride); offset = rewriter.create(loc, idxTy, sc, offset); } else { @@ -2433,8 +2463,7 @@ struct XArrayCoorOpConversion // 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(loc, voidPtrTy, base); llvm::SmallVector args{offset}; @@ -2645,8 +2674,8 @@ struct CoordinateOpConversion // 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()); @@ -2664,7 +2693,7 @@ struct CoordinateOpConversion 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(loc, idxTy, operands[index], stride); off = rewriter.create(loc, idxTy, sc, off); diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.h b/flang/lib/Optimizer/CodeGen/TypeConverter.h index c129e1c40cc40..4ddc073a31ca9 100644 --- a/flang/lib/Optimizer/CodeGen/TypeConverter.h +++ b/flang/lib/Optimizer/CodeGen/TypeConverter.h @@ -144,7 +144,18 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter { 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> 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, diff --git a/flang/test/Fir/array-coor.fir b/flang/test/Fir/array-coor.fir index 8fa1fdaee17ca..2177f95303697 100644 --- a/flang/test/Fir/array-coor.fir +++ b/flang/test/Fir/array-coor.fir @@ -11,7 +11,7 @@ func.func @array_coor_box_value(%29 : !fir.box>, // 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 diff --git a/flang/test/Fir/arrexp.fir b/flang/test/Fir/arrexp.fir index 6c769bf25fd38..87a2763608250 100644 --- a/flang/test/Fir/arrexp.fir +++ b/flang/test/Fir/arrexp.fir @@ -112,7 +112,7 @@ func.func @f5(%arg0: !fir.box>, %arg1: !fir.box>) -> !fir.array // CHECK: icmp sgt %4 = fir.do_loop %arg3 = %c0 to %1 step %c1 iter_args(%arg4 = %2) -> (!fir.array) { - // 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 @@ -170,7 +170,7 @@ func.func @f7(%arg0: !fir.ref, %arg1: !fir.box>) { %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.shift<1>, index) -> !fir.ref diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir index b6b4fea75eedd..85b8f666a18f8 100644 --- a/flang/test/Fir/convert-to-llvm.fir +++ b/flang/test/Fir/convert-to-llvm.fir @@ -2036,8 +2036,7 @@ func.func @ext_array_coor3(%arg0: !fir.box>) { // 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, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>, i64) -> !llvm.ptr +// CHECK: %[[GEPSTRIDE:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>) -> !llvm.ptr // CHECK: %[[LOADEDSTRIDE:.*]] = llvm.load %[[GEPSTRIDE]] : !llvm.ptr // CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[LOADEDSTRIDE]] : i64 // CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] : i64 @@ -2211,11 +2210,9 @@ func.func @test_rebox_1(%arg0: !fir.box>) { //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, 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, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>, i64) -> !llvm.ptr +//CHECK: %[[DIM1_STRIDE_REF:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>) -> !llvm.ptr //CHECK: %[[DIM1_STRIDE:.*]] = llvm.load %[[DIM1_STRIDE_REF]] : !llvm.ptr -//CHECK: %[[DIM2:.*]] = llvm.mlir.constant(1 : i64) : i64 -//CHECK: %[[DIM2_STRIDE_REF:.*]] = llvm.getelementptr %[[ARG0]][0, 7, %[[DIM2]], 2] : (!llvm.ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>, i64) -> !llvm.ptr +//CHECK: %[[DIM2_STRIDE_REF:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 1, 2] : (!llvm.ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>) -> !llvm.ptr //CHECK: %[[DIM2_STRIDE:.*]] = llvm.load %[[DIM2_STRIDE_REF]] : !llvm.ptr //CHECK: %[[SOURCE_ARRAY_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>) -> !llvm.ptr> //CHECK: %[[SOURCE_ARRAY:.*]] = llvm.load %[[SOURCE_ARRAY_PTR]] : !llvm.ptr> @@ -2283,8 +2280,7 @@ func.func @foo(%arg0: !fir.box} //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, 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)>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>>, i64) -> !llvm.ptr +//CHECK: %[[SRC_STRIDE_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr)>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>>) -> !llvm.ptr //CHECK: %[[SRC_STRIDE:.*]] = llvm.load %[[SRC_STRIDE_PTR]] : !llvm.ptr //CHECK: %[[SRC_ARRAY_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr)>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>>) -> !llvm.ptr)>>> //CHECK: %[[SRC_ARRAY:.*]] = llvm.load %[[SRC_ARRAY_PTR]] : !llvm.ptr)>>> @@ -2407,8 +2403,7 @@ func.func @coordinate_box_array_1d(%arg0: !fir.box>, %arg1: // CHECK-NEXT: %[[ARRAY_OBJECT:.*]] = llvm.load %[[ARRAY_ADDR]] : !llvm.ptr>> // 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>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>, i64) -> !llvm.ptr +// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>) -> !llvm.ptr // CHECK-NEXT: %[[DIM_1_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_1_MEM_STRIDE_ADDR]] : !llvm.ptr // CHECK-NEXT: %[[BYTE_OFFSET:.*]] = llvm.mul %[[COORDINATE]], %[[DIM_1_MEM_STRIDE_VAL]] : i64 // CHECK-NEXT: %[[SUBOJECT_OFFSET:.*]] = llvm.add %[[BYTE_OFFSET]], %[[OFFSET_INIT]] : i64 @@ -2429,8 +2424,7 @@ func.func @coordinate_of_box_dynamic_array_1d(%arg0: !fir.box> // 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, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>, i64) -> !llvm.ptr +// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>) -> !llvm.ptr // CHECK-NEXT: %[[DIM_1_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_1_MEM_STRIDE_ADDR]] : !llvm.ptr // CHECK-NEXT: %[[BYTE_OFFSET:.*]] = llvm.mul %[[COORDINATE]], %[[DIM_1_MEM_STRIDE_VAL]] : i64 // CHECK-NEXT: %[[SUBOJECT_OFFSET:.*]] = llvm.add %[[BYTE_OFFSET]], %[[OFFSET_INIT]] : i64 @@ -2453,14 +2447,12 @@ func.func @coordinate_box_array_2d(%arg0: !fir.box>, % // CHECK-NEXT: %[[ARRAY_OBJECT:.*]] = llvm.load %[[ARRAY_ADDR]] : !llvm.ptr>>> // 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>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>>, i64) -> !llvm.ptr +// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>>) -> !llvm.ptr // CHECK-NEXT: %[[DIM_1_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_1_MEM_STRIDE_ADDR]] : !llvm.ptr // 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>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>>, i64) -> !llvm.ptr +// CHECK-NEXT: %[[DIM_2_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 1, 2] : (!llvm.ptr>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>>) -> !llvm.ptr // CHECK-NEXT: %[[DIM_2_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_2_MEM_STRIDE_ADDR]] : !llvm.ptr // 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 @@ -2485,8 +2477,7 @@ func.func @coordinate_box_derived_inside_array(%arg0: !fir.box>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>>) -> !llvm.ptr>>> // CHECK: %[[ARRAY:.*]] = llvm.load %[[VAL_6]] : !llvm.ptr>>> // 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>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>>, i64) -> !llvm.ptr +// CHECK: %[[VAL_13:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>>) -> !llvm.ptr // CHECK: %[[VAL_14:.*]] = llvm.load %[[VAL_13]] : !llvm.ptr // CHECK: %[[VAL_15:.*]] = llvm.mul %[[COORDINATE_1]], %[[VAL_14]] : i64 // CHECK: %[[OFFSET:.*]] = llvm.add %[[VAL_15]], %[[VAL_8]] : i64 diff --git a/flang/test/Fir/coordinateof.fir b/flang/test/Fir/coordinateof.fir index 6603996fef60e..c605f43a15437 100644 --- a/flang/test/Fir/coordinateof.fir +++ b/flang/test/Fir/coordinateof.fir @@ -66,7 +66,7 @@ func.func @foo5(%box : !fir.box>>, %i : index) -> i32 func.func @foo6(%box : !fir.box>>>, %i : i64 , %res : !fir.ref>) { // 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 diff --git a/flang/test/Fir/rebox-global.fir b/flang/test/Fir/rebox-global.fir new file mode 100644 index 0000000000000..d63e2b0e0ab08 --- /dev/null +++ b/flang/test/Fir/rebox-global.fir @@ -0,0 +1,12 @@ +// RUN: tco %s | FileCheck %s +// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s + +fir.global @x target : i32 + +fir.global @p : !fir.box> { + %0 = fir.address_of(@x) : !fir.ref + %1 = fir.embox %0 : (!fir.ref) -> !fir.box + %2 = fir.rebox %1 : (!fir.box) -> !fir.box> + fir.has_value %2 : !fir.box> +} +// CHECK: @p = global { ptr, i64, i32, i8, i8, i8, i8 } { ptr @x, {{.*}}, i32 {{.*}}, i8 0, i8 9, i8 1, i8 0 } diff --git a/flang/test/Fir/rebox-susbtring.fir b/flang/test/Fir/rebox-susbtring.fir index a92e686162873..70df4dfde9d50 100644 --- a/flang/test/Fir/rebox-susbtring.fir +++ b/flang/test/Fir/rebox-susbtring.fir @@ -19,10 +19,10 @@ func.func @char_section(%arg0: !fir.box>>) { // 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>> // CHECK: %[[VAL_38:.*]] = llvm.load %[[VAL_37]] : !llvm.ptr>> +// CHECK: %[[VAL_30:.*]] = llvm.mlir.constant(0 : i64) : i64 // CHECK: %[[VAL_39:.*]] = llvm.bitcast %[[VAL_38]] : !llvm.ptr> to !llvm.ptr> // CHECK: %[[VAL_40:.*]] = llvm.getelementptr %[[VAL_39]]{{\[}}%[[VAL_30]], %[[VAL_4]]] : (!llvm.ptr>, i64, i64) -> !llvm.ptr // CHECK: llvm.bitcast %[[VAL_40]] : !llvm.ptr to !llvm.ptr @@ -51,10 +51,10 @@ func.func @foo(%arg0: !fir.box} // 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> // CHECK: %[[VAL_31:.*]] = llvm.load %[[VAL_30]] : !llvm.ptr> +// 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 // CHECK: llvm.bitcast %[[VAL_33]] : !llvm.ptr to !llvm.ptr diff --git a/flang/test/Fir/rebox.fir b/flang/test/Fir/rebox.fir index 518bfe255cd82..60f4d59b5f732 100644 --- a/flang/test/Fir/rebox.fir +++ b/flang/test/Fir/rebox.fir @@ -22,9 +22,9 @@ func.func @test_rebox_1(%arg0: !fir.box>) { %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]] @@ -86,7 +86,7 @@ func.func @test_rebox_3(%arg0: !fir.box>) { %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]] @@ -115,9 +115,9 @@ func.func @test_rebox_3(%arg0: !fir.box>) { // CHECK-SAME: ptr %[[INPUT:.*]]) func.func @test_rebox_4(%arg0: !fir.box>>) { // 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]] diff --git a/flang/test/Lower/default-initialization-globals.f90 b/flang/test/Lower/default-initialization-globals.f90 index 3f7a6cd7ada56..bbcea75a5b1f9 100644 --- a/flang/test/Lower/default-initialization-globals.f90 +++ b/flang/test/Lower/default-initialization-globals.f90 @@ -101,8 +101,9 @@ module tinit ! 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> ! CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1> - ! CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box>> - ! CHECK: %[[VAL_23:.*]] = fir.insert_value %[[VAL_19]], %[[VAL_22]], ["x", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.box>>) -> !fir.type<_QMtinitTt1{{.*}}> + ! CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + ! CHECK: %[[VAL_22_B:.*]] = fir.rebox %[[VAL_22]] : (!fir.box>) -> !fir.box>> + ! CHECK: %[[VAL_23:.*]] = fir.insert_value %[[VAL_19]], %[[VAL_22_B]], ["x", !fir.type<_QMtinitTt1{{.*}}>] : (!fir.type<_QMtinitTt1{{.*}}>, !fir.box>>) -> !fir.type<_QMtinitTt1{{.*}}> ! CHECK: %[[VAL_24:.*]] = fir.zero_bits !fir.ptr> ! CHECK: %[[VAL_25:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1> ! CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_24]](%[[VAL_25]]) : (!fir.ptr>, !fir.shape<1>) -> !fir.box>> diff --git a/flang/test/Lower/derived-pointer-components.f90 b/flang/test/Lower/derived-pointer-components.f90 index 88d23c074408c..d01f6bb91d42b 100644 --- a/flang/test/Lower/derived-pointer-components.f90 +++ b/flang/test/Lower/derived-pointer-components.f90 @@ -732,8 +732,9 @@ module pinit ! 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) -> !fir.box> - ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[box]], ["p", !fir.type<_QMpcompTreal_p0{p:!fir.box>}>] : + ! CHECK: %[[box:.*]] = fir.embox %[[target]] : (!fir.ref) -> !fir.box + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box) -> !fir.box> + ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[rebox]], ["p", !fir.type<_QMpcompTreal_p0{p:!fir.box>}>] : ! CHECK: fir.has_value %[[insert]] type(real_p0) :: arp0 = real_p0(real_target) @@ -759,7 +760,7 @@ module pinit ! 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.shape<1>, !fir.slice<1>) -> !fir.box> -! CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_2]](%[[VAL_18]]) {{\[}}%[[VAL_19]]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>) -> !fir.box>> +! CHECK: %[[VAL_21:.*]] = fir.rebox %[[VAL_20]] : (!fir.box>) -> !fir.box>> ! CHECK: %[[VAL_22:.*]] = fir.insert_value %[[VAL_0]], %[[VAL_21]], ["p", !fir.type<_QMpcompTreal_p1{p:!fir.box>>}>] : (!fir.type<_QMpcompTreal_p1{p:!fir.box>>}>, !fir.box>>) -> !fir.type<_QMpcompTreal_p1{p:!fir.box>>}> ! CHECK: fir.has_value %[[VAL_22]] : !fir.type<_QMpcompTreal_p1{p:!fir.box>>}> ! CHECK: } @@ -769,8 +770,9 @@ module pinit ! 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.box>> - ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[box]], ["p", !fir.type<_QMpcompTcst_char_p0{p:!fir.box>>}>] : + ! CHECK: %[[box:.*]] = fir.embox %[[target]] : (!fir.ref>) -> !fir.box> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>) -> !fir.box>> + ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[rebox]], ["p", !fir.type<_QMpcompTcst_char_p0{p:!fir.box>>}>] : ! CHECK: fir.has_value %[[insert]] type(cst_char_p0) :: ccp0 = cst_char_p0(char_target) @@ -778,10 +780,10 @@ module pinit ! 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.ptr>> ! CHECK-DAG: %[[shape:.*]] = fir.shape %c100{{.*}} - ! CHECK-DAG: %[[box:.*]] = fir.embox %[[cast]](%[[shape]]) typeparams %c10{{.*}} : (!fir.ptr>>, !fir.shape<1>, index) -> !fir.box>>> - ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[box]], ["p", !fir.type<_QMpcompTdef_char_p1{p:!fir.box>>>}>] : + ! CHECK-DAG: %[[box:.*]] = fir.embox %[[target]](%[[shape]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> + ! CHECK-DAG: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>>) -> !fir.box>>> + ! CHECK: %[[insert:.*]] = fir.insert_value %[[undef]], %[[rebox]], ["p", !fir.type<_QMpcompTdef_char_p1{p:!fir.box>>>}>] : ! CHECK: fir.has_value %[[insert]] type(def_char_p1) :: dcp1 = def_char_p1(char_array_target) end module diff --git a/flang/test/Lower/pointer-initial-target-2.f90 b/flang/test/Lower/pointer-initial-target-2.f90 index c49c298d6b7cc..9a7393dcb122c 100644 --- a/flang/test/Lower/pointer-initial-target-2.f90 +++ b/flang/test/Lower/pointer-initial-target-2.f90 @@ -14,8 +14,9 @@ ! CHECK-LABEL: fir.global @_QBa : tuple>> ! CHECK: %[[undef:.*]] = fir.undefined tuple>> ! CHECK: %[[b:.*]] = fir.address_of(@_QEb) : !fir.ref - ! CHECK: %[[box:.*]] = fir.embox %[[b]] : (!fir.ref) -> !fir.box> - ! CHECK: %[[a:.*]] = fir.insert_value %[[undef]], %[[box]], [0 : index] : (tuple>>, !fir.box>) -> tuple>> + ! CHECK: %[[box:.*]] = fir.embox %[[b]] : (!fir.ref) -> !fir.box + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box) -> !fir.box> + ! CHECK: %[[a:.*]] = fir.insert_value %[[undef]], %[[rebox]], [0 : index] : (tuple>>, !fir.box>) -> tuple>> ! CHECK: fir.has_value %[[a]] : tuple>> end block data @@ -45,8 +46,9 @@ block data snake ! CHECK: %[[byteView:.*]] = fir.convert %[[snakeAddr:.*]] : (!fir.ref>, i32>>) -> !fir.ref> ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[byteView]], %c24{{.*}} : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[bAddr:.*]] = fir.convert %[[coor]] : (!fir.ref) -> !fir.ref - ! CHECK: %[[box:.*]] = fir.embox %[[bAddr]] : (!fir.ref) -> !fir.box> - ! CHECK: %[[tuple1:.*]] = fir.insert_value %[[tuple0]], %[[box]], [0 : index] : (tuple>, i32>, !fir.box>) -> tuple>, i32> + ! CHECK: %[[box:.*]] = fir.embox %[[bAddr]] : (!fir.ref) -> !fir.box + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box) -> !fir.box> + ! CHECK: %[[tuple1:.*]] = fir.insert_value %[[tuple0]], %[[rebox]], [0 : index] : (tuple>, i32>, !fir.box>) -> tuple>, i32> ! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple1]], %c42{{.*}}, [1 : index] : (tuple>, i32>, i32) -> tuple>, i32> ! CHECK: fir.has_value %[[tuple2]] : tuple>, i32> end block data @@ -58,8 +60,9 @@ module some_mod ! CHECK-LABEL: fir.global @_QMsome_modEp : !fir.box>> { ! CHECK: %[[x:.*]] = fir.address_of(@_QMsome_modEx) : !fir.ref> ! CHECK: %[[shape:.*]] = fir.shape %c100{{.*}} : (index) -> !fir.shape<1> - ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box>> - ! CHECK: fir.has_value %[[box]] : !fir.box>> + ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>) -> !fir.box>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>> end module ! Test initial data target in a common block @@ -74,6 +77,8 @@ module some_mod_2 ! CHECK: %[[yRaw:.*]] = fir.coordinate_of %[[com]], %c400{{.*}} : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[y:.*]] = fir.convert %[[yRaw]] : (!fir.ref) -> !fir.ref> ! CHECK: %[[shape:.*]] = fir.shape_shift %c10{{.*}}, %c200{{.*}} : (index, index) -> !fir.shapeshift<1> - ! CHECK: %[[box:.*]] = fir.embox %[[y]](%[[shape]]) : (!fir.ref>, !fir.shapeshift<1>) -> !fir.box>> - ! CHECK: fir.has_value %[[box]] : !fir.box>> + ! CHECK: %[[box:.*]] = fir.embox %[[y]](%[[shape]]) : (!fir.ref>, !fir.shapeshift<1>) -> !fir.box> + ! CHECK: %[[shift:.*]] = fir.shift %c10{{.*}} : (index) -> !fir.shift<1> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]](%[[shift]]) : (!fir.box>, !fir.shift<1>) -> !fir.box>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>> end module diff --git a/flang/test/Lower/pointer-initial-target.f90 b/flang/test/Lower/pointer-initial-target.f90 index dc05c07e6de0d..a52f2d7a32dff 100644 --- a/flang/test/Lower/pointer-initial-target.f90 +++ b/flang/test/Lower/pointer-initial-target.f90 @@ -10,8 +10,9 @@ subroutine scalar() real, pointer :: p => x ! CHECK-LABEL: fir.global internal @_QFscalarEp : !fir.box> ! CHECK: %[[x:.*]] = fir.address_of(@_QFscalarEx) : !fir.ref - ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref) -> !fir.box> - ! CHECK: fir.has_value %[[box]] : !fir.box> + ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref) -> !fir.box + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box) -> !fir.box> + ! CHECK: fir.has_value %[[rebox]] : !fir.box> end subroutine subroutine scalar_char() @@ -19,9 +20,9 @@ subroutine scalar_char() character(:), pointer :: p => x ! CHECK-LABEL: fir.global internal @_QFscalar_charEp : !fir.box>> ! CHECK: %[[x:.*]] = fir.address_of(@_QFscalar_charEx) : !fir.ref> - ! CHECK: %[[xCast:.*]] = fir.convert %[[x]] : (!fir.ref>) -> !fir.ptr> - ! CHECK: %[[box:.*]] = fir.embox %[[xCast]] typeparams %c10{{.*}} : (!fir.ptr>, index) -> !fir.box>> - ! CHECK: fir.has_value %[[box]] : !fir.box>> + ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref>) -> !fir.box> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>) -> !fir.box>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>> end subroutine subroutine scalar_char_2() @@ -29,8 +30,9 @@ subroutine scalar_char_2() character(10), pointer :: p => x ! CHECK-LABEL: fir.global internal @_QFscalar_char_2Ep : !fir.box>> ! CHECK: %[[x:.*]] = fir.address_of(@_QFscalar_char_2Ex) : !fir.ref> - ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref>) -> !fir.box>> - ! CHECK: fir.has_value %[[box]] : !fir.box>> + ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref>) -> !fir.box> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>) -> !fir.box>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>> end subroutine subroutine scalar_derived() @@ -42,8 +44,9 @@ subroutine scalar_derived() type(t), pointer :: p => x ! CHECK-LABEL: fir.global internal @_QFscalar_derivedEp : !fir.box>> ! CHECK: %[[x:.*]] = fir.address_of(@_QFscalar_derivedEx) : !fir.ref> - ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref>) -> !fir.box>> - ! CHECK: fir.has_value %[[box]] : !fir.box>> + ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref>) -> !fir.box> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>) -> !fir.box>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>> end subroutine subroutine scalar_null() @@ -64,8 +67,9 @@ subroutine array() ! CHECK-LABEL: fir.global internal @_QFarrayEp : !fir.box>> ! CHECK: %[[x:.*]] = fir.address_of(@_QFarrayEx) : !fir.ref> ! CHECK: %[[shape:.*]] = fir.shape %c100{{.*}} : (index) -> !fir.shape<1> - ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box>> - ! CHECK: fir.has_value %[[box]] : !fir.box>> + ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>) -> !fir.box>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>> end subroutine subroutine array_char() @@ -74,9 +78,9 @@ subroutine array_char() ! CHECK-LABEL: fir.global internal @_QFarray_charEp : !fir.box>>> ! CHECK: %[[x:.*]] = fir.address_of(@_QFarray_charEx) : !fir.ref>> ! CHECK: %[[shape:.*]] = fir.shape %c20{{.*}} : (index) -> !fir.shape<1> - ! CHECK: %[[xCast:.*]] = fir.convert %[[x]] : (!fir.ref>>) -> !fir.ptr>> - ! CHECK: %[[box:.*]] = fir.embox %[[xCast]](%[[shape]]) typeparams %c10{{.*}} : (!fir.ptr>>, !fir.shape<1>, index) -> !fir.box>>> - ! CHECK: fir.has_value %[[box]] : !fir.box>>> + ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>>) -> !fir.box>>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>>> end subroutine subroutine array_char_2() @@ -85,8 +89,9 @@ subroutine array_char_2() ! CHECK-LABEL: fir.global internal @_QFarray_char_2Ep : !fir.box>>> ! CHECK: %[[x:.*]] = fir.address_of(@_QFarray_char_2Ex) : !fir.ref>> ! CHECK: %[[shape:.*]] = fir.shape %c20{{.*}} : (index) -> !fir.shape<1> - ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>>> - ! CHECK: fir.has_value %[[box]] : !fir.box>>> + ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>>) -> !fir.box>>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>>> end subroutine subroutine array_derived() @@ -99,8 +104,9 @@ subroutine array_derived() ! CHECK-LABEL: fir.global internal @_QFarray_derivedEp : !fir.box>>> ! CHECK: %[[x:.*]] = fir.address_of(@_QFarray_derivedEx) : !fir.ref>> ! CHECK: %[[shape:.*]] = fir.shape %c100{{.*}} : (index) -> !fir.shape<1> - ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>>> - ! CHECK: fir.has_value %[[box]] : !fir.box>>> + ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref>>, !fir.shape<1>) -> !fir.box>> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>>) -> !fir.box>>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>>> end subroutine subroutine array_null() @@ -124,8 +130,9 @@ subroutine scalar_ref() ! CHECK: %[[lb:.*]] = fir.convert %c4 : (index) -> i64 ! CHECK: %[[idx:.*]] = arith.subi %c50{{.*}}, %[[lb]] : i64 ! CHECK: %[[elt:.*]] = fir.coordinate_of %[[x]], %[[idx]] : (!fir.ref>, i64) -> !fir.ref - ! CHECK: %[[box:.*]] = fir.embox %[[elt]] : (!fir.ref) -> !fir.box> - ! CHECK: fir.has_value %[[box]] : !fir.box> + ! CHECK: %[[box:.*]] = fir.embox %[[elt]] : (!fir.ref) -> !fir.box + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box) -> !fir.box> + ! CHECK: fir.has_value %[[rebox]] : !fir.box> end subroutine subroutine scalar_char_ref() @@ -138,9 +145,9 @@ subroutine scalar_char_ref() ! CHECK: %[[eltCast:.*]] = fir.convert %[[elt:.*]] : (!fir.ref>) -> !fir.ref>> ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[eltCast]], %{{.*}} : (!fir.ref>>, index) -> !fir.ref> ! CHECK: %[[substring:.*]] = fir.convert %[[coor]] : (!fir.ref>) -> !fir.ref> - ! CHECK: %[[substringCast:.*]] = fir.convert %[[substring]] : (!fir.ref>) -> !fir.ptr> - ! CHECK: %[[box:.*]] = fir.embox %[[substringCast]] : (!fir.ptr>) -> !fir.box>> - ! CHECK: fir.has_value %[[box]] : !fir.box>> + ! CHECK: %[[box:.*]] = fir.embox %[[substring]] typeparams %{{.*}}: (!fir.ref>, index) -> !fir.box> + ! CHECK: %[[rebox:.*]] = fir.rebox %[[box]] : (!fir.box>) -> !fir.box>> + ! CHECK: fir.has_value %[[rebox]] : !fir.box>> end subroutine ! ----------------------------------------------------------------------------- @@ -180,6 +187,6 @@ subroutine array_ref() ! 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.shapeshift<2>, !fir.slice<2>) -> !fir.box> -! CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_0]](%[[VAL_23]]) {{\[}}%[[VAL_24]]] : (!fir.ref>, !fir.shapeshift<2>, !fir.slice<2>) -> !fir.box>> +! CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_25]] : (!fir.box>) -> !fir.box>> ! CHECK: fir.has_value %[[VAL_26]] : !fir.box>> ! CHECK: }