1// Test hlfir.element_addr operation parse, verify (no errors), and unparse. 2// RUN: fir-opt %s | fir-opt | FileCheck %s 3 4func.func @test_element_addr(%x: !fir.ref<!fir.array<100xf32>>, %vector: !fir.ref<!fir.array<20xi32>>, %y: !fir.ref<!fir.array<20xf32>>) { 5 %c20 = arith.constant 20 : index 6 %vector_shape = fir.shape %c20 : (index) -> !fir.shape<1> 7 hlfir.region_assign { 8 hlfir.yield %y : !fir.ref<!fir.array<20xf32>> 9 } to { 10 hlfir.elemental_addr %vector_shape : !fir.shape<1> { 11 ^bb0(%i: index): 12 %0 = hlfir.designate %vector (%i) : (!fir.ref<!fir.array<20xi32>>, index) -> !fir.ref<i32> 13 %1 = fir.load %0 : !fir.ref<i32> 14 %x_element_addr = hlfir.designate %x (%1) : (!fir.ref<!fir.array<100xf32>>, i32) -> !fir.ref<f32> 15 hlfir.yield %x_element_addr : !fir.ref<f32> 16 } 17 } 18 return 19} 20// CHECK-LABEL: func.func @test_element_addr( 21// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>, 22// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.array<20xi32>>, 23// CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<!fir.array<20xf32>>) { 24// CHECK: %[[VAL_3:.*]] = arith.constant 20 : index 25// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> 26// CHECK: hlfir.region_assign { 27// CHECK: hlfir.yield %[[VAL_2]] : !fir.ref<!fir.array<20xf32>> 28// CHECK: } to { 29// CHECK: hlfir.elemental_addr %[[VAL_4]] : !fir.shape<1> { 30// CHECK: ^bb0(%[[VAL_5:.*]]: index): 31// CHECK: %[[VAL_6:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_5]]) : (!fir.ref<!fir.array<20xi32>>, index) -> !fir.ref<i32> 32// CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_6]] : !fir.ref<i32> 33// CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_7]]) : (!fir.ref<!fir.array<100xf32>>, i32) -> !fir.ref<f32> 34// CHECK: hlfir.yield %[[VAL_8]] : !fir.ref<f32> 35// CHECK: } 36// CHECK: } 37 38 39 40func.func @test_element_addr_cleanup(%x: !fir.box<!fir.array<?x!fir.char<1,?>>>, %y: !fir.box<!fir.array<?x!fir.char<1,?>>>) { 41 hlfir.region_assign { 42 hlfir.yield %y : !fir.box<!fir.array<?x!fir.char<1,?>>> 43 } to { 44 %c0 = arith.constant 0 : index 45 %len = fir.box_elesize %x : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index 46 %vector = fir.call @returns_alloc() : () -> !fir.box<!fir.heap<!fir.array<?xi32>>> 47 %vector_dim:3 = fir.box_dims %x, %c0 : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index) -> (index, index, index) 48 %vector_shape = fir.shape %vector_dim#1 : (index) -> !fir.shape<1> 49 hlfir.elemental_addr %vector_shape typeparams %len : !fir.shape<1>, index { 50 ^bb0(%i: index): 51 %0 = hlfir.designate %vector (%i) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32> 52 %1 = fir.load %0 : !fir.ref<i32> 53 %x_element_addr = hlfir.designate %x (%1) typeparams %len : (!fir.box<!fir.array<?x!fir.char<1,?>>>, i32, index) -> !fir.boxchar<1> 54 hlfir.yield %x_element_addr : !fir.boxchar<1> 55 } cleanup { 56 %addr = fir.box_addr %vector : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>> 57 fir.freemem %addr : !fir.heap<!fir.array<?xi32>> 58 } 59 } 60 return 61} 62// CHECK-LABEL: func.func @test_element_addr_cleanup( 63// CHECK-SAME: %[[VAL_0:[^:]*]]: !fir.box<!fir.array<?x!fir.char<1,?>>>, 64// CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?x!fir.char<1,?>>>) { 65// CHECK: hlfir.region_assign { 66// CHECK: hlfir.yield %[[VAL_1]] : !fir.box<!fir.array<?x!fir.char<1,?>>> 67// CHECK: } to { 68// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index 69// CHECK: %[[VAL_3:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index 70// CHECK: %[[VAL_4:.*]] = fir.call @returns_alloc() : () -> !fir.box<!fir.heap<!fir.array<?xi32>>> 71// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index) -> (index, index, index) 72// CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_5]]#1 : (index) -> !fir.shape<1> 73// CHECK: hlfir.elemental_addr %[[VAL_6]] typeparams %[[VAL_3]] : !fir.shape<1>, index { 74// CHECK: ^bb0(%[[VAL_7:.*]]: index): 75// CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_4]] (%[[VAL_7]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32> 76// CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<i32> 77// CHECK: %[[VAL_10:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_9]]) typeparams %[[VAL_3]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, i32, index) -> !fir.boxchar<1> 78// CHECK: hlfir.yield %[[VAL_10]] : !fir.boxchar<1> 79// CHECK: } cleanup { 80// CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>> 81// CHECK: fir.freemem %[[VAL_11]] : !fir.heap<!fir.array<?xi32>> 82// CHECK: } 83// CHECK: } 84 85func.func @unordered() { 86 %c10 = arith.constant 10 : index 87 %c20 = arith.constant 20 : index 88 %0 = fir.shape %c10, %c20 : (index, index) -> !fir.shape<2> 89 hlfir.region_assign { 90 %addr = fir.undefined !fir.ref<!fir.array<10x20xf32>> 91 hlfir.yield %addr : !fir.ref<!fir.array<10x20xf32>> 92 } to { 93 hlfir.elemental_addr %0 unordered : !fir.shape<2> { 94 ^bb0(%i: index, %j: index): 95 %addr = fir.undefined !fir.ref<f32> 96 hlfir.yield %addr : !fir.ref<f32> 97 } 98 } 99 return 100} 101// CHECK-LABEL: func.func @unordered() { 102// CHECK: %[[VAL_0:.*]] = arith.constant 10 : index 103// CHECK: %[[VAL_1:.*]] = arith.constant 20 : index 104// CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_0]], %[[VAL_1]] : (index, index) -> !fir.shape<2> 105// CHECK: hlfir.region_assign { 106// CHECK: %[[VAL_3:.*]] = fir.undefined !fir.ref<!fir.array<10x20xf32>> 107// CHECK: hlfir.yield %[[VAL_3]] : !fir.ref<!fir.array<10x20xf32>> 108// CHECK: } to { 109// CHECK: hlfir.elemental_addr %[[VAL_2]] unordered : !fir.shape<2> { 110// CHECK: ^bb0(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: index): 111// CHECK: %[[VAL_6:.*]] = fir.undefined !fir.ref<f32> 112// CHECK: hlfir.yield %[[VAL_6]] : !fir.ref<f32> 113// CHECK: } 114// CHECK: } 115// CHECK: return 116// CHECK: } 117 118// "X(VECTOR) = Y" with polymorphic X and Y and user defined assignment. 119func.func @test_mold(%x: !fir.class<!fir.array<?x!fir.type<t>>>, %y: !fir.class<!fir.array<?x!fir.type<t>>>, %vector: !fir.box<!fir.array<?xi64>>) { 120 hlfir.region_assign { 121 hlfir.yield %y : !fir.class<!fir.array<?x!fir.type<t>>> 122 } to { 123 %c0 = arith.constant 0 : index 124 %0:3 = fir.box_dims %vector, %c0 : (!fir.box<!fir.array<?xi64>>, index) -> (index, index, index) 125 %1 = fir.shape %0#1 : (index) -> !fir.shape<1> 126 hlfir.elemental_addr %1 mold %x unordered : !fir.shape<1>, !fir.class<!fir.array<?x!fir.type<t>>> { 127 ^bb0(%arg3: index): 128 %2 = hlfir.designate %vector (%arg3) : (!fir.box<!fir.array<?xi64>>, index) -> !fir.ref<i64> 129 %3 = fir.load %2 : !fir.ref<i64> 130 %4 = hlfir.designate %x (%3) : (!fir.class<!fir.array<?x!fir.type<t>>>, i64) -> !fir.class<!fir.type<t>> 131 hlfir.yield %4 : !fir.class<!fir.type<t>> 132 } 133 } user_defined_assign (%arg3: !fir.class<!fir.type<t>>) to (%arg4: !fir.class<!fir.type<t>>) { 134 fir.call @user_def_assign(%arg4, %arg3) : (!fir.class<!fir.type<t>>, !fir.class<!fir.type<t>>) -> () 135 } 136 return 137} 138func.func private @user_def_assign(!fir.class<!fir.type<t>>, !fir.class<!fir.type<t>>) 139// CHECK-LABEL: func.func @test_mold( 140// CHECK-SAME: %[[VAL_0:[^:]*]]: !fir.class<!fir.array<?x!fir.type<t>>>, 141// CHECK-SAME: %[[VAL_1:.*]]: !fir.class<!fir.array<?x!fir.type<t>>>, 142// CHECK-SAME: %[[VAL_2:.*]]: !fir.box<!fir.array<?xi64>>) { 143// CHECK: hlfir.region_assign { 144// CHECK: hlfir.yield %[[VAL_1]] : !fir.class<!fir.array<?x!fir.type<t>>> 145// CHECK: } to { 146// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index 147// CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_3]] : (!fir.box<!fir.array<?xi64>>, index) -> (index, index, index) 148// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]]#1 : (index) -> !fir.shape<1> 149// CHECK: hlfir.elemental_addr %[[VAL_5]] mold %[[VAL_0]] unordered : !fir.shape<1>, !fir.class<!fir.array<?x!fir.type<t>>> { 150// CHECK: ^bb0(%[[VAL_6:.*]]: index): 151// CHECK: %[[VAL_7:.*]] = hlfir.designate %[[VAL_2]] (%[[VAL_6]]) : (!fir.box<!fir.array<?xi64>>, index) -> !fir.ref<i64> 152// CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ref<i64> 153// CHECK: %[[VAL_9:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_8]]) : (!fir.class<!fir.array<?x!fir.type<t>>>, i64) -> !fir.class<!fir.type<t>> 154// CHECK: hlfir.yield %[[VAL_9]] : !fir.class<!fir.type<t>> 155// CHECK: } 156// CHECK: } user_defined_assign (%[[VAL_10:.*]]: !fir.class<!fir.type<t>>) to (%[[VAL_11:.*]]: !fir.class<!fir.type<t>>) { 157// CHECK: fir.call @user_def_assign(%[[VAL_11]], %[[VAL_10]]) : (!fir.class<!fir.type<t>>, !fir.class<!fir.type<t>>) -> () 158// CHECK: } 159