if (isStaticallyAbsent(target))
return fir::factory::genIsAllocatedOrAssociatedTest(builder, loc, *pointer);
- mlir::Value targetBox = builder.createBox(loc, target);
+ mlir::Value targetBox;
if (fir::valueHasFirAttribute(fir::getBase(target),
fir::getOptionalAttrName())) {
// Subtle: contrary to other intrinsic optional arguments, disassociated
// to rerun false. The runtime deals with the disassociated/unallocated
// case. Simply ensures that TARGET that are OPTIONAL get conditionally
// emboxed here to convey the optional aspect to the runtime.
+ mlir::Type boxType = fir::BoxType::get(builder.getNoneType());
auto isPresent = builder.create<fir::IsPresentOp>(loc, builder.getI1Type(),
fir::getBase(target));
- auto absentBox = builder.create<fir::AbsentOp>(loc, targetBox.getType());
- targetBox = builder.create<mlir::arith::SelectOp>(loc, isPresent, targetBox,
- absentBox);
+ targetBox = builder
+ .genIfOp(loc, {boxType}, isPresent,
+ /*withElseRegion=*/true)
+ .genThen([&]() {
+ mlir::Value box = builder.createBox(loc, target);
+ mlir::Value cast =
+ builder.createConvert(loc, boxType, box);
+ builder.create<fir::ResultOp>(loc, cast);
+ })
+ .genElse([&]() {
+ mlir::Value absentBox =
+ builder.create<fir::AbsentOp>(loc, boxType);
+ builder.create<fir::ResultOp>(loc, absentBox);
+ })
+ .getResults()[0];
+ } else {
+ targetBox = builder.createBox(loc, target);
}
mlir::Value pointerBoxRef =
fir::factory::getMutableIRBox(builder, loc, *pointer);
real, optional, target :: optionales_ziel(10)
print *, associated(p, optionales_ziel)
! CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
- ! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
- ! CHECK: %[[VAL_9:.*]] = fir.embox %[[VAL_1]](%[[VAL_8]]) : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xf32>>
- ! CHECK: %[[VAL_10:.*]] = fir.is_present %[[VAL_1]] : (!fir.ref<!fir.array<10xf32>>) -> i1
- ! CHECK: %[[VAL_11:.*]] = fir.absent !fir.box<!fir.array<10xf32>>
- ! CHECK: %[[VAL_12:.*]] = arith.select %[[VAL_10]], %[[VAL_9]], %[[VAL_11]] : !fir.box<!fir.array<10xf32>>
+ ! CHECK: %[[VAL_3:.*]] = fir.is_present %[[VAL_1]] : (!fir.ref<!fir.array<10xf32>>) -> i1
+ ! CHECK: %[[VAL_4:.*]] = fir.if %[[VAL_3]] -> (!fir.box<none>) {
+ ! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_1]](%[[VAL_5]]) : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xf32>>
+ ! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.box<!fir.array<10xf32>>) -> !fir.box<none>
+ ! CHECK: fir.result %[[VAL_7]] : !fir.box<none>
+ ! CHECK: } else {
+ ! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<none>
+ ! CHECK: fir.result %[[VAL_8]] : !fir.box<none>
+ ! CHECK: }
! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.box<none>
- ! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.array<10xf32>>) -> !fir.box<none>
- ! CHECK: fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_14]], %[[VAL_15]]) : (!fir.box<none>, !fir.box<none>) -> i1
+ ! CHECK: fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_14]], %[[VAL_4]]) : (!fir.box<none>, !fir.box<none>) -> i1
end subroutine
! CHECK-LABEL: func @_QPtest_optional_target_2(
real, optional, target :: optionales_ziel(:)
print *, associated(p, optionales_ziel)
! CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?xf32>>) -> i1
- ! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.array<?xf32>>
- ! CHECK: %[[VAL_9:.*]] = arith.select %[[VAL_7]], %[[VAL_1]], %[[VAL_8]] : !fir.box<!fir.array<?xf32>>
+ ! CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box<none>) {
+ ! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
+ ! CHECK: fir.result %[[VAL_9]] : !fir.box<none>
+ ! CHECK: } else {
+ ! CHECK: %[[VAL_10:.*]] = fir.absent !fir.box<none>
+ ! CHECK: fir.result %[[VAL_10]] : !fir.box<none>
+ ! CHECK: }
! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.box<none>
- ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
- ! CHECK: fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_11]], %[[VAL_12]]) : (!fir.box<none>, !fir.box<none>) -> i1
+ ! CHECK: fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_11]], %[[VAL_8]]) : (!fir.box<none>, !fir.box<none>) -> i1
end subroutine
! CHECK-LABEL: func @_QPtest_optional_target_3(
real, pointer :: p(:)
real, optional, pointer :: optionales_ziel(:)
print *, associated(p, optionales_ziel)
- ! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
! CHECK: %[[VAL_8:.*]] = fir.is_present %[[VAL_1]] : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> i1
- ! CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<!fir.ptr<!fir.array<?xf32>>>
- ! CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_8]], %[[VAL_7]], %[[VAL_9]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>
+ ! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_8]] -> (!fir.box<none>) {
+ ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+ ! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.box<none>
+ ! CHECK: fir.result %[[VAL_11]] : !fir.box<none>
+ ! CHECK: } else {
+ ! CHECK: %[[VAL_12:.*]] = fir.absent !fir.box<none>
+ ! CHECK: fir.result %[[VAL_12]] : !fir.box<none>
+ ! CHECK: }
! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.box<none>
- ! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_10]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.box<none>
- ! CHECK: fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_12]], %[[VAL_13]]) : (!fir.box<none>, !fir.box<none>) -> i1
+ ! CHECK: fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_12]], %[[VAL_9]]) : (!fir.box<none>, !fir.box<none>) -> i1
end subroutine
! CHECK-LABEL: func @_QPtest_optional_target_4(
real, pointer :: p(:)
real, optional, allocatable, target :: optionales_ziel(:)
print *, associated(p, optionales_ziel)
- ! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
! CHECK: %[[VAL_8:.*]] = fir.is_present %[[VAL_1]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> i1
- ! CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<!fir.heap<!fir.array<?xf32>>>
- ! CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_8]], %[[VAL_7]], %[[VAL_9]] : !fir.box<!fir.heap<!fir.array<?xf32>>>
+ ! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_8]] -> (!fir.box<none>) {
+ ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ ! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.box<none>
+ ! CHECK: fir.result %[[VAL_11]] : !fir.box<none>
+ ! CHECK: } else {
+ ! CHECK: %[[VAL_12:.*]] = fir.absent !fir.box<none>
+ ! CHECK: fir.result %[[VAL_12]] : !fir.box<none>
+ ! CHECK: }
! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.box<none>
- ! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_10]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.box<none>
- ! CHECK: fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_12]], %[[VAL_13]]) : (!fir.box<none>, !fir.box<none>) -> i1
+ ! CHECK: fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_12]], %[[VAL_9]]) : (!fir.box<none>, !fir.box<none>) -> i1
end subroutine
! CHECK-LABEL: func @_QPtest_pointer_target(