1// RUN: fir-opt --split-input-file --cfg-conversion --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s 2 3func.func @_QPsb1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"}) { 4 %c1_i64 = arith.constant 1 : i64 5 %c1_i32 = arith.constant 1 : i32 6 %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"} 7 omp.parallel { 8 %1 = fir.alloca i32 {adapt.valuebyref, pinned} 9 %2 = fir.load %arg0 : !fir.ref<i32> 10 omp.wsloop nowait { 11 omp.loop_nest (%arg2) : i32 = (%c1_i32) to (%2) inclusive step (%c1_i32) { 12 fir.store %arg2 to %1 : !fir.ref<i32> 13 %3 = fir.load %1 : !fir.ref<i32> 14 %4 = fir.convert %3 : (i32) -> i64 15 %5 = arith.subi %4, %c1_i64 : i64 16 %6 = fir.coordinate_of %arg1, %5 : (!fir.ref<!fir.array<?xi32>>, i64) -> !fir.ref<i32> 17 fir.store %3 to %6 : !fir.ref<i32> 18 omp.yield 19 } 20 } 21 omp.terminator 22 } 23 return 24} 25 26// CHECK-LABEL: _QPsb1 27// CHECK-SAME: %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}, %[[ARR_REF:.*]]: !llvm.ptr {fir.bindc_name = "arr"}) { 28// CHECK: %[[ONE_0:.*]] = llvm.mlir.constant(1 : i64) : i64 29// CHECK: %[[ONE_1:.*]] = llvm.mlir.constant(1 : i64) : i64 30// CHECK: %[[ONE_2:.*]] = llvm.mlir.constant(1 : i32) : i32 31// CHECK: omp.parallel { 32// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64 33// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr 34// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32 35// CHECK: omp.wsloop nowait 36// CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) inclusive step (%[[ONE_2]]) { 37// CHECK: llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr 38// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32 39// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64 40// CHECK: %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]] : i64 41// CHECK: %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr 42// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr 43// CHECK: omp.yield 44// CHECK: } 45// CHECK: } 46// CHECK: omp.terminator 47// CHECK: } 48// CHECK: llvm.return 49// CHECK: } 50 51// ----- 52 53func.func @_QPsb2(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) { 54 omp.parallel { 55 omp.master { 56 %0 = fir.load %arg1 : !fir.ref<i32> 57 fir.store %0 to %arg0 : !fir.ref<i32> 58 omp.terminator 59 } 60 omp.terminator 61 } 62 return 63} 64 65// CHECK-LABEL: _QPsb2 66// CHECK-SAME: %[[X_REF:.*]]: !llvm.ptr {fir.bindc_name = "x"}, %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}) { 67// CHECK: omp.parallel { 68// CHECK: omp.master { 69// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32 70// CHECK: llvm.store %[[N]], %[[X_REF]] : i32, !llvm.ptr 71// CHECK: omp.terminator 72// CHECK: } 73// CHECK: omp.terminator 74// CHECK: } 75// CHECK: llvm.return 76// CHECK: } 77 78// ----- 79 80func.func @_QPsb(%arr: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "arr"}) { 81 %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"} 82 omp.parallel { 83 %c1 = arith.constant 1 : i32 84 %c50 = arith.constant 50 : i32 85 omp.wsloop { 86 omp.loop_nest (%indx) : i32 = (%c1) to (%c50) inclusive step (%c1) { 87 %1 = fir.convert %indx : (i32) -> i64 88 %c1_i64 = arith.constant 1 : i64 89 %2 = arith.subi %1, %c1_i64 : i64 90 %3 = fir.coordinate_of %arr, %2 : (!fir.box<!fir.array<?xi32>>, i64) -> !fir.ref<i32> 91 fir.store %indx to %3 : !fir.ref<i32> 92 omp.yield 93 } 94 } 95 omp.terminator 96 } 97 return 98} 99 100// Check only for the structure of the OpenMP portion and the feasibility of the conversion 101// CHECK-LABEL: @_QPsb 102// CHECK-SAME: %{{.*}}: !llvm.ptr {fir.bindc_name = "arr"} 103// CHECK: omp.parallel { 104// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i32) : i32 105// CHECK: %[[C50:.*]] = llvm.mlir.constant(50 : i32) : i32 106// CHECK: omp.wsloop { 107// CHECK-NEXT: omp.loop_nest (%[[INDX:.*]]) : i32 = (%[[C1]]) to (%[[C50]]) inclusive step (%[[C1]]) { 108// CHECK: llvm.store %[[INDX]], %{{.*}} : i32, !llvm.ptr 109// CHECK: omp.yield 110// CHECK: omp.terminator 111// CHECK: llvm.return 112 113// ----- 114 115func.func private @foo() 116func.func private @bar() 117 118func.func @sections_no_data() { 119 omp.sections { 120 omp.section { 121 fir.call @foo() : () -> () 122 omp.terminator 123 } 124 omp.section { 125 fir.call @bar() : () -> () 126 omp.terminator 127 } 128 omp.terminator 129 } 130 return 131} 132 133// CHECK-LABEL: llvm.func @sections_no_data 134// CHECK: omp.sections { 135// CHECK: omp.section { 136// CHECK: llvm.call @foo() : () -> () 137// CHECK: omp.terminator 138// CHECK: } 139// CHECK: omp.section { 140// CHECK: llvm.call @bar() : () -> () 141// CHECK: omp.terminator 142// CHECK: } 143// CHECK: omp.terminator 144// CHECK: } 145 146// ----- 147 148func.func private @foo(!fir.ref<i32>) 149func.func private @bar(!fir.ref<i32>, !fir.ref<i32>) 150 151func.func @sections_data_without_clauses(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "b"}) { 152 omp.sections { 153 omp.section { 154 fir.call @foo(%arg0) : (!fir.ref<i32>) -> () 155 omp.terminator 156 } 157 omp.section { 158 fir.call @bar(%arg0, %arg1) : (!fir.ref<i32>, !fir.ref<i32>) -> () 159 omp.terminator 160 } 161 omp.terminator 162 } 163 return 164} 165 166// CHECK-LABEL: llvm.func @sections_data_without_clauses 167// CHECK-SAME: (%[[ARG0:.+]]: !llvm.ptr {fir.bindc_name = "a"}, %[[ARG1:.+]]: !llvm.ptr {fir.bindc_name = "b"}) 168// CHECK: omp.sections { 169// CHECK: omp.section { 170// CHECK: llvm.call @foo(%arg0) : (!llvm.ptr) -> () 171// CHECK: omp.terminator 172// CHECK: } 173// CHECK: omp.section { 174// CHECK: llvm.call @bar(%[[ARG0]], %[[ARG1]]) : (!llvm.ptr, !llvm.ptr) -> () 175// CHECK: omp.terminator 176// CHECK: } 177// CHECK: omp.terminator 178// CHECK: } 179 180// ----- 181 182func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"}) { 183 %c1_i64 = arith.constant 1 : i64 184 %c1_i32 = arith.constant 1 : i32 185 %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"} 186 omp.parallel { 187 %1 = fir.alloca i32 {adapt.valuebyref, pinned} 188 %2 = fir.load %arg0 : !fir.ref<i32> 189 omp.simd { 190 omp.loop_nest (%arg2) : i32 = (%c1_i32) to (%2) step (%c1_i32) { 191 fir.store %arg2 to %1 : !fir.ref<i32> 192 %3 = fir.load %1 : !fir.ref<i32> 193 %4 = fir.convert %3 : (i32) -> i64 194 %5 = arith.subi %4, %c1_i64 : i64 195 %6 = fir.coordinate_of %arg1, %5 : (!fir.ref<!fir.array<?xi32>>, i64) -> !fir.ref<i32> 196 fir.store %3 to %6 : !fir.ref<i32> 197 omp.yield 198 } 199 } 200 omp.terminator 201 } 202 return 203} 204 205// CHECK-LABEL: _QPsimd1 206// CHECK-SAME: %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}, %[[ARR_REF:.*]]: !llvm.ptr {fir.bindc_name = "arr"}) { 207// CHECK: %[[ONE_0:.*]] = llvm.mlir.constant(1 : i64) : i64 208// CHECK: %[[ONE_1:.*]] = llvm.mlir.constant(1 : i64) : i64 209// CHECK: %[[ONE_2:.*]] = llvm.mlir.constant(1 : i32) : i32 210// CHECK: omp.parallel { 211// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64 212// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr 213// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32 214// CHECK: omp.simd { 215// CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) step (%[[ONE_2]]) { 216// CHECK: llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr 217// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32 218// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64 219// CHECK: %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]] : i64 220// CHECK: %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr 221// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr 222// CHECK: omp.yield 223// CHECK: } 224// CHECK: } 225// CHECK: omp.terminator 226// CHECK: } 227// CHECK: llvm.return 228// CHECK: } 229 230// ----- 231 232func.func @_QPomp_target_data() { 233 %c1024 = arith.constant 1024 : index 234 %0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_dataEa"} 235 %c1024_0 = arith.constant 1024 : index 236 %1 = fir.alloca !fir.array<1024xi32> {bindc_name = "b", uniq_name = "_QFomp_target_dataEb"} 237 %c1024_1 = arith.constant 1024 : index 238 %2 = fir.alloca !fir.array<1024xi32> {bindc_name = "c", uniq_name = "_QFomp_target_dataEc"} 239 %c1024_2 = arith.constant 1024 : index 240 %3 = fir.alloca !fir.array<1024xi32> {bindc_name = "d", uniq_name = "_QFomp_target_dataEd"} 241 %c1 = arith.constant 1 : index 242 %c0 = arith.constant 0 : index 243 %4 = arith.subi %c1024, %c1 : index 244 %5 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%4 : index) extent(%c1024 : index) stride(%c1 : index) start_idx(%c1 : index) 245 %6 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(to) capture(ByRef) bounds(%5) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} 246 %c1_3 = arith.constant 1 : index 247 %c0_4 = arith.constant 0 : index 248 %7 = arith.subi %c1024_0, %c1_3 : index 249 %8 = omp.map.bounds lower_bound(%c0_4 : index) upper_bound(%7 : index) extent(%c1024_0 : index) stride(%c1_3 : index) start_idx(%c1_3 : index) 250 %9 = omp.map.info var_ptr(%1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(to) capture(ByRef) bounds(%8) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} 251 %c1_5 = arith.constant 1 : index 252 %c0_6 = arith.constant 0 : index 253 %10 = arith.subi %c1024_1, %c1_5 : index 254 %11 = omp.map.bounds lower_bound(%c0_6 : index) upper_bound(%10 : index) extent(%c1024_1 : index) stride(%c1_5 : index) start_idx(%c1_5 : index) 255 %12 = omp.map.info var_ptr(%2 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%11) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} 256 omp.target_enter_data map_entries(%6, %9, %12 : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) 257 %c1_7 = arith.constant 1 : index 258 %c0_8 = arith.constant 0 : index 259 %13 = arith.subi %c1024, %c1_7 : index 260 %14 = omp.map.bounds lower_bound(%c0_8 : index) upper_bound(%13 : index) extent(%c1024 : index) stride(%c1_7 : index) start_idx(%c1_7 : index) 261 %15 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(from) capture(ByRef) bounds(%14) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} 262 %c1_9 = arith.constant 1 : index 263 %c0_10 = arith.constant 0 : index 264 %16 = arith.subi %c1024_0, %c1_9 : index 265 %17 = omp.map.bounds lower_bound(%c0_10 : index) upper_bound(%16 : index) extent(%c1024_0 : index) stride(%c1_9 : index) start_idx(%c1_9 : index) 266 %18 = omp.map.info var_ptr(%1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(from) capture(ByRef) bounds(%17) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} 267 %c1_11 = arith.constant 1 : index 268 %c0_12 = arith.constant 0 : index 269 %19 = arith.subi %c1024_1, %c1_11 : index 270 %20 = omp.map.bounds lower_bound(%c0_12 : index) upper_bound(%19 : index) extent(%c1024_1 : index) stride(%c1_11 : index) start_idx(%c1_11 : index) 271 %21 = omp.map.info var_ptr(%2 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%20) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} 272 %c1_13 = arith.constant 1 : index 273 %c0_14 = arith.constant 0 : index 274 %22 = arith.subi %c1024_2, %c1_13 : index 275 %23 = omp.map.bounds lower_bound(%c0_14 : index) upper_bound(%22 : index) extent(%c1024_2 : index) stride(%c1_13 : index) start_idx(%c1_13 : index) 276 %24 = omp.map.info var_ptr(%3 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, delete) capture(ByRef) bounds(%23) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} 277 omp.target_exit_data map_entries(%15, %18, %21, %24 : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) 278 return 279} 280 281// CHECK-LABEL: llvm.func @_QPomp_target_data() { 282// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(1 : i64) : i64 283// CHECK: %[[VAL_2:.*]] = llvm.alloca %[[VAL_1]] x !llvm.array<1024 x i32> {bindc_name = "d"} : (i64) -> !llvm.ptr 284// CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(1 : i64) : i64 285// CHECK: %[[VAL_4:.*]] = llvm.alloca %[[VAL_3]] x !llvm.array<1024 x i32> {bindc_name = "c"} : (i64) -> !llvm.ptr 286// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(1 : i64) : i64 287// CHECK: %[[VAL_6:.*]] = llvm.alloca %[[VAL_5]] x !llvm.array<1024 x i32> {bindc_name = "b"} : (i64) -> !llvm.ptr 288// CHECK: %[[VAL_7:.*]] = llvm.mlir.constant(1 : i64) : i64 289// CHECK: %[[VAL_8:.*]] = llvm.alloca %[[VAL_7]] x !llvm.array<1024 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr 290// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1024 : index) : i64 291// CHECK: %[[VAL_9:.*]] = llvm.mlir.constant(1024 : index) : i64 292// CHECK: %[[VAL_10:.*]] = llvm.mlir.constant(1024 : index) : i64 293// CHECK: %[[VAL_11:.*]] = llvm.mlir.constant(1024 : index) : i64 294// CHECK: %[[VAL_12:.*]] = llvm.mlir.constant(1 : index) : i64 295// CHECK: %[[VAL_13:.*]] = llvm.mlir.constant(0 : index) : i64 296// CHECK: %[[VAL_14:.*]] = llvm.mlir.constant(1023 : index) : i64 297// CHECK: %[[VAL_15:.*]] = omp.map.bounds lower_bound(%[[VAL_13]] : i64) upper_bound(%[[VAL_14]] : i64) extent(%[[VAL_0]] : i64) stride(%[[VAL_12]] : i64) start_idx(%[[VAL_12]] : i64) 298// CHECK: %[[VAL_16:.*]] = omp.map.info var_ptr(%[[VAL_8]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%[[VAL_15]]) -> !llvm.ptr {name = "a"} 299// CHECK: %[[VAL_17:.*]] = llvm.mlir.constant(1 : index) : i64 300// CHECK: %[[VAL_18:.*]] = llvm.mlir.constant(0 : index) : i64 301// CHECK: %[[VAL_19:.*]] = llvm.mlir.constant(1023 : index) : i64 302// CHECK: %[[VAL_20:.*]] = omp.map.bounds lower_bound(%[[VAL_18]] : i64) upper_bound(%[[VAL_19]] : i64) extent(%[[VAL_9]] : i64) stride(%[[VAL_17]] : i64) start_idx(%[[VAL_17]] : i64) 303// CHECK: %[[VAL_21:.*]] = omp.map.info var_ptr(%[[VAL_6]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%[[VAL_20]]) -> !llvm.ptr {name = "b"} 304// CHECK: %[[VAL_22:.*]] = llvm.mlir.constant(1 : index) : i64 305// CHECK: %[[VAL_23:.*]] = llvm.mlir.constant(0 : index) : i64 306// CHECK: %[[VAL_24:.*]] = llvm.mlir.constant(1023 : index) : i64 307// CHECK: %[[VAL_25:.*]] = omp.map.bounds lower_bound(%[[VAL_23]] : i64) upper_bound(%[[VAL_24]] : i64) extent(%[[VAL_10]] : i64) stride(%[[VAL_22]] : i64) start_idx(%[[VAL_22]] : i64) 308// CHECK: %[[VAL_26:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%[[VAL_25]]) -> !llvm.ptr {name = "c"} 309// CHECK: omp.target_enter_data map_entries(%[[VAL_16]], %[[VAL_21]], %[[VAL_26]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) 310// CHECK: %[[VAL_27:.*]] = llvm.mlir.constant(1 : index) : i64 311// CHECK: %[[VAL_28:.*]] = llvm.mlir.constant(0 : index) : i64 312// CHECK: %[[VAL_29:.*]] = llvm.mlir.constant(1023 : index) : i64 313// CHECK: %[[VAL_30:.*]] = omp.map.bounds lower_bound(%[[VAL_28]] : i64) upper_bound(%[[VAL_29]] : i64) extent(%[[VAL_0]] : i64) stride(%[[VAL_27]] : i64) start_idx(%[[VAL_27]] : i64) 314// CHECK: %[[VAL_31:.*]] = omp.map.info var_ptr(%[[VAL_8]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%[[VAL_30]]) -> !llvm.ptr {name = "a"} 315// CHECK: %[[VAL_32:.*]] = llvm.mlir.constant(1 : index) : i64 316// CHECK: %[[VAL_33:.*]] = llvm.mlir.constant(0 : index) : i64 317// CHECK: %[[VAL_34:.*]] = llvm.mlir.constant(1023 : index) : i64 318// CHECK: %[[VAL_35:.*]] = omp.map.bounds lower_bound(%[[VAL_33]] : i64) upper_bound(%[[VAL_34]] : i64) extent(%[[VAL_9]] : i64) stride(%[[VAL_32]] : i64) start_idx(%[[VAL_32]] : i64) 319// CHECK: %[[VAL_36:.*]] = omp.map.info var_ptr(%[[VAL_6]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%[[VAL_35]]) -> !llvm.ptr {name = "b"} 320// CHECK: %[[VAL_37:.*]] = llvm.mlir.constant(1 : index) : i64 321// CHECK: %[[VAL_38:.*]] = llvm.mlir.constant(0 : index) : i64 322// CHECK: %[[VAL_39:.*]] = llvm.mlir.constant(1023 : index) : i64 323// CHECK: %[[VAL_40:.*]] = omp.map.bounds lower_bound(%[[VAL_38]] : i64) upper_bound(%[[VAL_39]] : i64) extent(%[[VAL_10]] : i64) stride(%[[VAL_37]] : i64) start_idx(%[[VAL_37]] : i64) 324// CHECK: %[[VAL_41:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%[[VAL_40]]) -> !llvm.ptr {name = "c"} 325// CHECK: %[[VAL_42:.*]] = llvm.mlir.constant(1 : index) : i64 326// CHECK: %[[VAL_43:.*]] = llvm.mlir.constant(0 : index) : i64 327// CHECK: %[[VAL_44:.*]] = llvm.mlir.constant(1023 : index) : i64 328// CHECK: %[[VAL_45:.*]] = omp.map.bounds lower_bound(%[[VAL_43]] : i64) upper_bound(%[[VAL_44]] : i64) extent(%[[VAL_11]] : i64) stride(%[[VAL_42]] : i64) start_idx(%[[VAL_42]] : i64) 329// CHECK: %[[VAL_46:.*]] = omp.map.info var_ptr(%[[VAL_2]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, delete) capture(ByRef) bounds(%[[VAL_45]]) -> !llvm.ptr {name = "d"} 330// CHECK: omp.target_exit_data map_entries(%[[VAL_31]], %[[VAL_36]], %[[VAL_41]], %[[VAL_46]] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) 331// CHECK: llvm.return 332// CHECK: } 333 334// ----- 335 336func.func @_QPopenmp_target_data_region() { 337 %0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFopenmp_target_data_regionEa"} 338 %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFopenmp_target_data_regionEi"} 339 %c1024 = arith.constant 1024 : index 340 %c3 = arith.constant 1 : index 341 %c0 = arith.constant 0 : index 342 %c2 = arith.subi %c1024, %c3 : index 343 %bound = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c2 : index) extent(%c1024 : index) stride(%c3 : index) start_idx(%c3 : index) 344 %entry = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%bound) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} 345 omp.target_data map_entries(%entry : !fir.ref<!fir.array<1024xi32>>) { 346 %c1_i32 = arith.constant 1 : i32 347 %2 = fir.convert %c1_i32 : (i32) -> index 348 %c1024_i32 = arith.constant 1024 : i32 349 %3 = fir.convert %c1024_i32 : (i32) -> index 350 %c1 = arith.constant 1 : index 351 %4 = fir.convert %2 : (index) -> i32 352 %5:2 = fir.do_loop %arg0 = %2 to %3 step %c1 iter_args(%arg1 = %4) -> (index, i32) { 353 fir.store %arg1 to %1 : !fir.ref<i32> 354 %6 = fir.load %1 : !fir.ref<i32> 355 %7 = fir.load %1 : !fir.ref<i32> 356 %8 = fir.convert %7 : (i32) -> i64 357 %c1_i64 = arith.constant 1 : i64 358 %9 = arith.subi %8, %c1_i64 : i64 359 %10 = fir.coordinate_of %0, %9 : (!fir.ref<!fir.array<1024xi32>>, i64) -> !fir.ref<i32> 360 fir.store %6 to %10 : !fir.ref<i32> 361 %11 = arith.addi %arg0, %c1 overflow<nsw> : index 362 %12 = fir.convert %c1 : (index) -> i32 363 %13 = fir.load %1 : !fir.ref<i32> 364 %14 = arith.addi %13, %12 overflow<nsw> : i32 365 fir.result %11, %14 : index, i32 366 } 367 fir.store %5#1 to %1 : !fir.ref<i32> 368 omp.terminator 369 } 370 return 371} 372 373// CHECK-LABEL: llvm.func @_QPopenmp_target_data_region() { 374// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(1 : i64) : i64 375// CHECK: %[[VAL_3:.*]] = llvm.alloca %[[VAL_2]] x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr 376// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64 377// CHECK: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<1024 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr 378// CHECK: %[[VAL_MAX:.*]] = llvm.mlir.constant(1024 : index) : i64 379// CHECK: %[[VAL_ONE:.*]] = llvm.mlir.constant(1 : index) : i64 380// CHECK: %[[VAL_ZERO:.*]] = llvm.mlir.constant(0 : index) : i64 381// CHECK: %[[VAL_UPPER:.*]] = llvm.mlir.constant(1023 : index) : i64 382// CHECK: %[[VAL_BOUNDS:.*]] = omp.map.bounds lower_bound(%[[VAL_ZERO]] : i64) upper_bound(%[[VAL_UPPER]] : i64) extent(%[[VAL_MAX]] : i64) stride(%[[VAL_ONE]] : i64) start_idx(%[[VAL_ONE]] : i64) 383// CHECK: %[[VAL_MAP:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_BOUNDS]]) -> !llvm.ptr {name = "a"} 384// CHECK: omp.target_data map_entries(%[[VAL_MAP]] : !llvm.ptr) { 385// CHECK: %[[VAL_4:.*]] = llvm.mlir.constant(1 : i32) : i32 386// CHECK: %[[VAL_5:.*]] = llvm.sext %[[VAL_4]] : i32 to i64 387// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(1024 : i32) : i32 388// CHECK: %[[VAL_7:.*]] = llvm.sext %[[VAL_6]] : i32 to i64 389// CHECK: %[[VAL_8:.*]] = llvm.mlir.constant(1 : index) : i64 390// CHECK: %[[VAL_9:.*]] = llvm.trunc %[[VAL_5]] : i64 to i32 391// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_7]], %[[VAL_5]] : i64 392// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_10]], %[[VAL_8]] : i64 393// CHECK: llvm.br ^bb1(%[[VAL_5]], %[[VAL_9]], %[[VAL_11]] : i64, i32, i64) 394// CHECK: ^bb1(%[[VAL_12:.*]]: i64, %[[VAL_13:.*]]: i32, %[[VAL_14:.*]]: i64): 395// CHECK: %[[VAL_15:.*]] = llvm.mlir.constant(0 : index) : i64 396// CHECK: %[[VAL_16:.*]] = llvm.icmp "sgt" %[[VAL_14]], %[[VAL_15]] : i64 397// CHECK: llvm.cond_br %[[VAL_16]], ^bb2, ^bb3 398// CHECK: ^bb2: 399// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr 400// CHECK: %[[VAL_17:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32 401// CHECK: %[[VAL_18:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32 402// CHECK: %[[VAL_19:.*]] = llvm.sext %[[VAL_18]] : i32 to i64 403// CHECK: %[[VAL_20:.*]] = llvm.mlir.constant(1 : i64) : i64 404// CHECK: %[[VAL_21:.*]] = llvm.sub %[[VAL_19]], %[[VAL_20]] : i64 405// CHECK: %[[VAL_22:.*]] = llvm.getelementptr %[[VAL_1]][0, %[[VAL_21]]] : (!llvm.ptr, i64) -> !llvm.ptr 406// CHECK: llvm.store %[[VAL_17]], %[[VAL_22]] : i32, !llvm.ptr 407// CHECK: %[[VAL_23:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] overflow<nsw> : i64 408// CHECK: %[[VAL_24:.*]] = llvm.trunc %[[VAL_8]] : i64 to i32 409// CHECK: %[[VAL_25:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32 410// CHECK: %[[VAL_26:.*]] = llvm.add %[[VAL_25]], %[[VAL_24]] overflow<nsw> : i32 411// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] overflow<nsw> : i64 412// CHECK: %[[VAL_28:.*]] = llvm.mlir.constant(1 : index) : i64 413// CHECK: %[[VAL_29:.*]] = llvm.sub %[[VAL_14]], %[[VAL_28]] : i64 414// CHECK: llvm.br ^bb1(%[[VAL_27]], %[[VAL_26]], %[[VAL_29]] : i64, i32, i64) 415// CHECK: ^bb3: 416// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr 417// CHECK: omp.terminator 418// CHECK: } 419// CHECK: llvm.return 420// CHECK: } 421 422// ----- 423 424func.func @_QPomp_target_data_empty() { 425 %0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_data_emptyEa"} 426 omp.target_data use_device_addr(%0 -> %arg0 : !fir.ref<!fir.array<1024xi32>>) { 427 omp.terminator 428 } 429 return 430} 431 432// CHECK-LABEL: llvm.func @_QPomp_target_data_empty 433// CHECK: omp.target_data use_device_addr(%1 -> %{{.*}} : !llvm.ptr) { 434// CHECK: } 435 436// ----- 437 438func.func @_QPomp_target() { 439 %c512 = arith.constant 512 : index 440 %0 = fir.alloca !fir.array<512xi32> {bindc_name = "a", uniq_name = "_QFomp_targetEa"} 441 %c64_i32 = arith.constant 64 : i32 442 %c1 = arith.constant 1 : index 443 %c0 = arith.constant 0 : index 444 %1 = arith.subi %c512, %c1 : index 445 %2 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%1 : index) extent(%c512 : index) stride(%c1 : index) start_idx(%c1 : index) 446 %3 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<512xi32>>, !fir.array<512xi32>) map_clauses(tofrom) capture(ByRef) bounds(%2) -> !fir.ref<!fir.array<512xi32>> {name = "a"} 447 omp.target thread_limit(%c64_i32 : i32) map_entries(%3 -> %arg0 : !fir.ref<!fir.array<512xi32>>) { 448 %c10_i32 = arith.constant 10 : i32 449 %c1_i64 = arith.constant 1 : i64 450 %c1_i64_0 = arith.constant 1 : i64 451 %4 = arith.subi %c1_i64, %c1_i64_0 : i64 452 %5 = fir.coordinate_of %arg0, %4 : (!fir.ref<!fir.array<512xi32>>, i64) -> !fir.ref<i32> 453 fir.store %c10_i32 to %5 : !fir.ref<i32> 454 omp.terminator 455 } 456 return 457} 458 459// CHECK-LABEL: llvm.func @_QPomp_target() { 460// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64 461// CHECK: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<512 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr 462// CHECK: %[[EXTENT:.*]] = llvm.mlir.constant(512 : index) : i64 463// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(64 : i32) : i32 464// CHECK: %[[STRIDE:.*]] = llvm.mlir.constant(1 : index) : i64 465// CHECK: %[[LOWER:.*]] = llvm.mlir.constant(0 : index) : i64 466// CHECK: %[[UPPER:.*]] = llvm.mlir.constant(511 : index) : i64 467// CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[LOWER]] : i64) upper_bound(%[[UPPER]] : i64) extent(%[[EXTENT]] : i64) stride(%[[STRIDE]] : i64) start_idx(%[[STRIDE]] : i64) 468// CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<512 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr {name = "a"} 469// CHECK: omp.target thread_limit(%[[VAL_2]] : i32) map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !llvm.ptr) { 470// CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(10 : i32) : i32 471// CHECK: %[[VAL_4:.*]] = llvm.mlir.constant(1 : i64) : i64 472// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(1 : i64) : i64 473// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(0 : i64) : i64 474// CHECK: %[[VAL_7:.*]] = llvm.getelementptr %[[ARG_0]][0, %[[VAL_6]]] : (!llvm.ptr, i64) -> !llvm.ptr 475// CHECK: llvm.store %[[VAL_3]], %[[VAL_7]] : i32, !llvm.ptr 476// CHECK: omp.terminator 477// CHECK: } 478// CHECK: llvm.return 479// CHECK: } 480 481// ----- 482 483func.func @_QPsimd_with_nested_loop() { 484 %0 = fir.alloca i32 {adapt.valuebyref} 485 %1 = fir.alloca !fir.array<10xi32> {bindc_name = "a", uniq_name = "_QFsimd_with_nested_loopEa"} 486 %2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimd_with_nested_loopEi"} 487 %3 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFsimd_with_nested_loopEj"} 488 %c1_i32 = arith.constant 1 : i32 489 %c10_i32 = arith.constant 10 : i32 490 %c1_i32_0 = arith.constant 1 : i32 491 omp.simd { 492 omp.loop_nest (%arg0) : i32 = (%c1_i32) to (%c10_i32) inclusive step (%c1_i32_0) { 493 fir.store %arg0 to %0 : !fir.ref<i32> 494 %c1_i32_1 = arith.constant 1 : i32 495 %4 = fir.convert %c1_i32_1 : (i32) -> index 496 %c10_i32_2 = arith.constant 10 : i32 497 %5 = fir.convert %c10_i32_2 : (i32) -> index 498 %c1 = arith.constant 1 : index 499 %6 = fir.do_loop %arg1 = %4 to %5 step %c1 -> index { 500 %8 = fir.convert %arg1 : (index) -> i32 501 fir.store %8 to %3 : !fir.ref<i32> 502 %9 = fir.load %0 : !fir.ref<i32> 503 %10 = fir.load %0 : !fir.ref<i32> 504 %11 = fir.convert %10 : (i32) -> i64 505 %c1_i64 = arith.constant 1 : i64 506 %12 = arith.subi %11, %c1_i64 : i64 507 %13 = fir.coordinate_of %1, %12 : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32> 508 fir.store %9 to %13 : !fir.ref<i32> 509 %14 = arith.addi %arg1, %c1 : index 510 fir.result %14 : index 511 } 512 %7 = fir.convert %6 : (index) -> i32 513 fir.store %7 to %3 : !fir.ref<i32> 514 omp.yield 515 } 516 } 517 return 518} 519 520// CHECK-LABEL: llvm.func @_QPsimd_with_nested_loop() { 521// CHECK: %[[LOWER:.*]] = llvm.mlir.constant(1 : i32) : i32 522// CHECK: %[[UPPER:.*]] = llvm.mlir.constant(10 : i32) : i32 523// CHECK: %[[STEP:.*]] = llvm.mlir.constant(1 : i32) : i32 524// CHECK: omp.simd { 525// CHECK-NEXT: omp.loop_nest (%[[CNT:.*]]) : i32 = (%[[LOWER]]) to (%[[UPPER]]) inclusive step (%[[STEP]]) { 526// CHECK: llvm.br ^bb1(%[[VAL_1:.*]], %[[VAL_2:.*]] : i64, i64) 527// CHECK: ^bb1(%[[VAL_3:.*]]: i64, %[[VAL_4:.*]]: i64): 528// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(0 : index) : i64 529// CHECK: %[[VAL_6:.*]] = llvm.icmp "sgt" %[[VAL_4]], %[[VAL_5]] : i64 530// CHECK: llvm.cond_br %[[VAL_6]], ^bb2, ^bb3 531// CHECK: ^bb2: 532// CHECK: llvm.br ^bb1(%[[VAL_7:.*]], %[[VAL_8:.*]] : i64, i64) 533// CHECK: ^bb3: 534// CHECK: omp.yield 535// CHECK: } 536// CHECK: } 537// CHECK: llvm.return 538// CHECK: } 539 540// ----- 541 542func.func @_QPomp_taskgroup() { 543 omp.taskgroup { 544 omp.task { 545 fir.call @_QPwork() : () -> () 546 omp.terminator 547 } 548 omp.terminator 549 } 550 return 551} 552func.func private @_QPwork() 553 554// CHECK-LABEL: llvm.func @_QPomp_taskgroup() { 555// CHECK: omp.taskgroup { 556// CHECK: omp.task { 557// CHECK: llvm.call @_QPwork() : () -> () 558// CHECK: omp.terminator 559// CHECK: } 560// CHECK: omp.terminator 561// CHECK: } 562// CHECK: llvm.return 563// CHECK: } 564// CHECK: llvm.func @_QPwork() attributes {sym_visibility = "private"} 565// CHECK: } 566 567// ----- 568 569 570func.func @_QQmain() { 571 %c0 = arith.constant 0 : index 572 %c5 = arith.constant 5 : index 573 %c1 = arith.constant 1 : index 574 %0 = fir.alloca i32 575 omp.taskgroup { 576 %1 = fir.convert %c1 : (index) -> i32 577 cf.br ^bb1(%1, %c5 : i32, index) 578 ^bb1(%2: i32, %3: index): // 2 preds: ^bb0, ^bb2 579 %4 = arith.cmpi sgt, %3, %c0 : index 580 cf.cond_br %4, ^bb2, ^bb3 581 ^bb2: // pred: ^bb1 582 fir.store %2 to %0 : !fir.ref<i32> 583 omp.task { 584 fir.call @_QFPdo_work(%0) : (!fir.ref<i32>) -> () 585 omp.terminator 586 } 587 %5 = fir.load %0 : !fir.ref<i32> 588 %6 = arith.addi %5, %1 : i32 589 %7 = arith.subi %3, %c1 : index 590 cf.br ^bb1(%6, %7 : i32, index) 591 ^bb3: // pred: ^bb1 592 fir.store %2 to %0 : !fir.ref<i32> 593 omp.terminator 594 } 595 return 596} 597func.func private @_QFPdo_work(!fir.ref<i32>) 598 599// CHECK-LABEL: llvm.func @_QQmain 600// CHECK: omp.taskgroup { 601// CHECK: omp.task { 602// CHECK: llvm.call @_QFPdo_work({{.*}}) : (!llvm.ptr) -> () 603// CHECK: omp.terminator 604// CHECK: } 605// CHECK: omp.terminator 606// CHECK: } 607// CHECK: llvm.return 608// CHECK: } 609// CHECK: llvm.func @_QFPdo_work(!llvm.ptr) 610// CHECK: } 611 612// ----- 613 614func.func @_QPs() { 615 %0 = fir.address_of(@_QFsEc) : !fir.ref<i32> 616 omp.atomic.update %0 : !fir.ref<i32> { 617 ^bb0(%arg0: i32): 618 %c1_i32 = arith.constant 1 : i32 619 %1 = arith.addi %arg0, %c1_i32 : i32 620 omp.yield(%1 : i32) 621 } 622 return 623} 624fir.global internal @_QFsEc : i32 { 625 %c10_i32 = arith.constant 10 : i32 626 fir.has_value %c10_i32 : i32 627} 628 629// CHECK-LABEL: llvm.func @_QPs() { 630// CHECK: %[[GLOBAL_VAR:.*]] = llvm.mlir.addressof @[[GLOBAL:.*]] : !llvm.ptr 631// CHECK: omp.atomic.update %[[GLOBAL_VAR]] : !llvm.ptr { 632// CHECK: ^bb0(%[[IN_VAL:.*]]: i32): 633// CHECK: %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32 634// CHECK: %[[OUT_VAL:.*]] = llvm.add %[[IN_VAL]], %[[CONST_1]] : i32 635// CHECK: omp.yield(%[[OUT_VAL]] : i32) 636// CHECK: } 637// CHECK: llvm.return 638// CHECK: } 639// CHECK: llvm.mlir.global internal @[[GLOBAL]]() {{.*}} : i32 { 640// CHECK: %[[INIT_10:.*]] = llvm.mlir.constant(10 : i32) : i32 641// CHECK: llvm.return %[[INIT_10]] : i32 642// CHECK: } 643 644func.func @_QPsb() { 645 %c10 = arith.constant 10 : index 646 %c1 = arith.constant 1 : index 647 %c1_i32 = arith.constant 1 : i32 648 %c0_i32 = arith.constant 0 : i32 649 %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"} 650 %1 = fir.alloca i32 {bindc_name = "li", uniq_name = "_QFsbEli"} 651 fir.store %c0_i32 to %1 : !fir.ref<i32> 652 omp.sections { 653 omp.section { 654 %2 = fir.convert %c1 : (index) -> i32 655 %3:2 = fir.do_loop %arg0 = %c1 to %c10 step %c1 iter_args(%arg1 = %2) -> (index, i32) { 656 fir.store %arg1 to %0 : !fir.ref<i32> 657 %4 = fir.load %1 : !fir.ref<i32> 658 %5 = arith.addi %4, %c1_i32 : i32 659 fir.store %5 to %1 : !fir.ref<i32> 660 %6 = arith.addi %arg0, %c1 : index 661 %7 = fir.convert %c1 : (index) -> i32 662 %8 = fir.load %0 : !fir.ref<i32> 663 %9 = arith.addi %8, %7 : i32 664 fir.result %6, %9 : index, i32 665 } 666 fir.store %3#1 to %0 : !fir.ref<i32> 667 omp.terminator 668 } 669 omp.terminator 670 } 671 return 672} 673 674// CHECK: llvm.func @_QPsb() { 675// CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i64) : i64 676// CHECK: %[[LI_REF:.*]] = llvm.alloca %[[SIZE]] x i32 {bindc_name = "li"} : (i64) -> !llvm.ptr 677// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i32) : i32 678// CHECK: omp.sections { 679// CHECK: omp.section { 680// CHECK: llvm.br ^[[BB_ENTRY:.*]]({{.*}}) 681// CHECK: ^[[BB_ENTRY]]({{.*}}): 682// CHECK: %[[EXIT_COND:.*]] = llvm.icmp "sgt" 683// CHECK: llvm.cond_br %[[EXIT_COND]], ^[[BB_LOOP_BODY:.*]], ^[[BB_EXIT:.*]] 684// CHECK: ^[[BB_LOOP_BODY]]: 685// CHECK: %[[LI_VAL:.*]] = llvm.load %[[LI_REF]] : !llvm.ptr -> i32 686// CHECK: %[[LI_INC:.*]] = llvm.add %[[LI_VAL]], %[[ONE]] : i32 687// CHECK: llvm.store %[[LI_INC]], %[[LI_REF]] : i32, !llvm.ptr 688// CHECK: llvm.br ^[[BB_ENTRY]]({{.*}}) 689// CHECK: ^[[BB_EXIT]]: 690// CHECK: omp.terminator 691// CHECK: } 692// CHECK: omp.terminator 693// CHECK: } 694// CHECK: llvm.return 695// CHECK: } 696 697// ----- 698 699// CHECK: omp.declare_reduction @[[EQV_REDUCTION:.*]] : i32 init { 700// CHECK: ^bb0(%{{.*}}: i32): 701// CHECK: %[[TRUE:.*]] = llvm.mlir.constant(1 : i64) : i32 702// CHECK: omp.yield(%[[TRUE]] : i32) 703// CHECK: } combiner { 704// CHECK: ^bb0(%[[ARG_1:.*]]: i32, %[[ARG_2:.*]]: i32): 705// CHECK: %[[ZERO_1:.*]] = llvm.mlir.constant(0 : i64) : i32 706// CHECK: %[[ARGVAL_1:.*]] = llvm.icmp "ne" %[[ARG_1]], %[[ZERO_1]] : i32 707// CHECK: %[[ZERO_2:.*]] = llvm.mlir.constant(0 : i64) : i32 708// CHECK: %[[ARGVAL_2:.*]] = llvm.icmp "ne" %[[ARG_2]], %[[ZERO_2]] : i32 709// CHECK: %[[RES:.*]] = llvm.icmp "eq" %[[ARGVAL_1]], %[[ARGVAL_2]] : i1 710// CHECK: %[[RES_EXT:.*]] = llvm.zext %[[RES]] : i1 to i32 711// CHECK: omp.yield(%[[RES_EXT]] : i32) 712// CHECK: } 713// CHECK-LABEL: @_QPsimple_reduction 714// CHECK-SAME: %[[ARRAY_REF:.*]]: !llvm.ptr 715// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(1 : i64) : i64 716// CHECK: %[[RED_ACCUMULATOR:.*]] = llvm.alloca %[[VAL_1]] x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr 717// CHECK: omp.parallel { 718// CHECK: omp.wsloop reduction(@[[EQV_REDUCTION]] %[[RED_ACCUMULATOR]] -> %[[PRV:.+]] : !llvm.ptr) { 719// CHECK-NEXT: omp.loop_nest 720// CHECK: %[[ARRAY_ELEM_REF:.*]] = llvm.getelementptr %[[ARRAY_REF]][0, %{{.*}}] : (!llvm.ptr, i64) -> !llvm.ptr 721// CHECK: %[[ARRAY_ELEM:.*]] = llvm.load %[[ARRAY_ELEM_REF]] : !llvm.ptr -> i32 722// CHECK: %[[LPRV:.+]] = llvm.load %[[PRV]] : !llvm.ptr -> i32 723// CHECK: %[[ZERO_1:.*]] = llvm.mlir.constant(0 : i64) : i32 724// CHECK: %[[ARGVAL_1:.*]] = llvm.icmp "ne" %[[LPRV]], %[[ZERO_1]] : i32 725// CHECK: %[[ZERO_2:.*]] = llvm.mlir.constant(0 : i64) : i32 726// CHECK: %[[ARGVAL_2:.*]] = llvm.icmp "ne" %[[ARRAY_ELEM]], %[[ZERO_2]] : i32 727// CHECK: %[[RES:.*]] = llvm.icmp "eq" %[[ARGVAL_2]], %[[ARGVAL_1]] : i1 728// CHECK: %[[RES_EXT:.*]] = llvm.zext %[[RES]] : i1 to i32 729// CHECK: llvm.store %[[RES_EXT]], %[[PRV]] : i32, !llvm.ptr 730// CHECK: omp.yield 731// CHECK: omp.terminator 732// CHECK: llvm.return 733 734omp.declare_reduction @eqv_reduction : !fir.logical<4> init { 735^bb0(%arg0: !fir.logical<4>): 736 %true = arith.constant true 737 %0 = fir.convert %true : (i1) -> !fir.logical<4> 738 omp.yield(%0 : !fir.logical<4>) 739} combiner { 740^bb0(%arg0: !fir.logical<4>, %arg1: !fir.logical<4>): 741 %0 = fir.convert %arg0 : (!fir.logical<4>) -> i1 742 %1 = fir.convert %arg1 : (!fir.logical<4>) -> i1 743 %2 = arith.cmpi eq, %0, %1 : i1 744 %3 = fir.convert %2 : (i1) -> !fir.logical<4> 745 omp.yield(%3 : !fir.logical<4>) 746} 747func.func @_QPsimple_reduction(%arg0: !fir.ref<!fir.array<100x!fir.logical<4>>> {fir.bindc_name = "y"}) { 748 %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_reductionEi"} 749 %1 = fir.alloca !fir.logical<4> {bindc_name = "x", uniq_name = "_QFsimple_reductionEx"} 750 %true = arith.constant true 751 %2 = fir.convert %true : (i1) -> !fir.logical<4> 752 fir.store %2 to %1 : !fir.ref<!fir.logical<4>> 753 omp.parallel { 754 %3 = fir.alloca i32 {adapt.valuebyref, pinned} 755 %c1_i32 = arith.constant 1 : i32 756 %c100_i32 = arith.constant 100 : i32 757 %c1_i32_0 = arith.constant 1 : i32 758 omp.wsloop reduction(@eqv_reduction %1 -> %prv : !fir.ref<!fir.logical<4>>) { 759 omp.loop_nest (%arg1) : i32 = (%c1_i32) to (%c100_i32) inclusive step (%c1_i32_0) { 760 fir.store %arg1 to %3 : !fir.ref<i32> 761 %4 = fir.load %3 : !fir.ref<i32> 762 %5 = fir.convert %4 : (i32) -> i64 763 %c1_i64 = arith.constant 1 : i64 764 %6 = arith.subi %5, %c1_i64 : i64 765 %7 = fir.coordinate_of %arg0, %6 : (!fir.ref<!fir.array<100x!fir.logical<4>>>, i64) -> !fir.ref<!fir.logical<4>> 766 %8 = fir.load %7 : !fir.ref<!fir.logical<4>> 767 %lprv = fir.load %prv : !fir.ref<!fir.logical<4>> 768 %lprv1 = fir.convert %lprv : (!fir.logical<4>) -> i1 769 %9 = fir.convert %8 : (!fir.logical<4>) -> i1 770 %10 = arith.cmpi eq, %9, %lprv1 : i1 771 %11 = fir.convert %10 : (i1) -> !fir.logical<4> 772 fir.store %11 to %prv : !fir.ref<!fir.logical<4>> 773 omp.yield 774 } 775 } 776 omp.terminator 777 } 778 return 779} 780 781// ----- 782 783// CHECK: llvm.func @_QPs 784// CHECK: omp.atomic.read %{{.*}} = %{{.*}} : !llvm.ptr, !llvm.ptr, !llvm.struct<(f32, f32)> 785 786func.func @_QPs(%arg0: !fir.ref<complex<f32>> {fir.bindc_name = "x"}) { 787 %0 = fir.alloca complex<f32> {bindc_name = "v", uniq_name = "_QFsEv"} 788 omp.atomic.read %0 = %arg0 : !fir.ref<complex<f32>>, !fir.ref<complex<f32>>, complex<f32> 789 return 790} 791 792// ----- 793 794// Test if llvm.alloca is properly inserted in the omp section 795 796//CHECK: %[[CONST0:.*]] = llvm.mlir.constant(1 : i64) : i64 797//CHECK: %[[CONST:.*]] = llvm.mlir.constant(1 : i64) : i64 798//CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[CONST]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> {bindc_name = "iattr"} : (i64) -> !llvm.ptr 799//CHECK: omp.parallel { 800//CHECK: %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32 801//CHECK: %[[ALLOCA_1:.*]] = llvm.alloca %[[CONST_1:.*]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> {alignment = 8 : i64} : (i32) -> !llvm.ptr 802//CHECK: %[[SIZE:.*]] = llvm.mlir.constant(24 : i32) : i32 803//CHECK: "llvm.intr.memcpy"(%[[ALLOCA_1]], %[[ALLOCA]], %[[SIZE]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () 804//CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ALLOCA_1]][0, 0] : (!llvm.ptr) -> !llvm.ptr 805//CHECK: %[[LOAD_2:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> !llvm.ptr 806//CHECK: omp.terminator 807//CHECK: } 808 809func.func @_QQmain() attributes {fir.bindc_name = "mn"} { 810 %0 = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = "iattr", uniq_name = "_QFEiattr"} 811 %1 = fir.zero_bits !fir.ptr<i32> 812 %2 = fir.embox %1 : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>> 813 fir.store %2 to %0 : !fir.ref<!fir.box<!fir.ptr<i32>>> 814 %3 = fir.address_of(@_QFEx) : !fir.ref<i32> 815 %4 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"} 816 %5 = fir.embox %3 : (!fir.ref<i32>) -> !fir.box<!fir.ptr<i32>> 817 fir.store %5 to %0 : !fir.ref<!fir.box<!fir.ptr<i32>>> 818 omp.parallel { 819 %6 = fir.load %4 : !fir.ref<i32> 820 %7 = fir.load %0 : !fir.ref<!fir.box<!fir.ptr<i32>>> 821 %8 = fir.box_addr %7 : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32> 822 fir.store %6 to %8 : !fir.ptr<i32> 823 omp.terminator 824 } 825 return 826} 827fir.global internal @_QFEx target : i32 { 828 %0 = fir.zero_bits i32 829 fir.has_value %0 : i32 830} 831 832// ----- 833 834// Test if llvm.alloca is properly inserted in the omp ordered region 835 836// CHECK: llvm.func @sub_ 837func.func @sub_() { 838 %c0 = arith.constant 0 : index 839 %c1 = arith.constant 1 : index 840 %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsubEi"} 841// CHECK: omp.ordered.region 842 omp.ordered.region { 843 %1 = fir.convert %c1 : (index) -> i32 844 cf.br ^bb1(%1, %c1 : i32, index) 845 ^bb1(%2: i32, %3: index): // 2 preds: ^bb0, ^bb2 846 %4 = arith.cmpi sgt, %3, %c0 : index 847 cf.cond_br %4, ^bb2, ^bb3 848 ^bb2: // pred: ^bb1 849 fir.store %2 to %0 : !fir.ref<i32> 850 %5 = fir.load %0 : !fir.ref<i32> 851// CHECK: llvm.add 852 %6 = arith.addi %5, %1 : i32 853// CHECK: llvm.sub 854 %7 = arith.subi %3, %c1 : index 855 cf.br ^bb1(%6, %7 : i32, index) 856 ^bb3: // pred: ^bb1 857 fir.store %2 to %0 : !fir.ref<i32> 858// CHECK: omp.terminator 859 omp.terminator 860 } 861 return 862} 863 864// ----- 865 866// CHECK-LABEL: llvm.func @flush_standalone_ 867// CHECK-SAME: %[[ARG_A:.*]]: !llvm.ptr {fir.bindc_name = "a"}, %[[ARG_B:.*]]: !llvm.ptr {fir.bindc_name = "b"}, %[[ARG_C:.*]]: !llvm.ptr {fir.bindc_name = "c"}) 868 func.func @flush_standalone_(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "b"}, %arg2: !fir.ref<i32> {fir.bindc_name = "c"}) { 869// CHECK: omp.flush(%[[ARG_A]], %[[ARG_B]], %[[ARG_C]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) 870 omp.flush(%arg0, %arg1, %arg2 : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>) 871// CHECK: omp.flush 872 omp.flush 873 return 874 } 875 876// CHECK-LABEL: llvm.func @flush_parallel_ 877// CHECK-SAME: %[[ARG_A:.*]]: !llvm.ptr {fir.bindc_name = "a"}, %[[ARG_B:.*]]: !llvm.ptr {fir.bindc_name = "b"}, %[[ARG_C:.*]]: !llvm.ptr {fir.bindc_name = "c"}) 878 func.func @flush_parallel_(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "b"}, %arg2: !fir.ref<i32> {fir.bindc_name = "c"}) { 879// CHECK: omp.parallel { 880 omp.parallel { 881// CHECK: omp.flush(%[[ARG_A]], %[[ARG_B]], %[[ARG_C]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) 882 omp.flush(%arg0, %arg1, %arg2 : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>) 883// CHECK: omp.flush 884 omp.flush 885// CHECK: %[[A_VAL:.*]] = llvm.load %[[ARG_A]] : !llvm.ptr -> i32 886 %0 = fir.load %arg0 : !fir.ref<i32> 887// CHECK: %[[B_VAL:.*]] = llvm.load %[[ARG_B]] : !llvm.ptr -> i32 888 %1 = fir.load %arg1 : !fir.ref<i32> 889// CHECK: %[[C_VAL:.*]] = llvm.add %[[A_VAL]], %[[B_VAL]] : i32 890 %2 = arith.addi %0, %1 : i32 891// CHECK: llvm.store %[[C_VAL]], %[[ARG_C]] : i32, !llvm.ptr 892 fir.store %2 to %arg2 : !fir.ref<i32> 893// CHECK: omp.terminator 894 omp.terminator 895// CHECK: } 896 } 897 return 898 } 899 900// ----- 901 902// CHECK: omp.critical.declare @help hint(contended) 903omp.critical.declare @help hint(contended) 904 905// CHECK: llvm.func @omp_critical_() { 906func.func @omp_critical_() { 907// CHECK: %[[Y_REF:.*]] = llvm.alloca %{{.*}} x i32 {bindc_name = "y"} : (i64) -> !llvm.ptr 908 %0 = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_criticalEx"} 909// CHECK: %[[X_REF:.*]] = llvm.alloca %{{.*}} x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr 910 %1 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFomp_criticalEy"} 911// CHECK: omp.critical(@help) 912 omp.critical(@help) { 913// CHECK: %[[X_VAL:.*]] = llvm.load %[[X_REF]] : !llvm.ptr -> i32 914 %2 = fir.load %0 : !fir.ref<i32> 915// CHECK: %[[Y_VAL:.*]] = llvm.load %[[Y_REF]] : !llvm.ptr -> i32 916 %3 = fir.load %1 : !fir.ref<i32> 917// CHECK: %[[RESULT:.*]] = llvm.add %[[X_VAL]], %[[Y_VAL]] : i32 918 %4 = arith.addi %2, %3 : i32 919// CHECK: llvm.store %[[RESULT]], %[[X_REF]] : i32, !llvm.ptr 920 fir.store %4 to %0 : !fir.ref<i32> 921// CHECK: omp.terminator 922 omp.terminator 923 } 924 return 925} 926 927// ----- 928 929// CHECK-LABEL: llvm.func @omp_map_info_descriptor_type_conversion 930// CHECK-SAME: %[[ARG_0:.*]]: !llvm.ptr) 931 932func.func @omp_map_info_descriptor_type_conversion(%arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>) { 933 // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> 934 %0 = fir.box_offset %arg0 base_addr : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> !fir.llvm_ptr<!fir.ref<i32>> 935 // CHECK: %[[MEMBER_MAP:.*]] = omp.map.info var_ptr(%[[GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} 936 %1 = omp.map.info var_ptr(%0 : !fir.llvm_ptr<!fir.ref<i32>>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} 937 // CHECK: %[[DESC_MAP:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(always, delete) capture(ByRef) members(%[[MEMBER_MAP]] : [0] : !llvm.ptr) -> !llvm.ptr {name = ""} 938 %2 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(always, delete) capture(ByRef) members(%1 : [0] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.heap<i32>>> {name = ""} 939 // CHECK: omp.target_exit_data map_entries(%[[DESC_MAP]] : !llvm.ptr) 940 omp.target_exit_data map_entries(%2 : !fir.ref<!fir.box<!fir.heap<i32>>>) 941 return 942} 943 944// ----- 945 946// CHECK-LABEL: llvm.func @omp_map_info_derived_type_explicit_member_conversion 947// CHECK-SAME: %[[ARG_0:.*]]: !llvm.ptr) 948 949func.func @omp_map_info_derived_type_explicit_member_conversion(%arg0 : !fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>) { 950 // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFderived_type", (f32, array<10 x i32>, i32)> 951 %0 = fir.field_index int, !fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}> 952 %1 = fir.coordinate_of %arg0, %0 : (!fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>, !fir.field) -> !fir.ref<i32> 953 // CHECK: %[[MAP_MEMBER_1:.*]] = omp.map.info var_ptr(%[[GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "dtype%int"} 954 %2 = omp.map.info var_ptr(%1 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "dtype%int"} 955 // CHECK: %[[GEP_2:.*]] = llvm.getelementptr %[[ARG_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFderived_type", (f32, array<10 x i32>, i32)> 956 %3 = fir.field_index real, !fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}> 957 %4 = fir.coordinate_of %arg0, %3 : (!fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>, !fir.field) -> !fir.ref<f32> 958 // CHECK: %[[MAP_MEMBER_2:.*]] = omp.map.info var_ptr(%[[GEP_2]] : !llvm.ptr, f32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "dtype%real"} 959 %5 = omp.map.info var_ptr(%4 : !fir.ref<f32>, f32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<f32> {name = "dtype%real"} 960 // CHECK: %[[MAP_PARENT:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.struct<"_QFderived_type", (f32, array<10 x i32>, i32)>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBER_1]], %[[MAP_MEMBER_2]] : [2], [0] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {name = "dtype", partial_map = true} 961 %6 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>, !fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>) map_clauses(tofrom) capture(ByRef) members(%2, %5 : [2], [0] : !fir.ref<i32>, !fir.ref<f32>) -> !fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>> {name = "dtype", partial_map = true} 962 // CHECK: omp.target map_entries(%[[MAP_MEMBER_1]] -> %[[ARG_1:.*]], %[[MAP_MEMBER_2]] -> %[[ARG_2:.*]], %[[MAP_PARENT]] -> %[[ARG_3:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) { 963 omp.target map_entries(%2 -> %arg1, %5 -> %arg2, %6 -> %arg3 : !fir.ref<i32>, !fir.ref<f32>, !fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>) { 964 omp.terminator 965 } 966 return 967} 968 969// ----- 970 971// CHECK-LABEL: llvm.func @omp_map_info_nested_derived_type_explicit_member_conversion 972// CHECK-SAME: %[[ARG_0:.*]]: !llvm.ptr) 973 974func.func @omp_map_info_nested_derived_type_explicit_member_conversion(%arg0 : !fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>) { 975 // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFTtop_layer", (array<10 x i32>, struct<"_QFTbottom_layer", (array<10 x f32>, f64)>, i32)> 976 %0 = fir.field_index nested, !fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}> 977 %1 = fir.coordinate_of %arg0, %0 : (!fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>, !fir.field) -> !fir.ref<!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>> 978 // CHECK: %[[GEP_2:.*]] = llvm.getelementptr %[[GEP]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFTbottom_layer", (array<10 x f32>, f64)> 979 %2 = fir.field_index i2, !fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}> 980 %3 = fir.coordinate_of %1, %2 : (!fir.ref<!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>>, !fir.field) -> !fir.ref<f64> 981 // CHECK: %[[MAP_MEMBER_1:.*]] = omp.map.info var_ptr(%[[GEP_2]] : !llvm.ptr, f64) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 982 %4 = omp.map.info var_ptr(%3 : !fir.ref<f64>, f64) map_clauses(tofrom) capture(ByRef) -> !fir.ref<f64> 983 // CHECK: %[[GEP_3:.*]] = llvm.getelementptr %[[ARG_0]][0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFTtop_layer", (array<10 x i32>, struct<"_QFTbottom_layer", (array<10 x f32>, f64)>, i32)> 984 %5 = fir.field_index k, !fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}> 985 %6 = fir.coordinate_of %arg0, %5 : (!fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>, !fir.field) -> !fir.ref<i32> 986 // CHECK: %[[MAP_MEMBER_2:.*]] = omp.map.info var_ptr(%[[GEP_3]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 987 %7 = omp.map.info var_ptr(%6 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> 988 // CHECK: %[[PARENT_MAP:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.struct<"_QFTtop_layer", (array<10 x i32>, struct<"_QFTbottom_layer", (array<10 x f32>, f64)>, i32)>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBER_1]], %[[MAP_MEMBER_2]] : [1, 1], [2] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {partial_map = true} 989 %9 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>, !fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>) map_clauses(tofrom) capture(ByRef) members(%4, %7 : [1,1], [2] : !fir.ref<f64>, !fir.ref<i32>) -> !fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>> {partial_map = true} 990 // CHECK: omp.target map_entries(%[[MAP_MEMBER_1]] -> %{{.*}}, %[[MAP_MEMBER_2]] -> %{{.*}}, %[[PARENT_MAP]] -> %{{.*}} : !llvm.ptr, !llvm.ptr, !llvm.ptr) { 991 omp.target map_entries(%4 -> %arg1, %7 -> %arg2, %9 -> %arg3 : !fir.ref<f64>, !fir.ref<i32>, !fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>) { 992 omp.terminator 993 } 994 return 995} 996 997// ----- 998 999// CHECK-LABEL: llvm.func @omp_map_common_block_using_common_block_symbol 1000 1001// CHECK: %[[ADDR_OF:.*]] = llvm.mlir.addressof @var_common_ : !llvm.ptr 1002// CHECK: %[[CB_MAP:.*]] = omp.map.info var_ptr(%[[ADDR_OF]] : !llvm.ptr, !llvm.array<8 x i8>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "var_common"} 1003// CHECK: omp.target map_entries(%[[CB_MAP]] -> %[[ARG0:.*]] : !llvm.ptr) { 1004// CHECK: %[[VAR_2_OFFSET:.*]] = llvm.mlir.constant(4 : index) : i64 1005// CHECK: %[[VAR_1_OFFSET:.*]] = llvm.mlir.constant(0 : index) : i64 1006// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[VAR_1_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8 1007// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[VAR_2_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8 1008 1009func.func @omp_map_common_block_using_common_block_symbol() { 1010 %0 = fir.address_of(@var_common_) : !fir.ref<!fir.array<8xi8>> 1011 %1 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<8xi8>>, !fir.array<8xi8>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.array<8xi8>> {name = "var_common"} 1012 omp.target map_entries(%1 -> %arg0 : !fir.ref<!fir.array<8xi8>>) { 1013 %c4 = arith.constant 4 : index 1014 %c0 = arith.constant 0 : index 1015 %c20_i32 = arith.constant 20 : i32 1016 %2 = fir.convert %arg0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>> 1017 %3 = fir.coordinate_of %2, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8> 1018 %4 = fir.convert %3 : (!fir.ref<i8>) -> !fir.ref<i32> 1019 %5 = fir.convert %arg0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>> 1020 %6 = fir.coordinate_of %5, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8> 1021 %7 = fir.convert %6 : (!fir.ref<i8>) -> !fir.ref<i32> 1022 %8 = fir.load %4 : !fir.ref<i32> 1023 %9 = arith.addi %8, %c20_i32 : i32 1024 fir.store %9 to %7 : !fir.ref<i32> 1025 omp.terminator 1026 } 1027 return 1028} 1029 1030fir.global common @var_common_(dense<0> : vector<8xi8>) {alignment = 4 : i64} : !fir.array<8xi8> 1031 1032// ----- 1033 1034// CHECK-LABEL: llvm.func @omp_map_common_block_using_common_block_members 1035 1036// CHECK: %[[VAR_2_OFFSET:.*]] = llvm.mlir.constant(4 : index) : i64 1037// CHECK: %[[VAR_1_OFFSET:.*]] = llvm.mlir.constant(0 : index) : i64 1038// CHECK: %[[ADDR_OF:.*]] = llvm.mlir.addressof @var_common_ : !llvm.ptr 1039// CHECK: %[[VAR_1_CB_GEP:.*]] = llvm.getelementptr %[[ADDR_OF]][%[[VAR_1_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8 1040// CHECK: %[[VAR_2_CB_GEP:.*]] = llvm.getelementptr %[[ADDR_OF]][%[[VAR_2_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8 1041// CHECK: %[[MAP_CB_VAR_1:.*]] = omp.map.info var_ptr(%[[VAR_1_CB_GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "var1"} 1042// CHECK: %[[MAP_CB_VAR_2:.*]] = omp.map.info var_ptr(%[[VAR_2_CB_GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "var2"} 1043// CHECK: omp.target map_entries(%[[MAP_CB_VAR_1]] -> %[[ARG0:.*]], %[[MAP_CB_VAR_2]] -> %[[ARG1:.*]] : !llvm.ptr, !llvm.ptr) { 1044 1045func.func @omp_map_common_block_using_common_block_members() { 1046 %c4 = arith.constant 4 : index 1047 %c0 = arith.constant 0 : index 1048 %0 = fir.address_of(@var_common_) : !fir.ref<!fir.array<8xi8>> 1049 %1 = fir.convert %0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>> 1050 %2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8> 1051 %3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<i32> 1052 %4 = fir.convert %0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>> 1053 %5 = fir.coordinate_of %4, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8> 1054 %6 = fir.convert %5 : (!fir.ref<i8>) -> !fir.ref<i32> 1055 %7 = omp.map.info var_ptr(%3 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "var1"} 1056 %8 = omp.map.info var_ptr(%6 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "var2"} 1057 omp.target map_entries(%7 -> %arg0, %8 -> %arg1 : !fir.ref<i32>, !fir.ref<i32>) { 1058 %c10_i32 = arith.constant 10 : i32 1059 %9 = fir.load %arg0 : !fir.ref<i32> 1060 %10 = arith.muli %9, %c10_i32 : i32 1061 fir.store %10 to %arg1 : !fir.ref<i32> 1062 omp.terminator 1063 } 1064 return 1065} 1066 1067fir.global common @var_common_(dense<0> : vector<8xi8>) {alignment = 4 : i64} : !fir.array<8xi8> 1068 1069// ----- 1070 1071 1072func.func @use_string(%arg0 : !fir.ref<!fir.char<1,?>>) { 1073 return 1074} 1075 1076func.func @use_index(%arg0 : index) { 1077 return 1078} 1079 1080// CHECK-LABEL: llvm.func @alloca_hoisting_openmp() { 1081// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(6 : index) : i64 1082// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(1 : i32) : i32 1083// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(42 : i32) : i32 1084// CHECK: omp.parallel { 1085// CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(6 : index) : i64 1086// CHECK: %[[VAL_4:.*]] = llvm.alloca %[[VAL_3]] x i8 : (i64) -> !llvm.ptr 1087// CHECK: omp.wsloop { 1088// CHECK: omp.loop_nest (%[[VAL_5:.*]]) : i32 = (%[[VAL_1]]) to (%[[VAL_2]]) inclusive step (%[[VAL_1]]) { 1089// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(1 : i64) : i64 1090// CHECK: llvm.call @use_string(%[[VAL_4]]) : (!llvm.ptr) -> () 1091// CHECK: omp.yield 1092// CHECK: } 1093// CHECK: } 1094// CHECK: omp.terminator 1095// CHECK: } 1096// CHECK: llvm.call @use_index(%[[VAL_0]]) : (i64) -> () 1097// CHECK: llvm.return 1098// CHECK: } 1099func.func @alloca_hoisting_openmp() { 1100 %c6 = arith.constant 6 : index 1101 %c1_i32 = arith.constant 1 : i32 1102 %c42_i32 = arith.constant 42 : i32 1103 omp.parallel { 1104 omp.wsloop { 1105 omp.loop_nest (%arg0) : i32 = (%c1_i32) to (%c42_i32) inclusive step (%c1_i32) { 1106 %0 = fir.alloca !fir.char<1,?>(%c6 : index) 1107 fir.call @use_string(%0) : (!fir.ref<!fir.char<1,?>>) -> () 1108 omp.yield 1109 } 1110 } 1111 omp.terminator 1112 } 1113 fir.call @use_index(%c6) : (index) -> () 1114 return 1115} 1116 1117// ----- 1118 1119// NOTE: This test (and the other allocatable member map tests below) uses mock 1120// bounds to simplify the example, the real bounds generation is more complex 1121// as it has to access the box information. However, it's not what the test 1122// aims to check. The test aims to check the parent member bindings and 1123// acceses are appropriately maintained when lowering to the LLVM dialect. 1124 1125// CHECK-LABEL: llvm.func @map_dtype_alloca_mem 1126// CHECK-SAME: %[[ARG_0:.*]]: !llvm.ptr) 1127func.func @map_dtype_alloca_mem(%arg0 : !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>) { 1128 %c4 = arith.constant 4 : index 1129 %c1 = arith.constant 1 : index 1130 %c0 = arith.constant 0 : index 1131 // CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) {stride_in_bytes = true} 1132 %0 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c4 : index) extent(%c4 : index) stride(%c1 : index) start_idx(%c0 : index) {stride_in_bytes = true} 1133 // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 4] : (!llvm.ptr) -> !llvm.ptr, [[STRUCT_TY:!llvm.struct<"_QFRecTy", \(f32, struct<\(ptr, i64, i32, i8, i8, i8, i8\)>, array<10 x i32>, f32, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>]] 1134 %1 = fir.coordinate_of %arg0, %c4 : (!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> 1135 // CHECK: %[[BADDR_GEP:.*]] = llvm.getelementptr %[[GEP]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[STRUCT_TY2:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>]] 1136 %2 = fir.box_offset %1 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> 1137 // CHECK: %[[MAP_MEMBER_BADDR:.*]] = omp.map.info var_ptr(%[[GEP]] : !llvm.ptr, i32) var_ptr_ptr(%[[BADDR_GEP]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr 1138 %3 = omp.map.info var_ptr(%1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%2 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%0) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> 1139 // CHECK: %[[MAP_MEMBER_DESCRIPTOR:.*]] = omp.map.info var_ptr(%[[GEP]] : !llvm.ptr, [[STRUCT_TY2]]) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 1140 %4 = omp.map.info var_ptr(%1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> 1141 // CHECK: %[[MAP_PARENT_DTYPE:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[STRUCT_TY]]) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBER_DESCRIPTOR]], %[[MAP_MEMBER_BADDR]] : [4], [4, 0] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {partial_map = true} 1142 %5 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, !fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>) map_clauses(tofrom) capture(ByRef) members(%4, %3 : [4], [4,0] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>> {partial_map = true} 1143 // CHECK: omp.target map_entries(%[[MAP_MEMBER_DESCRIPTOR]] -> %[[ARG_1:.*]], %[[MAP_MEMBER_BADDR]] -> %[[ARG_2:.*]], %[[MAP_PARENT_DTYPE]] -> %[[ARG_3:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) { 1144 omp.target map_entries(%4 -> %arg1, %3 -> %arg2, %5 -> %arg3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>) { 1145 omp.terminator 1146 } 1147 return 1148} 1149 1150// ----- 1151 1152// CHECK-LABEL: llvm.func @map_dtype_alloca_mem2 1153// CHECK-SAME: %[[ARG_0:.*]]: !llvm.ptr) 1154func.func @map_dtype_alloca_mem2(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>) { 1155 // CHECK: %[[DTYPE_ALLOCATABLE_ALOCA_2:.*]] = llvm.alloca {{.*}} x [[DESC_TY:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, ptr, array<1 x i64>\)>]] {alignment = 8 : i64} : (i32) -> !llvm.ptr 1156 // CHECK: %[[DTYPE_ALLOCATABLE_ALOCA:.*]] = llvm.alloca {{.*}} x [[DESC_TY]] {alignment = 8 : i64} : (i32) -> !llvm.ptr 1157 %c5 = arith.constant 5 : index 1158 %c4 = arith.constant 4 : index 1159 %c1 = arith.constant 1 : index 1160 %c0 = arith.constant 0 : index 1161 // CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) {stride_in_bytes = true} 1162 %0 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c4 : index) extent(%c4 : index) stride(%c1 : index) start_idx(%c0 : index) {stride_in_bytes = true} 1163 // CHECK: "llvm.intr.memcpy"(%[[DTYPE_ALLOCATABLE_ALOCA]], %[[ARG_0]], {{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () 1164 %1 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>> 1165 // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[DTYPE_ALLOCATABLE_ALOCA]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]] 1166 // CHECK: %[[LOAD_DTYPE_BADDR:.*]] = llvm.load %[[GEP_DTYPE_BADDR]] : !llvm.ptr -> !llvm.ptr 1167 // CHECK: %[[GEP_DTYPE_MEMBER:.*]] = llvm.getelementptr %[[LOAD_DTYPE_BADDR]][0, 4] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY:!llvm.struct<"_QFRecTy", \(f32, struct<\(ptr, i64, i32, i8, i8, i8, i8\)>, array<10 x i32>, f32, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>]] 1168 %2 = fir.coordinate_of %1, %c4 : (!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> 1169 // CHECK: %[[DTYPE_MEMBER_BADDR:.*]] = llvm.getelementptr %[[GEP_DTYPE_MEMBER]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY2:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>]] 1170 %3 = fir.box_offset %2 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> 1171 // CHECK: %[[MAP_MEMBER_BADDR:.*]] = omp.map.info var_ptr(%[[GEP_DTYPE_MEMBER]] : !llvm.ptr, i32) var_ptr_ptr(%[[DTYPE_MEMBER_BADDR]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr 1172 %4 = omp.map.info var_ptr(%2 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%3 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%0) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> 1173 // CHECK: %[[MAP_MEMBER_DESC:.*]] = omp.map.info var_ptr(%[[GEP_DTYPE_MEMBER]] : !llvm.ptr, [[DESC_TY2]]) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 1174 %5 = omp.map.info var_ptr(%2 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> 1175 // CHECK: "llvm.intr.memcpy"(%[[DTYPE_ALLOCATABLE_ALOCA_2]], %[[ARG_0]], {{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () 1176 %6 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>> 1177 // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[DTYPE_ALLOCATABLE_ALOCA_2]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]] 1178 // CHECK: %[[LOAD_DTYPE_BADDR:.*]] = llvm.load %[[GEP_DTYPE_BADDR]] : !llvm.ptr -> !llvm.ptr 1179 // CHECK: %[[GEP_DTYPE_REGULAR_MEMBER:.*]] = llvm.getelementptr %[[LOAD_DTYPE_BADDR]][0, 5] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY]] 1180 %7 = fir.coordinate_of %6, %c5 : (!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>, index) -> !fir.ref<i32> 1181 // CHECK: %[[MAP_REGULAR_MEMBER:.*]] = omp.map.info var_ptr(%[[GEP_DTYPE_REGULAR_MEMBER]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 1182 %8 = omp.map.info var_ptr(%7 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> 1183 // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[ARG_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]] 1184 %9 = fir.box_offset %arg0 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>> 1185 // CHECK: %[[MAP_DTYPE_PARENT_BADDR:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[REC_TY]]) var_ptr_ptr(%[[GEP_DTYPE_BADDR]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 1186 %10 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>, !fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>) var_ptr_ptr(%9 : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>> 1187 // CHECK: %[[MAP_DTYPE_PARENT_DESC:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[DESC_TY]]) map_clauses(tofrom) capture(ByRef) members(%[[MAP_DTYPE_PARENT_BADDR]], %[[MAP_MEMBER_DESC]], %[[MAP_MEMBER_BADDR]], %[[MAP_REGULAR_MEMBER]] : [0], [0, 4], [0, 4, 0], [0, 5] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> !llvm.ptr 1188 %11 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>, !fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>) map_clauses(tofrom) capture(ByRef) members(%10, %5, %4, %8 : [0], [0,4], [0,4,0], [0,5] : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<i32>) -> !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>> 1189 // CHECK: omp.target map_entries(%[[MAP_DTYPE_PARENT_BADDR]] -> %[[ARG_1:.*]], %[[MAP_MEMBER_DESC]] -> %[[ARG_2:.*]], %[[MAP_MEMBER_BADDR]] -> %[[ARG_3:.*]], %[[MAP_REGULAR_MEMBER]] -> %[[ARG_4:.*]], %[[MAP_DTYPE_PARENT_DESC]] -> %[[ARG_5:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) { 1190 omp.target map_entries(%10 -> %arg1, %5 -> %arg2, %4 -> %arg3, %8 -> %arg4, %11 -> %arg5 : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<i32>, !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>) { 1191 omp.terminator 1192 } 1193 return 1194} 1195 1196// ----- 1197 1198// CHECK-LABEL: llvm.func @map_nested_dtype_alloca_mem 1199// CHECK-SAME: %[[ARG_0:.*]]: !llvm.ptr) 1200func.func @map_nested_dtype_alloca_mem(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>) { 1201 // CHECK: %[[DTYPE_ALLOCATABLE_ALOCA_2:.*]] = llvm.alloca {{.*}} x [[DESC_TY:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, ptr, array<1 x i64>\)>]] {alignment = 8 : i64} : (i32) -> !llvm.ptr 1202 // CHECK: %[[DTYPE_ALLOCATABLE_ALOCA:.*]] = llvm.alloca {{.*}} x [[DESC_TY]] {alignment = 8 : i64} : (i32) -> !llvm.ptr 1203 %c3 = arith.constant 3 : index 1204 %c4 = arith.constant 4 : index 1205 %c6 = arith.constant 6 : index 1206 %c1 = arith.constant 1 : index 1207 %c2 = arith.constant 2 : index 1208 %c0 = arith.constant 0 : index 1209 // CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) {stride_in_bytes = true} 1210 %0 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c4 : index) extent(%c4 : index) stride(%c1 : index) start_idx(%c0 : index) {stride_in_bytes = true} 1211 // CHECK: "llvm.intr.memcpy"(%[[DTYPE_ALLOCATABLE_ALOCA]], %[[ARG_0]], {{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () 1212 %1 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>> 1213 // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[DTYPE_ALLOCATABLE_ALOCA]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]] 1214 // CHECK: %[[LOAD_GEP_DTYPE_BADDR:.*]] = llvm.load %[[GEP_DTYPE_BADDR]] : !llvm.ptr -> !llvm.ptr 1215 // CHECK: %[[LOAD_NESTED_DTYPE:.*]] = llvm.getelementptr %[[LOAD_GEP_DTYPE_BADDR]][0, 6] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY:!llvm.struct<"_QFRecTy", \(f32, struct<\(ptr, i64, i32, i8, i8, i8, i8\)>, array<10 x i32>, f32, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32, struct<"_QFRecTy2", \(f32, array<10 x i32>, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>\)>]] 1216 %2 = fir.coordinate_of %1, %c6 : (!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>, index) -> !fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>> 1217 // CHECK: %[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER:.*]] = llvm.getelementptr %[[LOAD_NESTED_DTYPE]][0, 2] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY2:!llvm.struct<"_QFRecTy2", \(f32, array<10 x i32>, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>]] 1218 %3 = fir.coordinate_of %2, %c2 : (!fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> 1219 // CHECK: %[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER_BADDR:.*]] = llvm.getelementptr %[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY2:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>]] 1220 %4 = fir.box_offset %3 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> 1221 // CHECK: %[[MAP_NESTED_MEMBER_BADDR:.*]] = omp.map.info var_ptr(%[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER]] : !llvm.ptr, i32) var_ptr_ptr(%[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER_BADDR]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr 1222 %5 = omp.map.info var_ptr(%3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%4 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%0) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> 1223 // CHECK: %[[MAP_NESTED_MEMBER_DESC:.*]] = omp.map.info var_ptr(%[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER]] : !llvm.ptr, [[DESC_TY2]]) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 1224 %6 = omp.map.info var_ptr(%3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> 1225 // CHECK: "llvm.intr.memcpy"(%[[DTYPE_ALLOCATABLE_ALOCA_2]], %[[ARG_0]], {{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () 1226 // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[DTYPE_ALLOCATABLE_ALOCA_2]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]] 1227 // CHECK: %[[LOAD_GEP_DTYPE_BADDR:.*]] = llvm.load %[[GEP_DTYPE_BADDR]] : !llvm.ptr -> !llvm.ptr 1228 %7 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>> 1229 // CHECK: %[[LOAD_NESTED_DTYPE:.*]] = llvm.getelementptr %[[LOAD_GEP_DTYPE_BADDR]][0, 6] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY]] 1230 %8 = fir.coordinate_of %7, %c6 : (!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>, index) -> !fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>> 1231 // CHECK: %[[NESTED_DTYPE_REGULAR_MEMBER_GEP:.*]] = llvm.getelementptr %[[LOAD_NESTED_DTYPE]][0, 3] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY2]] 1232 %9 = fir.coordinate_of %8, %c3 : (!fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, index) -> !fir.ref<i32> 1233 // CHECK: %[[MAP_REGULAR_NESTED_MEMBER:.*]] = omp.map.info var_ptr(%[[NESTED_DTYPE_REGULAR_MEMBER_GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 1234 %10 = omp.map.info var_ptr(%9 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> 1235 // CHECK: %[[DTYPE_BADDR_GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]] 1236 %11 = fir.box_offset %arg0 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>> 1237 // CHECK: %[[MAP_PARENT_BADDR:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[REC_TY]]) var_ptr_ptr(%[[DTYPE_BADDR_GEP]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 1238 %12 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>, !fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>) var_ptr_ptr(%11 : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>> 1239 // CHECK: %[[MAP_PARENT_DESC:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[DESC_TY]]) map_clauses(tofrom) capture(ByRef) members(%[[MAP_PARENT_BADDR]], %[[MAP_NESTED_MEMBER_DESC]], %[[MAP_NESTED_MEMBER_BADDR]], %[[MAP_REGULAR_NESTED_MEMBER]] : [0], [0, 6, 2], [0, 6, 2, 0], [0, 6, 3] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> !llvm.ptr 1240 %13 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>, !fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>) map_clauses(tofrom) capture(ByRef) members(%12, %6, %5, %10 : [0], [0,6,2], [0,6,2,0], [0,6,3] : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<i32>) -> !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>> 1241 // CHECK: omp.target map_entries(%[[MAP_PARENT_BADDR]] -> %[[ARG_1:.*]], %[[MAP_NESTED_MEMBER_DESC]] -> %[[ARG_2:.*]], %[[MAP_NESTED_MEMBER_BADDR]] -> %[[ARG_3:.*]], %[[MAP_REGULAR_NESTED_MEMBER]] -> %[[ARG_4:.*]], %[[MAP_PARENT_DESC]] -> %[[ARG_5:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) { 1242 omp.target map_entries(%12 -> %arg1, %6 -> %arg2, %5 -> %arg3, %10 -> %arg4, %13 -> %arg5 : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<i32>, !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>) { 1243 omp.terminator 1244 } 1245 return 1246} 1247 1248// ----- 1249 1250// CHECK-LABEL: llvm.func @map_nested_dtype_alloca_mem2 1251// CHECK-SAME: %[[ARG_0:.*]]: !llvm.ptr) 1252func.func @map_nested_dtype_alloca_mem2(%arg0 : !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>) { 1253 %c4 = arith.constant 4 : index 1254 %c1 = arith.constant 1 : index 1255 %c2 = arith.constant 2 : index 1256 %c0 = arith.constant 0 : index 1257 %c6 = arith.constant 6 : index 1258 // CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) {stride_in_bytes = true} 1259 %0 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c4 : index) extent(%c4 : index) stride(%c1 : index) start_idx(%c0 : index) {stride_in_bytes = true} 1260 // CHECK: %[[NESTED_DTYPE_MEMBER_GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 6] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY:!llvm.struct<"_QFRecTy", \(f32, struct<\(ptr, i64, i32, i8, i8, i8, i8\)>, array<10 x i32>, f32, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32, struct<"_QFRecTy2", \(f32, array<10 x i32>, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>\)>]] 1261 %1 = fir.coordinate_of %arg0, %c6 : (!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>, index) -> !fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>> 1262 // CHECK: %[[NESTED_ALLOCATABLE_MEMBER_GEP:.*]] = llvm.getelementptr %[[NESTED_DTYPE_MEMBER_GEP]][0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFRecTy2", (f32, array<10 x i32>, struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>, i32)> 1263 %2 = fir.coordinate_of %1, %c2 : (!fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> 1264 // CHECK: %[[NESTED_ALLOCATABLE_MEMBER_BADDR_GEP:.*]] = llvm.getelementptr %[[NESTED_ALLOCATABLE_MEMBER_GEP]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY2]] 1265 %3 = fir.box_offset %2 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> 1266 // CHECK: %[[MAP_NESTED_ALLOCATABLE_MEMBER_BADDR:.*]] = omp.map.info var_ptr(%[[NESTED_ALLOCATABLE_MEMBER_GEP]] : !llvm.ptr, i32) var_ptr_ptr(%[[NESTED_ALLOCATABLE_MEMBER_BADDR_GEP]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr 1267 %4 = omp.map.info var_ptr(%2 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%3 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%0) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> 1268 // CHECK: %[[MAP_NESTED_ALLOCATABLE_MEMBER_DESC:.*]] = omp.map.info var_ptr(%[[NESTED_ALLOCATABLE_MEMBER_GEP]] : !llvm.ptr, [[DESC_TY2]]) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr 1269 %5 = omp.map.info var_ptr(%2 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> 1270 // CHECK: %[[MAP_PARENT:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[REC_TY]]) map_clauses(tofrom) capture(ByRef) members(%[[MAP_NESTED_ALLOCATABLE_MEMBER_DESC]], %[[MAP_NESTED_ALLOCATABLE_MEMBER_BADDR]] : [6, 2], [6, 2, 0] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {partial_map = true} 1271 %6 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>, !fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>) map_clauses(tofrom) capture(ByRef) members(%5, %4 : [6,2], [6,2,0] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>> {partial_map = true} 1272 // CHECK: omp.target map_entries(%[[MAP_NESTED_ALLOCATABLE_MEMBER_DESC]] -> %[[ARG_1:.*]], %[[MAP_NESTED_ALLOCATABLE_MEMBER_BADDR]] -> %[[ARG_2:.*]], %[[MAP_PARENT]] -> %[[ARG_3:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) { 1273 omp.target map_entries(%5 -> %arg1, %4 -> %arg2, %6 -> %arg3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>) { 1274 omp.terminator 1275 } 1276 return 1277} 1278