// RUN: mlir-opt %s -canonicalize="test-convergence" -split-input-file | FileCheck %s func.func @testenterdataop(%a: memref) -> () { %ifCond = arith.constant true %0 = acc.create varPtr(%a : memref) -> memref acc.enter_data if(%ifCond) dataOperands(%0 : memref) return } // CHECK: acc.enter_data dataOperands(%{{.*}} : memref) // ----- func.func @testenterdataop(%a: memref) -> () { %ifCond = arith.constant false %0 = acc.create varPtr(%a : memref) -> memref acc.enter_data if(%ifCond) dataOperands(%0 : memref) return } // CHECK: func @testenterdataop // CHECK-NOT: acc.enter_data // ----- func.func @testexitdataop(%a: memref) -> () { %ifCond = arith.constant true %0 = acc.getdeviceptr varPtr(%a : memref) -> memref acc.exit_data if(%ifCond) dataOperands(%0 : memref) acc.delete accPtr(%0 : memref) return } // CHECK: acc.exit_data dataOperands(%{{.*}} : memref) // ----- func.func @testexitdataop(%a: memref) -> () { %ifCond = arith.constant false %0 = acc.getdeviceptr varPtr(%a : memref) -> memref acc.exit_data if(%ifCond) dataOperands(%0 : memref) acc.delete accPtr(%0 : memref) return } // CHECK: func @testexitdataop // CHECK-NOT: acc.exit_data // ----- func.func @testupdateop(%a: memref) -> () { %0 = acc.getdeviceptr varPtr(%a : memref) -> memref acc.update_host accPtr(%0 : memref) to varPtr(%a : memref) %ifCond = arith.constant true acc.update if(%ifCond) dataOperands(%0: memref) return } // CHECK: acc.update dataOperands(%{{.*}} : memref) // ----- func.func @testupdateop(%a: memref) -> () { %0 = acc.getdeviceptr varPtr(%a : memref) -> memref acc.update_host accPtr(%0 : memref) to varPtr(%a : memref) %ifCond = arith.constant false acc.update if(%ifCond) dataOperands(%0: memref) return } // CHECK: func @testupdateop // CHECK-NOT: acc.update{{.$}} // ----- func.func @testenterdataop(%a: memref, %ifCond: i1) -> () { %0 = acc.create varPtr(%a : memref) -> memref acc.enter_data if(%ifCond) dataOperands(%0 : memref) return } // CHECK: func @testenterdataop(%{{.*}}: memref, [[IFCOND:%.*]]: i1) // CHECK: acc.enter_data if(%{{.*}}) dataOperands(%{{.*}} : memref) // ----- func.func @testexitdataop(%a: memref, %ifCond: i1) -> () { %0 = acc.getdeviceptr varPtr(%a : memref) -> memref acc.exit_data if(%ifCond) dataOperands(%0 : memref) acc.delete accPtr(%0 : memref) return } // CHECK: func @testexitdataop(%{{.*}}: memref, [[IFCOND:%.*]]: i1) // CHECK: acc.exit_data if(%{{.*}}) dataOperands(%{{.*}} : memref) // ----- func.func @testupdateop(%a: memref, %ifCond: i1) -> () { %0 = acc.getdeviceptr varPtr(%a : memref) -> memref acc.update_host accPtr(%0 : memref) to varPtr(%a : memref) acc.update if(%ifCond) dataOperands(%0: memref) return } // CHECK: func @testupdateop(%{{.*}}: memref, [[IFCOND:%.*]]: i1) // CHECK: acc.update if(%{{.*}}) dataOperands(%{{.*}} : memref) // ----- func.func @testhostdataop(%a: memref, %ifCond: i1) -> () { %0 = acc.use_device varPtr(%a : memref) -> memref %1 = arith.constant 1 : i32 %2 = arith.constant 10 : i32 %false = arith.constant false acc.host_data dataOperands(%0 : memref) if(%false) { acc.loop (%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) { acc.yield } attributes { inclusiveUpperbound = array } acc.loop (%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) { acc.yield } attributes { inclusiveUpperbound = array } acc.terminator } return } // CHECK-LABEL: func.func @testhostdataop // CHECK-NOT: acc.host_data // CHECK: acc.loop // CHECK: acc.yield // CHECK: acc.loop // CHECK: acc.yield // ----- func.func @testhostdataop(%a: memref, %ifCond: i1) -> () { %0 = acc.use_device varPtr(%a : memref) -> memref %true = arith.constant true acc.host_data dataOperands(%0 : memref) if(%true) { } return } // CHECK-LABEL: func.func @testhostdataop // CHECK: acc.host_data dataOperands(%{{.*}} : memref) { // ----- func.func @update_no_op(%x : memref) { acc.atomic.update %x : memref { ^bb0(%xval : i32): acc.yield %xval : i32 } return } // CHECK-LABEL: func.func @update_no_op // CHECK-NOT: acc.atomic.update // ----- func.func @update_write_op(%x : memref, %value: i32) { acc.atomic.update %x : memref { ^bb0(%xval : i32): acc.yield %value : i32 } return } // CHECK-LABEL: func.func @update_write_op // CHECK-SAME: (%[[X:.+]]: memref, %[[VALUE:.+]]: i32) // CHECK: acc.atomic.write %[[X]] = %[[VALUE]] : memref, i32 // CHECK-NOT: acc.atomic.update // ----- func.func @update_normal(%x : memref, %value: i32) { acc.atomic.update %x : memref { ^bb0(%xval : i32): %newval = arith.addi %xval, %value : i32 acc.yield %newval : i32 } return } // CHECK-LABEL: func.func @update_normal // CHECK: acc.atomic.update // CHECK: arith.addi // CHECK: acc.yield // ----- func.func @update_unnecessary_computations(%x: memref) { %c0 = arith.constant 0 : i32 acc.atomic.update %x : memref { ^bb0(%xval: i32): %newval = arith.addi %xval, %c0 : i32 acc.yield %newval: i32 } return } // CHECK-LABEL: func.func @update_unnecessary_computations // CHECK-NOT: acc.atomic.update // ----- func.func @update_unnecessary_computations(%x: memref) { %c0 = arith.constant 0 : i32 acc.atomic.update %x : memref { ^bb0(%xval: i32): %newval = arith.muli %xval, %c0 : i32 acc.yield %newval: i32 } return } // CHECK-LABEL: func.func @update_unnecessary_computations // CHECK-NOT: acc.atomic.update // CHECK: acc.atomic.write