249 lines · plain
1// RUN: mlir-opt %s -canonicalize="test-convergence" -split-input-file | FileCheck %s2 3func.func @testenterdataop(%a: memref<f32>) -> () {4 %ifCond = arith.constant true5 %0 = acc.create varPtr(%a : memref<f32>) -> memref<f32>6 acc.enter_data if(%ifCond) dataOperands(%0 : memref<f32>)7 return8}9 10// CHECK: acc.enter_data dataOperands(%{{.*}} : memref<f32>)11 12// -----13 14func.func @testenterdataop(%a: memref<f32>) -> () {15 %ifCond = arith.constant false16 %0 = acc.create varPtr(%a : memref<f32>) -> memref<f32>17 acc.enter_data if(%ifCond) dataOperands(%0 : memref<f32>)18 return19}20 21// CHECK: func @testenterdataop22// CHECK-NOT: acc.enter_data23 24// -----25 26func.func @testexitdataop(%a: memref<f32>) -> () {27 %ifCond = arith.constant true28 %0 = acc.getdeviceptr varPtr(%a : memref<f32>) -> memref<f32>29 acc.exit_data if(%ifCond) dataOperands(%0 : memref<f32>)30 acc.delete accPtr(%0 : memref<f32>)31 return32}33 34// CHECK: acc.exit_data dataOperands(%{{.*}} : memref<f32>)35 36// -----37 38func.func @testexitdataop(%a: memref<f32>) -> () {39 %ifCond = arith.constant false40 %0 = acc.getdeviceptr varPtr(%a : memref<f32>) -> memref<f32>41 acc.exit_data if(%ifCond) dataOperands(%0 : memref<f32>)42 acc.delete accPtr(%0 : memref<f32>)43 return44}45 46// CHECK: func @testexitdataop47// CHECK-NOT: acc.exit_data48 49// -----50 51func.func @testupdateop(%a: memref<f32>) -> () {52 %0 = acc.getdeviceptr varPtr(%a : memref<f32>) -> memref<f32>53 acc.update_host accPtr(%0 : memref<f32>) to varPtr(%a : memref<f32>)54 %ifCond = arith.constant true55 acc.update if(%ifCond) dataOperands(%0: memref<f32>)56 return57}58 59// CHECK: acc.update dataOperands(%{{.*}} : memref<f32>)60 61// -----62 63func.func @testupdateop(%a: memref<f32>) -> () {64 %0 = acc.getdeviceptr varPtr(%a : memref<f32>) -> memref<f32>65 acc.update_host accPtr(%0 : memref<f32>) to varPtr(%a : memref<f32>)66 %ifCond = arith.constant false67 acc.update if(%ifCond) dataOperands(%0: memref<f32>)68 return69}70 71// CHECK: func @testupdateop72// CHECK-NOT: acc.update{{.$}}73 74// -----75 76func.func @testenterdataop(%a: memref<f32>, %ifCond: i1) -> () {77 %0 = acc.create varPtr(%a : memref<f32>) -> memref<f32>78 acc.enter_data if(%ifCond) dataOperands(%0 : memref<f32>)79 return80}81 82// CHECK: func @testenterdataop(%{{.*}}: memref<f32>, [[IFCOND:%.*]]: i1)83// CHECK: acc.enter_data if(%{{.*}}) dataOperands(%{{.*}} : memref<f32>)84 85// -----86 87func.func @testexitdataop(%a: memref<f32>, %ifCond: i1) -> () {88 %0 = acc.getdeviceptr varPtr(%a : memref<f32>) -> memref<f32>89 acc.exit_data if(%ifCond) dataOperands(%0 : memref<f32>)90 acc.delete accPtr(%0 : memref<f32>)91 return92}93 94// CHECK: func @testexitdataop(%{{.*}}: memref<f32>, [[IFCOND:%.*]]: i1)95// CHECK: acc.exit_data if(%{{.*}}) dataOperands(%{{.*}} : memref<f32>)96 97// -----98 99func.func @testupdateop(%a: memref<f32>, %ifCond: i1) -> () {100 %0 = acc.getdeviceptr varPtr(%a : memref<f32>) -> memref<f32>101 acc.update_host accPtr(%0 : memref<f32>) to varPtr(%a : memref<f32>)102 acc.update if(%ifCond) dataOperands(%0: memref<f32>)103 return104}105 106// CHECK: func @testupdateop(%{{.*}}: memref<f32>, [[IFCOND:%.*]]: i1)107// CHECK: acc.update if(%{{.*}}) dataOperands(%{{.*}} : memref<f32>)108 109// -----110 111func.func @testhostdataop(%a: memref<f32>, %ifCond: i1) -> () {112 %0 = acc.use_device varPtr(%a : memref<f32>) -> memref<f32>113 %1 = arith.constant 1 : i32114 %2 = arith.constant 10 : i32115 %false = arith.constant false116 acc.host_data dataOperands(%0 : memref<f32>) if(%false) {117 acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {118 acc.yield119 } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}120 acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {121 acc.yield122 } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}123 acc.terminator124 }125 return126}127 128// CHECK-LABEL: func.func @testhostdataop129// CHECK-NOT: acc.host_data130// CHECK: acc.loop131// CHECK: acc.yield132// CHECK: acc.loop133// CHECK: acc.yield134 135// -----136 137func.func @testhostdataop(%a: memref<f32>, %ifCond: i1) -> () {138 %0 = acc.use_device varPtr(%a : memref<f32>) -> memref<f32>139 %true = arith.constant true140 acc.host_data dataOperands(%0 : memref<f32>) if(%true) {141 }142 return143}144 145// CHECK-LABEL: func.func @testhostdataop146// CHECK: acc.host_data dataOperands(%{{.*}} : memref<f32>) {147 148// -----149 150func.func @update_no_op(%x : memref<i32>) {151 acc.atomic.update %x : memref<i32> {152 ^bb0(%xval : i32):153 acc.yield %xval : i32154 }155 return156}157 158// CHECK-LABEL: func.func @update_no_op159// CHECK-NOT: acc.atomic.update160 161// -----162 163func.func @update_write_op(%x : memref<i32>, %value: i32) {164 acc.atomic.update %x : memref<i32> {165 ^bb0(%xval : i32):166 acc.yield %value : i32167 }168 return169}170 171// CHECK-LABEL: func.func @update_write_op172// CHECK-SAME: (%[[X:.+]]: memref<i32>, %[[VALUE:.+]]: i32)173// CHECK: acc.atomic.write %[[X]] = %[[VALUE]] : memref<i32>, i32174// CHECK-NOT: acc.atomic.update175 176// -----177 178func.func @update_normal(%x : memref<i32>, %value: i32) {179 acc.atomic.update %x : memref<i32> {180 ^bb0(%xval : i32):181 %newval = arith.addi %xval, %value : i32182 acc.yield %newval : i32183 }184 return185}186 187// CHECK-LABEL: func.func @update_normal188// CHECK: acc.atomic.update189// CHECK: arith.addi190// CHECK: acc.yield191 192// -----193 194func.func @update_unnecessary_computations(%x: memref<i32>) {195 %c0 = arith.constant 0 : i32196 acc.atomic.update %x : memref<i32> {197 ^bb0(%xval: i32):198 %newval = arith.addi %xval, %c0 : i32199 acc.yield %newval: i32200 }201 return202}203 204// CHECK-LABEL: func.func @update_unnecessary_computations205// CHECK-NOT: acc.atomic.update206 207// -----208 209func.func @update_unnecessary_computations(%x: memref<i32>) {210 %c0 = arith.constant 0 : i32211 acc.atomic.update %x : memref<i32> {212 ^bb0(%xval: i32):213 %newval = arith.muli %xval, %c0 : i32214 acc.yield %newval: i32215 }216 return217}218 219// CHECK-LABEL: func.func @update_unnecessary_computations220// CHECK-NOT: acc.atomic.update221// CHECK: acc.atomic.write222 223// -----224 225func.func @kernel_environment_canonicalization(%q1: i32, %q2: i32, %q3: i32) {226 // Empty kernel_environment (no wait) - should be removed227 acc.kernel_environment {228 }229 230 acc.kernel_environment wait({%q1 : i32, %q2 : i32}) {231 }232 233 acc.kernel_environment wait {234 }235 236 acc.kernel_environment wait({%q3 : i32} [#acc.device_type<nvidia>]) {237 }238 239 return240}241 242// CHECK-LABEL: func.func @kernel_environment_canonicalization243// CHECK-SAME: ([[Q1:%.*]]: i32, [[Q2:%.*]]: i32, [[Q3:%.*]]: i32)244// CHECK-NOT: acc.kernel_environment wait({{.*}}[#acc.device_type<none>])245// CHECK: acc.wait([[Q1]], [[Q2]] : i32, i32)246// CHECK: acc.wait{{$}}247// CHECK: acc.kernel_environment wait({{.*}}[#acc.device_type<nvidia>])248// CHECK: return249