return builder.create<mlir::arith::SelectOp>(loc, dimIsEmpty, one, lb);
}
-/// Create a fir.box to be passed to the LBOUND runtime.
+/// Create a fir.box to be passed to the LBOUND/UBOUND runtime.
/// This ensure that local lower bounds of assumed shape are propagated and that
/// a fir.box with equivalent LBOUNDs but an explicit shape is created for
/// assumed size arrays to avoid undefined behaviors in codegen or the runtime.
-static mlir::Value createBoxForLBOUND(mlir::Location loc,
- fir::FirOpBuilder &builder,
- const fir::ExtendedValue &array) {
+static mlir::Value
+createBoxForRuntimeBoundInquiry(mlir::Location loc, fir::FirOpBuilder &builder,
+ const fir::ExtendedValue &array) {
if (!array.isAssumedSize())
return array.match(
[&](const fir::BoxValue &boxValue) -> mlir::Value {
return builder.createConvert(loc, resultType, lb);
}
- fir::ExtendedValue box = createBoxForLBOUND(loc, builder, array);
+ fir::ExtendedValue box = createBoxForRuntimeBoundInquiry(loc, builder, array);
return builder.createConvert(
loc, resultType,
fir::runtime::genLboundDim(builder, loc, fir::getBase(box), dim));
mlir::Value resultIrBox =
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
- fir::runtime::genUbound(builder, loc, resultIrBox, fir::getBase(args[0]),
- kind);
+ fir::ExtendedValue box =
+ createBoxForRuntimeBoundInquiry(loc, builder, args[0]);
+ fir::runtime::genUbound(builder, loc, resultIrBox, fir::getBase(box), kind);
return readAndAddCleanUp(resultMutableBox, resultType, "UBOUND");
}
--- /dev/null
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! Check that assumed shape lower bounds are applied before passing the
+! descriptor to the runtime call.
+
+ real, target :: a(10:20,99:100)
+ call s2(a,17,-100)
+contains
+ subroutine show(bounds)
+ integer(8) :: bounds(:)
+ print *, bounds
+ end subroutine
+ subroutine s2(a,n,n2)
+ Real a(n:,n2:)
+ call show(ubound(a, kind=8))
+ End Subroutine
+end
+
+! CHECK-LABEL: func.func @_QFPs2
+! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x?xf32>>
+! CHECK: %[[BOX:.*]] = fir.rebox %[[ARG0]](%{{.*}}) : (!fir.box<!fir.array<?x?xf32>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xf32>>
+! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+! CHECK: %{{.*}} = fir.call @_FortranAUbound(%{{.*}}, %[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none