brintos

brintos / llvm-project-archived public Read only

0
0
Text · 111.7 KiB · e004a88 Raw
2362 lines · plain
1// RUN: mlir-opt -split-input-file %s | FileCheck %s --check-prefixes=CHECK,CHECK-32// Verify the printed output can be parsed.3// RUN: mlir-opt -split-input-file %s | mlir-opt  -split-input-file  | FileCheck %s --check-prefixes=CHECK,CHECK-34// Verify the generic form can be parsed.5// RUN: mlir-opt -split-input-file -mlir-print-op-generic %s | mlir-opt -split-input-file | FileCheck %s --check-prefixes=CHECK,CHECK-36 7func.func @compute1(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x10xf32>) -> memref<10x10xf32> {8  %c0 = arith.constant 0 : index9  %c10 = arith.constant 10 : index10  %c1 = arith.constant 1 : index11  %async = arith.constant 1 : i6412 13  acc.parallel async(%async: i64) {14    acc.loop gang vector control(%arg3 : index, %arg4 : index, %arg5 : index) = (%c0, %c0, %c0 : index, index, index) to (%c10, %c10, %c10 : index, index, index) step (%c1, %c1, %c1 : index, index, index) {15      %a = memref.load %A[%arg3, %arg5] : memref<10x10xf32>16      %b = memref.load %B[%arg5, %arg4] : memref<10x10xf32>17      %cij = memref.load %C[%arg3, %arg4] : memref<10x10xf32>18      %p = arith.mulf %a, %b : f3219      %co = arith.addf %cij, %p : f3220      memref.store %co, %C[%arg3, %arg4] : memref<10x10xf32>21      acc.yield22    } attributes { collapse = [3], collapseDeviceType = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true, true, true>, independent = [#acc.device_type<none>]}23    acc.yield24  }25 26  return %C : memref<10x10xf32>27}28 29// CHECK-LABEL: func @compute130//  CHECK-NEXT:   %{{.*}} = arith.constant 0 : index31//  CHECK-NEXT:   %{{.*}} = arith.constant 10 : index32//  CHECK-NEXT:   %{{.*}} = arith.constant 1 : index33//  CHECK-NEXT:   [[ASYNC:%.*]] = arith.constant 1 : i6434//  CHECK-NEXT:   acc.parallel async([[ASYNC]] : i64) {35//  CHECK-NEXT:     acc.loop gang vector control(%{{.*}}) = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) {36//  CHECK-NEXT:       %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>37//  CHECK-NEXT:       %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>38//  CHECK-NEXT:       %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>39//  CHECK-NEXT:       %{{.*}} = arith.mulf %{{.*}}, %{{.*}} : f3240//  CHECK-NEXT:       %{{.*}} = arith.addf %{{.*}}, %{{.*}} : f3241//  CHECK-NEXT:       memref.store %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>42//  CHECK-NEXT:       acc.yield43//  CHECK-NEXT:     } attributes {collapse = [3], collapseDeviceType = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true, true, true>, independent = [#acc.device_type<none>]}44//  CHECK-NEXT:     acc.yield45//  CHECK-NEXT:   }46//  CHECK-NEXT:   return %{{.*}} : memref<10x10xf32>47 48 49// -----50 51func.func @compute2(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x10xf32>) -> memref<10x10xf32> {52  %c0 = arith.constant 0 : index53  %c10 = arith.constant 10 : index54  %c1 = arith.constant 1 : index55 56  acc.parallel {57    acc.loop control(%arg3 : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {58      scf.for %arg4 = %c0 to %c10 step %c1 {59        scf.for %arg5 = %c0 to %c10 step %c1 {60          %a = memref.load %A[%arg3, %arg5] : memref<10x10xf32>61          %b = memref.load %B[%arg5, %arg4] : memref<10x10xf32>62          %cij = memref.load %C[%arg3, %arg4] : memref<10x10xf32>63          %p = arith.mulf %a, %b : f3264          %co = arith.addf %cij, %p : f3265          memref.store %co, %C[%arg3, %arg4] : memref<10x10xf32>66        }67      }68      acc.yield69    } attributes {seq = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true>}70    acc.yield71  }72 73  return %C : memref<10x10xf32>74}75 76// CHECK-LABEL: func @compute2(77//  CHECK-NEXT:   %{{.*}} = arith.constant 0 : index78//  CHECK-NEXT:   %{{.*}} = arith.constant 10 : index79//  CHECK-NEXT:   %{{.*}} = arith.constant 1 : index80//  CHECK-NEXT:   acc.parallel {81//  CHECK-NEXT:     acc.loop  control(%{{.*}}) = (%{{.*}}) to (%{{.*}}) step (%{{.*}})82//  CHECK-NEXT:       scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {83//  CHECK-NEXT:         scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {84//  CHECK-NEXT:           %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>85//  CHECK-NEXT:           %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>86//  CHECK-NEXT:           %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>87//  CHECK-NEXT:           %{{.*}} = arith.mulf %{{.*}}, %{{.*}} : f3288//  CHECK-NEXT:           %{{.*}} = arith.addf %{{.*}}, %{{.*}} : f3289//  CHECK-NEXT:           memref.store %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>90//  CHECK-NEXT:         }91//  CHECK-NEXT:       }92//  CHECK-NEXT:       acc.yield93//  CHECK-NEXT:     } attributes {inclusiveUpperbound = array<i1: true>, seq = [#acc.device_type<none>]}94//  CHECK-NEXT:     acc.yield95//  CHECK-NEXT:   }96//  CHECK-NEXT:   return %{{.*}} : memref<10x10xf32>97//  CHECK-NEXT: }98 99// -----100 101acc.private.recipe @privatization_memref_10_f32 : memref<10xf32> init {102^bb0(%arg0: memref<10xf32>):103  %0 = memref.alloc() : memref<10xf32>104  acc.yield %0 : memref<10xf32>105} destroy {106^bb0(%arg0: memref<10xf32>):107  memref.dealloc %arg0 : memref<10xf32> 108  acc.terminator109}110 111func.func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10xf32>, %d: memref<10xf32>) -> memref<10xf32> {112  %lb = arith.constant 0 : index113  %st = arith.constant 1 : index114  %c10 = arith.constant 10 : index115  %numGangs = arith.constant 10 : i64116  %numWorkers = arith.constant 10 : i64117 118  %pa = acc.present varPtr(%a : memref<10x10xf32>) varType(tensor<10x10xf32>) -> memref<10x10xf32>119  %pb = acc.present varPtr(%b : memref<10x10xf32>) varType(tensor<10x10xf32>) -> memref<10x10xf32>120  %pc = acc.present varPtr(%c : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>121  %pd = acc.present varPtr(%d : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>122  acc.data dataOperands(%pa, %pb, %pc, %pd: memref<10x10xf32>, memref<10x10xf32>, memref<10xf32>, memref<10xf32>) {123    %private = acc.private varPtr(%c : memref<10xf32>) varType(tensor<10xf32>) recipe(@privatization_memref_10_f32) -> memref<10xf32>124    acc.parallel num_gangs({%numGangs: i64}) num_workers(%numWorkers: i64 [#acc.device_type<nvidia>]) private(%private : memref<10xf32>) {125      acc.loop gang control(%x : index) = (%lb : index) to (%c10 : index) step (%st : index) {126        acc.loop worker control(%y : index) = (%lb : index) to (%c10 : index) step (%st : index) {127          %axy = memref.load %a[%x, %y] : memref<10x10xf32>128          %bxy = memref.load %b[%x, %y] : memref<10x10xf32>129          %tmp = arith.addf %axy, %bxy : f32130          memref.store %tmp, %c[%y] : memref<10xf32>131          acc.yield132        } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}133 134        acc.loop control(%i : index) = (%lb : index) to (%c10 : index) step (%st : index) {135          // for i = 0 to 10 step 1136          //   d[x] += c[i]137          %ci = memref.load %c[%i] : memref<10xf32>138          %dx = memref.load %d[%x] : memref<10xf32>139          %z = arith.addf %ci, %dx : f32140          memref.store %z, %d[%x] : memref<10xf32>141          acc.yield142        } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>], seq = [#acc.device_type<nvidia>]}143        acc.yield144      } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}145      acc.yield146    }147    acc.terminator148  }149 150  return %d : memref<10xf32>151}152 153// CHECK:      func @compute3({{.*}}: memref<10x10xf32>, {{.*}}: memref<10x10xf32>, [[ARG2:%.*]]: memref<10xf32>, {{.*}}: memref<10xf32>) -> memref<10xf32> {154// CHECK-NEXT:   [[C0:%.*]] = arith.constant 0 : index155// CHECK-NEXT:   [[C1:%.*]] = arith.constant 1 : index156// CHECK-NEXT:   [[C10:%.*]] = arith.constant 10 : index157// CHECK-NEXT:   [[NUMGANG:%.*]] = arith.constant 10 : i64158// CHECK-NEXT:   [[NUMWORKERS:%.*]] = arith.constant 10 : i64159// CHECK:        acc.data dataOperands(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : memref<10x10xf32>, memref<10x10xf32>, memref<10xf32>, memref<10xf32>) {160// CHECK-NEXT:     %[[P_ARG2:.*]] = acc.private varPtr([[ARG2]] : memref<10xf32>) varType(tensor<10xf32>) recipe(@privatization_memref_10_f32) -> memref<10xf32>161// CHECK-NEXT:     acc.parallel num_gangs({[[NUMGANG]] : i64}) num_workers([[NUMWORKERS]] : i64 [#acc.device_type<nvidia>]) private(%[[P_ARG2]] : memref<10xf32>) {162// CHECK-NEXT:       acc.loop gang control(%{{.*}}) = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) {163// CHECK-NEXT:         acc.loop worker control(%{{.*}}) = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) {164// CHECK-NEXT:           %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>165// CHECK-NEXT:           %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>166// CHECK-NEXT:           %{{.*}} = arith.addf %{{.*}}, %{{.*}} : f32167// CHECK-NEXT:           memref.store %{{.*}}, %{{.*}}[%{{.*}}] : memref<10xf32>168// CHECK-NEXT:           acc.yield169// CHECK-NEXT:         } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}170// CHECK-NEXT:         acc.loop control(%{{.*}}) = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) {171// CHECK-NEXT:           %{{.*}} = memref.load %{{.*}}[%{{.*}}] : memref<10xf32>172// CHECK-NEXT:           %{{.*}} = memref.load %{{.*}}[%{{.*}}] : memref<10xf32>173// CHECK-NEXT:           %{{.*}} = arith.addf %{{.*}}, %{{.*}} : f32174// CHECK-NEXT:           memref.store %{{.*}}, %{{.*}}[%{{.*}}] : memref<10xf32>175// CHECK-NEXT:           acc.yield176// CHECK-NEXT:         } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>], seq = [#acc.device_type<nvidia>]}177// CHECK-NEXT:         acc.yield178// CHECK-NEXT:       } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}179// CHECK-NEXT:       acc.yield180// CHECK-NEXT:     }181// CHECK-NEXT:     acc.terminator182// CHECK-NEXT:   }183// CHECK-NEXT:   return %{{.*}} : memref<10xf32>184// CHECK-NEXT: }185 186// -----187 188func.func @testloopop(%a : memref<10xf32>) -> () {189  %i64Value = arith.constant 1 : i64190  %i32Value = arith.constant 128 : i32191  %idxValue = arith.constant 8 : index192  %c0 = arith.constant 0 : index193  %c10 = arith.constant 10 : index194  %c1 = arith.constant 1 : index195 196  acc.loop gang vector worker control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {197    "test.openacc_dummy_op"() : () -> ()198    acc.yield199  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}200  acc.loop gang({num=%i64Value: i64}) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {201    "test.openacc_dummy_op"() : () -> ()202    acc.yield203  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}204  acc.loop gang({static=%i64Value: i64}) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {205    "test.openacc_dummy_op"() : () -> ()206    acc.yield207  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}208  acc.loop worker(%i64Value: i64) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {209    "test.openacc_dummy_op"() : () -> ()210    acc.yield211  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}212  acc.loop worker(%i32Value: i32) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {213    "test.openacc_dummy_op"() : () -> ()214    acc.yield215  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}216  acc.loop worker(%idxValue: index) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {217    "test.openacc_dummy_op"() : () -> ()218    acc.yield219  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}220  acc.loop vector(%i64Value: i64) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {221    "test.openacc_dummy_op"() : () -> ()222    acc.yield223  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}224  acc.loop vector(%i32Value: i32) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {225    "test.openacc_dummy_op"() : () -> ()226    acc.yield227  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}228  acc.loop vector(%idxValue: index) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {229    "test.openacc_dummy_op"() : () -> ()230    acc.yield231  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}232  acc.loop gang({num=%i64Value: i64}) worker vector control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {233    "test.openacc_dummy_op"() : () -> ()234    acc.yield235  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}236  acc.loop gang({num=%i64Value: i64, static=%i64Value: i64}) worker(%i64Value: i64) vector(%i64Value: i64) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {237    "test.openacc_dummy_op"() : () -> ()238    acc.yield239  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}240  acc.loop gang({num=%i32Value: i32, static=%idxValue: index}) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {241    "test.openacc_dummy_op"() : () -> ()242    acc.yield243  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}244  acc.loop tile({%i64Value : i64, %i64Value : i64}) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {245    "test.openacc_dummy_op"() : () -> ()246    acc.yield247  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}248  acc.loop tile({%i32Value : i32, %i32Value : i32}) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {249    "test.openacc_dummy_op"() : () -> ()250    acc.yield251  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}252  acc.loop gang({static=%i64Value: i64, num=%i64Value: i64}) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {253    "test.openacc_dummy_op"() : () -> ()254    acc.yield255  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}256  acc.loop gang({dim=%i64Value : i64, static=%i64Value: i64}) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {257    "test.openacc_dummy_op"() : () -> ()258    acc.yield259  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}260  %b = acc.cache varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>261  acc.loop cache(%b : memref<10xf32>) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {262    "test.openacc_dummy_op"() : () -> ()263    acc.yield264  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}265  return266}267 268// CHECK:      [[I64VALUE:%.*]] = arith.constant 1 : i64269// CHECK-NEXT: [[I32VALUE:%.*]] = arith.constant 128 : i32270// CHECK-NEXT: [[IDXVALUE:%.*]] = arith.constant 8 : index271// CHECK:      acc.loop272// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()273// CHECK-NEXT:   acc.yield274// CHECK-NEXT: attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}275// CHECK:      acc.loop gang({num=[[I64VALUE]] : i64})276// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()277// CHECK-NEXT:   acc.yield278// CHECK:      acc.loop gang({static=[[I64VALUE]] : i64})279// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()280// CHECK-NEXT:   acc.yield281// CHECK:      acc.loop worker([[I64VALUE]] : i64)282// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()283// CHECK-NEXT:   acc.yield284// CHECK:      acc.loop worker([[I32VALUE]] : i32)285// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()286// CHECK-NEXT:   acc.yield287// CHECK:      acc.loop worker([[IDXVALUE]] : index)288// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()289// CHECK-NEXT:   acc.yield290// CHECK:      acc.loop vector([[I64VALUE]] : i64)291// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()292// CHECK-NEXT:   acc.yield293// CHECK:      acc.loop vector([[I32VALUE]] : i32)294// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()295// CHECK-NEXT:   acc.yield296// CHECK:      acc.loop vector([[IDXVALUE]] : index)297// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()298// CHECK-NEXT:   acc.yield299// CHECK:      acc.loop gang({num=[[I64VALUE]] : i64}) worker vector300// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()301// CHECK-NEXT:   acc.yield302// CHECK:      acc.loop gang({num=[[I64VALUE]] : i64, static=[[I64VALUE]] : i64}) worker([[I64VALUE]] : i64) vector([[I64VALUE]] : i64)303// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()304// CHECK-NEXT:   acc.yield305// CHECK:      acc.loop gang({num=[[I32VALUE]] : i32, static=[[IDXVALUE]] : index})306// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()307// CHECK-NEXT:   acc.yield308// CHECK:      acc.loop tile({[[I64VALUE]] : i64, [[I64VALUE]] : i64})309// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()310// CHECK-NEXT:   acc.yield311// CHECK:      acc.loop tile({[[I32VALUE]] : i32, [[I32VALUE]] : i32})312// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()313// CHECK-NEXT:   acc.yield314// CHECK:      acc.loop gang({static=[[I64VALUE]] : i64, num=[[I64VALUE]] : i64})315// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()316// CHECK-NEXT:   acc.yield317// CHECK:      acc.loop gang({dim=[[I64VALUE]] : i64, static=[[I64VALUE]] : i64})318// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()319// CHECK-NEXT:   acc.yield320// CHECK:      %{{.*}} = acc.cache varPtr(%{{.*}} : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>321// CHECK-NEXT: acc.loop cache(%{{.*}} : memref<10xf32>)322// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()323// CHECK-NEXT:   acc.yield324 325// -----326 327func.func @acc_loop_multiple_block() {328  %c0 = arith.constant 0 : index329  %c10 = arith.constant 10 : index330  %c1 = arith.constant 1 : index331  acc.parallel {332    acc.loop control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {333      %c1_1 = arith.constant 1 : index334      cf.br ^bb1(%c1_1 : index)335    ^bb1(%9: index):336      %c0_1 = arith.constant 0 : index337      %12 = arith.cmpi sgt, %9, %c0_1 : index338      cf.cond_br %12, ^bb2, ^bb3339    ^bb2:340      %c1_0 = arith.constant 1 : index341      %c10_1 = arith.constant 10 : index342      %22 = arith.subi %c10_1, %c1_0 : index343      cf.br ^bb1(%22 : index)344    ^bb3:345      acc.yield346    } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}347    acc.yield348  }349  return350}351 352// CHECK-LABEL: func.func @acc_loop_multiple_block()353// CHECK: acc.parallel354// CHECK: acc.loop355// CHECK-3: ^bb{{.*}}356// CHECK: acc.yield357// CHECK: acc.yield358 359// -----360 361acc.firstprivate.recipe @firstprivatization_memref_10xf32 : memref<10xf32> init {362^bb0(%arg0: memref<10xf32>):363  %0 = memref.alloca() : memref<10xf32>364  acc.yield %0 : memref<10xf32>365} copy {366^bb0(%arg0: memref<10xf32>, %arg1: memref<10xf32>):367  memref.copy %arg0, %arg1 : memref<10xf32> to memref<10xf32>368  acc.terminator369} destroy {370^bb0(%arg0: memref<10xf32>):371  acc.terminator372}373 374func.func @testloopfirstprivate(%a: memref<10xf32>, %b: memref<10xf32>) -> () {375  %c0 = arith.constant 0 : index376  %c10 = arith.constant 10 : index377  %c1 = arith.constant 1 : index378  %firstprivate = acc.firstprivate varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) recipe(@firstprivatization_memref_10xf32) -> memref<10xf32>379  acc.loop firstprivate(%firstprivate : memref<10xf32>) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {380    "test.openacc_dummy_op"() : () -> ()381    acc.yield382  } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}383  return384}385 386// CHECK-LABEL: func.func @testloopfirstprivate(387// CHECK-SAME:    %[[ARG0:.*]]: memref<10xf32>, %[[ARG1:.*]]: memref<10xf32>)388// CHECK:         %[[FIRSTPRIVATE:.*]] = acc.firstprivate varPtr(%[[ARG0]] : memref<10xf32>) varType(tensor<10xf32>) recipe(@firstprivatization_memref_10xf32) -> memref<10xf32>389// CHECK:         acc.loop firstprivate(%[[FIRSTPRIVATE]] : memref<10xf32>) control(%{{.*}}) = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) {390// CHECK:           "test.openacc_dummy_op"() : () -> ()391// CHECK:           acc.yield392// CHECK:         } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}393 394// -----395 396acc.private.recipe @privatization_memref_10_f32 : memref<10xf32> init {397^bb0(%arg0: memref<10xf32>):398  %0 = memref.alloc() : memref<10xf32>399  acc.yield %0 : memref<10xf32>400} destroy {401^bb0(%arg0: memref<10xf32>):402  memref.dealloc %arg0 : memref<10xf32> 403  acc.terminator404}405 406acc.private.recipe @privatization_memref_10_10_f32 : memref<10x10xf32> init {407^bb0(%arg0: memref<10x10xf32>):408  %0 = memref.alloc() : memref<10x10xf32>409  acc.yield %0 : memref<10x10xf32>410} destroy {411^bb0(%arg0: memref<10x10xf32>):412  memref.dealloc %arg0 : memref<10x10xf32> 413  acc.terminator414}415 416acc.firstprivate.recipe @privatization_memref_10xf32 : memref<10xf32> init {417^bb0(%arg0: memref<10xf32>):418  %0 = memref.alloc() : memref<10xf32>419  acc.yield %0 : memref<10xf32>420} copy {421^bb0(%arg0: memref<10xf32>, %arg1: memref<10xf32>):422  acc.terminator423} destroy {424^bb0(%arg0: memref<10xf32>):425  memref.dealloc %arg0 : memref<10xf32> 426  acc.terminator427}428 429func.func @testparallelop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {430  %i64value = arith.constant 1 : i64431  %i32value = arith.constant 1 : i32432  %idxValue = arith.constant 1 : index433  acc.parallel async(%i64value: i64) {434  }435  acc.parallel async(%i32value: i32) {436  }437  acc.parallel async(%idxValue: index) {438  }439  acc.parallel wait({%i64value: i64}) {440  }441  acc.parallel wait({%i32value: i32}) {442  }443  acc.parallel wait({%idxValue: index}) {444  }445  acc.parallel wait({%i64value : i64, %i32value : i32, %idxValue : index}) {446  }447  acc.parallel num_gangs({%i64value: i64}) {448  }449  acc.parallel num_gangs({%i32value: i32}) {450  }451  acc.parallel num_gangs({%idxValue: index}) {452  }453  acc.parallel num_gangs({%i64value: i64, %i64value: i64, %idxValue: index}) {454  }455  acc.parallel num_workers(%i64value: i64 [#acc.device_type<nvidia>]) {456  }457  acc.parallel num_workers(%i32value: i32 [#acc.device_type<default>]) {458  }459  acc.parallel num_workers(%idxValue: index) {460  }461  acc.parallel vector_length(%i64value: i64) {462  }463  acc.parallel vector_length(%i32value: i32) {464  }465  acc.parallel vector_length(%idxValue: index) {466  }467  %private_a = acc.private varPtr(%a : memref<10xf32>) recipe(@privatization_memref_10_f32) -> memref<10xf32>468  %private_c = acc.private varPtr(%c : memref<10x10xf32>) recipe(@privatization_memref_10_10_f32) -> memref<10x10xf32>469  %firstprivate_b = acc.firstprivate varPtr(%b : memref<10xf32>) recipe(@privatization_memref_10xf32) -> memref<10xf32>470  acc.parallel private(%private_a, %private_c : memref<10xf32>, memref<10x10xf32>) firstprivate(%firstprivate_b : memref<10xf32>) {471  }472  acc.parallel {473  } attributes {defaultAttr = #acc<defaultvalue none>}474  acc.parallel {475  } attributes {defaultAttr = #acc<defaultvalue present>}476  acc.parallel async {477  }478  acc.parallel wait {479  }480  acc.parallel {481  } attributes {selfAttr}482  return483}484 485// CHECK:      func @testparallelop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {486// CHECK:      [[I64VALUE:%.*]] = arith.constant 1 : i64487// CHECK:      [[I32VALUE:%.*]] = arith.constant 1 : i32488// CHECK:      [[IDXVALUE:%.*]] = arith.constant 1 : index489// CHECK:      acc.parallel async([[I64VALUE]] : i64) {490// CHECK-NEXT: }491// CHECK:      acc.parallel async([[I32VALUE]] : i32) {492// CHECK-NEXT: }493// CHECK:      acc.parallel async([[IDXVALUE]] : index) {494// CHECK-NEXT: }495// CHECK:      acc.parallel wait({[[I64VALUE]] : i64}) {496// CHECK-NEXT: }497// CHECK:      acc.parallel wait({[[I32VALUE]] : i32}) {498// CHECK-NEXT: }499// CHECK:      acc.parallel wait({[[IDXVALUE]] : index}) {500// CHECK-NEXT: }501// CHECK:      acc.parallel wait({[[I64VALUE]] : i64, [[I32VALUE]] : i32, [[IDXVALUE]] : index}) {502// CHECK-NEXT: }503// CHECK:      acc.parallel num_gangs({[[I64VALUE]] : i64}) {504// CHECK-NEXT: }505// CHECK:      acc.parallel num_gangs({[[I32VALUE]] : i32}) {506// CHECK-NEXT: }507// CHECK:      acc.parallel num_gangs({[[IDXVALUE]] : index}) {508// CHECK-NEXT: }509// CHECK:      acc.parallel num_gangs({[[I64VALUE]] : i64, [[I64VALUE]] : i64, [[IDXVALUE]] : index}) {510// CHECK-NEXT: }511// CHECK:      acc.parallel num_workers([[I64VALUE]] : i64 [#acc.device_type<nvidia>]) {512// CHECK-NEXT: }513// CHECK:      acc.parallel num_workers([[I32VALUE]] : i32 [#acc.device_type<default>]) {514// CHECK-NEXT: }515// CHECK:      acc.parallel num_workers([[IDXVALUE]] : index) {516// CHECK-NEXT: }517// CHECK:      acc.parallel vector_length([[I64VALUE]] : i64) {518// CHECK-NEXT: }519// CHECK:      acc.parallel vector_length([[I32VALUE]] : i32) {520// CHECK-NEXT: }521// CHECK:      acc.parallel vector_length([[IDXVALUE]] : index) {522// CHECK-NEXT: }523// CHECK:      %[[PRIVATE_A:.*]] = acc.private varPtr([[ARGA]] : memref<10xf32>) recipe(@privatization_memref_10_f32) -> memref<10xf32>524// CHECK-NEXT: %[[PRIVATE_C:.*]] = acc.private varPtr([[ARGC]] : memref<10x10xf32>) recipe(@privatization_memref_10_10_f32) -> memref<10x10xf32>525// CHECK-NEXT: %[[FIRSTPRIVATE_B:.*]] = acc.firstprivate varPtr([[ARGB]] : memref<10xf32>) recipe(@privatization_memref_10xf32) -> memref<10xf32>526// CHECK-NEXT: acc.parallel firstprivate(%[[FIRSTPRIVATE_B]] : memref<10xf32>) private(%[[PRIVATE_A]], %[[PRIVATE_C]] : memref<10xf32>, memref<10x10xf32>) {527// CHECK-NEXT: }528// CHECK:      acc.parallel {529// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}530// CHECK:      acc.parallel {531// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue present>}532// CHECK:      acc.parallel async {533// CHECK-NEXT: }534// CHECK:      acc.parallel wait {535// CHECK-NEXT: }536// CHECK:      acc.parallel {537// CHECK-NEXT: } attributes {selfAttr}538 539// -----540 541acc.private.recipe @privatization_memref_10_f32 : memref<10xf32> init {542^bb0(%arg0: memref<10xf32>):543  %0 = memref.alloc() : memref<10xf32>544  acc.yield %0 : memref<10xf32>545} destroy {546^bb0(%arg0: memref<10xf32>):547  memref.dealloc %arg0 : memref<10xf32> 548  acc.terminator549}550 551acc.private.recipe @privatization_memref_10_10_f32 : memref<10x10xf32> init {552^bb0(%arg0: memref<10x10xf32>):553  %0 = memref.alloc() : memref<10x10xf32>554  acc.yield %0 : memref<10x10xf32>555} destroy {556^bb0(%arg0: memref<10x10xf32>):557  memref.dealloc %arg0 : memref<10x10xf32> 558  acc.terminator559}560 561// Test optional destroy region562acc.firstprivate.recipe @firstprivatization_memref_20xf32 : memref<20xf32> init {563^bb0(%arg0: memref<20xf32>):564  %0 = memref.alloc() : memref<20xf32>565  acc.yield %0 : memref<20xf32>566} copy {567^bb0(%arg0: memref<20xf32>, %arg1: memref<20xf32>):568  acc.terminator569}570 571// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_memref_20xf32 : memref<20xf32> init572 573acc.firstprivate.recipe @firstprivatization_memref_10xf32 : memref<10xf32> init {574^bb0(%arg0: memref<10xf32>):575  %0 = memref.alloc() : memref<10xf32>576  acc.yield %0 : memref<10xf32>577} copy {578^bb0(%arg0: memref<10xf32>, %arg1: memref<10xf32>):579  memref.copy %arg0, %arg1 : memref<10xf32> to memref<10xf32>580  acc.terminator581} destroy {582^bb0(%arg0: memref<10xf32>):583  memref.dealloc %arg0 : memref<10xf32> 584  acc.terminator585}586 587func.func @testserialop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {588  %i64value = arith.constant 1 : i64589  %i32value = arith.constant 1 : i32590  %idxValue = arith.constant 1 : index591  acc.serial async(%i64value: i64) {592  }593  acc.serial async(%i32value: i32) {594  }595  acc.serial async(%idxValue: index) {596  }597  acc.serial wait({%i64value: i64}) {598  }599  acc.serial wait({%i32value: i32}) {600  }601  acc.serial wait({%idxValue: index}) {602  }603  acc.serial wait({%i64value : i64, %i32value : i32, %idxValue : index}) {604  }605  %private_a = acc.private varPtr(%a : memref<10xf32>) recipe(@privatization_memref_10_f32) -> memref<10xf32>606  %private_c = acc.private varPtr(%c : memref<10x10xf32>) recipe(@privatization_memref_10_10_f32) -> memref<10x10xf32>607  %firstprivate = acc.firstprivate varPtr(%b : memref<10xf32>) varType(tensor<10xf32>) recipe(@firstprivatization_memref_10xf32) -> memref<10xf32>608  acc.serial private(%private_a, %private_c : memref<10xf32>, memref<10x10xf32>) firstprivate(%firstprivate : memref<10xf32>) {609  }610  acc.serial {611  } attributes {defaultAttr = #acc<defaultvalue none>}612  acc.serial {613  } attributes {defaultAttr = #acc<defaultvalue present>}614  acc.serial async {615  }616  acc.serial wait {617  }618  acc.serial {619  } attributes {selfAttr}620  acc.serial {621    acc.yield622  } attributes {selfAttr}623  return624}625 626// CHECK:      func @testserialop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {627// CHECK:      [[I64VALUE:%.*]] = arith.constant 1 : i64628// CHECK:      [[I32VALUE:%.*]] = arith.constant 1 : i32629// CHECK:      [[IDXVALUE:%.*]] = arith.constant 1 : index630// CHECK:      acc.serial async([[I64VALUE]] : i64) {631// CHECK-NEXT: }632// CHECK:      acc.serial async([[I32VALUE]] : i32) {633// CHECK-NEXT: }634// CHECK:      acc.serial async([[IDXVALUE]] : index) {635// CHECK-NEXT: }636// CHECK:      acc.serial wait({[[I64VALUE]] : i64}) {637// CHECK-NEXT: }638// CHECK:      acc.serial wait({[[I32VALUE]] : i32}) {639// CHECK-NEXT: }640// CHECK:      acc.serial wait({[[IDXVALUE]] : index}) {641// CHECK-NEXT: }642// CHECK:      acc.serial wait({[[I64VALUE]] : i64, [[I32VALUE]] : i32, [[IDXVALUE]] : index}) {643// CHECK-NEXT: }644// CHECK:      %[[PRIVATE_A:.*]] = acc.private varPtr([[ARGA]] : memref<10xf32>) recipe(@privatization_memref_10_f32) -> memref<10xf32>645// CHECK-NEXT: %[[PRIVATE_C:.*]] = acc.private varPtr([[ARGC]] : memref<10x10xf32>) recipe(@privatization_memref_10_10_f32) -> memref<10x10xf32>646// CHECK-NEXT: %[[FIRSTP:.*]] = acc.firstprivate varPtr([[ARGB]] : memref<10xf32>) varType(tensor<10xf32>) recipe(@firstprivatization_memref_10xf32) -> memref<10xf32>647// CHECK-NEXT: acc.serial firstprivate(%[[FIRSTP]] : memref<10xf32>) private(%[[PRIVATE_A]], %[[PRIVATE_C]] : memref<10xf32>, memref<10x10xf32>) {648// CHECK-NEXT: }649// CHECK:      acc.serial {650// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}651// CHECK:      acc.serial {652// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue present>}653// CHECK:      acc.serial async {654// CHECK-NEXT: }655// CHECK:      acc.serial wait {656// CHECK-NEXT: }657// CHECK:      acc.serial {658// CHECK-NEXT: } attributes {selfAttr}659// CHECK:      acc.serial {660// CHECK:        acc.yield661// CHECK-NEXT: } attributes {selfAttr}662 663// -----664 665 666func.func @testserialop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {667  %i64value = arith.constant 1 : i64668  %i32value = arith.constant 1 : i32669  %idxValue = arith.constant 1 : index670  acc.kernels async(%i64value: i64) {671  }672  acc.kernels async(%i32value: i32) {673  }674  acc.kernels async(%idxValue: index) {675  }676  acc.kernels wait({%i64value: i64}) {677  }678  acc.kernels wait({%i32value: i32}) {679  }680  acc.kernels wait({%idxValue: index}) {681  }682  acc.kernels wait({%i64value : i64, %i32value : i32, %idxValue : index}) {683  }684  acc.kernels {685  } attributes {defaultAttr = #acc<defaultvalue none>}686  acc.kernels {687  } attributes {defaultAttr = #acc<defaultvalue present>}688  acc.kernels async {689  }690  acc.kernels wait {691  }692  acc.kernels {693  } attributes {selfAttr}694  acc.kernels {695    acc.terminator696  } attributes {selfAttr}697  return698}699 700// CHECK:      func @testserialop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {701// CHECK:      [[I64VALUE:%.*]] = arith.constant 1 : i64702// CHECK:      [[I32VALUE:%.*]] = arith.constant 1 : i32703// CHECK:      [[IDXVALUE:%.*]] = arith.constant 1 : index704// CHECK:      acc.kernels async([[I64VALUE]] : i64) {705// CHECK-NEXT: }706// CHECK:      acc.kernels async([[I32VALUE]] : i32) {707// CHECK-NEXT: }708// CHECK:      acc.kernels async([[IDXVALUE]] : index) {709// CHECK-NEXT: }710// CHECK:      acc.kernels wait({[[I64VALUE]] : i64}) {711// CHECK-NEXT: }712// CHECK:      acc.kernels wait({[[I32VALUE]] : i32}) {713// CHECK-NEXT: }714// CHECK:      acc.kernels wait({[[IDXVALUE]] : index}) {715// CHECK-NEXT: }716// CHECK:      acc.kernels wait({[[I64VALUE]] : i64, [[I32VALUE]] : i32, [[IDXVALUE]] : index}) {717// CHECK-NEXT: }718// CHECK:      acc.kernels {719// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}720// CHECK:      acc.kernels {721// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue present>}722// CHECK:      acc.kernels async {723// CHECK-NEXT: }724// CHECK:      acc.kernels wait {725// CHECK-NEXT: }726// CHECK:      acc.kernels {727// CHECK-NEXT: } attributes {selfAttr}728// CHECK:      acc.kernels {729// CHECK:        acc.terminator730// CHECK-NEXT: } attributes {selfAttr}731 732// -----733 734func.func @testdataop(%a: memref<f32>, %b: memref<f32>, %c: memref<f32>) -> () {735  %ifCond = arith.constant true736 737  %0 = acc.present varPtr(%a : memref<f32>) -> memref<f32>738  acc.data if(%ifCond) dataOperands(%0 : memref<f32>) {739  }740 741  %1 = acc.present varPtr(%a : memref<f32>) -> memref<f32>742  acc.data dataOperands(%1 : memref<f32>) if(%ifCond) {743  }744 745  %2 = acc.present varPtr(%a : memref<f32>) -> memref<f32>746  %3 = acc.present varPtr(%b : memref<f32>) -> memref<f32>747  %4 = acc.present varPtr(%c : memref<f32>) -> memref<f32>748  acc.data dataOperands(%2, %3, %4 : memref<f32>, memref<f32>, memref<f32>) {749  }750 751  %5 = acc.copyin varPtr(%a : memref<f32>) -> memref<f32>752  %6 = acc.copyin varPtr(%b : memref<f32>) -> memref<f32>753  %7 = acc.copyin varPtr(%c : memref<f32>) -> memref<f32>754  acc.data dataOperands(%5, %6, %7 : memref<f32>, memref<f32>, memref<f32>) {755  }756 757  %8 = acc.copyin varPtr(%a : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyin_readonly>}758  %9 = acc.copyin varPtr(%b : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyin_readonly>}759  %10 = acc.copyin varPtr(%c : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyin_readonly>}760  acc.data dataOperands(%8, %9, %10 : memref<f32>, memref<f32>, memref<f32>) {761  }762 763  %11 = acc.create varPtr(%a : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}764  %12 = acc.create varPtr(%b : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}765  %13 = acc.create varPtr(%c : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}766  acc.data dataOperands(%11, %12, %13 : memref<f32>, memref<f32>, memref<f32>) {767  }768  acc.copyout accPtr(%11 : memref<f32>) to varPtr(%a : memref<f32>)769  acc.copyout accPtr(%12 : memref<f32>) to varPtr(%b : memref<f32>)770  acc.copyout accPtr(%13 : memref<f32>) to varPtr(%c : memref<f32>)771 772  %14 = acc.create varPtr(%a : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout_zero>}773  %15 = acc.create varPtr(%b : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout_zero>}774  %16 = acc.create varPtr(%c : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout_zero>}775  acc.data dataOperands(%14, %15, %16 : memref<f32>, memref<f32>, memref<f32>) {776  }777  acc.copyout accPtr(%14 : memref<f32>) to varPtr(%a : memref<f32>) {dataClause = #acc<data_clause acc_copyout_zero>}778  acc.copyout accPtr(%15 : memref<f32>) to varPtr(%b : memref<f32>) {dataClause = #acc<data_clause acc_copyout_zero>}779  acc.copyout accPtr(%16 : memref<f32>) to varPtr(%c : memref<f32>) {dataClause = #acc<data_clause acc_copyout_zero>}780 781  %17 = acc.create varPtr(%a : memref<f32>) -> memref<f32>782  %18 = acc.create varPtr(%b : memref<f32>) -> memref<f32>783  %19 = acc.create varPtr(%c : memref<f32>) -> memref<f32>784  acc.data dataOperands(%17, %18, %19 : memref<f32>, memref<f32>, memref<f32>) {785  }786  acc.delete accPtr(%17 : memref<f32>) {dataClause = #acc<data_clause acc_create>}787  acc.delete accPtr(%18 : memref<f32>) {dataClause = #acc<data_clause acc_create>}788  acc.delete accPtr(%19 : memref<f32>) {dataClause = #acc<data_clause acc_create>}789  790  %20 = acc.create varPtr(%a : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_create_zero>}791  %21 = acc.create varPtr(%b : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_create_zero>}792  %22 = acc.create varPtr(%c : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_create_zero>}793  acc.data dataOperands(%20, %21, %22 : memref<f32>, memref<f32>, memref<f32>) {794  }795  acc.delete accPtr(%20 : memref<f32>) {dataClause = #acc<data_clause acc_create_zero>}796  acc.delete accPtr(%21 : memref<f32>) {dataClause = #acc<data_clause acc_create_zero>}797  acc.delete accPtr(%22 : memref<f32>) {dataClause = #acc<data_clause acc_create_zero>}798 799  %23 = acc.nocreate varPtr(%a : memref<f32>) -> memref<f32>800  %24 = acc.nocreate varPtr(%b : memref<f32>) -> memref<f32>801  %25 = acc.nocreate varPtr(%c : memref<f32>) -> memref<f32>802  acc.data dataOperands(%23, %24, %25 : memref<f32>, memref<f32>, memref<f32>) {803  }804 805  %26 = acc.deviceptr varPtr(%a : memref<f32>) -> memref<f32>806  %27 = acc.deviceptr varPtr(%b : memref<f32>) -> memref<f32>807  %28 = acc.deviceptr varPtr(%c : memref<f32>) -> memref<f32>808  acc.data dataOperands(%26, %27, %28 : memref<f32>, memref<f32>, memref<f32>) {809  }810 811  %29 = acc.attach varPtr(%a : memref<f32>) -> memref<f32>812  %30 = acc.attach varPtr(%b : memref<f32>) -> memref<f32>813  %31 = acc.attach varPtr(%c : memref<f32>) -> memref<f32>814  acc.data dataOperands(%29, %30, %31 : memref<f32>, memref<f32>, memref<f32>) {815  }816 817  %32 = acc.copyin varPtr(%a : memref<f32>) -> memref<f32>818  %33 = acc.create varPtr(%b : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}819  %34 = acc.present varPtr(%c : memref<f32>) -> memref<f32>820  acc.data dataOperands(%32, %33, %34 : memref<f32>, memref<f32>, memref<f32>) {821  }822  acc.copyout accPtr(%33 : memref<f32>) to varPtr(%b : memref<f32>)823 824  %35 = acc.present varPtr(%a : memref<f32>) -> memref<f32>825  acc.data dataOperands(%35 : memref<f32>) {826  } attributes { defaultAttr = #acc<defaultvalue none> }827  828 829  %36 = acc.present varPtr(%a : memref<f32>) -> memref<f32>830  acc.data dataOperands(%36 : memref<f32>) {831  } attributes { defaultAttr = #acc<defaultvalue present> }832 833  acc.data {834  } attributes { defaultAttr = #acc<defaultvalue none> }835 836  acc.data async {837  } attributes { defaultAttr = #acc<defaultvalue none> }838 839  %a1 = arith.constant 1 : i64840  acc.data async(%a1 : i64) {841  } attributes { defaultAttr = #acc<defaultvalue none> }842 843  acc.data wait {844  } attributes { defaultAttr = #acc<defaultvalue none> }845 846  %w1 = arith.constant 1 : i64847  acc.data wait({%w1 : i64}) {848  } attributes { defaultAttr = #acc<defaultvalue none> }849 850  %wd1 = arith.constant 1 : i64851  acc.data wait({devnum: %wd1 : i64, %w1 : i64}) {852  } attributes { defaultAttr = #acc<defaultvalue none> }853 854  return855}856 857// CHECK:      func @testdataop(%[[ARGA:.*]]: memref<f32>, %[[ARGB:.*]]: memref<f32>, %[[ARGC:.*]]: memref<f32>) {858 859// CHECK:      %[[IFCOND1:.*]] = arith.constant true860// CHECK:      %[[PRESENT_A:.*]] = acc.present varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>861// CHECK:      acc.data if(%[[IFCOND1]]) dataOperands(%[[PRESENT_A]] : memref<f32>) {862// CHECK-NEXT: }863 864// CHECK:      %[[PRESENT_A:.*]] = acc.present varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>865// CHECK:      acc.data if(%[[IFCOND1]]) dataOperands(%[[PRESENT_A]] : memref<f32>) {866// CHECK-NEXT: }867 868// CHECK:      %[[PRESENT_A:.*]] = acc.present varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>869// CHECK:      %[[PRESENT_B:.*]] = acc.present varPtr(%[[ARGB]] : memref<f32>) -> memref<f32>870// CHECK:      %[[PRESENT_C:.*]] = acc.present varPtr(%[[ARGC]] : memref<f32>) -> memref<f32>871// CHECK:      acc.data dataOperands(%[[PRESENT_A]], %[[PRESENT_B]], %[[PRESENT_C]] : memref<f32>, memref<f32>, memref<f32>) {872// CHECK-NEXT: }873 874// CHECK:      %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>875// CHECK:      %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[ARGB]] : memref<f32>) -> memref<f32>876// CHECK:      %[[COPYIN_C:.*]] = acc.copyin varPtr(%[[ARGC]] : memref<f32>) -> memref<f32>877// CHECK:      acc.data dataOperands(%[[COPYIN_A]], %[[COPYIN_B]], %[[COPYIN_C]] : memref<f32>, memref<f32>, memref<f32>) {878// CHECK-NEXT: }879 880// CHECK:      %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[ARGA]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyin_readonly>}881// CHECK:      %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[ARGB]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyin_readonly>}882// CHECK:      %[[COPYIN_C:.*]] = acc.copyin varPtr(%[[ARGC]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyin_readonly>}883// CHECK:      acc.data dataOperands(%[[COPYIN_A]], %[[COPYIN_B]], %[[COPYIN_C]] : memref<f32>, memref<f32>, memref<f32>) {884// CHECK-NEXT: }885 886// CHECK:      %[[CREATE_A:.*]] = acc.create varPtr(%[[ARGA]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}887// CHECK:      %[[CREATE_B:.*]] = acc.create varPtr(%[[ARGB]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}888// CHECK:      %[[CREATE_C:.*]] = acc.create varPtr(%[[ARGC]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}889// CHECK:      acc.data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : memref<f32>, memref<f32>, memref<f32>) {890// CHECK-NEXT: }891// CHECK:      acc.copyout accPtr(%[[CREATE_A]] : memref<f32>) to varPtr(%[[ARGA]] : memref<f32>)892// CHECK:      acc.copyout accPtr(%[[CREATE_B]] : memref<f32>) to varPtr(%[[ARGB]] : memref<f32>)893// CHECK:      acc.copyout accPtr(%[[CREATE_C]] : memref<f32>) to varPtr(%[[ARGC]] : memref<f32>)894 895// CHECK:      %[[CREATE_A:.*]] = acc.create varPtr(%[[ARGA]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout_zero>}896// CHECK:      %[[CREATE_B:.*]] = acc.create varPtr(%[[ARGB]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout_zero>}897// CHECK:      %[[CREATE_C:.*]] = acc.create varPtr(%[[ARGC]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout_zero>}898// CHECK:      acc.data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : memref<f32>, memref<f32>, memref<f32>) {899// CHECK-NEXT: }900// CHECK:      acc.copyout accPtr(%[[CREATE_A]] : memref<f32>) to varPtr(%[[ARGA]] : memref<f32>) {dataClause = #acc<data_clause acc_copyout_zero>}901// CHECK:      acc.copyout accPtr(%[[CREATE_B]] : memref<f32>) to varPtr(%[[ARGB]] : memref<f32>) {dataClause = #acc<data_clause acc_copyout_zero>}902// CHECK:      acc.copyout accPtr(%[[CREATE_C]] : memref<f32>) to varPtr(%[[ARGC]] : memref<f32>) {dataClause = #acc<data_clause acc_copyout_zero>}903 904// CHECK:      %[[CREATE_A:.*]] = acc.create varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>905// CHECK:      %[[CREATE_B:.*]] = acc.create varPtr(%[[ARGB]] : memref<f32>) -> memref<f32>906// CHECK:      %[[CREATE_C:.*]] = acc.create varPtr(%[[ARGC]] : memref<f32>) -> memref<f32>907// CHECK:      acc.data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : memref<f32>, memref<f32>, memref<f32>) {908// CHECK-NEXT: }909 910// CHECK:      %[[CREATE_A:.*]] = acc.create varPtr(%[[ARGA]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_create_zero>}911// CHECK:      %[[CREATE_B:.*]] = acc.create varPtr(%[[ARGB]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_create_zero>}912// CHECK:      %[[CREATE_C:.*]] = acc.create varPtr(%[[ARGC]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_create_zero>}913// CHECK:      acc.data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : memref<f32>, memref<f32>, memref<f32>) {914// CHECK-NEXT: }915 916// CHECK:      %[[NOCREATE_A:.*]] = acc.nocreate varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>917// CHECK:      %[[NOCREATE_B:.*]] = acc.nocreate varPtr(%[[ARGB]] : memref<f32>) -> memref<f32>918// CHECK:      %[[NOCREATE_C:.*]] = acc.nocreate varPtr(%[[ARGC]] : memref<f32>) -> memref<f32>919// CHECK:      acc.data dataOperands(%[[NOCREATE_A]], %[[NOCREATE_B]], %[[NOCREATE_C]] : memref<f32>, memref<f32>, memref<f32>) {920// CHECK-NEXT: }921 922// CHECK:      %[[DEVICEPTR_A:.*]] = acc.deviceptr varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>923// CHECK:      %[[DEVICEPTR_B:.*]] = acc.deviceptr varPtr(%[[ARGB]] : memref<f32>) -> memref<f32>924// CHECK:      %[[DEVICEPTR_C:.*]] = acc.deviceptr varPtr(%[[ARGC]] : memref<f32>) -> memref<f32>925// CHECK:      acc.data dataOperands(%[[DEVICEPTR_A]], %[[DEVICEPTR_B]], %[[DEVICEPTR_C]] : memref<f32>, memref<f32>, memref<f32>) {926// CHECK-NEXT: }927 928// CHECK:      %[[ATTACH_A:.*]] = acc.attach varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>929// CHECK:      %[[ATTACH_B:.*]] = acc.attach varPtr(%[[ARGB]] : memref<f32>) -> memref<f32>930// CHECK:      %[[ATTACH_C:.*]] = acc.attach varPtr(%[[ARGC]] : memref<f32>) -> memref<f32>931// CHECK:      acc.data dataOperands(%[[ATTACH_A]], %[[ATTACH_B]], %[[ATTACH_C]] : memref<f32>, memref<f32>, memref<f32>) {932// CHECK-NEXT: }933 934 935// CHECK:      %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>936// CHECK:      %[[CREATE_B:.*]] = acc.create varPtr(%[[ARGB]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}937// CHECK:      %[[PRESENT_C:.*]] = acc.present varPtr(%[[ARGC]] : memref<f32>) -> memref<f32>938// CHECK:      acc.data dataOperands(%[[COPYIN_A]], %[[CREATE_B]], %[[PRESENT_C]] : memref<f32>, memref<f32>, memref<f32>) {939// CHECK-NEXT: }940// CHECK:      acc.copyout accPtr(%[[CREATE_B]] : memref<f32>) to varPtr(%[[ARGB]] : memref<f32>)941 942// CHECK:      %[[PRESENT_A:.*]] = acc.present varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>943// CHECK:      acc.data dataOperands(%[[PRESENT_A]] : memref<f32>) {944// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}945 946// CHECK:      %[[PRESENT_A:.*]] = acc.present varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>947// CHECK:      acc.data dataOperands(%[[PRESENT_A]] : memref<f32>) {948// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue present>}949 950// CHECK:      acc.data {951// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}952 953// CHECK:      acc.data async {954// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}955 956// CHECK:      acc.data async(%{{.*}} : i64) {957// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}958 959// CHECK:      acc.data wait {960// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}961 962// CHECK:      acc.data wait({%{{.*}} : i64}) {963// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}964 965// CHECK:      acc.data wait({devnum: %{{.*}} : i64, %{{.*}} : i64}) {966// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}967 968// -----969 970func.func @testdataopmodifiers(%a: memref<f32>, %b: memref<f32>, %c: memref<f32>) -> () {971  %0 = acc.create varPtr(%a : memref<f32>) -> memref<f32> {modifiers = #acc<data_clause_modifier capture,zero>}972  %1 = acc.copyin varPtr(%b : memref<f32>) -> memref<f32> {modifiers = #acc<data_clause_modifier readonly,capture,always>}973  %2 = acc.copyin varPtr(%c : memref<f32>) -> memref<f32> {modifiers = #acc<data_clause_modifier always>}974  %3 = acc.create varPtr(%c : memref<f32>) -> memref<f32> {modifiers = #acc<data_clause_modifier always>}975  acc.data dataOperands(%0, %1, %2, %3 : memref<f32>, memref<f32>, memref<f32>, memref<f32>) {976  }977  acc.copyout accPtr(%0 : memref<f32>) to varPtr(%a : memref<f32>) {modifiers = #acc<data_clause_modifier zero,capture,always>}978  acc.delete accPtr(%2 : memref<f32>) {modifiers = #acc<data_clause_modifier always>}979  acc.copyout accPtr(%3 : memref<f32>) to varPtr(%c : memref<f32>) {modifiers = #acc<data_clause_modifier always>}980 981  func.return982}983 984// CHECK:      func @testdataopmodifiers(%[[ARGA:.*]]: memref<f32>, %[[ARGB:.*]]: memref<f32>, %[[ARGC:.*]]: memref<f32>) {985// CHECK:      %[[CREATEA:.*]] = acc.create varPtr(%[[ARGA]] : memref<f32>) -> memref<f32> {modifiers = #acc<data_clause_modifier zero,capture>}986// CHECK:      %[[COPYINB:.*]] = acc.copyin varPtr(%[[ARGB]] : memref<f32>) -> memref<f32> {modifiers = #acc<data_clause_modifier always,readonly,capture>}987// CHECK:      %[[COPYINC:.*]] = acc.copyin varPtr(%[[ARGC]] : memref<f32>) -> memref<f32> {modifiers = #acc<data_clause_modifier always>}988// CHECK:      %[[CREATEC:.*]] = acc.create varPtr(%[[ARGC]] : memref<f32>) -> memref<f32> {modifiers = #acc<data_clause_modifier always>}989// CHECK:      acc.copyout accPtr(%[[CREATEA]] : memref<f32>) to varPtr(%[[ARGA]] : memref<f32>) {modifiers = #acc<data_clause_modifier always,zero,capture>}990// CHECK:      acc.delete accPtr(%[[COPYINC]] : memref<f32>) {modifiers = #acc<data_clause_modifier always>}991// CHECK:      acc.copyout accPtr(%[[CREATEC]] : memref<f32>) to varPtr(%[[ARGC]] : memref<f32>) {modifiers = #acc<data_clause_modifier always>}992 993// -----994 995func.func @testupdateop(%a: memref<f32>, %b: memref<f32>, %c: memref<f32>) -> () {996  %i64Value = arith.constant 1 : i64997  %i32Value = arith.constant 1 : i32998  %idxValue = arith.constant 1 : index999  %ifCond = arith.constant true1000  %0 = acc.update_device varPtr(%a : memref<f32>) -> memref<f32>1001  %1 = acc.update_device varPtr(%b : memref<f32>) -> memref<f32>1002  %2 = acc.update_device varPtr(%c : memref<f32>) -> memref<f32>1003  1004  acc.update async(%i64Value: i64) dataOperands(%0: memref<f32>)1005  acc.update async(%i32Value: i32) dataOperands(%0: memref<f32>)1006  acc.update async(%i32Value: i32) dataOperands(%0: memref<f32>)1007  acc.update async(%idxValue: index) dataOperands(%0: memref<f32>)1008  acc.update wait({devnum: %i64Value: i64, %i32Value : i32, %idxValue : index}) dataOperands(%0: memref<f32>)1009  acc.update if(%ifCond) dataOperands(%0: memref<f32>)1010  acc.update dataOperands(%0: memref<f32>)1011  acc.update dataOperands(%0, %1, %2 : memref<f32>, memref<f32>, memref<f32>)1012  acc.update async dataOperands(%0, %1, %2 : memref<f32>, memref<f32>, memref<f32>)1013  acc.update wait dataOperands(%0, %1, %2 : memref<f32>, memref<f32>, memref<f32>)1014  acc.update dataOperands(%0, %1, %2 : memref<f32>, memref<f32>, memref<f32>) attributes {ifPresent}1015  return1016}1017 1018// CHECK: func.func @testupdateop(%{{.*}}: memref<f32>, %{{.*}}: memref<f32>, %{{.*}}: memref<f32>)1019// CHECK:   [[I64VALUE:%.*]] = arith.constant 1 : i641020// CHECK:   [[I32VALUE:%.*]] = arith.constant 1 : i321021// CHECK:   [[IDXVALUE:%.*]] = arith.constant 1 : index1022// CHECK:   [[IFCOND:%.*]] = arith.constant true1023// CHECK:   acc.update async([[I64VALUE]] : i64) dataOperands(%{{.*}} : memref<f32>)1024// CHECK:   acc.update async([[I32VALUE]] : i32) dataOperands(%{{.*}} : memref<f32>)1025// CHECK:   acc.update async([[I32VALUE]] : i32) dataOperands(%{{.*}} : memref<f32>)1026// CHECK:   acc.update async([[IDXVALUE]] : index) dataOperands(%{{.*}} : memref<f32>)1027// CHECK:   acc.update wait({devnum: [[I64VALUE]] : i64, [[I32VALUE]] : i32, [[IDXVALUE]] : index}) dataOperands(%{{.*}} : memref<f32>)1028// CHECK:   acc.update if([[IFCOND]]) dataOperands(%{{.*}} : memref<f32>)1029// CHECK:   acc.update dataOperands(%{{.*}} : memref<f32>)1030// CHECK:   acc.update dataOperands(%{{.*}}, %{{.*}}, %{{.*}} : memref<f32>, memref<f32>, memref<f32>)1031// CHECK:   acc.update async dataOperands(%{{.*}}, %{{.*}}, %{{.*}} : memref<f32>, memref<f32>, memref<f32>)1032// CHECK:   acc.update wait dataOperands(%{{.*}}, %{{.*}}, %{{.*}} : memref<f32>, memref<f32>, memref<f32>)1033// CHECK:   acc.update dataOperands(%{{.*}}, %{{.*}}, %{{.*}} : memref<f32>, memref<f32>, memref<f32>) attributes {ifPresent}1034 1035// -----1036 1037%i64Value = arith.constant 1 : i641038%i32Value = arith.constant 1 : i321039%idxValue = arith.constant 1 : index1040%ifCond = arith.constant true1041acc.wait1042acc.wait(%i64Value: i64)1043acc.wait(%i32Value: i32)1044acc.wait(%idxValue: index)1045acc.wait(%i32Value, %idxValue : i32, index)1046acc.wait async(%i64Value: i64)1047acc.wait async(%i32Value: i32)1048acc.wait async(%idxValue: index)1049acc.wait(%i32Value: i32) async(%idxValue: index)1050acc.wait(%i64Value: i64) wait_devnum(%i32Value: i32)1051acc.wait async1052acc.wait(%i64Value: i64) async(%idxValue: index) wait_devnum(%i32Value: i32)1053acc.wait(%i64Value: i64) wait_devnum(%i32Value: i32) async(%idxValue: index)1054acc.wait if(%ifCond)1055 1056// CHECK: [[I64VALUE:%.*]] = arith.constant 1 : i641057// CHECK: [[I32VALUE:%.*]] = arith.constant 1 : i321058// CHECK: [[IDXVALUE:%.*]] = arith.constant 1 : index1059// CHECK: [[IFCOND:%.*]] = arith.constant true1060// CHECK: acc.wait1061// CHECK: acc.wait([[I64VALUE]] : i64)1062// CHECK: acc.wait([[I32VALUE]] : i32)1063// CHECK: acc.wait([[IDXVALUE]] : index)1064// CHECK: acc.wait([[I32VALUE]], [[IDXVALUE]] : i32, index)1065// CHECK: acc.wait async([[I64VALUE]] : i64)1066// CHECK: acc.wait async([[I32VALUE]] : i32)1067// CHECK: acc.wait async([[IDXVALUE]] : index)1068// CHECK: acc.wait([[I32VALUE]] : i32) async([[IDXVALUE]] : index)1069// CHECK: acc.wait([[I64VALUE]] : i64) wait_devnum([[I32VALUE]] : i32)1070// CHECK: acc.wait async1071// CHECK: acc.wait([[I64VALUE]] : i64) async([[IDXVALUE]] : index) wait_devnum([[I32VALUE]] : i32)1072// CHECK: acc.wait([[I64VALUE]] : i64) async([[IDXVALUE]] : index) wait_devnum([[I32VALUE]] : i32)1073// CHECK: acc.wait if([[IFCOND]])1074 1075// -----1076 1077%i64Value = arith.constant 1 : i641078%i32Value = arith.constant 1 : i321079%i32Value2 = arith.constant 2 : i321080%idxValue = arith.constant 1 : index1081%ifCond = arith.constant true1082acc.init1083acc.init attributes {acc.device_types = [#acc.device_type<nvidia>]}1084acc.init device_num(%i64Value : i64)1085acc.init device_num(%i32Value : i32)1086acc.init device_num(%idxValue : index)1087acc.init if(%ifCond)1088acc.init if(%ifCond) device_num(%idxValue : index)1089acc.init device_num(%idxValue : index) if(%ifCond)1090 1091// CHECK: [[I64VALUE:%.*]] = arith.constant 1 : i641092// CHECK: [[I32VALUE:%.*]] = arith.constant 1 : i321093// CHECK: [[I32VALUE2:%.*]] = arith.constant 2 : i321094// CHECK: [[IDXVALUE:%.*]] = arith.constant 1 : index1095// CHECK: [[IFCOND:%.*]] = arith.constant true1096// CHECK: acc.init1097// CHECK: acc.init attributes {acc.device_types = [#acc.device_type<nvidia>]} 1098// CHECK: acc.init device_num([[I64VALUE]] : i64)1099// CHECK: acc.init device_num([[I32VALUE]] : i32)1100// CHECK: acc.init device_num([[IDXVALUE]] : index)1101// CHECK: acc.init if([[IFCOND]])1102// CHECK: acc.init device_num([[IDXVALUE]] : index) if([[IFCOND]])1103// CHECK: acc.init device_num([[IDXVALUE]] : index) if([[IFCOND]])1104 1105// -----1106 1107%i64Value = arith.constant 1 : i641108%i32Value = arith.constant 1 : i321109%i32Value2 = arith.constant 2 : i321110%idxValue = arith.constant 1 : index1111%ifCond = arith.constant true1112acc.shutdown1113acc.shutdown attributes {acc.device_types = [#acc.device_type<default>]}1114acc.shutdown device_num(%i64Value : i64)1115acc.shutdown device_num(%i32Value : i32)1116acc.shutdown device_num(%idxValue : index)1117acc.shutdown if(%ifCond)1118acc.shutdown if(%ifCond) device_num(%idxValue : index)1119acc.shutdown device_num(%idxValue : index) if(%ifCond)1120 1121// CHECK: [[I64VALUE:%.*]] = arith.constant 1 : i641122// CHECK: [[I32VALUE:%.*]] = arith.constant 1 : i321123// CHECK: [[I32VALUE2:%.*]] = arith.constant 2 : i321124// CHECK: [[IDXVALUE:%.*]] = arith.constant 1 : index1125// CHECK: [[IFCOND:%.*]] = arith.constant true1126// CHECK: acc.shutdown1127// CHECK: acc.shutdown attributes {acc.device_types = [#acc.device_type<default>]}1128// CHECK: acc.shutdown device_num([[I64VALUE]] : i64)1129// CHECK: acc.shutdown device_num([[I32VALUE]] : i32)1130// CHECK: acc.shutdown device_num([[IDXVALUE]] : index)1131// CHECK: acc.shutdown if([[IFCOND]])1132// CHECK: acc.shutdown device_num([[IDXVALUE]] : index) if([[IFCOND]])1133// CHECK: acc.shutdown device_num([[IDXVALUE]] : index) if([[IFCOND]])1134 1135// -----1136 1137func.func @testexitdataop(%a: !llvm.ptr) -> () {1138  %ifCond = arith.constant true1139  %i64Value = arith.constant 1 : i641140  %i32Value = arith.constant 1 : i321141  %idxValue = arith.constant 1 : index1142 1143  %0 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1144  acc.exit_data dataOperands(%0 : !llvm.ptr)1145  acc.copyout accPtr(%0 : !llvm.ptr) to varPtr(%a : !llvm.ptr) varType(f64)1146 1147  %1 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1148  acc.exit_data dataOperands(%1 : !llvm.ptr)1149  acc.delete accPtr(%1 : !llvm.ptr)1150 1151  %2 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1152  acc.exit_data async dataOperands(%2 : !llvm.ptr) attributes {finalize}1153  acc.delete accPtr(%2 : !llvm.ptr)1154 1155  %3 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1156  acc.exit_data dataOperands(%3 : !llvm.ptr)1157  acc.detach accPtr(%3 : !llvm.ptr)1158 1159  %4 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1160  acc.exit_data async dataOperands(%4 : !llvm.ptr)1161  acc.copyout accPtr(%4 : !llvm.ptr) to varPtr(%a : !llvm.ptr) varType(f64)1162 1163  %5 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1164  acc.exit_data wait dataOperands(%5 : !llvm.ptr)1165  acc.delete accPtr(%5 : !llvm.ptr)1166 1167  %6 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1168  acc.exit_data async(%i64Value : i64) dataOperands(%6 : !llvm.ptr)1169  acc.copyout accPtr(%6 : !llvm.ptr) to varPtr(%a : !llvm.ptr) varType(f64)1170 1171  %7 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1172  acc.exit_data dataOperands(%7 : !llvm.ptr) async(%i64Value : i64)1173  acc.copyout accPtr(%7 : !llvm.ptr) to varPtr(%a : !llvm.ptr) varType(f64)1174 1175  %8 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1176  acc.exit_data if(%ifCond) dataOperands(%8 : !llvm.ptr)1177  acc.copyout accPtr(%8 : !llvm.ptr) to varPtr(%a : !llvm.ptr) varType(f64)1178 1179  %9 = acc.getdeviceptr varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1180  acc.exit_data wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) dataOperands(%9 : !llvm.ptr)1181  acc.copyout accPtr(%9 : !llvm.ptr) to varPtr(%a : !llvm.ptr) varType(f64)1182 1183  return1184}1185 1186// CHECK: func @testexitdataop(%[[ARGA:.*]]: !llvm.ptr) {1187// CHECK: %[[IFCOND:.*]] = arith.constant true1188// CHECK: %[[I64VALUE:.*]] = arith.constant 1 : i641189// CHECK: %[[I32VALUE:.*]] = arith.constant 1 : i321190// CHECK: %[[IDXVALUE:.*]] = arith.constant 1 : index1191 1192// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1193// CHECK: acc.exit_data dataOperands(%[[DEVPTR]] : !llvm.ptr)1194// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) varType(f64)1195 1196// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1197// CHECK: acc.exit_data dataOperands(%[[DEVPTR]] : !llvm.ptr)1198// CHECK: acc.delete accPtr(%[[DEVPTR]] : !llvm.ptr)1199 1200// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1201// CHECK: acc.exit_data async dataOperands(%[[DEVPTR]] : !llvm.ptr) attributes {finalize}1202// CHECK: acc.delete accPtr(%[[DEVPTR]] : !llvm.ptr)1203 1204// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1205// CHECK: acc.exit_data dataOperands(%[[DEVPTR]] : !llvm.ptr)1206// CHECK: acc.detach accPtr(%[[DEVPTR]] : !llvm.ptr)1207 1208// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1209// CHECK: acc.exit_data async dataOperands(%[[DEVPTR]] : !llvm.ptr)1210// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) varType(f64)1211 1212// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1213// CHECK: acc.exit_data wait dataOperands(%[[DEVPTR]] : !llvm.ptr)1214// CHECK: acc.delete accPtr(%[[DEVPTR]] : !llvm.ptr)1215 1216// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1217// CHECK: acc.exit_data async(%[[I64VALUE]] : i64) dataOperands(%[[DEVPTR]] : !llvm.ptr)1218// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) varType(f64)1219 1220// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1221// CHECK: acc.exit_data async(%[[I64VALUE]] : i64) dataOperands(%[[DEVPTR]] : !llvm.ptr)1222// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) varType(f64)1223 1224// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1225// CHECK: acc.exit_data if(%[[IFCOND]]) dataOperands(%[[DEVPTR]] : !llvm.ptr)1226// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) varType(f64)1227 1228// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1229// CHECK: acc.exit_data wait_devnum(%[[I64VALUE]] : i64) wait(%[[I32VALUE]], %[[IDXVALUE]] : i32, index) dataOperands(%[[DEVPTR]] : !llvm.ptr)1230// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) varType(f64)1231 1232// -----1233 1234 1235func.func @testenterdataop(%a: !llvm.ptr, %b: !llvm.ptr, %c: !llvm.ptr) -> () {1236  %ifCond = arith.constant true1237  %i64Value = arith.constant 1 : i641238  %i32Value = arith.constant 1 : i321239  %idxValue = arith.constant 1 : index1240 1241  %0 = acc.copyin varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1242  acc.enter_data dataOperands(%0 : !llvm.ptr)1243  %1 = acc.create varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1244  %2 = acc.create varPtr(%b : !llvm.ptr) varType(f64) -> !llvm.ptr {dataClause = #acc<data_clause acc_create_zero>}1245  %3 = acc.create varPtr(%c : !llvm.ptr) varType(f64) -> !llvm.ptr {dataClause = #acc<data_clause acc_create_zero>}1246  acc.enter_data dataOperands(%1, %2, %3 : !llvm.ptr, !llvm.ptr, !llvm.ptr)1247  %4 = acc.attach varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1248  acc.enter_data dataOperands(%4 : !llvm.ptr)1249  %5 = acc.copyin varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1250  acc.enter_data async dataOperands(%5 : !llvm.ptr)1251  %6 = acc.create varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1252  acc.enter_data wait dataOperands(%6 : !llvm.ptr)1253  %7 = acc.copyin varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1254  acc.enter_data async(%i64Value : i64) dataOperands(%7 : !llvm.ptr)1255  %8 = acc.copyin varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1256  acc.enter_data dataOperands(%8 : !llvm.ptr) async(%i64Value : i64)1257  %9 = acc.copyin varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1258  acc.enter_data if(%ifCond) dataOperands(%9 : !llvm.ptr)1259  %10 = acc.copyin varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1260  acc.enter_data wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) dataOperands(%10 : !llvm.ptr)1261 1262  return1263}1264 1265// CHECK: func @testenterdataop(%[[ARGA:.*]]: !llvm.ptr, %[[ARGB:.*]]: !llvm.ptr, %[[ARGC:.*]]: !llvm.ptr) {1266// CHECK: [[IFCOND:%.*]] = arith.constant true1267// CHECK: [[I64VALUE:%.*]] = arith.constant 1 : i641268// CHECK: [[I32VALUE:%.*]] = arith.constant 1 : i321269// CHECK: [[IDXVALUE:%.*]] = arith.constant 1 : index1270// CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1271// CHECK: acc.enter_data dataOperands(%[[COPYIN]] : !llvm.ptr)1272// CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1273// CHECK: %[[CREATE_B:.*]] = acc.create varPtr(%[[ARGB]] : !llvm.ptr) varType(f64) -> !llvm.ptr {dataClause = #acc<data_clause acc_create_zero>}1274// CHECK: %[[CREATE_C:.*]] = acc.create varPtr(%[[ARGC]] : !llvm.ptr) varType(f64) -> !llvm.ptr {dataClause = #acc<data_clause acc_create_zero>}1275// CHECK: acc.enter_data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : !llvm.ptr, !llvm.ptr, !llvm.ptr)1276// CHECK: %[[ATTACH:.*]] = acc.attach varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1277// CHECK: acc.enter_data dataOperands(%[[ATTACH]] : !llvm.ptr)1278// CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1279// CHECK: acc.enter_data async dataOperands(%[[COPYIN]] : !llvm.ptr)1280// CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1281// CHECK: acc.enter_data wait dataOperands(%[[CREATE]] : !llvm.ptr)1282// CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1283// CHECK: acc.enter_data async([[I64VALUE]] : i64) dataOperands(%[[COPYIN]] : !llvm.ptr)1284// CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1285// CHECK: acc.enter_data async([[I64VALUE]] : i64) dataOperands(%[[COPYIN]] : !llvm.ptr)1286// CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1287// CHECK: acc.enter_data if([[IFCOND]]) dataOperands(%[[COPYIN]] : !llvm.ptr)1288// CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ARGA]] : !llvm.ptr) varType(f64) -> !llvm.ptr1289// CHECK: acc.enter_data wait_devnum([[I64VALUE]] : i64) wait([[I32VALUE]], [[IDXVALUE]] : i32, index) dataOperands(%[[COPYIN]] : !llvm.ptr)1290 1291// -----1292 1293func.func @teststructureddataclauseops(%a: memref<10xf32>, %b: memref<memref<10xf32>>, %c: memref<10x20xf32>) -> () {1294  %deviceptr = acc.deviceptr varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {name = "arrayA"}1295  acc.parallel dataOperands(%deviceptr : memref<10xf32>) {1296  }1297 1298  %present = acc.present varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>1299  acc.data dataOperands(%present : memref<10xf32>) {1300  }1301 1302  %copyin = acc.copyin varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>1303  acc.parallel dataOperands(%copyin : memref<10xf32>) {1304  }1305 1306  %copyinreadonly = acc.copyin varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copyin_readonly>}1307  acc.kernels dataOperands(%copyinreadonly : memref<10xf32>) {1308  }1309 1310  %copyinfromcopy = acc.copyin varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copy>}1311  acc.serial dataOperands(%copyinfromcopy : memref<10xf32>) {1312  }1313  acc.copyout accPtr(%copyinfromcopy : memref<10xf32>) to varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) {dataClause = #acc<data_clause acc_copy>}1314 1315  %create = acc.create varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>1316  %createimplicit = acc.create varPtr(%c : memref<10x20xf32>) varType(tensor<10x20xf32>) -> memref<10x20xf32> {implicit = true}1317  acc.parallel dataOperands(%create, %createimplicit : memref<10xf32>, memref<10x20xf32>) {1318  }1319  acc.delete accPtr(%create : memref<10xf32>) {dataClause = #acc<data_clause acc_create>}1320  acc.delete accPtr(%createimplicit : memref<10x20xf32>) {dataClause = #acc<data_clause acc_create>, implicit = true}1321 1322  %copyoutzero = acc.create varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copyout_zero>}1323  acc.parallel dataOperands(%copyoutzero: memref<10xf32>) {1324  }1325  acc.copyout accPtr(%copyoutzero : memref<10xf32>) to varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) {dataClause = #acc<data_clause acc_copyout_zero>}1326 1327  %attach = acc.attach varPtr(%b : memref<memref<10xf32>>) -> memref<memref<10xf32>>1328  acc.parallel dataOperands(%attach : memref<memref<10xf32>>) {1329  }1330  acc.detach accPtr(%attach : memref<memref<10xf32>>) {dataClause = #acc<data_clause acc_attach>}1331 1332  %copyinparent = acc.copyin varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) varPtrPtr(%b : memref<memref<10xf32>>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copy>}1333  acc.parallel dataOperands(%copyinparent : memref<10xf32>) {1334  }1335  acc.copyout accPtr(%copyinparent : memref<10xf32>) to varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) {dataClause = #acc<data_clause acc_copy>}1336 1337  %c0 = arith.constant 0 : index1338  %c1 = arith.constant 1 : index1339  %c4 = arith.constant 4 : index1340  %c9 = arith.constant 9 : index1341  %c10 = arith.constant 10 : index1342  %c20 = arith.constant 20 : index1343 1344  %bounds1full = acc.bounds lowerbound(%c0 : index) upperbound(%c9 : index) stride(%c1 : index)1345  %copyinfullslice1 = acc.copyin varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) bounds(%bounds1full) -> memref<10xf32> {name = "arrayA[0:9]"}1346  // Specify full-bounds but assume that startIdx of array reference is 1.1347  %bounds2full = acc.bounds lowerbound(%c1 : index) upperbound(%c20 : index) extent(%c20 : index) stride(%c4 : index) startIdx(%c1 : index) {strideInBytes = true}1348  %copyinfullslice2 = acc.copyin varPtr(%c : memref<10x20xf32>) varType(tensor<10x20xf32>) bounds(%bounds1full, %bounds2full) -> memref<10x20xf32>1349  acc.parallel dataOperands(%copyinfullslice1, %copyinfullslice2 : memref<10xf32>, memref<10x20xf32>) {1350  }1351 1352  %bounds1partial = acc.bounds lowerbound(%c4 : index) upperbound(%c9 : index) stride(%c1 : index)1353  %copyinpartial = acc.copyin varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) bounds(%bounds1partial) -> memref<10xf32> {dataClause = #acc<data_clause acc_copy>}1354  acc.parallel dataOperands(%copyinpartial : memref<10xf32>) {1355  }1356  acc.copyout accPtr(%copyinpartial : memref<10xf32>) bounds(%bounds1partial) to varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) {dataClause = #acc<data_clause acc_copy>}1357 1358  return1359}1360 1361// CHECK: func.func @teststructureddataclauseops([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<memref<10xf32>>, [[ARGC:%.*]]: memref<10x20xf32>) {1362// CHECK: [[DEVICEPTR:%.*]] = acc.deviceptr varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {name = "arrayA"}1363// CHECK-NEXT: acc.parallel dataOperands([[DEVICEPTR]] : memref<10xf32>) {1364// CHECK-NEXT: }1365// CHECK: [[PRESENT:%.*]] = acc.present varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>1366// CHECK-NEXT: acc.data dataOperands([[PRESENT]] : memref<10xf32>) {1367// CHECK-NEXT: }1368// CHECK: [[COPYIN:%.*]] = acc.copyin varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>1369// CHECK-NEXT: acc.parallel dataOperands([[COPYIN]] : memref<10xf32>) {1370// CHECK-NEXT: }1371// CHECK: [[COPYINRO:%.*]] = acc.copyin varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copyin_readonly>}1372// CHECK-NEXT: acc.kernels dataOperands([[COPYINRO]] : memref<10xf32>) {1373// CHECK-NEXT: }1374// CHECK: [[COPYINCOPY:%.*]] = acc.copyin varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copy>}1375// CHECK-NEXT: acc.serial dataOperands([[COPYINCOPY]] : memref<10xf32>) {1376// CHECK-NEXT: }1377// CHECK-NEXT: acc.copyout accPtr([[COPYINCOPY]] : memref<10xf32>) to varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) {dataClause = #acc<data_clause acc_copy>}1378// CHECK: [[CREATE:%.*]] = acc.create varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>1379// CHECK-NEXT: [[CREATEIMP:%.*]] = acc.create varPtr([[ARGC]] : memref<10x20xf32>) varType(tensor<10x20xf32>) -> memref<10x20xf32> {implicit = true}1380// CHECK-NEXT: acc.parallel dataOperands([[CREATE]], [[CREATEIMP]] : memref<10xf32>, memref<10x20xf32>) {1381// CHECK-NEXT: }1382// CHECK-NEXT: acc.delete accPtr([[CREATE]] : memref<10xf32>) {dataClause = #acc<data_clause acc_create>}1383// CHECK-NEXT: acc.delete accPtr([[CREATEIMP]] : memref<10x20xf32>) {dataClause = #acc<data_clause acc_create>, implicit = true}1384// CHECK: [[COPYOUTZ:%.*]] = acc.create varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copyout_zero>}1385// CHECK-NEXT: acc.parallel dataOperands([[COPYOUTZ]] : memref<10xf32>) {1386// CHECK-NEXT: }1387// CHECK-NEXT: acc.copyout accPtr([[COPYOUTZ]] : memref<10xf32>) to varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) {dataClause = #acc<data_clause acc_copyout_zero>}1388// CHECK: [[ATTACH:%.*]] = acc.attach varPtr([[ARGB]] : memref<memref<10xf32>>) -> memref<memref<10xf32>>1389// CHECK-NEXT: acc.parallel dataOperands([[ATTACH]] : memref<memref<10xf32>>) {1390// CHECK-NEXT: }1391// CHECK-NEXT: acc.detach accPtr([[ATTACH]] : memref<memref<10xf32>>) {dataClause = #acc<data_clause acc_attach>}1392// CHECK: [[COPYINP:%.*]] = acc.copyin varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) varPtrPtr([[ARGB]] : memref<memref<10xf32>>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copy>}1393// CHECK-NEXT: acc.parallel dataOperands([[COPYINP]] : memref<10xf32>) {1394// CHECK-NEXT: }1395// CHECK-NEXT: acc.copyout accPtr([[COPYINP]] : memref<10xf32>) to varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) {dataClause = #acc<data_clause acc_copy>}1396// CHECK-DAG: [[CON0:%.*]] = arith.constant 0 : index1397// CHECK-DAG: [[CON1:%.*]] = arith.constant 1 : index1398// CHECK-DAG: [[CON4:%.*]] = arith.constant 4 : index1399// CHECK-DAG: [[CON9:%.*]] = arith.constant 9 : index1400// CHECK-DAG: [[CON20:%.*]] = arith.constant 20 : index1401// CHECK: [[BOUNDS1F:%.*]] = acc.bounds lowerbound([[CON0]] : index) upperbound([[CON9]] : index) stride([[CON1]] : index)1402// CHECK-NEXT: [[COPYINF1:%.*]] = acc.copyin varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) bounds([[BOUNDS1F]]) -> memref<10xf32> {name = "arrayA[0:9]"}1403// CHECK-NEXT: [[BOUNDS2F:%.*]] = acc.bounds lowerbound([[CON1]] : index) upperbound([[CON20]] : index) extent([[CON20]] : index) stride([[CON4]] : index) startIdx([[CON1]] : index) {strideInBytes = true}1404// CHECK-NEXT: [[COPYINF2:%.*]] = acc.copyin varPtr([[ARGC]] : memref<10x20xf32>) varType(tensor<10x20xf32>) bounds([[BOUNDS1F]], [[BOUNDS2F]]) -> memref<10x20xf32>1405// CHECK-NEXT: acc.parallel dataOperands([[COPYINF1]], [[COPYINF2]] : memref<10xf32>, memref<10x20xf32>) {1406// CHECK-NEXT: }1407// CHECK: [[BOUNDS1P:%.*]] = acc.bounds lowerbound([[CON4]] : index) upperbound([[CON9]] : index) stride([[CON1]] : index)1408// CHECK-NEXT: [[COPYINPART:%.*]] = acc.copyin varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) bounds([[BOUNDS1P]]) -> memref<10xf32> {dataClause = #acc<data_clause acc_copy>}1409// CHECK-NEXT: acc.parallel dataOperands([[COPYINPART]] : memref<10xf32>) {1410// CHECK-NEXT: }1411// CHECK-NEXT: acc.copyout accPtr([[COPYINPART]] : memref<10xf32>) bounds([[BOUNDS1P]]) to varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) {dataClause = #acc<data_clause acc_copy>}1412 1413// -----1414 1415func.func @testunstructuredclauseops(%a: memref<10xf32>) -> () {1416  %copyin = acc.copyin varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {structured = false}1417  acc.enter_data dataOperands(%copyin : memref<10xf32>)1418 1419  %devptr = acc.getdeviceptr varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copyout>}1420  acc.exit_data dataOperands(%devptr : memref<10xf32>)1421  acc.copyout accPtr(%devptr : memref<10xf32>) to varPtr(%a : memref<10xf32>) varType(tensor<10xf32>) {structured = false}1422 1423  return1424}1425 1426// CHECK: func.func @testunstructuredclauseops([[ARGA:%.*]]: memref<10xf32>) {1427// CHECK: [[COPYIN:%.*]] = acc.copyin varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {structured = false}1428// CHECK-NEXT: acc.enter_data dataOperands([[COPYIN]] : memref<10xf32>)1429// CHECK: [[DEVPTR:%.*]] = acc.getdeviceptr varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32> {dataClause = #acc<data_clause acc_copyout>}1430// CHECK-NEXT: acc.exit_data dataOperands([[DEVPTR]] : memref<10xf32>)1431// CHECK-NEXT: acc.copyout accPtr([[DEVPTR]] : memref<10xf32>) to varPtr([[ARGA]] : memref<10xf32>) varType(tensor<10xf32>) {structured = false}1432 1433// -----1434 1435func.func @host_device_ops(%a: memref<f32>) -> () {1436  %devptr = acc.getdeviceptr varPtr(%a : memref<f32>) -> memref<f32>1437  acc.update_host accPtr(%devptr : memref<f32>) to varPtr(%a : memref<f32>) {structured = false}1438  acc.update dataOperands(%devptr : memref<f32>)1439 1440  %accPtr = acc.update_device varPtr(%a : memref<f32>) -> memref<f32>1441  acc.update dataOperands(%accPtr : memref<f32>)1442  return1443}1444 1445// CHECK-LABEL: func.func @host_device_ops(1446// CHECK-SAME:    %[[A:.*]]: memref<f32>)1447// CHECK: %[[DEVPTR_A:.*]] = acc.getdeviceptr varPtr(%[[A]] : memref<f32>)   -> memref<f32>1448// CHECK: acc.update_host accPtr(%[[DEVPTR_A]] : memref<f32>) to varPtr(%[[A]] : memref<f32>) {structured = false}1449// CHECK: acc.update dataOperands(%[[DEVPTR_A]] : memref<f32>)1450// CHECK: %[[DEVPTR_A:.*]] = acc.update_device varPtr(%[[A]] : memref<f32>)   -> memref<f32>1451// CHECK: acc.update dataOperands(%[[DEVPTR_A]] : memref<f32>)1452 1453// -----1454 1455func.func @host_data_ops(%a: !llvm.ptr, %ifCond: i1) -> () {1456  %0 = acc.use_device varPtr(%a : !llvm.ptr) varType(f64) -> !llvm.ptr1457  acc.host_data dataOperands(%0: !llvm.ptr) {1458  }1459  acc.host_data dataOperands(%0: !llvm.ptr) {1460  } attributes {if_present}1461  acc.host_data if(%ifCond) dataOperands(%0: !llvm.ptr) {1462  }1463  return1464}1465 1466// CHECK-LABEL: func.func @host_data_ops(1467// CHECK-SAME:    %[[A:.*]]: !llvm.ptr, %[[IFCOND:.*]]: i1)1468// CHECK: %[[PTR:.*]] = acc.use_device varPtr(%[[A]] : !llvm.ptr) varType(f64) -> !llvm.ptr1469// CHECK: acc.host_data dataOperands(%[[PTR]] : !llvm.ptr)1470// CHECK: acc.host_data dataOperands(%[[PTR]] : !llvm.ptr) {1471// CHECK: } attributes {if_present}1472// CHECK: acc.host_data if(%[[IFCOND]]) dataOperands(%[[PTR]] : !llvm.ptr)1473 1474// -----1475 1476acc.private.recipe @privatization_i32 : !llvm.ptr init {1477^bb0(%arg0: !llvm.ptr):1478  %c1 = arith.constant 1 : i321479  %c0 = arith.constant 0 : i321480  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr1481  llvm.store %c0, %0 : i32, !llvm.ptr1482  acc.yield %0 : !llvm.ptr1483}1484 1485// CHECK: acc.private.recipe @privatization_i32 : !llvm.ptr init {1486// CHECK: %[[C1:.*]] = arith.constant 1 : i321487// CHECK: %[[C0:.*]] = arith.constant 0 : i321488// CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[C1]] x i32 : (i32) -> !llvm.ptr1489// CHECK: llvm.store %[[C0]], %[[ALLOCA]] : i32, !llvm.ptr1490// CHECK: acc.yield %[[ALLOCA]] : !llvm.ptr1491 1492// -----1493 1494func.func private @destroy_struct(!llvm.struct<(i32, i32)>) -> ()1495 1496acc.private.recipe @privatization_struct_i32_i64 : !llvm.struct<(i32, i32)> init {1497^bb0(%arg0 : !llvm.struct<(i32, i32)>):1498  %c1 = arith.constant 1 : i321499  %0 = llvm.mlir.undef : !llvm.struct<(i32, i32)>1500  %1 = llvm.insertvalue %c1, %0[0] : !llvm.struct<(i32, i32)>1501  %2 = llvm.insertvalue %c1, %1[1] : !llvm.struct<(i32, i32)>1502  acc.yield %2 : !llvm.struct<(i32, i32)>1503} destroy {1504^bb0(%arg0: !llvm.struct<(i32, i32)>):1505  func.call @destroy_struct(%arg0) : (!llvm.struct<(i32, i32)>) -> ()1506  acc.terminator1507}1508 1509// CHECK: func.func private @destroy_struct(!llvm.struct<(i32, i32)>)1510 1511// CHECK: acc.private.recipe @privatization_struct_i32_i64 : !llvm.struct<(i32, i32)> init {1512// CHECK:   %[[C1:.*]] = arith.constant 1 : i321513// CHECK:   %[[UNDEF:.*]] = llvm.mlir.undef : !llvm.struct<(i32, i32)>1514// CHECK:   %[[UNDEF1:.*]] = llvm.insertvalue %[[C1]], %[[UNDEF]][0] : !llvm.struct<(i32, i32)> 1515// CHECK:   %[[UNDEF2:.*]] = llvm.insertvalue %[[C1]], %[[UNDEF1]][1] : !llvm.struct<(i32, i32)> 1516// CHECK:   acc.yield %[[UNDEF2]] : !llvm.struct<(i32, i32)>1517// CHECK: } destroy {1518// CHECK: ^bb0(%[[ARG0:.*]]: !llvm.struct<(i32, i32)>):1519// CHECK:   func.call @destroy_struct(%[[ARG0]]) : (!llvm.struct<(i32, i32)>) -> ()1520// CHECK:   acc.terminator1521 1522// -----1523 1524acc.reduction.recipe @reduction_add_memref_i64 : memref<i64> reduction_operator <add> init {1525^bb0(%arg0: memref<i64>):1526  %c0_i64 = arith.constant 0 : i641527  %alloca = memref.alloca() : memref<i64>1528  memref.store %c0_i64, %alloca[] : memref<i64>1529  acc.yield %alloca : memref<i64>1530} combiner {1531^bb0(%arg0: memref<i64>, %arg1: memref<i64>):1532  %0 = memref.load %arg0[] : memref<i64>1533  %1 = memref.load %arg1[] : memref<i64>1534  %2 = arith.addi %0, %1 : i641535  memref.store %2, %arg0[] : memref<i64>1536  acc.yield %arg0 : memref<i64>1537}1538 1539// CHECK-LABEL: acc.reduction.recipe @reduction_add_memref_i64 : memref<i64> reduction_operator <add> init {1540// CHECK:       ^bb0(%{{.*}}: memref<i64>):1541// CHECK:         %[[C0:.*]] = arith.constant 0 : i641542// CHECK:         %[[ALLOCA:.*]] = memref.alloca() : memref<i64>1543// CHECK:         memref.store %[[C0]], %[[ALLOCA]][] : memref<i64>1544// CHECK:         acc.yield %[[ALLOCA]] : memref<i64>1545// CHECK:       } combiner {1546// CHECK:       ^bb0(%[[ARG0:.*]]: memref<i64>, %[[ARG1:.*]]: memref<i64>):1547// CHECK:         %[[LOAD0:.*]] = memref.load %[[ARG0]][] : memref<i64>1548// CHECK:         %[[LOAD1:.*]] = memref.load %[[ARG1]][] : memref<i64>1549// CHECK:         %[[RES:.*]] = arith.addi %[[LOAD0]], %[[LOAD1]] : i641550// CHECK:         memref.store %[[RES]], %[[ARG0]][] : memref<i64>1551// CHECK:         acc.yield %[[ARG0]] : memref<i64>1552// CHECK:       }1553 1554func.func @acc_reduc_test(%a : memref<i64>) -> () {1555  %c0 = arith.constant 0 : index1556  %c10 = arith.constant 10 : index1557  %c1 = arith.constant 1 : index1558  %reduction_a = acc.reduction varPtr(%a : memref<i64>) recipe(@reduction_add_memref_i64) ->  memref<i64>1559  acc.parallel reduction(%reduction_a :  memref<i64>) {1560    acc.loop reduction(%reduction_a :  memref<i64>) control(%iv : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {1561      acc.yield1562    } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}1563    acc.yield1564  }1565  return1566}1567 1568// CHECK-LABEL: func.func @acc_reduc_test(1569// CHECK-SAME:    %[[ARG0:.*]]: memref<i64>)1570// CHECK:         %[[REDUCTION_A:.*]] = acc.reduction varPtr(%[[ARG0]] : memref<i64>) recipe(@reduction_add_memref_i64) -> memref<i64>1571// CHECK-NEXT:    acc.parallel reduction(%[[REDUCTION_A]] : memref<i64>)1572// CHECK:           acc.loop reduction(%[[REDUCTION_A]] : memref<i64>)1573 1574// -----1575 1576acc.reduction.recipe @reduction_add_memref_i64 : memref<i64> reduction_operator <add> init {1577^bb0(%arg0: memref<i64>):1578  %c0_i64 = arith.constant 0 : i641579  %alloca = memref.alloca() : memref<i64>1580  memref.store %c0_i64, %alloca[] : memref<i64>1581  acc.yield %alloca : memref<i64>1582} combiner {1583^bb0(%arg0: memref<i64>, %arg1: memref<i64>):1584  %0 = memref.load %arg0[] : memref<i64>1585  %1 = memref.load %arg1[] : memref<i64>1586  %2 = arith.addi %0, %1 : i641587  memref.store %2, %arg0[] : memref<i64>1588  acc.yield %arg0 : memref<i64>1589}1590 1591func.func @acc_reduc_test(%a : memref<i64>) -> () {1592  %reduction_a = acc.reduction varPtr(%a : memref<i64>) recipe(@reduction_add_memref_i64) -> memref<i64>1593  acc.serial reduction(%reduction_a : memref<i64>) {1594  }1595  return1596}1597 1598// CHECK-LABEL: func.func @acc_reduc_test(1599// CHECK-SAME:    %[[ARG0:.*]]: memref<i64>)1600// CHECK:         %[[REDUCTION_A:.*]] = acc.reduction varPtr(%[[ARG0]] : memref<i64>) recipe(@reduction_add_memref_i64) -> memref<i64>1601// CHECK-NEXT:    acc.serial reduction(%[[REDUCTION_A]] : memref<i64>)1602 1603// -----1604 1605func.func @testdeclareop(%a: memref<f32>, %b: memref<f32>, %c: memref<f32>) -> () {1606  %0 = acc.copyin varPtr(%a : memref<f32>) -> memref<f32>1607  // copyin(zero)1608  %1 = acc.copyin varPtr(%b : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyin_readonly>}1609  // copy1610  %2 = acc.copyin varPtr(%c : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copy>}1611  acc.declare_enter dataOperands(%0, %1, %2 : memref<f32>, memref<f32>, memref<f32>)1612 1613  %3 = acc.create varPtr(%a : memref<f32>) -> memref<f32>1614  // copyout1615  %4 = acc.create varPtr(%b : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}1616  %5 = acc.present varPtr(%c : memref<f32>) -> memref<f32>1617  acc.declare_enter dataOperands(%3, %4, %5 : memref<f32>, memref<f32>, memref<f32>)1618 1619  %6 = acc.deviceptr varPtr(%a : memref<f32>) -> memref<f32>1620  %7 = acc.declare_device_resident varPtr(%b : memref<f32>) -> memref<f32>1621  %8 = acc.declare_link varPtr(%c : memref<f32>) -> memref<f32>1622  acc.declare_enter dataOperands(%6, %7, %8 : memref<f32>, memref<f32>, memref<f32>)1623 1624  acc.declare_exit dataOperands(%7, %8 : memref<f32>, memref<f32>)1625  acc.delete accPtr(%7 : memref<f32>) {dataClause = #acc<data_clause acc_declare_device_resident> }1626  acc.delete accPtr(%8 : memref<f32>) {dataClause = #acc<data_clause acc_declare_link> }1627 1628  acc.declare_exit dataOperands(%3, %4, %5 : memref<f32>, memref<f32>, memref<f32>)1629  acc.delete accPtr(%3 : memref<f32>) {dataClause = #acc<data_clause acc_create> }1630  acc.copyout accPtr(%4 : memref<f32>) to varPtr(%b : memref<f32>)1631  acc.delete accPtr(%5 : memref<f32>) {dataClause = #acc<data_clause acc_present> }1632 1633  acc.declare_exit dataOperands(%0, %1, %2 : memref<f32>, memref<f32>, memref<f32>)1634  acc.delete accPtr(%0 : memref<f32>) {dataClause = #acc<data_clause acc_copyin> }1635  acc.delete accPtr(%1 : memref<f32>) {dataClause = #acc<data_clause acc_copyin_readonly> }1636  acc.copyout accPtr(%2 : memref<f32>) to varPtr(%c : memref<f32>) { dataClause = #acc<data_clause acc_copy> }1637 1638  return1639}1640 1641// CHECK-LABEL: func.func @testdeclareop(1642// CHECK-SAME: %[[ARGA:.*]]: memref<f32>, %[[ARGB:.*]]: memref<f32>, %[[ARGC:.*]]: memref<f32>)1643// CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>1644// CHECK-NEXT: %[[COPYINRO:.*]] = acc.copyin varPtr(%[[ARGB]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyin_readonly>}1645// CHECK-NEXT: %[[COPY:.*]] = acc.copyin varPtr(%[[ARGC]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copy>}1646// CHECK-NEXT: acc.declare_enter dataOperands(%[[COPYIN]], %[[COPYINRO]], %[[COPY]] : memref<f32>, memref<f32>, memref<f32>)1647// CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>1648// CHECK-NEXT: %[[COPYOUT:.*]] = acc.create varPtr(%[[ARGB]] : memref<f32>) -> memref<f32> {dataClause = #acc<data_clause acc_copyout>}1649// CHECK-NEXT: %[[PRESENT:.*]] = acc.present varPtr(%[[ARGC]] : memref<f32>) -> memref<f32>1650// CHECK-NEXT: acc.declare_enter dataOperands(%[[CREATE]], %[[COPYOUT]], %[[PRESENT]] : memref<f32>, memref<f32>, memref<f32>)1651// CHECK: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[ARGA]] : memref<f32>) -> memref<f32>1652// CHECK-NEXT: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[ARGB]] : memref<f32>) -> memref<f32>1653// CHECK-NEXT: %[[LINK:.*]] = acc.declare_link varPtr(%[[ARGC]] : memref<f32>) -> memref<f32>1654// CHECK-NEXT: acc.declare_enter dataOperands(%[[DEVICEPTR]], %[[DEVICERES]], %[[LINK]] : memref<f32>, memref<f32>, memref<f32>)1655// CHECK: acc.declare_exit dataOperands(%[[DEVICERES]], %[[LINK]] : memref<f32>, memref<f32>)1656// CHECK-NEXT: acc.delete accPtr(%[[DEVICERES]] : memref<f32>) {dataClause = #acc<data_clause acc_declare_device_resident>}1657// CHECK-NEXT: acc.delete accPtr(%[[LINK]] : memref<f32>) {dataClause = #acc<data_clause acc_declare_link>}1658// CHECK: acc.declare_exit dataOperands(%[[CREATE]], %[[COPYOUT]], %[[PRESENT]] : memref<f32>, memref<f32>, memref<f32>)1659// CHECK-NEXT: acc.delete accPtr(%[[CREATE]] : memref<f32>) {dataClause = #acc<data_clause acc_create>}1660// CHECK-NEXT: acc.copyout accPtr(%[[COPYOUT]] : memref<f32>) to varPtr(%[[ARGB]] : memref<f32>)1661// CHECK-NEXT: acc.delete accPtr(%[[PRESENT]] : memref<f32>) {dataClause = #acc<data_clause acc_present>}1662// CHECK: acc.declare_exit dataOperands(%[[COPYIN]], %[[COPYINRO]], %[[COPY]] : memref<f32>, memref<f32>, memref<f32>)1663// CHECK-NEXT: acc.delete accPtr(%[[COPYIN]] : memref<f32>) {dataClause = #acc<data_clause acc_copyin>}1664// CHECK-NEXT: acc.delete accPtr(%[[COPYINRO]] : memref<f32>) {dataClause = #acc<data_clause acc_copyin_readonly>}1665// CHECK-NEXT: acc.copyout accPtr(%[[COPY]] : memref<f32>) to varPtr(%[[ARGC]] : memref<f32>) {dataClause = #acc<data_clause acc_copy>}1666 1667// -----1668 1669llvm.mlir.global external @globalvar() { acc.declare = #acc.declare<dataClause = acc_create> } : i32 {1670  %0 = llvm.mlir.constant(0 : i32) : i321671  llvm.return %0 : i321672}1673 1674acc.global_ctor @acc_constructor {1675  %0 = llvm.mlir.addressof @globalvar { acc.declare = #acc.declare<dataClause = acc_create> } : !llvm.ptr1676  %1 = acc.create varPtr(%0 : !llvm.ptr) varType(i32) -> !llvm.ptr1677  acc.declare_enter dataOperands(%1 : !llvm.ptr)1678  acc.terminator1679}1680 1681acc.global_dtor @acc_destructor {1682  %0 = llvm.mlir.addressof @globalvar { acc.declare = #acc.declare<dataClause = acc_create> } : !llvm.ptr1683  %1 = acc.getdeviceptr varPtr(%0 : !llvm.ptr) varType(i32) -> !llvm.ptr {dataClause = #acc<data_clause acc_create>}1684  acc.declare_exit dataOperands(%1 : !llvm.ptr)1685  acc.delete accPtr(%1 : !llvm.ptr)1686  acc.terminator1687}1688 1689// CHECK-LABEL: acc.global_ctor @acc_constructor1690// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @globalvar {acc.declare = #acc.declare<dataClause = acc_create>} : !llvm.ptr1691// CHECK-NEXT: %[[CREATE:.*]] = acc.create varPtr(%[[ADDR]] : !llvm.ptr) varType(i32) -> !llvm.ptr1692// CHECK-NEXT: acc.declare_enter dataOperands(%[[CREATE]] : !llvm.ptr)1693// CHECK: acc.global_dtor @acc_destructor1694// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @globalvar {acc.declare = #acc.declare<dataClause = acc_create>} : !llvm.ptr1695// CHECK-NEXT: %[[DELETE:.*]] = acc.getdeviceptr varPtr(%[[ADDR]] : !llvm.ptr) varType(i32) -> !llvm.ptr {dataClause = #acc<data_clause acc_create>}1696// CHECK-NEXT: acc.declare_exit dataOperands(%[[DELETE]] : !llvm.ptr)1697// CHECK-NEXT: acc.delete accPtr(%[[DELETE]] : !llvm.ptr)1698 1699// -----1700 1701func.func @acc_func(%a : i64) -> () attributes {acc.routine_info = #acc.routine_info<[@acc_func_rout1,@acc_func_rout2,@acc_func_rout3,1702    @acc_func_rout4,@acc_func_rout5,@acc_func_rout6,@acc_func_rout7,@acc_func_rout8,@acc_func_rout9]>} {1703  return1704}1705 1706acc.routine @acc_func_rout1 func(@acc_func)1707acc.routine @acc_func_rout2 func(@acc_func) bind("acc_func_gpu")1708acc.routine @acc_func_rout3 func(@acc_func) bind("acc_func_gpu_gang") gang1709acc.routine @acc_func_rout4 func(@acc_func) bind("acc_func_gpu_vector") vector1710acc.routine @acc_func_rout5 func(@acc_func) bind("acc_func_gpu_worker") worker1711acc.routine @acc_func_rout6 func(@acc_func) bind("acc_func_gpu_seq") seq1712acc.routine @acc_func_rout7 func(@acc_func) bind("acc_func_gpu_imp_gang") implicit gang1713acc.routine @acc_func_rout8 func(@acc_func) bind("acc_func_gpu_vector_nohost") vector nohost1714acc.routine @acc_func_rout9 func(@acc_func) bind("acc_func_gpu_gang_dim1") gang(dim: 1 : i64)1715 1716// CHECK-LABEL: func.func @acc_func(1717// CHECK: attributes {acc.routine_info = #acc.routine_info<[@acc_func_rout1, @acc_func_rout2, @acc_func_rout3,1718// CHECK: @acc_func_rout4, @acc_func_rout5, @acc_func_rout6, @acc_func_rout7, @acc_func_rout8, @acc_func_rout9]>}1719// CHECK: acc.routine @acc_func_rout1 func(@acc_func)1720// CHECK: acc.routine @acc_func_rout2 func(@acc_func) bind("acc_func_gpu")1721// CHECK: acc.routine @acc_func_rout3 func(@acc_func) bind("acc_func_gpu_gang") gang1722// CHECK: acc.routine @acc_func_rout4 func(@acc_func) bind("acc_func_gpu_vector") vector1723// CHECK: acc.routine @acc_func_rout5 func(@acc_func) bind("acc_func_gpu_worker") worker1724// CHECK: acc.routine @acc_func_rout6 func(@acc_func) bind("acc_func_gpu_seq") seq1725// CHECK: acc.routine @acc_func_rout7 func(@acc_func) bind("acc_func_gpu_imp_gang") gang implicit1726// CHECK: acc.routine @acc_func_rout8 func(@acc_func) bind("acc_func_gpu_vector_nohost") vector nohost1727// CHECK: acc.routine @acc_func_rout9 func(@acc_func) bind("acc_func_gpu_gang_dim1") gang(dim: 1 : i64)1728 1729// -----1730 1731func.func @acc_func() -> () {1732  "test.openacc_dummy_op"() {acc.declare_action = #acc.declare_action<postAlloc = @_QMacc_declareFacc_declare_allocateEa_acc_declare_update_desc_post_alloc>} : () -> ()1733  return1734}1735 1736// CHECK-LABEL: func.func @acc_func1737// CHECK: "test.openacc_dummy_op"() {acc.declare_action = #acc.declare_action<postAlloc = @_QMacc_declareFacc_declare_allocateEa_acc_declare_update_desc_post_alloc>}1738 1739// -----1740 1741func.func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10xf32>, %d: memref<10xf32>) {1742  %lb = arith.constant 0 : index1743  %st = arith.constant 1 : index1744  %c10 = arith.constant 10 : index1745  %numGangs = arith.constant 10 : i641746  %numWorkers = arith.constant 10 : i641747 1748  %c20 = arith.constant 20 : i321749  %alloc = llvm.alloca %c20 x i32 { acc.declare = #acc.declare<dataClause = acc_create, implicit = true> } : (i32) -> !llvm.ptr1750  %createlocal = acc.create varPtr(%alloc : !llvm.ptr) varType(!llvm.array<20 x i32>) -> !llvm.ptr {implicit = true}1751 1752  %pa = acc.present varPtr(%a : memref<10x10xf32>) varType(tensor<10x10xf32>) -> memref<10x10xf32>1753  %pb = acc.present varPtr(%b : memref<10x10xf32>) varType(tensor<10x10xf32>) -> memref<10x10xf32>1754  %pc = acc.present varPtr(%c : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>1755  %pd = acc.present varPtr(%d : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>1756  acc.declare dataOperands(%pa, %pb, %pc, %pd, %createlocal: memref<10x10xf32>, memref<10x10xf32>, memref<10xf32>, memref<10xf32>, !llvm.ptr) {1757  }1758 1759  return1760}1761 1762// CHECK-LABEL: func.func @compute31763// CHECK: acc.declare dataOperands(1764 1765// -----1766 1767%i64Value = arith.constant 1 : i641768%i32Value = arith.constant 1 : i321769%i32Value2 = arith.constant 2 : i321770%idxValue = arith.constant 1 : index1771%ifCond = arith.constant true1772acc.set attributes {device_type = #acc.device_type<nvidia>}1773acc.set device_num(%i64Value : i64)1774acc.set device_num(%i32Value : i32)1775acc.set device_num(%idxValue : index)1776acc.set device_num(%idxValue : index) if(%ifCond)1777acc.set default_async(%i32Value : i32)1778 1779// CHECK: [[I64VALUE:%.*]] = arith.constant 1 : i641780// CHECK: [[I32VALUE:%.*]] = arith.constant 1 : i321781// CHECK: [[I32VALUE2:%.*]] = arith.constant 2 : i321782// CHECK: [[IDXVALUE:%.*]] = arith.constant 1 : index1783// CHECK: [[IFCOND:%.*]] = arith.constant true1784// CHECK: acc.set attributes {device_type = #acc.device_type<nvidia>}1785// CHECK: acc.set device_num([[I64VALUE]] : i64)1786// CHECK: acc.set device_num([[I32VALUE]] : i32)1787// CHECK: acc.set device_num([[IDXVALUE]] : index)1788// CHECK: acc.set device_num([[IDXVALUE]] : index) if([[IFCOND]])1789// CHECK: acc.set default_async([[I32VALUE]] : i32)1790 1791// -----1792 1793// CHECK-LABEL: func.func @acc_atomic_read1794// CHECK-SAME: (%[[v:.*]]: memref<i32>, %[[x:.*]]: memref<i32>)1795func.func @acc_atomic_read(%v: memref<i32>, %x: memref<i32>) {1796  // CHECK: acc.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321797  acc.atomic.read %v = %x : memref<i32>, memref<i32>, i321798 1799  // CHECK-NEXT: %[[IFCOND1:.*]] = arith.constant true1800  // CHECK-NEXT: acc.atomic.read if(%[[IFCOND1]]) %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321801  %ifCond = arith.constant true1802  acc.atomic.read if(%ifCond) %v = %x : memref<i32>, memref<i32>, i321803 1804  return1805}1806 1807// -----1808 1809// CHECK-LABEL: func.func @acc_atomic_write1810// CHECK-SAME: (%[[ADDR:.*]]: memref<i32>, %[[VAL:.*]]: i32)1811func.func @acc_atomic_write(%addr : memref<i32>, %val : i32) {1812  // CHECK: acc.atomic.write %[[ADDR]] = %[[VAL]] : memref<i32>, i321813  acc.atomic.write %addr = %val : memref<i32>, i321814 1815  // CHECK-NEXT: %[[IFCOND1:.*]] = arith.constant true1816  // CHECK-NEXT: acc.atomic.write if(%[[IFCOND1]]) %[[ADDR]] = %[[VAL]] : memref<i32>, i321817  %ifCond = arith.constant true1818  acc.atomic.write if(%ifCond) %addr = %val : memref<i32>, i321819 1820  return1821}1822 1823// -----1824 1825// CHECK-LABEL: func.func @acc_atomic_update1826// CHECK-SAME: (%[[X:.*]]: memref<i32>, %[[EXPR:.*]]: i32, %[[XBOOL:.*]]: memref<i1>, %[[EXPRBOOL:.*]]: i1)1827func.func @acc_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>, %exprBool : i1) {1828  // CHECK: acc.atomic.update %[[X]] : memref<i32>1829  // CHECK-NEXT: (%[[XVAL:.*]]: i32):1830  // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321831  // CHECK-NEXT:   acc.yield %[[NEWVAL]] : i321832  acc.atomic.update %x : memref<i32> {1833  ^bb0(%xval: i32):1834    %newval = llvm.add %xval, %expr : i321835    acc.yield %newval : i321836  }1837 1838  // CHECK: %[[IFCOND1:.*]] = arith.constant true1839  // CHECK-NEXT: acc.atomic.update if(%[[IFCOND1]]) %[[X]] : memref<i32>1840  // CHECK-NEXT: (%[[XVAL:.*]]: i32):1841  // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321842  // CHECK-NEXT:   acc.yield %[[NEWVAL]] : i321843  %ifCond = arith.constant true1844  acc.atomic.update if (%ifCond) %x : memref<i32> {1845  ^bb0(%xval: i32):1846    %newval = llvm.add %xval, %expr : i321847    acc.yield %newval : i321848  }1849 1850  // CHECK: acc.atomic.update %[[XBOOL]] : memref<i1>1851  // CHECK-NEXT: (%[[XVAL:.*]]: i1):1852  // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.and %[[XVAL]], %[[EXPRBOOL]] : i11853  // CHECK-NEXT:   acc.yield %[[NEWVAL]] : i11854  acc.atomic.update %xBool : memref<i1> {1855  ^bb0(%xval: i1):1856    %newval = llvm.and %xval, %exprBool : i11857    acc.yield %newval : i11858  }1859  // CHECK: acc.atomic.update %[[X]] : memref<i32>1860  // CHECK-NEXT: (%[[XVAL:.*]]: i32):1861  // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.shl %[[XVAL]], %[[EXPR]] : i321862  // CHECK-NEXT:   acc.yield %[[NEWVAL]] : i321863  // CHECK-NEXT: }1864  acc.atomic.update %x : memref<i32> {1865  ^bb0(%xval: i32):1866    %newval = llvm.shl %xval, %expr : i321867    acc.yield %newval : i321868  }1869  // CHECK: acc.atomic.update %[[X]] : memref<i32>1870  // CHECK-NEXT: (%[[XVAL:.*]]: i32):1871  // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.intr.smax(%[[XVAL]], %[[EXPR]]) : (i32, i32) -> i321872  // CHECK-NEXT:   acc.yield %[[NEWVAL]] : i321873  // CHECK-NEXT: }1874  acc.atomic.update %x : memref<i32> {1875  ^bb0(%xval: i32):1876    %newval = llvm.intr.smax(%xval, %expr) : (i32, i32) -> i321877    acc.yield %newval : i321878  }1879 1880  // CHECK: acc.atomic.update %[[XBOOL]] : memref<i1>1881  // CHECK-NEXT: (%[[XVAL:.*]]: i1):1882  // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.icmp "eq" %[[XVAL]], %[[EXPRBOOL]] : i11883  // CHECK-NEXT:   acc.yield %[[NEWVAL]] : i11884  // }1885  acc.atomic.update %xBool : memref<i1> {1886  ^bb0(%xval: i1):1887    %newval = llvm.icmp "eq" %xval, %exprBool : i11888    acc.yield %newval : i11889  }1890 1891  // CHECK: acc.atomic.update %[[X]] : memref<i32> {1892  // CHECK-NEXT: (%[[XVAL:.*]]: i32):1893  // CHECK-NEXT:   acc.yield %[[XVAL]] : i321894  // CHECK-NEXT: }1895  acc.atomic.update %x : memref<i32> {1896  ^bb0(%xval:i32):1897    acc.yield %xval : i321898  }1899 1900  // CHECK: acc.atomic.update %[[X]] : memref<i32> {1901  // CHECK-NEXT: (%[[XVAL:.*]]: i32):1902  // CHECK-NEXT:   acc.yield %{{.+}} : i321903  // CHECK-NEXT: }1904  %const = arith.constant 42 : i321905  acc.atomic.update %x : memref<i32> {1906  ^bb0(%xval:i32):1907    acc.yield %const : i321908  }1909 1910  return1911}1912 1913// -----1914 1915// CHECK-LABEL: func.func @acc_atomic_capture1916// CHECK-SAME: (%[[v:.*]]: memref<i32>, %[[x:.*]]: memref<i32>, %[[expr:.*]]: i32)1917func.func @acc_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {1918  // CHECK: acc.atomic.capture {1919  // CHECK-NEXT: acc.atomic.update %[[x]] : memref<i32>1920  // CHECK-NEXT: (%[[xval:.*]]: i32):1921  // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321922  // CHECK-NEXT:   acc.yield %[[newval]] : i321923  // CHECK-NEXT: }1924  // CHECK-NEXT: acc.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321925  // CHECK-NEXT: }1926  acc.atomic.capture {1927    acc.atomic.update %x : memref<i32> {1928    ^bb0(%xval: i32):1929      %newval = llvm.add %xval, %expr : i321930      acc.yield %newval : i321931    }1932    acc.atomic.read %v = %x : memref<i32>, memref<i32>, i321933  }1934  // CHECK: acc.atomic.capture {1935  // CHECK-NEXT: acc.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321936  // CHECK-NEXT: acc.atomic.update %[[x]] : memref<i32>1937  // CHECK-NEXT: (%[[xval:.*]]: i32):1938  // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321939  // CHECK-NEXT:   acc.yield %[[newval]] : i321940  // CHECK-NEXT: }1941  // CHECK-NEXT: }1942  acc.atomic.capture {1943    acc.atomic.read %v = %x : memref<i32>, memref<i32>, i321944    acc.atomic.update %x : memref<i32> {1945    ^bb0(%xval: i32):1946      %newval = llvm.add %xval, %expr : i321947      acc.yield %newval : i321948    }1949  }1950  // CHECK: acc.atomic.capture {1951  // CHECK-NEXT: acc.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321952  // CHECK-NEXT: acc.atomic.write %[[x]] = %[[expr]] : memref<i32>, i321953  // CHECK-NEXT: }1954  acc.atomic.capture {1955    acc.atomic.read %v = %x : memref<i32>, memref<i32>, i321956    acc.atomic.write %x = %expr : memref<i32>, i321957  }1958 1959  // CHECK: %[[IFCOND1:.*]] = arith.constant true1960  // CHECK-NEXT: acc.atomic.capture if(%[[IFCOND1]]) {1961  // CHECK-NEXT: acc.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321962  // CHECK-NEXT: acc.atomic.write %[[x]] = %[[expr]] : memref<i32>, i321963  // CHECK-NEXT: }1964  %ifCond = arith.constant true1965  acc.atomic.capture if (%ifCond) {1966    acc.atomic.read %v = %x : memref<i32>, memref<i32>, i321967    acc.atomic.write %x = %expr : memref<i32>, i321968  }1969 1970  return1971}1972 1973// -----1974 1975// CHECK-LABEL: func.func @acc_num_gangs1976func.func @acc_num_gangs() {1977  %c2 = arith.constant 2 : i321978  %c1 = arith.constant 1 : i321979  acc.parallel num_gangs({%c2 : i32} [#acc.device_type<default>], {%c1 : i32, %c1 : i32, %c1 : i32} [#acc.device_type<nvidia>]) {1980  }1981 1982  return1983}1984 1985// CHECK: acc.parallel num_gangs({%c2{{.*}} : i32} [#acc.device_type<default>], {%c1{{.*}} : i32, %c1{{.*}} : i32, %c1{{.*}} : i32} [#acc.device_type<nvidia>])1986 1987// -----1988 1989// CHECK-LABEL: func.func @acc_combined1990func.func @acc_combined() {1991  %c0 = arith.constant 0 : index1992  %c10 = arith.constant 10 : index1993  %c1 = arith.constant 1 : index1994 1995  acc.parallel combined(loop) {1996    acc.loop combined(parallel) control(%arg3 : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {1997      acc.yield1998    } attributes {independent = [#acc.device_type<none>]}1999    acc.terminator2000  }2001 2002  acc.kernels combined(loop) {2003    acc.loop combined(kernels) control(%arg3 : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {2004      acc.yield2005    } attributes {auto_ = [#acc.device_type<none>]}2006    acc.terminator2007  }2008 2009  acc.serial combined(loop) {2010    acc.loop combined(serial) control(%arg3 : index) = (%c0 : index) to (%c10 : index) step (%c1 : index) {2011      acc.yield2012    } attributes {seq = [#acc.device_type<none>]}2013    acc.terminator2014  }2015 2016  return2017}2018 2019// CHECK: acc.parallel combined(loop)2020// CHECK: acc.loop combined(parallel)2021// CHECK: acc.kernels combined(loop)2022// CHECK: acc.loop combined(kernels)2023// CHECK: acc.serial combined(loop)2024// CHECK: acc.loop combined(serial)2025 2026acc.firstprivate.recipe @firstprivatization_memref_i32 : memref<i32> init {2027^bb0(%arg0: memref<i32>):2028  %alloca = memref.alloca() : memref<i32>2029  acc.yield %alloca : memref<i32>2030} copy {2031^bb0(%arg0: memref<i32>, %arg1: memref<i32>):2032  %0 = memref.load %arg1[] : memref<i32>2033  memref.store %0, %arg0[] : memref<i32>2034  acc.terminator2035}2036 2037// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_memref_i322038// CHECK:       memref.alloca2039 2040acc.reduction.recipe @reduction_add_memref_i32 : memref<i32> reduction_operator <add> init {2041^bb0(%arg0: memref<i32>):2042  %c0_i32 = arith.constant 0 : i322043  %alloca = memref.alloca() : memref<i32>2044  memref.store %c0_i32, %alloca[] : memref<i32>2045  acc.yield %alloca : memref<i32>2046} combiner {2047^bb0(%arg0: memref<i32>, %arg1: memref<i32>):2048  %0 = memref.load %arg0[] : memref<i32>2049  %1 = memref.load %arg1[] : memref<i32>2050  %2 = arith.addi %0, %1 : i322051  memref.store %2, %arg0[] : memref<i32>2052  acc.yield %arg0 : memref<i32>2053}2054 2055// CHECK-LABEL: acc.reduction.recipe @reduction_add_memref_i322056// CHECK:       memref.alloca2057 2058// -----2059 2060// Test reduction recipe with destroy region using dynamic memory allocation2061acc.reduction.recipe @reduction_add_with_destroy : memref<?xf32> reduction_operator<add> init {2062^bb0(%arg0: memref<?xf32>):2063  %cst = arith.constant 0.000000e+00 : f322064  %c0 = arith.constant 0 : index2065  %size = memref.dim %arg0, %c0 : memref<?xf32>2066  %alloc = memref.alloc(%size) : memref<?xf32>2067  %c1 = arith.constant 1 : index2068  scf.for %i = %c0 to %size step %c1 {2069    memref.store %cst, %alloc[%i] : memref<?xf32>2070  }2071  acc.yield %alloc : memref<?xf32>2072} combiner {2073^bb0(%arg0: memref<?xf32>, %arg1: memref<?xf32>):2074  %c0 = arith.constant 0 : index2075  %c1 = arith.constant 1 : index2076  %size = memref.dim %arg0, %c0 : memref<?xf32>2077  scf.for %i = %c0 to %size step %c1 {2078    %val0 = memref.load %arg0[%i] : memref<?xf32>2079    %val1 = memref.load %arg1[%i] : memref<?xf32>2080    %sum = arith.addf %val0, %val1 : f322081    memref.store %sum, %arg0[%i] : memref<?xf32>2082  }2083  acc.yield %arg0 : memref<?xf32>2084} destroy {2085^bb0(%arg0: memref<?xf32>):2086  // destroy region to deallocate dynamically allocated memory2087  memref.dealloc %arg0 : memref<?xf32>2088  acc.yield2089}2090 2091// CHECK-LABEL: acc.reduction.recipe @reduction_add_with_destroy : memref<?xf32> reduction_operator <add> init {2092// CHECK:       ^bb0(%[[ARG:.*]]: memref<?xf32>):2093// CHECK:         %[[CST:.*]] = arith.constant 0.000000e+00 : f322094// CHECK:         %[[C0:.*]] = arith.constant 0 : index2095// CHECK:         %[[SIZE:.*]] = memref.dim %[[ARG]], %[[C0]] : memref<?xf32>2096// CHECK:         %[[ALLOC:.*]] = memref.alloc(%[[SIZE]]) : memref<?xf32>2097// CHECK:         %[[C1:.*]] = arith.constant 1 : index2098// CHECK:         scf.for %[[I:.*]] = %[[C0]] to %[[SIZE]] step %[[C1]] {2099// CHECK:           memref.store %[[CST]], %[[ALLOC]][%[[I]]] : memref<?xf32>2100// CHECK:         }2101// CHECK:         acc.yield %[[ALLOC]] : memref<?xf32>2102// CHECK:       } combiner {2103// CHECK:       ^bb0(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>):2104// CHECK:         %[[C0_1:.*]] = arith.constant 0 : index2105// CHECK:         %[[C1_1:.*]] = arith.constant 1 : index2106// CHECK:         %[[SIZE_1:.*]] = memref.dim %[[ARG0]], %[[C0_1]] : memref<?xf32>2107// CHECK:         scf.for %[[I_1:.*]] = %[[C0_1]] to %[[SIZE_1]] step %[[C1_1]] {2108// CHECK:           %{{.*}} = memref.load %[[ARG0]][%[[I_1]]] : memref<?xf32>2109// CHECK:           %{{.*}} = memref.load %[[ARG1]][%[[I_1]]] : memref<?xf32>2110// CHECK:           %[[SUM:.*]] = arith.addf %{{.*}}, %{{.*}} : f322111// CHECK:           memref.store %[[SUM]], %[[ARG0]][%[[I_1]]] : memref<?xf32>2112// CHECK:         }2113// CHECK:         acc.yield %[[ARG0]] : memref<?xf32>2114// CHECK:       } destroy {2115// CHECK:       ^bb0(%[[ARG_DESTROY:.*]]: memref<?xf32>):2116// CHECK:         memref.dealloc %[[ARG_DESTROY]] : memref<?xf32>2117// CHECK:         acc.yield2118// CHECK:       }2119 2120// -----2121 2122acc.private.recipe @privatization_memref_i32 : memref<i32> init {2123^bb0(%arg0: memref<i32>):2124  %alloca = memref.alloca() : memref<i32>2125  acc.yield %alloca : memref<i32>2126}2127 2128// CHECK-LABEL: acc.private.recipe @privatization_memref_i322129// CHECK:       memref.alloca2130 2131// -----2132 2133func.func @acc_loop_container() {2134  %c0 = arith.constant 0 : index2135  %c10 = arith.constant 10 : index2136  %c1 = arith.constant 1 : index2137  acc.loop {2138    scf.for %arg4 = %c0 to %c10 step %c1 {2139      scf.yield2140    }2141    acc.yield2142  } attributes {independent = [#acc.device_type<none>]}2143  return2144}2145 2146// CHECK-LABEL: func.func @acc_loop_container2147// CHECK:       acc.loop2148// CHECK:       scf.for2149 2150// -----2151 2152func.func @acc_loop_container() {2153  %c0 = arith.constant 0 : index2154  %c10 = arith.constant 10 : index2155  %c1 = arith.constant 1 : index2156  acc.loop {2157    scf.for %arg4 = %c0 to %c10 step %c1 {2158      scf.for %arg5 = %c0 to %c10 step %c1 {2159        scf.yield2160      }2161      scf.yield2162    }2163    acc.yield2164  } attributes { collapse = [2], collapseDeviceType = [#acc.device_type<none>], independent = [#acc.device_type<none>]}2165  return2166}2167 2168// CHECK-LABEL: func.func @acc_loop_container2169// CHECK:       acc.loop2170// CHECK:       scf.for2171// CHECK:       scf.for2172 2173// -----2174 2175func.func @acc_unstructured_loop() {2176  acc.loop {2177    acc.yield2178  } attributes {independent = [#acc.device_type<none>], unstructured}2179  return2180}2181 2182// CHECK-LABEL: func.func @acc_unstructured_loop2183// CHECK:       acc.loop2184// CHECK:         acc.yield2185// CHECK:       } attributes {independent = [#acc.device_type<none>], unstructured}2186 2187// -----2188 2189// Test private recipe with data bounds for array slicing2190acc.private.recipe @privatization_memref_slice : memref<10x10xf32> init {2191^bb0(%arg0: memref<10x10xf32>, %bounds0: !acc.data_bounds_ty, %bounds1: !acc.data_bounds_ty):2192  // NOTE: OpenACC bounds are ordered from inner-most to outer-most dimension (rank 0 = inner-most)2193  // MLIR memref<10x10xf32> has first dimension as outer (10) and second as inner (10)2194  // So bounds0 corresponds to memref's second dimension (inner), bounds1 to first dimension (outer)2195 2196  // Extract bounds information for the slice2197  // bounds0 = inner dimension (memref dimension 1)2198  %lb0 = acc.get_lowerbound %bounds0 : (!acc.data_bounds_ty) -> index2199  %extent0 = acc.get_extent %bounds0 : (!acc.data_bounds_ty) -> index2200  %stride0 = acc.get_stride %bounds0 : (!acc.data_bounds_ty) -> index2201 2202  // bounds1 = outer dimension (memref dimension 0)2203  %lb1 = acc.get_lowerbound %bounds1 : (!acc.data_bounds_ty) -> index2204  %extent1 = acc.get_extent %bounds1 : (!acc.data_bounds_ty) -> index2205  %stride1 = acc.get_stride %bounds1 : (!acc.data_bounds_ty) -> index2206 2207  // Allocate memory for only the slice dimensions on the stack2208  // Note: memref dimensions are outer-first, so extent1 (outer) comes first, extent0 (inner) second2209  %slice_alloc = memref.alloca(%extent1, %extent0) : memref<?x?xf32>2210 2211  // Adjust base pointer to account for the slice offset2212  // We need to create a view that makes the slice appear as if it starts at the original indices2213  %c0 = arith.constant 0 : index2214  %c10 = arith.constant 10 : index2215  %c1 = arith.constant 1 : index2216 2217  // Calculate linear offset: -(lb1 * stride1 + lb0 * stride0)2218  // For memref<10x10xf32>, stride1=10, stride0=12219  %lb1_scaled = arith.muli %lb1, %c10 : index  // lb1 * 102220  %lb0_scaled = arith.muli %lb0, %c1 : index   // lb0 * 12221  %total_offset = arith.addi %lb1_scaled, %lb0_scaled : index  // lb1*10 + lb0*12222  %neg_offset = arith.subi %c0, %total_offset : index  // -(lb1*10 + lb0*1)2223 2224  // Create a view that adjusts for the lowerbound offset2225  // This makes accesses like result[lb1][lb0] map to slice_alloc[0][0]2226  //2227  // Example for slice a[2:4, 3:5] where:2228  // - bounds0 (inner): lb0=3, extent0=22229  // - bounds1 (outer): lb1=2, extent1=22230  // - Allocated memory: 2x2 array (extent1 x extent0 = 2 rows x 2 cols)2231  // - Linear offset calculation: -(2*10 + 3*1) = -232232  // - Result mapping:2233  //   * result[2][3] -> slice_alloc[0][0] (because 2*10+3 + (-23) = 0)2234  //   * result[2][4] -> slice_alloc[0][1] (because 2*10+4 + (-23) = 1)2235  //   * result[3][3] -> slice_alloc[1][0] (because 3*10+3 + (-23) = 10)2236  //   * result[3][4] -> slice_alloc[1][1] (because 3*10+4 + (-23) = 11)2237  %adjusted_view = memref.reinterpret_cast %slice_alloc to2238    offset: [%neg_offset], sizes: [10, 10], strides: [%c10, %c1]2239    : memref<?x?xf32> to memref<10x10xf32, strided<[?, ?], offset: ?>>2240 2241  // Cast to the expected return type2242  %result = memref.cast %adjusted_view : memref<10x10xf32, strided<[?, ?], offset: ?>> to memref<10x10xf32>2243 2244  acc.yield %result : memref<10x10xf32>2245}2246 2247// -----2248 2249func.func @test_firstprivate_map(%arg0: memref<10xf32>) {2250  // Map the function argument using firstprivate_map to enable2251  // moving to accelerator but prevent any present counter updates.2252  %mapped = acc.firstprivate_map varPtr(%arg0 : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>2253 2254  acc.parallel {2255    // Allocate a local variable inside the parallel region to represent2256    // materialized privatization.2257    %local = memref.alloca() : memref<10xf32>2258 2259    // Initialize the local variable with the mapped firstprivate value2260    %c0 = arith.constant 0 : index2261    %c10 = arith.constant 10 : index2262    %c1 = arith.constant 1 : index2263 2264    scf.for %i = %c0 to %c10 step %c1 {2265      %val = memref.load %mapped[%i] : memref<10xf32>2266      memref.store %val, %local[%i] : memref<10xf32>2267    }2268 2269    acc.yield2270  }2271 2272  return2273}2274 2275// CHECK-LABEL: func @test_firstprivate_map2276// CHECK-NEXT:   %[[MAPPED:.*]] = acc.firstprivate_map varPtr(%{{.*}} : memref<10xf32>) varType(tensor<10xf32>) -> memref<10xf32>2277// CHECK-NEXT:   acc.parallel {2278// CHECK-NEXT:     %[[LOCAL:.*]] = memref.alloca() : memref<10xf32>2279// CHECK-NEXT:     %[[C0:.*]] = arith.constant 0 : index2280// CHECK-NEXT:     %[[C10:.*]] = arith.constant 10 : index2281// CHECK-NEXT:     %[[C1:.*]] = arith.constant 1 : index2282// CHECK-NEXT:     scf.for %{{.*}} = %[[C0]] to %[[C10]] step %[[C1]] {2283// CHECK-NEXT:       %{{.*}} = memref.load %[[MAPPED]][%{{.*}}] : memref<10xf32>2284// CHECK-NEXT:       memref.store %{{.*}}, %[[LOCAL]][%{{.*}}] : memref<10xf32>2285// CHECK-NEXT:     }2286// CHECK-NEXT:     acc.yield2287// CHECK-NEXT:   }2288// CHECK-NEXT:   return2289 2290// -----2291 2292func.func @test_kernel_environment(%arg0: memref<1024xf32>, %arg1: memref<1024xf32>) {2293  %c1 = arith.constant 1 : index2294  %c1024 = arith.constant 1024 : index2295 2296  // Create data clause operands for the kernel environment2297  %copyin = acc.copyin varPtr(%arg0 : memref<1024xf32>) -> memref<1024xf32>2298  %create = acc.create varPtr(%arg1 : memref<1024xf32>) -> memref<1024xf32>2299 2300  // Kernel environment wraps gpu.launch and captures data mapping2301  acc.kernel_environment dataOperands(%copyin, %create : memref<1024xf32>, memref<1024xf32>) {2302    gpu.launch blocks(%bx, %by, %bz) in (%grid_x = %c1, %grid_y = %c1, %grid_z = %c1)2303               threads(%tx, %ty, %tz) in (%block_x = %c1024, %block_y = %c1, %block_z = %c1) {2304      // Kernel body uses the mapped data2305      %val = memref.load %copyin[%tx] : memref<1024xf32>2306      %result = arith.mulf %val, %val : f322307      memref.store %result, %create[%tx] : memref<1024xf32>2308      gpu.terminator2309    }2310  }2311 2312  // Copy results back to host and deallocate device memory2313  acc.copyout accPtr(%create : memref<1024xf32>) to varPtr(%arg1 : memref<1024xf32>)2314  acc.delete accPtr(%copyin : memref<1024xf32>)2315 2316  return2317}2318 2319// CHECK-LABEL: func @test_kernel_environment2320// CHECK:         %[[COPYIN:.*]] = acc.copyin varPtr(%{{.*}} : memref<1024xf32>) -> memref<1024xf32>2321// CHECK:         %[[CREATE:.*]] = acc.create varPtr(%{{.*}} : memref<1024xf32>) -> memref<1024xf32>2322// CHECK:         acc.kernel_environment dataOperands(%[[COPYIN]], %[[CREATE]] : memref<1024xf32>, memref<1024xf32>) {2323// CHECK:           gpu.launch2324// CHECK:             memref.load %[[COPYIN]]2325// CHECK:             memref.store %{{.*}}, %[[CREATE]]2326// CHECK:           }2327// CHECK:         }2328// CHECK:         acc.copyout accPtr(%[[CREATE]] : memref<1024xf32>) to varPtr(%{{.*}} : memref<1024xf32>)2329// CHECK:         acc.delete accPtr(%[[COPYIN]] : memref<1024xf32>)2330 2331// -----2332 2333func.func @test_kernel_environment_with_async(%arg0: memref<1024xf32>) {2334  %c1 = arith.constant 1 : index2335  %c1024 = arith.constant 1024 : index2336  %async_val = arith.constant 1 : i322337 2338  %create = acc.create varPtr(%arg0 : memref<1024xf32>) async(%async_val : i32) -> memref<1024xf32>2339 2340  // Kernel environment with async clause2341  acc.kernel_environment dataOperands(%create : memref<1024xf32>) async(%async_val : i32) {2342    gpu.launch blocks(%bx, %by, %bz) in (%grid_x = %c1, %grid_y = %c1, %grid_z = %c1)2343               threads(%tx, %ty, %tz) in (%block_x = %c1024, %block_y = %c1, %block_z = %c1) {2344      %f0 = arith.constant 0.0 : f322345      memref.store %f0, %create[%tx] : memref<1024xf32>2346      gpu.terminator2347    }2348  }2349 2350  acc.copyout accPtr(%create : memref<1024xf32>) async(%async_val : i32) to varPtr(%arg0 : memref<1024xf32>)2351 2352  return2353}2354 2355// CHECK-LABEL: func @test_kernel_environment_with_async2356// CHECK:         %[[ASYNC:.*]] = arith.constant 1 : i322357// CHECK:         %[[CREATE:.*]] = acc.create varPtr(%{{.*}} : memref<1024xf32>) async(%[[ASYNC]] : i32) -> memref<1024xf32>2358// CHECK:         acc.kernel_environment dataOperands(%[[CREATE]] : memref<1024xf32>) async(%[[ASYNC]] : i32)2359// CHECK:           gpu.launch2360// CHECK:             memref.store %{{.*}}, %[[CREATE]]2361// CHECK:         acc.copyout accPtr(%[[CREATE]] : memref<1024xf32>) async(%[[ASYNC]] : i32) to varPtr(%{{.*}} : memref<1024xf32>)2362