Skip to content

Commit 65f746e

Browse files
authored
[flang] Update UBOUND runtime API and lowering (#95085)
LBOUND and SHAPE runtime were added with an API that avoids making a dynamic allocation for the small result storage. Update the UBOUND API that was already there and used in lowering outside of the assumed-rank case. Add tests for the assumed-rank case.
1 parent 2b66d28 commit 65f746e

File tree

6 files changed

+195
-119
lines changed

6 files changed

+195
-119
lines changed

flang/include/flang/Runtime/inquiry.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ std::int64_t RTDECL(Size)(
3535
std::int64_t RTDECL(SizeDim)(const Descriptor &array, int dim,
3636
const char *sourceFile = nullptr, int line = 0);
3737

38-
void RTDECL(Ubound)(Descriptor &result, const Descriptor &array, int kind,
38+
void RTDECL(Ubound)(void *result, const Descriptor &array, int kind,
3939
const char *sourceFile = nullptr, int line = 0);
4040

4141
} // extern "C"

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 79 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6071,33 +6071,80 @@ mlir::Value IntrinsicLibrary::genSetExponent(mlir::Type resultType,
60716071
fir::getBase(args[1])));
60726072
}
60736073

6074+
/// Create a fir.box to be passed to the LBOUND/UBOUND runtime.
6075+
/// This ensure that local lower bounds of assumed shape are propagated and that
6076+
/// a fir.box with equivalent LBOUNDs.
6077+
static mlir::Value
6078+
createBoxForRuntimeBoundInquiry(mlir::Location loc, fir::FirOpBuilder &builder,
6079+
const fir::ExtendedValue &array) {
6080+
// Assumed-rank descriptor must always carry accurate lower bound information
6081+
// in lowering since they cannot be tracked on the side in a vector at compile
6082+
// time.
6083+
if (array.hasAssumedRank())
6084+
return builder.createBox(loc, array);
6085+
6086+
return array.match(
6087+
[&](const fir::BoxValue &boxValue) -> mlir::Value {
6088+
// This entity is mapped to a fir.box that may not contain the local
6089+
// lower bound information if it is a dummy. Rebox it with the local
6090+
// shape information.
6091+
mlir::Value localShape = builder.createShape(loc, array);
6092+
mlir::Value oldBox = boxValue.getAddr();
6093+
return builder.create<fir::ReboxOp>(loc, oldBox.getType(), oldBox,
6094+
localShape,
6095+
/*slice=*/mlir::Value{});
6096+
},
6097+
[&](const auto &) -> mlir::Value {
6098+
// This is a pointer/allocatable, or an entity not yet tracked with a
6099+
// fir.box. For pointer/allocatable, createBox will forward the
6100+
// descriptor that contains the correct lower bound information. For
6101+
// other entities, a new fir.box will be made with the local lower
6102+
// bounds.
6103+
return builder.createBox(loc, array);
6104+
});
6105+
}
6106+
60746107
/// Generate runtime call to inquire about all the bounds/extents of an
6075-
/// assumed-rank array.
6108+
/// array (or an assumed-rank).
60766109
template <typename Func>
6077-
static fir::ExtendedValue genAssumedRankBoundInquiry(
6078-
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type resultType,
6079-
llvm::ArrayRef<fir::ExtendedValue> args, int kindPos, Func genRtCall) {
6110+
static fir::ExtendedValue
6111+
genBoundInquiry(fir::FirOpBuilder &builder, mlir::Location loc,
6112+
mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args,
6113+
int kindPos, Func genRtCall, bool needAccurateLowerBound) {
60806114
const fir::ExtendedValue &array = args[0];
6081-
// Allocate an array with the maximum rank, that is big enough to hold the
6082-
// result but still "small" (15 elements). Static size alloca make stack
6083-
// analysis/manipulation easier.
6115+
const bool hasAssumedRank = array.hasAssumedRank();
60846116
mlir::Type resultElementType = fir::unwrapSequenceType(resultType);
6085-
mlir::Type allocSeqType =
6086-
fir::SequenceType::get({Fortran::common::maxRank}, resultElementType);
6117+
// For assumed-rank arrays, allocate an array with the maximum rank, that is
6118+
// big enough to hold the result but still "small" (15 elements). Static size
6119+
// alloca make stack analysis/manipulation easier.
6120+
int rank = hasAssumedRank ? Fortran::common::maxRank : array.rank();
6121+
mlir::Type allocSeqType = fir::SequenceType::get(rank, resultElementType);
60876122
mlir::Value resultStorage = builder.createTemporary(loc, allocSeqType);
6088-
mlir::Value arrayBox = builder.createBox(loc, array);
6123+
mlir::Value arrayBox =
6124+
needAccurateLowerBound
6125+
? createBoxForRuntimeBoundInquiry(loc, builder, array)
6126+
: builder.createBox(loc, array);
60896127
mlir::Value kind = isStaticallyAbsent(args, kindPos)
60906128
? builder.createIntegerConstant(
60916129
loc, builder.getI32Type(),
60926130
builder.getKindMap().defaultIntegerKind())
60936131
: fir::getBase(args[kindPos]);
60946132
genRtCall(builder, loc, resultStorage, arrayBox, kind);
6095-
mlir::Type baseType =
6096-
fir::ReferenceType::get(builder.getVarLenSeqTy(resultElementType));
6097-
mlir::Value resultBase = builder.createConvert(loc, baseType, resultStorage);
6098-
mlir::Value rank =
6099-
builder.create<fir::BoxRankOp>(loc, builder.getIndexType(), arrayBox);
6100-
return fir::ArrayBoxValue{resultBase, {rank}};
6133+
if (hasAssumedRank) {
6134+
// Cast to fir.ref<array<?xik>> since the result extent is not a compile
6135+
// time constant.
6136+
mlir::Type baseType =
6137+
fir::ReferenceType::get(builder.getVarLenSeqTy(resultElementType));
6138+
mlir::Value resultBase =
6139+
builder.createConvert(loc, baseType, resultStorage);
6140+
mlir::Value rankValue =
6141+
builder.create<fir::BoxRankOp>(loc, builder.getIndexType(), arrayBox);
6142+
return fir::ArrayBoxValue{resultBase, {rankValue}};
6143+
}
6144+
// Result extent is a compile time constant in the other cases.
6145+
mlir::Value rankValue =
6146+
builder.createIntegerConstant(loc, builder.getIndexType(), rank);
6147+
return fir::ArrayBoxValue{resultStorage, {rankValue}};
61016148
}
61026149

61036150
// SHAPE
@@ -6107,8 +6154,9 @@ IntrinsicLibrary::genShape(mlir::Type resultType,
61076154
assert(args.size() >= 1);
61086155
const fir::ExtendedValue &array = args[0];
61096156
if (array.hasAssumedRank())
6110-
return genAssumedRankBoundInquiry(builder, loc, resultType, args,
6111-
/*kindPos=*/1, fir::runtime::genShape);
6157+
return genBoundInquiry(builder, loc, resultType, args,
6158+
/*kindPos=*/1, fir::runtime::genShape,
6159+
/*needAccurateLowerBound=*/false);
61126160
int rank = array.rank();
61136161
mlir::Type indexType = builder.getIndexType();
61146162
mlir::Type extentType = fir::unwrapSequenceType(resultType);
@@ -6344,33 +6392,6 @@ static mlir::Value computeLBOUND(fir::FirOpBuilder &builder, mlir::Location loc,
63446392
return builder.create<mlir::arith::SelectOp>(loc, dimIsEmpty, one, lb);
63456393
}
63466394

6347-
/// Create a fir.box to be passed to the LBOUND/UBOUND runtime.
6348-
/// This ensure that local lower bounds of assumed shape are propagated and that
6349-
/// a fir.box with equivalent LBOUNDs.
6350-
static mlir::Value
6351-
createBoxForRuntimeBoundInquiry(mlir::Location loc, fir::FirOpBuilder &builder,
6352-
const fir::ExtendedValue &array) {
6353-
return array.match(
6354-
[&](const fir::BoxValue &boxValue) -> mlir::Value {
6355-
// This entity is mapped to a fir.box that may not contain the local
6356-
// lower bound information if it is a dummy. Rebox it with the local
6357-
// shape information.
6358-
mlir::Value localShape = builder.createShape(loc, array);
6359-
mlir::Value oldBox = boxValue.getAddr();
6360-
return builder.create<fir::ReboxOp>(loc, oldBox.getType(), oldBox,
6361-
localShape,
6362-
/*slice=*/mlir::Value{});
6363-
},
6364-
[&](const auto &) -> mlir::Value {
6365-
// This is a pointer/allocatable, or an entity not yet tracked with a
6366-
// fir.box. For pointer/allocatable, createBox will forward the
6367-
// descriptor that contains the correct lower bound information. For
6368-
// other entities, a new fir.box will be made with the local lower
6369-
// bounds.
6370-
return builder.createBox(loc, array);
6371-
});
6372-
}
6373-
63746395
// LBOUND
63756396
fir::ExtendedValue
63766397
IntrinsicLibrary::genLbound(mlir::Type resultType,
@@ -6380,9 +6401,12 @@ IntrinsicLibrary::genLbound(mlir::Type resultType,
63806401
// Semantics builds signatures for LBOUND calls as either
63816402
// LBOUND(array, dim, [kind]) or LBOUND(array, [kind]).
63826403
const bool dimIsAbsent = args.size() == 2 || isStaticallyAbsent(args, 1);
6383-
if (array.hasAssumedRank() && dimIsAbsent)
6384-
return genAssumedRankBoundInquiry(builder, loc, resultType, args,
6385-
/*kindPos=*/1, fir::runtime::genLbound);
6404+
if (array.hasAssumedRank() && dimIsAbsent) {
6405+
int kindPos = args.size() == 2 ? 1 : 2;
6406+
return genBoundInquiry(builder, loc, resultType, args, kindPos,
6407+
fir::runtime::genLbound,
6408+
/*needAccurateLowerBound=*/true);
6409+
}
63866410

63876411
mlir::Type indexType = builder.getIndexType();
63886412

@@ -6434,36 +6458,21 @@ fir::ExtendedValue
64346458
IntrinsicLibrary::genUbound(mlir::Type resultType,
64356459
llvm::ArrayRef<fir::ExtendedValue> args) {
64366460
assert(args.size() == 3 || args.size() == 2);
6437-
if (args.size() == 3) {
6461+
const bool dimIsAbsent = args.size() == 2 || isStaticallyAbsent(args, 1);
6462+
if (!dimIsAbsent) {
64386463
// Handle calls to UBOUND with the DIM argument, which return a scalar
64396464
mlir::Value extent = fir::getBase(genSize(resultType, args));
64406465
mlir::Value lbound = fir::getBase(genLbound(resultType, args));
64416466

64426467
mlir::Value one = builder.createIntegerConstant(loc, resultType, 1);
64436468
mlir::Value ubound = builder.create<mlir::arith::SubIOp>(loc, lbound, one);
64446469
return builder.create<mlir::arith::AddIOp>(loc, ubound, extent);
6445-
} else {
6446-
// Handle calls to UBOUND without the DIM argument, which return an array
6447-
mlir::Value kind = isStaticallyAbsent(args[1])
6448-
? builder.createIntegerConstant(
6449-
loc, builder.getIndexType(),
6450-
builder.getKindMap().defaultIntegerKind())
6451-
: fir::getBase(args[1]);
6452-
6453-
// Create mutable fir.box to be passed to the runtime for the result.
6454-
mlir::Type type = builder.getVarLenSeqTy(resultType, /*rank=*/1);
6455-
fir::MutableBoxValue resultMutableBox =
6456-
fir::factory::createTempMutableBox(builder, loc, type);
6457-
mlir::Value resultIrBox =
6458-
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
6459-
6460-
fir::ExtendedValue box =
6461-
createBoxForRuntimeBoundInquiry(loc, builder, args[0]);
6462-
fir::runtime::genUbound(builder, loc, resultIrBox, fir::getBase(box), kind);
6463-
6464-
return readAndAddCleanUp(resultMutableBox, resultType, "UBOUND");
64656470
}
6466-
return mlir::Value();
6471+
// Handle calls to UBOUND without the DIM argument, which return an array
6472+
int kindPos = args.size() == 2 ? 1 : 2;
6473+
return genBoundInquiry(builder, loc, resultType, args, kindPos,
6474+
fir::runtime::genUbound,
6475+
/*needAccurateLowerBound=*/true);
64676476
}
64686477

64696478
// SPACING

flang/runtime/inquiry.cpp

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,14 @@ std::int64_t RTDEF(LboundDim)(
3939
return static_cast<std::int64_t>(dimension.LowerBound());
4040
}
4141

42-
void RTDEF(Ubound)(Descriptor &result, const Descriptor &array, int kind,
42+
void RTDEF(Ubound)(void *result, const Descriptor &array, int kind,
4343
const char *sourceFile, int line) {
44-
SubscriptValue extent[1]{array.rank()};
45-
result.Establish(TypeCategory::Integer, kind, nullptr, 1, extent,
46-
CFI_attribute_allocatable);
47-
// The array returned by UBOUND has a lower bound of 1 and an extent equal to
48-
// the rank of its input array.
49-
result.GetDimension(0).SetBounds(1, array.rank());
5044
Terminator terminator{sourceFile, line};
51-
if (int stat{result.Allocate()}) {
52-
terminator.Crash(
53-
"UBOUND: could not allocate memory for result; STAT=%d", stat);
54-
}
55-
auto storeIntegerAt = [&](std::size_t atIndex, std::int64_t value) {
56-
Fortran::runtime::ApplyIntegerKind<StoreIntegerAt, void>(
57-
kind, terminator, result, atIndex, value);
58-
};
59-
60-
INTERNAL_CHECK(result.rank() == 1);
45+
INTERNAL_CHECK(array.rank() <= common::maxRank);
6146
for (SubscriptValue i{0}; i < array.rank(); ++i) {
6247
const Dimension &dimension{array.GetDimension(i)};
63-
storeIntegerAt(i, dimension.UpperBound());
48+
Fortran::runtime::ApplyIntegerKind<RawStoreIntegerAt, void>(
49+
kind, terminator, result, i, dimension.UpperBound());
6450
}
6551
}
6652

flang/test/Lower/HLFIR/assumed-rank-inquiries-3.f90

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,86 @@ subroutine test_lbound_2(x)
109109
! CHECK: %[[VAL_13:.*]] = fir.box_rank %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> index
110110
! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1>
111111
! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_12]](%[[VAL_14]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
112+
113+
subroutine test_ubound(x)
114+
real :: x(..)
115+
call takes_integer_array(ubound(x))
116+
end subroutine
117+
! CHECK-LABEL: func.func @_QPtest_ubound(
118+
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi32>
119+
! CHECK: %[[VAL_4:.*]] = arith.constant 4 : i32
120+
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.llvm_ptr<i8>
121+
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_3:.*]] : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
122+
! CHECK: %[[VAL_10:.*]] = fir.call @_FortranAUbound(%[[VAL_7]], %[[VAL_8]], %[[VAL_4]], %{{.*}}, %{{.*}})
123+
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.ref<!fir.array<?xi32>>
124+
! CHECK: %[[VAL_12:.*]] = fir.box_rank %[[VAL_3]] : (!fir.box<!fir.array<*:f32>>) -> index
125+
! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
126+
! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_13]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
127+
! CHECK: %[[VAL_15:.*]] = arith.constant false
128+
! CHECK: %[[VAL_16:.*]] = hlfir.as_expr %[[VAL_14]]#0 move %[[VAL_15]] : (!fir.box<!fir.array<?xi32>>, i1) -> !hlfir.expr<?xi32>
129+
! CHECK: %[[VAL_17:.*]]:3 = hlfir.associate %[[VAL_16]](%[[VAL_13]]) {adapt.valuebyref} : (!hlfir.expr<?xi32>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>, i1)
130+
! CHECK: fir.call @_QPtakes_integer_array(%[[VAL_17]]#1) fastmath<contract> : (!fir.ref<!fir.array<?xi32>>) -> ()
131+
! CHECK: hlfir.end_associate %[[VAL_17]]#1, %[[VAL_17]]#2 : !fir.ref<!fir.array<?xi32>>, i1
132+
! CHECK: hlfir.destroy %[[VAL_16]] : !hlfir.expr<?xi32>
133+
! CHECK: return
134+
! CHECK: }
135+
136+
subroutine test_ubound_kind(x)
137+
real :: x(..)
138+
call takes_integer8_array(ubound(x, kind=8))
139+
end subroutine
140+
! CHECK-LABEL: func.func @_QPtest_ubound_kind(
141+
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi64>
142+
! CHECK: %[[VAL_4:.*]] = arith.constant 8 : i32
143+
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi64>>) -> !fir.llvm_ptr<i8>
144+
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_3:.*]] : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
145+
! CHECK: %[[VAL_10:.*]] = fir.call @_FortranAUbound(%[[VAL_7]], %[[VAL_8]], %[[VAL_4]], %{{.*}}, %{{.*}})
146+
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi64>>) -> !fir.ref<!fir.array<?xi64>>
147+
! CHECK: %[[VAL_12:.*]] = fir.box_rank %[[VAL_3]] : (!fir.box<!fir.array<*:f32>>) -> index
148+
! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
149+
! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_13]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi64>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi64>>, !fir.ref<!fir.array<?xi64>>)
150+
151+
subroutine test_ubound_2(x)
152+
real, pointer :: x(..)
153+
call takes_integer_array(ubound(x))
154+
end subroutine
155+
! CHECK-LABEL: func.func @_QPtest_ubound_2(
156+
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi32>
157+
! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3:.*]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
158+
! CHECK: %[[VAL_5:.*]] = arith.constant 4 : i32
159+
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.llvm_ptr<i8>
160+
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> !fir.box<none>
161+
! CHECK: %[[VAL_11:.*]] = fir.call @_FortranAUbound(%[[VAL_8]], %[[VAL_9]], %[[VAL_5]], %{{.*}}, %{{.*}})
162+
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.ref<!fir.array<?xi32>>
163+
! CHECK: %[[VAL_13:.*]] = fir.box_rank %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> index
164+
! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1>
165+
! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_12]](%[[VAL_14]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
166+
167+
subroutine test_lbound_dim(x)
168+
real :: x(..)
169+
call takes_integer(lbound(x, dim=2))
170+
end subroutine
171+
! CHECK-LABEL: func.func @_QPtest_lbound_dim(
172+
! CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
173+
! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2:.*]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
174+
! CHECK: %[[VAL_8:.*]] = fir.call @_FortranALboundDim(%[[VAL_6]], %[[VAL_3]],
175+
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i64) -> i32
176+
! CHECK: %[[VAL_10:.*]]:3 = hlfir.associate %[[VAL_9]]
177+
178+
179+
subroutine test_ubound_dim(x)
180+
real :: x(..)
181+
call takes_integer(ubound(x, dim=2))
182+
end subroutine
183+
! CHECK-LABEL: func.func @_QPtest_ubound_dim(
184+
! CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
185+
! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2:.*]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
186+
! CHECK: %[[VAL_8:.*]] = fir.call @_FortranASizeDim(%[[VAL_6]], %[[VAL_3]],
187+
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i64) -> i32
188+
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
189+
! CHECK: %[[VAL_14:.*]] = fir.call @_FortranALboundDim(%[[VAL_12]], %[[VAL_3]],
190+
! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> i32
191+
! CHECK: %[[VAL_16:.*]] = arith.constant 1 : i32
192+
! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_15]], %[[VAL_16]] : i32
193+
! CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_17]], %[[VAL_9]] : i32
194+
! CHECK: %[[VAL_19:.*]]:3 = hlfir.associate %[[VAL_18]]

flang/test/Lower/Intrinsics/ubound01.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ subroutine s2(a,n,n2)
2020
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x?xf32>>
2121
! CHECK: %[[BOX:.*]] = fir.rebox %[[ARG0]](%{{.*}}) : (!fir.box<!fir.array<?x?xf32>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xf32>>
2222
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
23-
! CHECK: %{{.*}} = fir.call @_FortranAUbound(%{{.*}}, %[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<!fir.box<none>>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none
23+
! CHECK: %{{.*}} = fir.call @_FortranAUbound(%{{.*}}, %[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr<i8>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none

0 commit comments

Comments
 (0)