brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · a5eba43 Raw
246 lines · plain
1// RUN: mlir-opt -test-last-modified --split-input-file %s 2>&1 |\2// RUN:          FileCheck %s --check-prefixes=CHECK,IP,IP_ONLY3// RUN: mlir-opt -test-last-modified='assume-func-writes=true' \4// RUN:          --split-input-file %s 2>&1 |\5// RUN:          FileCheck %s --check-prefixes=CHECK,IP,IP_AW6// RUN: mlir-opt -test-last-modified='interprocedural=false' \7// RUN:          --split-input-file %s 2>&1 |\8// RUN:          FileCheck %s --check-prefixes=CHECK,LOCAL9// RUN: mlir-opt \10// RUN:    -test-last-modified='interprocedural=false assume-func-writes=true' \11// RUN:    --split-input-file %s 2>&1 |\12// RUN:    FileCheck %s --check-prefixes=CHECK,LC_AW13 14// Check prefixes are as follows:15// 'check': common for all runs;16// 'ip': interprocedural runs;17// 'ip_aw': interpocedural runs assuming calls to external functions write to18//          all arguments;19// 'ip_only': interprocedural runs not assuming calls writing;20// 'local': local (non-interprocedural) analysis not assuming calls writing;21// 'lc_aw': local analysis assuming external calls writing to all arguments.22 23// CHECK-LABEL: test_tag: test_callsite24// IP:    operand #025// IP-NEXT: - a26// LOCAL: operand #027// LOCAL-NEXT: - <unknown>28// LC_AW: operand #029// LC_AW-NEXT: - <unknown>30func.func private @single_callsite_fn(%ptr: memref<i32>) -> memref<i32> {31  return {tag = "test_callsite"} %ptr : memref<i32>32}33 34func.func @test_callsite() {35  %ptr = memref.alloc() : memref<i32>36  %c0 = arith.constant 0 : i3237  memref.store %c0, %ptr[] {tag_name = "a"} : memref<i32>38  %0 = func.call @single_callsite_fn(%ptr) : (memref<i32>) -> memref<i32>39  return40}41 42// CHECK-LABEL: test_tag: test_return_site43// IP:    operand #044// IP-NEXT:    - b45// LOCAL: operand #046// LOCAL-NEXT: - <unknown>47// LC_AW: operand #048// LC_AW-NEXT: - <unknown>49func.func private @single_return_site_fn(%ptr: memref<i32>) -> memref<i32> {50  %c0 = arith.constant 0 : i3251  memref.store %c0, %ptr[] {tag_name = "b"} : memref<i32>52  return %ptr : memref<i32>53}54 55// CHECK-LABEL: test_tag: test_multiple_callsites56// IP:    operand #057// IP-NEXT:    write058// IP-NEXT:    write159// LOCAL: operand #060// LOCAL-NEXT: - <unknown>61// LC_AW: operand #062// LC_AW-NEXT: - <unknown>63func.func @test_return_site(%ptr: memref<i32>) -> memref<i32> {64  %0 = func.call @single_return_site_fn(%ptr) : (memref<i32>) -> memref<i32>65  return {tag = "test_return_site"} %0 : memref<i32>66}67 68func.func private @multiple_callsite_fn(%ptr: memref<i32>) -> memref<i32> {69  return {tag = "test_multiple_callsites"} %ptr : memref<i32>70}71 72func.func @test_multiple_callsites(%a: i32, %ptr: memref<i32>) -> memref<i32> {73  memref.store %a, %ptr[] {tag_name = "write0"} : memref<i32>74  %0 = func.call @multiple_callsite_fn(%ptr) : (memref<i32>) -> memref<i32>75  memref.store %a, %ptr[] {tag_name = "write1"} : memref<i32>76  %1 = func.call @multiple_callsite_fn(%ptr) : (memref<i32>) -> memref<i32>77  return %ptr : memref<i32>78}79 80// CHECK-LABEL: test_tag: test_multiple_return_sites81// IP:    operand #082// IP-NEXT:    return083// IP-NEXT:    return184// LOCAL: operand #085// LOCAL-NEXT: - <unknown>86// LC_AW: operand #087// LC_AW-NEXT: - <unknown>88func.func private @multiple_return_site_fn(%cond: i1, %a: i32, %ptr: memref<i32>) -> memref<i32> {89  cf.cond_br %cond, ^a, ^b90 91^a:92  memref.store %a, %ptr[] {tag_name = "return0"} : memref<i32>93  return %ptr : memref<i32>94 95^b:96  memref.store %a, %ptr[] {tag_name = "return1"} : memref<i32>97  return %ptr : memref<i32>98}99 100func.func @test_multiple_return_sites(%cond: i1, %a: i32, %ptr: memref<i32>) -> memref<i32> {101  %0 = func.call @multiple_return_site_fn(%cond, %a, %ptr) : (i1, i32, memref<i32>) -> memref<i32>102  return {tag = "test_multiple_return_sites"} %0 : memref<i32>103}104 105// -----106 107// CHECK-LABEL: test_tag: after_call108// IP:    operand #0109// IP-NEXT:    - write0110// LOCAL: operand #0111// LOCAL-NEXT: - <unknown>112// LC_AW: operand #0113// LC_AW-NEXT: - func.call114func.func private @void_return(%ptr: memref<i32>) {115  return116}117 118func.func @test_call_void_return() {119  %ptr = memref.alloc() : memref<i32>120  %c0 = arith.constant 0 : i32121  memref.store %c0, %ptr[] {tag_name = "write0"} : memref<i32>122  func.call @void_return(%ptr) : (memref<i32>) -> ()123  memref.load %ptr[] {tag = "after_call"} : memref<i32>124  return125}126 127// -----128 129func.func private @callee(%arg0: memref<f32>) -> memref<f32> {130  %2 = arith.constant 2.0 : f32131  memref.load %arg0[] {tag = "call_and_store_before::enter_callee"} : memref<f32>132  memref.store %2, %arg0[] {tag_name = "callee"} : memref<f32>133  memref.load %arg0[] {tag = "exit_callee"} : memref<f32>134  return %arg0 : memref<f32>135}136// In this test, the "call" operation also stores to %arg0 itself before137// transferring control flow to the callee. Therefore, the order of accesses is138// "pre" -> "call" -> "callee" -> "post"139 140// CHECK-LABEL: test_tag: call_and_store_before::enter_callee:141// IP:     operand #0142// IP:      - call143// LOCAL:  operand #0144// LOCAL:   - <unknown>145// LC_AW:  operand #0146// LC_AW:   - <unknown>147 148// CHECK: test_tag: exit_callee:149// CHECK:  operand #0150// CHECK:   - callee151 152// CHECK: test_tag: before_call:153// CHECK:  operand #0154// CHECK:   - pre155 156// CHECK: test_tag: after_call:157// IP:     operand #0158// IP:      - callee159// LOCAL:  operand #0160// LOCAL:   - <unknown>161// LC_AW:  operand #0162// LC_AW:   - call163 164// CHECK: test_tag: return:165// CHECK:  operand #0166// CHECK:   - post167func.func @call_and_store_before(%arg0: memref<f32>) -> memref<f32> {168  %0 = arith.constant 0.0 : f32169  %1 = arith.constant 1.0 : f32170  memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>171  memref.load %arg0[] {tag = "before_call"} : memref<f32>172  test.call_and_store @callee(%arg0), %arg0 {tag_name = "call", store_before_call = true} : (memref<f32>, memref<f32>) -> ()173  memref.load %arg0[] {tag = "after_call"} : memref<f32>174  memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>175  return {tag = "return"} %arg0 : memref<f32>176}177 178// -----179 180func.func private @callee(%arg0: memref<f32>) -> memref<f32> {181  %2 = arith.constant 2.0 : f32182  memref.load %arg0[] {tag = "call_and_store_after::enter_callee"} : memref<f32>183  memref.store %2, %arg0[] {tag_name = "callee"} : memref<f32>184  memref.load %arg0[] {tag = "exit_callee"} : memref<f32>185  return %arg0 : memref<f32>186}187 188// In this test, the "call" operation also stores to %arg0 itself after getting189// control flow back from the callee. Therefore, the order of accesses is190// "pre" -> "callee" -> "call" -> "post"191 192// CHECK-LABEL: test_tag: call_and_store_after::enter_callee:193// IP:     operand #0194// IP:      - pre195// LOCAL:  operand #0196// LOCAL:   - <unknown>197// LC_AW:  operand #0198// LC_AW:   - <unknown>199 200// CHECK: test_tag: exit_callee:201// CHECK:  operand #0202// CHECK:   - callee203 204// CHECK: test_tag: before_call:205// CHECK:  operand #0206// CHECK:   - pre207 208// CHECK:    test_tag: after_call:209// IP:     operand #0210// IP:      - call211// LOCAL:  operand #0212// LOCAL:   - <unknown>213// LC_AW:  operand #0214// LC_AW:   - call215 216// CHECK: test_tag: return:217// CHECK:  operand #0218// CHECK:   - post219func.func @call_and_store_after(%arg0: memref<f32>) -> memref<f32> {220  %0 = arith.constant 0.0 : f32221  %1 = arith.constant 1.0 : f32222  memref.store %0, %arg0[] {tag_name = "pre"} : memref<f32>223  memref.load %arg0[] {tag = "before_call"} : memref<f32>224  test.call_and_store @callee(%arg0), %arg0 {tag_name = "call", store_before_call = false} : (memref<f32>, memref<f32>) -> ()225  memref.load %arg0[] {tag = "after_call"} : memref<f32>226  memref.store %1, %arg0[] {tag_name = "post"} : memref<f32>227  return {tag = "return"} %arg0 : memref<f32>228}229 230// -----231 232func.func private @void_return(%ptr: memref<i32>)233 234// CHECK-LABEL: test_tag: after_opaque_call:235// CHECK:        operand #0236// IP_ONLY:       - <unknown>237// IP_AW:         - func.call238func.func @test_opaque_call_return() {239  %ptr = memref.alloc() : memref<i32>240  %c0 = arith.constant 0 : i32241  memref.store %c0, %ptr[] {tag_name = "write0"} : memref<i32>242  func.call @void_return(%ptr) : (memref<i32>) -> ()243  memref.load %ptr[] {tag = "after_opaque_call"} : memref<i32>244  return245}246