| // RUN: mlir-opt %s -canonicalize="test-convergence" -split-input-file | FileCheck %s |
| |
| func.func @update_no_op(%x : memref<i32>) { |
| omp.atomic.update %x : memref<i32> { |
| ^bb0(%xval : i32): |
| omp.yield(%xval : i32) |
| } |
| return |
| } |
| |
| // CHECK-LABEL: func.func @update_no_op |
| // CHECK-NOT: omp.atomic.update |
| |
| // ----- |
| |
| func.func @update_write_op(%x : memref<i32>, %value: i32) { |
| omp.atomic.update %x : memref<i32> { |
| ^bb0(%xval : i32): |
| omp.yield(%value : i32) |
| } |
| return |
| } |
| |
| // CHECK-LABEL: func.func @update_write_op |
| // CHECK-SAME: (%[[X:.+]]: memref<i32>, %[[VALUE:.+]]: i32) |
| // CHECK: omp.atomic.write %[[X]] = %[[VALUE]] : memref<i32>, i32 |
| // CHECK-NOT: omp.atomic.update |
| |
| // ----- |
| |
| func.func @update_normal(%x : memref<i32>, %value: i32) { |
| omp.atomic.update %x : memref<i32> { |
| ^bb0(%xval : i32): |
| %newval = arith.addi %xval, %value : i32 |
| omp.yield(%newval : i32) |
| } |
| return |
| } |
| |
| // CHECK-LABEL: func.func @update_normal |
| // CHECK: omp.atomic.update |
| // CHECK: arith.addi |
| // CHECK: omp.yield |
| |
| // ----- |
| |
| func.func @update_unnecessary_computations(%x: memref<i32>) { |
| %c0 = arith.constant 0 : i32 |
| omp.atomic.update %x : memref<i32> { |
| ^bb0(%xval: i32): |
| %newval = arith.addi %xval, %c0 : i32 |
| omp.yield(%newval: i32) |
| } |
| return |
| } |
| |
| // CHECK-LABEL: func.func @update_unnecessary_computations |
| // CHECK-NOT: omp.atomic.update |
| |
| // ----- |
| |
| func.func @update_unnecessary_computations(%x: memref<i32>) { |
| %c0 = arith.constant 0 : i32 |
| omp.atomic.update %x : memref<i32> { |
| ^bb0(%xval: i32): |
| %newval = arith.muli %xval, %c0 : i32 |
| omp.yield(%newval: i32) |
| } |
| return |
| } |
| |
| // CHECK-LABEL: func.func @update_unnecessary_computations |
| // CHECK-NOT: omp.atomic.update |
| // CHECK: omp.atomic.write |
| |
| // ----- |
| |
| // CHECK-LABEL: func.func @parallel_empty |
| func.func @parallel_empty() { |
| omp.parallel {} |
| return |
| } |
| |
| // CHECK-NOT: omp.parallel |
| |
| // ----- |
| |
| // CHECK-LABEL: func.func @parallel_only_terminator |
| func.func @parallel_only_terminator() { |
| omp.parallel { |
| omp.terminator |
| } |
| return |
| } |
| |
| // CHECK-NOT: omp.parallel |
| // CHECK-NOT: omp.terminator |
| |
| // ----- |
| |
| // CHECK-LABEL: func.func @parallel_no_side_effects |
| func.func @parallel_no_side_effects(%a: i32, %b: i32) { |
| omp.parallel { |
| %x = arith.addi %a, %b : i32 |
| omp.terminator |
| } |
| return |
| } |
| |
| // CHECK-NOT: omp.parallel |
| // CHECK-NOT: omp.terminator |
| |
| // ----- |
| |
| // CHECK-LABEL: func.func @parallel_maybe_side_effects |
| func.func @parallel_maybe_side_effects(%a: i32, %b: i32) { |
| omp.parallel { |
| func.call @foo() : () -> () |
| omp.terminator |
| } |
| return |
| } |
| |
| func.func private @foo() -> () |
| |
| // CHECK: omp.parallel |
| // CHECK: func.call @foo() : () -> () |
| // CHECK: omp.terminator |
| |
| // ----- |
| |
| func.func @constant_hoisting_target(%x : !llvm.ptr) { |
| omp.target { |
| ^bb0(%arg0: !llvm.ptr): |
| %c1 = arith.constant 10 : i32 |
| llvm.store %c1, %arg0 : i32, !llvm.ptr |
| omp.terminator |
| } |
| return |
| } |
| |
| // CHECK-LABEL: func.func @constant_hoisting_target |
| // CHECK-NOT: arith.constant |
| // CHECK: omp.target |
| // CHECK: arith.constant |