|
| 1 | +! RUN: bbc --emit-hlfir %s -o - | FileCheck %s |
| 2 | + |
| 3 | +! mask argument is dynamically optional, lowered as a box |
| 4 | +integer function test_optional_as_box(x, mask) |
| 5 | + integer :: x(:) |
| 6 | + logical, optional :: mask(:) |
| 7 | + test_optional_as_box = iall(x, mask=mask) |
| 8 | +end function |
| 9 | +! CHECK-LABEL: func.func @_QPtest_optional_as_box( |
| 10 | +! CHECK-SAME: %[[X_ARG:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "x"}, |
| 11 | +! CHECK-SAME: %[[MASK_ARG:.*]]: !fir.box<!fir.array<?x!fir.logical<4>>> {fir.bindc_name = "mask", fir.optional}) -> i32 { |
| 12 | +! CHECK: %[[MASK_VAR:.*]]:2 = hlfir.declare %[[MASK_ARG]] |
| 13 | +! CHECK: %[[RET_ALLOC:.*]] = fir.alloca i32 {bindc_name = "test_optional_as_box", uniq_name = "_QFtest_optional_as_boxEtest_optional_as_box"} |
| 14 | +! CHECK: %[[RET_VAR:.*]]:2 = hlfir.declare %[[RET_ALLOC]] |
| 15 | +! CHECK: %[[X_VAR:.*]]:2 = hlfir.declare %[[X_ARG]] |
| 16 | +! CHECK: %[[C0:.*]] = arith.constant 0 : index |
| 17 | +! CHECK: %[[SRC_LINE:.*]] = fir.address_of({{.*}}) : !fir.ref<!fir.char< |
| 18 | +! CHECK: %[[C7:.*]] = arith.constant 7 : i32 |
| 19 | +! CHECK: %[[VAL_6:.*]] = fir.convert %[[X_VAR]]#1 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none> |
| 20 | +! CHECK: %[[VAL_7:.*]] = fir.convert %[[SRC_LINE]] : (!fir.ref<!fir.char<{{.*}}>>) -> !fir.ref<i8> |
| 21 | +! CHECK: %[[VAL_8:.*]] = fir.convert %[[C0]] : (index) -> i32 |
| 22 | +! CHECK: %[[VAL_9:.*]] = fir.convert %[[MASK_VAR]]#1 : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none> |
| 23 | +! CHECK: %[[RES:.*]] = fir.call @_FortranAIAll4(%[[VAL_6]], %[[VAL_7]], %[[C7]], %[[VAL_8]], %[[VAL_9]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32 |
| 24 | +! CHECK: hlfir.assign %[[RES]] to %[[RET_VAR]]#0 : i32, !fir.ref<i32> |
| 25 | +! CHECK: %[[RET:.*]] = fir.load %[[RET_VAR]]#1 : !fir.ref<i32> |
| 26 | +! CHECK: return %[[RET]] : i32 |
| 27 | +! CHECK: } |
| 28 | + |
| 29 | +! mask argument is dynamically optional, lowered as a box |
| 30 | +integer function test_optional_as_box2(x, mask) |
| 31 | + integer :: x(:) |
| 32 | + logical, allocatable :: mask(:) |
| 33 | + test_optional_as_box2 = iall(x, mask=mask) |
| 34 | +end function |
| 35 | +! CHECK-LABEL: func.func @_QPtest_optional_as_box2( |
| 36 | +! CHECK-SAME: %[[X_ARG:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "x"}, |
| 37 | +! CHECK-SAME: %[[MASK_ARG:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>> {fir.bindc_name = "mask"}) -> i32 { |
| 38 | +! CHECK: %[[MASK_VAR:.*]]:2 = hlfir.declare %[[MASK_ARG]] |
| 39 | +! CHECK: %[[RET_ALLOC:.*]] = fir.alloca i32 {bindc_name = "test_optional_as_box2", uniq_name = "_QFtest_optional_as_box2Etest_optional_as_box2"} |
| 40 | +! CHECK: %[[RET_VAR:.*]]:2 = hlfir.declare %[[RET_ALLOC]] |
| 41 | +! CHECK: %[[X_VAR:.*]]:2 = hlfir.declare %[[X_ARG]] |
| 42 | +! CHECK: %[[MASK_LD:.*]] = fir.load %[[MASK_VAR]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>> |
| 43 | +! CHECK: %[[MASK_ADDR:.*]] = fir.box_addr %[[MASK_LD]] : (!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>) -> !fir.heap<!fir.array<?x!fir.logical<4>>> |
| 44 | +! CHECK: %[[MASK_INT:.*]] = fir.convert %[[MASK_ADDR]] : (!fir.heap<!fir.array<?x!fir.logical<4>>>) -> i64 |
| 45 | +! CHECK: %[[C0_I64:.*]] = arith.constant 0 : i64 |
| 46 | +! CHECK: %[[MASK_PRESENT:.*]] = arith.cmpi ne, %[[MASK_INT]], %[[C0_I64]] : i64 |
| 47 | +! CHECK: %[[MASK_LD2:.*]] = fir.load %[[MASK_VAR]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>> |
| 48 | +! CHECK: %[[C0:.*]] = arith.constant 0 : index |
| 49 | +! CHECK: %[[MASK_DIMS:.*]]:3 = fir.box_dims %[[MASK_LD2]], %[[C0]] : (!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>, index) -> (index, index, index) |
| 50 | +! CHECK: %[[MASK_ADDR2:.*]] = fir.box_addr %[[MASK_LD2]] : (!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>) -> !fir.heap<!fir.array<?x!fir.logical<4>>> |
| 51 | +! CHECK: %[[MASK_SHAPE:.*]] = fir.shape_shift %[[MASK_DIMS]]#0, %[[MASK_DIMS]]#1 : (index, index) -> !fir.shapeshift<1> |
| 52 | +! CHECK: %[[MASK_REBOX:.*]] = fir.embox %[[MASK_ADDR2]](%[[MASK_SHAPE]]) : (!fir.heap<!fir.array<?x!fir.logical<4>>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?x!fir.logical<4>>> |
| 53 | +! CHECK: %[[ABSENT:.*]] = fir.absent !fir.box<!fir.array<?x!fir.logical<4>>> |
| 54 | +! CHECK: %[[MASK_SEL:.*]] = arith.select %[[MASK_PRESENT]], %[[MASK_REBOX]], %[[ABSENT]] : !fir.box<!fir.array<?x!fir.logical<4>>> |
| 55 | +! CHECK: %[[VAL_16:.*]] = arith.constant 0 : index |
| 56 | +! CHECK: %[[VAL_17:.*]] = fir.address_of({{.*}}) : !fir.ref<!fir.char<{{.*}}>> |
| 57 | +! CHECK: %[[VAL_18:.*]] = arith.constant 33 : i32 |
| 58 | +! CHECK: %[[VAL_19:.*]] = fir.convert %[[X_VAR]]#1 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none> |
| 59 | +! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_17]] : (!fir.ref<!fir.char<{{.*}}>>) -> !fir.ref<i8> |
| 60 | +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_16]] : (index) -> i32 |
| 61 | +! CHECK: %[[VAL_22:.*]] = fir.convert %[[MASK_SEL]] : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none> |
| 62 | +! CHECK: %[[RES:.*]] = fir.call @_FortranAIAll4(%[[VAL_19]], %[[VAL_20]], %[[VAL_18]], %[[VAL_21]], %[[VAL_22]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32 |
| 63 | +! CHECK: hlfir.assign %[[RES]] to %[[RET_VAR]]#0 : i32, !fir.ref<i32> |
| 64 | +! CHECK: %[[RET:.*]] = fir.load %[[RET_VAR]]#1 : !fir.ref<i32> |
| 65 | +! CHECK: return %[[RET]] : i32 |
| 66 | +! CHECK: } |
| 67 | + |
| 68 | +! imaginary component is dyamically optional, lowered as a value |
| 69 | +complex function test_optional_as_value(real, imaginary) |
| 70 | + real :: real |
| 71 | + real, optional :: imaginary |
| 72 | + test_optional_as_value = cmplx(real, imaginary) |
| 73 | +end function |
| 74 | +! CHECK-LABEL: func.func @_QPtest_optional_as_value( |
| 75 | +! CHECK-SAME: %[[REAL_ARG:.*]]: !fir.ref<f32> {fir.bindc_name = "real"}, |
| 76 | +! CHECK-SAME: %[[IMAG_ARG:.*]]: !fir.ref<f32> {fir.bindc_name = "imaginary", fir.optional}) -> !fir.complex<4> { |
| 77 | +! CHECK: %[[IMAG_VAR:.*]]:2 = hlfir.declare %[[IMAG_ARG]] |
| 78 | +! CHECK: %[[REAL_VAR:.*]]:2 = hlfir.declare %[[REAL_ARG]] |
| 79 | +! CHECK: %[[RET_ALLOC:.*]] = fir.alloca !fir.complex<4> {bindc_name = "test_optional_as_value", uniq_name = "_QFtest_optional_as_valueEtest_optional_as_value"} |
| 80 | +! CHECK: %[[RET_VAR:.*]]:2 = hlfir.declare %[[RET_ALLOC]] |
| 81 | +! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[IMAG_VAR]]#0 : (!fir.ref<f32>) -> i1 |
| 82 | +! CHECK: %[[REAL_LD:.*]] = fir.load %[[REAL_VAR]]#0 : !fir.ref<f32> |
| 83 | +! CHECK: %[[IMAG_LD:.*]] = fir.if %[[IS_PRESENT]] -> (f32) { |
| 84 | +! CHECK: %[[IMAG_PRESENT:.*]] = fir.load %[[IMAG_VAR]]#0 : !fir.ref<f32> |
| 85 | +! CHECK: fir.result %[[IMAG_PRESENT]] : f32 |
| 86 | +! CHECK: } else { |
| 87 | +! CHECK: %[[IMAG_ABSENT:.*]] = arith.constant 0.000000e+00 : f32 |
| 88 | +! CHECK: fir.result %[[IMAG_ABSENT]] : f32 |
| 89 | +! CHECK: } |
| 90 | +! CHECK: %[[UNDEF:.*]] = fir.undefined !fir.complex<4> |
| 91 | +! CHECK: %[[INS_REAL:.*]] = fir.insert_value %[[UNDEF]], %[[REAL_LD]], [0 : index] : (!fir.complex<4>, f32) -> !fir.complex<4> |
| 92 | +! CHECK: %[[INS_IMAG:.*]] = fir.insert_value %[[INS_REAL]], %[[IMAG_LD:.*]], [1 : index] : (!fir.complex<4>, f32) -> !fir.complex<4> |
| 93 | +! CHECK: hlfir.assign %[[INS_IMAG]] to %[[RET_VAR]]#0 |
| 94 | +! CHECK: %[[RET:.*]] = fir.load %[[RET_VAR]]#1 : !fir.ref<!fir.complex<4>> |
| 95 | +! CHECK: return %[[RET]] : !fir.complex<4> |
| 96 | +! CHECK: } |
| 97 | + |
| 98 | +! stat argument is dynamically optional, lowered as an address |
| 99 | +subroutine test_optional_as_addr |
| 100 | + integer, allocatable :: from(:), to(:) |
| 101 | + integer, allocatable :: stat |
| 102 | + allocate(from(20)) |
| 103 | + call move_alloc(from, to, stat) |
| 104 | + deallocate(to) |
| 105 | +end subroutine |
| 106 | +! CHECK-LABEL: func.func @_QPtest_optional_as_addr() { |
| 107 | +! CHECK: %[[FROM_STACK:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "from", uniq_name = "_QFtest_optional_as_addrEfrom"} |
| 108 | +! CHECK: %[[NULLPTR:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>> |
| 109 | +! CHECK: %[[C0:.*]] = arith.constant 0 : index |
| 110 | +! CHECK: %[[ZERO_SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1> |
| 111 | +! CHECK: %[[ZERO_BOX:.*]] = fir.embox %[[NULLPTR]](%[[ZERO_SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>> |
| 112 | +! CHECK: fir.store %[[ZERO_BOX]] to %[[FROM_STACK]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> |
| 113 | +! CHECK: %[[FROM_VAR:.*]]:2 = hlfir.declare %[[FROM_STACK]] |
| 114 | +! CHECK: %[[STAT_STACK:.*]] = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "stat", uniq_name = "_QFtest_optional_as_addrEstat"} |
| 115 | +! CHECK: %[[STAT_NULLPTR:.*]] = fir.zero_bits !fir.heap<i32> |
| 116 | +! CHECK: %[[STAT_NULLBOX:.*]] = fir.embox %[[STAT_NULLPTR]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>> |
| 117 | +! CHECK: fir.store %[[STAT_NULLBOX]] to %[[STAT_STACK]] : !fir.ref<!fir.box<!fir.heap<i32>>> |
| 118 | +! CHECK: %[[STAT_VAR:.*]]:2 = hlfir.declare %[[STAT_STACK]] |
| 119 | +! CHECK: %[[TO_STACK:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "to", uniq_name = "_QFtest_optional_as_addrEto"} |
| 120 | +! CHECK: %[[TO_NULLPTR:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>> |
| 121 | +! CHECK: %[[C0_1:.*]] = arith.constant 0 : index |
| 122 | +! CHECK: %[[TO_ZERO_SHAPE:.*]] = fir.shape %[[C0_1]] : (index) -> !fir.shape<1> |
| 123 | +! CHECK: %[[TO_NULLBOX:.*]] = fir.embox %[[TO_NULLPTR]](%[[TO_ZERO_SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>> |
| 124 | +! CHECK: fir.store %[[TO_NULLBOX]] to %[[TO_STACK]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> |
| 125 | +! CHECK: %[[TO_VAR:.*]]:2 = hlfir.declare %[[TO_STACK]] |
| 126 | +! CHECK: %[[C20_I32:.*]] = arith.constant 20 : i32 |
| 127 | +! CHECK: %[[C20:.*]] = fir.convert %[[C20_I32]] : (i32) -> index |
| 128 | +! CHECK: %[[C0_2:.*]] = arith.constant 0 : index |
| 129 | +! CHECK: %[[CMPI:.*]] = arith.cmpi sgt, %[[C20]], %[[C0_2]] : index |
| 130 | +! CHECK: %[[ALLOC_SZ:.*]] = arith.select %[[CMPI]], %[[C20]], %[[C0_2]] : index |
| 131 | +! CHECK: %[[FROM_ALLOC:.*]] = fir.allocmem !fir.array<?xi32>, %[[ALLOC_SZ]] {fir.must_be_heap = true, uniq_name = "_QFtest_optional_as_addrEfrom.alloc"} |
| 132 | +! CHECK: %[[FROM_SHAPE:.*]] = fir.shape %[[ALLOC_SZ]] : (index) -> !fir.shape<1> |
| 133 | +! CHECK: %[[FROM_BOX:.*]] = fir.embox %[[FROM_ALLOC]](%[[FROM_SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>> |
| 134 | +! CHECK: fir.store %[[FROM_BOX]] to %[[FROM_VAR]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> |
| 135 | +! CHECK: %[[STAT_BOX:.*]] = fir.load %[[STAT_VAR]]#1 : !fir.ref<!fir.box<!fir.heap<i32>>> |
| 136 | +! CHECK: %[[STAT_ADDR:.*]] = fir.box_addr %[[STAT_BOX]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32> |
| 137 | +! CHECK: %[[ABSENT:.*]] = fir.absent !fir.box<none> |
| 138 | +! CHECK: %[[TRUE:.*]] = arith.constant true |
| 139 | +! CHECK: %[[VAL_25:.*]] = fir.address_of({{.*}}) : !fir.ref<!fir.char<{{.*}}>> |
| 140 | +! CHECK: %[[VAL_26:.*]] = arith.constant {{.*}} : i32 |
| 141 | +! CHECK: %[[VAL_27:.*]] = fir.zero_bits !fir.ref<none> |
| 142 | +! CHECK: %[[VAL_28:.*]] = fir.convert %[[TO_VAR]]#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>> |
| 143 | +! CHECK: %[[VAL_29:.*]] = fir.convert %[[FROM_VAR]]#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>> |
| 144 | +! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_25]] : (!fir.ref<!fir.char<{{.*}}>>) -> !fir.ref<i8> |
| 145 | +! CHECK: %[[RES:.*]] = fir.call @_FortranAMoveAlloc(%[[VAL_28]], %[[VAL_29]], %[[VAL_27]], %[[TRUE]], %[[ABSENT]], %[[VAL_30]], %[[VAL_26]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32 |
| 146 | +! CHECK: %[[STAT_INT:.*]] = fir.convert %[[STAT_ADDR]] : (!fir.heap<i32>) -> i64 |
| 147 | +! CHECK: %[[C0_3:.*]] = arith.constant 0 : i64 |
| 148 | +! CHECK: %[[STAT_NOT_NULL:.*]] = arith.cmpi ne, %[[STAT_INT]], %[[C0_3]] : i64 |
| 149 | +! CHECK: fir.if %[[STAT_NOT_NULL]] { |
| 150 | +! CHECK: fir.store %[[RES]] to %[[STAT_ADDR]] : !fir.heap<i32> |
| 151 | +! CHECK: } |
| 152 | +! [...] |
| 153 | +! CHECK: return |
| 154 | +! CHECK: } |
| 155 | + |
| 156 | +! TODO: there seem to be no intrinsics with dynamically optional arguments lowered asInquired |
| 157 | + |
0 commit comments