xref: /llvm-project/mlir/test/Analysis/DataFlow/test-written-to.mlir (revision 32a4e3fccaf304c8d541bdefdb1a7ef829f84c1c)
1*32a4e3fcSOleksandr "Alex" Zinenko// RUN: mlir-opt -split-input-file -test-written-to %s 2>&1 |\
2*32a4e3fcSOleksandr "Alex" Zinenko// RUN:          FileCheck %s --check-prefixes=CHECK,IP
3*32a4e3fcSOleksandr "Alex" Zinenko// RUN: mlir-opt -split-input-file -test-written-to='interprocedural=false' %s \
4*32a4e3fcSOleksandr "Alex" Zinenko// RUN:          2>&1 | FileCheck %s --check-prefixes=CHECK,LOCAL
5*32a4e3fcSOleksandr "Alex" Zinenko// RUN: mlir-opt -split-input-file \
6*32a4e3fcSOleksandr "Alex" Zinenko// RUN:          -test-written-to='assume-func-writes=true' %s 2>&1 |\
7*32a4e3fcSOleksandr "Alex" Zinenko// RUN:          FileCheck %s --check-prefixes=CHECK,IP_AW
8*32a4e3fcSOleksandr "Alex" Zinenko// RUN: mlir-opt -split-input-file \
9*32a4e3fcSOleksandr "Alex" Zinenko// RUN:       -test-written-to='interprocedural=false assume-func-writes=true' \
10*32a4e3fcSOleksandr "Alex" Zinenko// RUN:       %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LC_AW
11*32a4e3fcSOleksandr "Alex" Zinenko
12*32a4e3fcSOleksandr "Alex" Zinenko// Check prefixes are as follows:
13*32a4e3fcSOleksandr "Alex" Zinenko// 'check': common for all runs;
14*32a4e3fcSOleksandr "Alex" Zinenko// 'ip': interprocedural runs;
15*32a4e3fcSOleksandr "Alex" Zinenko// 'ip_aw': interpocedural runs assuming calls to external functions write to
16*32a4e3fcSOleksandr "Alex" Zinenko//          all arguments;
17*32a4e3fcSOleksandr "Alex" Zinenko// 'local': local (non-interprocedural) analysis not assuming calls writing;
18*32a4e3fcSOleksandr "Alex" Zinenko// 'lc_aw': local analysis assuming external calls writing to all arguments.
19*32a4e3fcSOleksandr "Alex" Zinenko
20*32a4e3fcSOleksandr "Alex" Zinenko// Note that despite the name of the test analysis being "written to", it is set
21*32a4e3fcSOleksandr "Alex" Zinenko// up in a peculiar way where passing a value through a block or region argument
22*32a4e3fcSOleksandr "Alex" Zinenko// (via visitCall/BranchOperand) is considered as "writing" that value to the
23*32a4e3fcSOleksandr "Alex" Zinenko// corresponding operand, which is itself a value and not necessarily "memory".
24*32a4e3fcSOleksandr "Alex" Zinenko// This is arguably okay for testing purposes, but may be surprising for readers
25*32a4e3fcSOleksandr "Alex" Zinenko// trying to interpret this test using their intuition.
264e98d611SMatthias Kramm
274e98d611SMatthias Kramm// CHECK-LABEL: test_tag: constant0
284e98d611SMatthias Kramm// CHECK: result #0: [a]
294e98d611SMatthias Kramm// CHECK-LABEL: test_tag: constant1
304e98d611SMatthias Kramm// CHECK: result #0: [b]
314e98d611SMatthias Krammfunc.func @test_two_writes(%m0: memref<i32>, %m1: memref<i32>) -> (memref<i32>, memref<i32>) {
324e98d611SMatthias Kramm  %c0 = arith.constant {tag = "constant0"} 0 : i32
334e98d611SMatthias Kramm  %c1 = arith.constant {tag = "constant1"} 1 : i32
344e98d611SMatthias Kramm  memref.store %c0, %m0[] {tag_name = "a"} : memref<i32>
354e98d611SMatthias Kramm  memref.store %c1, %m1[] {tag_name = "b"} : memref<i32>
364e98d611SMatthias Kramm  return %m0, %m1 : memref<i32>, memref<i32>
374e98d611SMatthias Kramm}
384e98d611SMatthias Kramm
394e98d611SMatthias Kramm// -----
404e98d611SMatthias Kramm
414e98d611SMatthias Kramm// CHECK-LABEL: test_tag: c0
424e98d611SMatthias Kramm// CHECK: result #0: [b]
434e98d611SMatthias Kramm// CHECK-LABEL: test_tag: c1
444e98d611SMatthias Kramm// CHECK: result #0: [b]
454e98d611SMatthias Kramm// CHECK-LABEL: test_tag: condition
464e98d611SMatthias Kramm// CHECK: result #0: [brancharg0]
474e98d611SMatthias Kramm// CHECK-LABEL: test_tag: c2
484e98d611SMatthias Kramm// CHECK: result #0: [a]
494e98d611SMatthias Kramm// CHECK-LABEL: test_tag: c3
504e98d611SMatthias Kramm// CHECK: result #0: [a]
514e98d611SMatthias Krammfunc.func @test_if(%m0: memref<i32>, %m1: memref<i32>, %condition: i1) {
524e98d611SMatthias Kramm  %c0 = arith.constant {tag = "c0"} 2 : i32
534e98d611SMatthias Kramm  %c1 = arith.constant {tag = "c1"} 3 : i32
544e98d611SMatthias Kramm  %condition2 = arith.addi %condition, %condition {tag = "condition"} : i1
554e98d611SMatthias Kramm  %0, %1 = scf.if %condition2 -> (i32, i32) {
564e98d611SMatthias Kramm    %c2 = arith.constant {tag = "c2"} 0 : i32
574e98d611SMatthias Kramm    scf.yield %c2, %c0: i32, i32
584e98d611SMatthias Kramm  } else {
594e98d611SMatthias Kramm    %c3 = arith.constant {tag = "c3"} 1 : i32
604e98d611SMatthias Kramm    scf.yield %c3, %c1: i32, i32
614e98d611SMatthias Kramm  }
624e98d611SMatthias Kramm  memref.store %0, %m0[] {tag_name = "a"} : memref<i32>
634e98d611SMatthias Kramm  memref.store %1, %m1[] {tag_name = "b"} : memref<i32>
644e98d611SMatthias Kramm  return
654e98d611SMatthias Kramm}
664e98d611SMatthias Kramm
674e98d611SMatthias Kramm// -----
684e98d611SMatthias Kramm
694e98d611SMatthias Kramm// CHECK-LABEL: test_tag: c0
704e98d611SMatthias Kramm// CHECK: result #0: [a c]
714e98d611SMatthias Kramm// CHECK-LABEL: test_tag: c1
724e98d611SMatthias Kramm// CHECK: result #0: [b c]
734e98d611SMatthias Kramm// CHECK-LABEL: test_tag: br
744e98d611SMatthias Kramm// CHECK: operand #0: [brancharg0]
754e98d611SMatthias Krammfunc.func @test_blocks(%m0: memref<i32>,
764e98d611SMatthias Kramm                       %m1: memref<i32>,
774e98d611SMatthias Kramm                       %m2: memref<i32>, %cond : i1) {
784e98d611SMatthias Kramm  %0 = arith.constant {tag = "c0"} 0 : i32
794e98d611SMatthias Kramm  %1 = arith.constant {tag = "c1"} 1 : i32
804e98d611SMatthias Kramm  cf.cond_br %cond, ^a(%0: i32), ^b(%1: i32) {tag = "br"}
814e98d611SMatthias Kramm^a(%a0: i32):
824e98d611SMatthias Kramm  memref.store %a0, %m0[] {tag_name = "a"} : memref<i32>
834e98d611SMatthias Kramm  cf.br ^c(%a0 : i32)
844e98d611SMatthias Kramm^b(%b0: i32):
854e98d611SMatthias Kramm  memref.store %b0, %m1[] {tag_name = "b"} : memref<i32>
864e98d611SMatthias Kramm  cf.br ^c(%b0 : i32)
874e98d611SMatthias Kramm^c(%c0 : i32):
884e98d611SMatthias Kramm  memref.store %c0, %m2[] {tag_name = "c"} : memref<i32>
894e98d611SMatthias Kramm  return
904e98d611SMatthias Kramm}
914e98d611SMatthias Kramm
924e98d611SMatthias Kramm// -----
934e98d611SMatthias Kramm
944e98d611SMatthias Kramm// CHECK-LABEL: test_tag: two
954e98d611SMatthias Kramm// CHECK: result #0: [a]
964e98d611SMatthias Krammfunc.func @test_infinite_loop(%m0: memref<i32>) {
974e98d611SMatthias Kramm  %0 = arith.constant 0 : i32
984e98d611SMatthias Kramm  %1 = arith.constant 1 : i32
994e98d611SMatthias Kramm  %2 = arith.constant {tag = "two"} 2 : i32
1004e98d611SMatthias Kramm  %3 = arith.constant -1 : i32
1014e98d611SMatthias Kramm  cf.br ^loop(%0, %1, %2: i32, i32, i32)
1024e98d611SMatthias Kramm^loop(%a: i32, %b: i32, %c: i32):
1034e98d611SMatthias Kramm  memref.store %a, %m0[] {tag_name = "a"} : memref<i32>
1044e98d611SMatthias Kramm  cf.br ^loop(%b, %c, %3 : i32, i32, i32)
1054e98d611SMatthias Kramm}
1064e98d611SMatthias Kramm
1074e98d611SMatthias Kramm// -----
1084e98d611SMatthias Kramm
1094e98d611SMatthias Kramm// CHECK-LABEL: test_tag: c0
1104e98d611SMatthias Kramm// CHECK: result #0: [a b c]
1114e98d611SMatthias Krammfunc.func @test_switch(%flag: i32, %m0: memref<i32>) {
1124e98d611SMatthias Kramm  %0 = arith.constant {tag = "c0"} 0 : i32
1134e98d611SMatthias Kramm  cf.switch %flag : i32, [
1144e98d611SMatthias Kramm      default: ^a(%0 : i32),
1154e98d611SMatthias Kramm      42: ^b(%0 : i32),
1164e98d611SMatthias Kramm      43: ^c(%0 : i32)
1174e98d611SMatthias Kramm  ]
1184e98d611SMatthias Kramm^a(%a0: i32):
1194e98d611SMatthias Kramm  memref.store %a0, %m0[] {tag_name = "a"} : memref<i32>
1204e98d611SMatthias Kramm  cf.br ^c(%a0 : i32)
1214e98d611SMatthias Kramm^b(%b0: i32):
1224e98d611SMatthias Kramm  memref.store %b0, %m0[] {tag_name = "b"} : memref<i32>
1234e98d611SMatthias Kramm  cf.br ^c(%b0 : i32)
1244e98d611SMatthias Kramm^c(%c0 : i32):
1254e98d611SMatthias Kramm  memref.store %c0, %m0[] {tag_name = "c"} : memref<i32>
1264e98d611SMatthias Kramm  return
1274e98d611SMatthias Kramm}
1284e98d611SMatthias Kramm
1294e98d611SMatthias Kramm// -----
1304e98d611SMatthias Kramm
1314e98d611SMatthias Kramm// CHECK-LABEL: test_tag: add
132*32a4e3fcSOleksandr "Alex" Zinenko// IP:    result #0: [a]
133*32a4e3fcSOleksandr "Alex" Zinenko// LOCAL: result #0: [callarg0]
134*32a4e3fcSOleksandr "Alex" Zinenko// LC_AW: result #0: [func.call]
1354e98d611SMatthias Krammfunc.func @test_caller(%m0: memref<f32>, %arg: f32) {
1364e98d611SMatthias Kramm  %0 = arith.addf %arg, %arg {tag = "add"} : f32
1374e98d611SMatthias Kramm  %1 = func.call @callee(%0) : (f32) -> f32
1384e98d611SMatthias Kramm  %2 = arith.mulf %1, %1 : f32
1394e98d611SMatthias Kramm  %3 = arith.mulf %2, %2 : f32
1404e98d611SMatthias Kramm  %4 = arith.mulf %3, %3 : f32
1414e98d611SMatthias Kramm  memref.store %4, %m0[] {tag_name = "a"} : memref<f32>
1424e98d611SMatthias Kramm  return
1434e98d611SMatthias Kramm}
1444e98d611SMatthias Kramm
1454e98d611SMatthias Krammfunc.func private @callee(%0 : f32) -> f32 {
1464e98d611SMatthias Kramm  %1 = arith.mulf %0, %0 : f32
1474e98d611SMatthias Kramm  %2 = arith.mulf %1, %1 : f32
1484e98d611SMatthias Kramm  func.return %2 : f32
1494e98d611SMatthias Kramm}
1504e98d611SMatthias Kramm
1514e98d611SMatthias Kramm// -----
1524e98d611SMatthias Kramm
1534e98d611SMatthias Krammfunc.func private @callee(%0 : f32) -> f32 {
1544e98d611SMatthias Kramm  %1 = arith.mulf %0, %0 : f32
1554e98d611SMatthias Kramm  func.return %1 : f32
1564e98d611SMatthias Kramm}
1574e98d611SMatthias Kramm
1584e98d611SMatthias Kramm// CHECK-LABEL: test_tag: sub
159*32a4e3fcSOleksandr "Alex" Zinenko// IP:    result #0: [a]
160*32a4e3fcSOleksandr "Alex" Zinenko// LOCAL: result #0: [callarg0]
161*32a4e3fcSOleksandr "Alex" Zinenko// LC_AW: result #0: [func.call]
1624e98d611SMatthias Krammfunc.func @test_caller_below_callee(%m0: memref<f32>, %arg: f32) {
1634e98d611SMatthias Kramm  %0 = arith.subf %arg, %arg {tag = "sub"} : f32
1644e98d611SMatthias Kramm  %1 = func.call @callee(%0) : (f32) -> f32
1654e98d611SMatthias Kramm  memref.store %1, %m0[] {tag_name = "a"} : memref<f32>
1664e98d611SMatthias Kramm  return
1674e98d611SMatthias Kramm}
1684e98d611SMatthias Kramm
1694e98d611SMatthias Kramm// -----
1704e98d611SMatthias Kramm
1714e98d611SMatthias Krammfunc.func private @callee1(%0 : f32) -> f32 {
1724e98d611SMatthias Kramm  %1 = func.call @callee2(%0) : (f32) -> f32
1734e98d611SMatthias Kramm  func.return %1 : f32
1744e98d611SMatthias Kramm}
1754e98d611SMatthias Kramm
1764e98d611SMatthias Krammfunc.func private @callee2(%0 : f32) -> f32 {
1774e98d611SMatthias Kramm  %1 = func.call @callee3(%0) : (f32) -> f32
1784e98d611SMatthias Kramm  func.return %1 : f32
1794e98d611SMatthias Kramm}
1804e98d611SMatthias Kramm
1814e98d611SMatthias Krammfunc.func private @callee3(%0 : f32) -> f32 {
1824e98d611SMatthias Kramm  func.return %0 : f32
1834e98d611SMatthias Kramm}
1844e98d611SMatthias Kramm
1854e98d611SMatthias Kramm// CHECK-LABEL: test_tag: mul
186*32a4e3fcSOleksandr "Alex" Zinenko// IP:    result #0: [a]
187*32a4e3fcSOleksandr "Alex" Zinenko// LOCAL: result #0: [callarg0]
188*32a4e3fcSOleksandr "Alex" Zinenko// LC_AW: result #0: [func.call]
1894e98d611SMatthias Krammfunc.func @test_callchain(%m0: memref<f32>, %arg: f32) {
1904e98d611SMatthias Kramm  %0 = arith.mulf %arg, %arg {tag = "mul"} : f32
1914e98d611SMatthias Kramm  %1 = func.call @callee1(%0) : (f32) -> f32
1924e98d611SMatthias Kramm  memref.store %1, %m0[] {tag_name = "a"} : memref<f32>
1934e98d611SMatthias Kramm  return
1944e98d611SMatthias Kramm}
1954e98d611SMatthias Kramm
1964e98d611SMatthias Kramm// -----
1974e98d611SMatthias Kramm
1984e98d611SMatthias Kramm// CHECK-LABEL: test_tag: zero
1994e98d611SMatthias Kramm// CHECK: result #0: [c]
2004e98d611SMatthias Kramm// CHECK-LABEL: test_tag: init
201a9ab845cSSrishti Srivastava// CHECK: result #0: [a b c]
2024e98d611SMatthias Kramm// CHECK-LABEL: test_tag: condition
2034e98d611SMatthias Kramm// CHECK: operand #0: [brancharg0]
204a9ab845cSSrishti Srivastava// CHECK: operand #2: [a b c]
2054e98d611SMatthias Krammfunc.func @test_while(%m0: memref<i32>, %init : i32, %cond: i1) {
2064e98d611SMatthias Kramm  %zero = arith.constant {tag = "zero"} 0 : i32
2074e98d611SMatthias Kramm  %init2 = arith.addi %init, %init {tag = "init"} : i32
2084e98d611SMatthias Kramm  %0, %1 = scf.while (%arg1 = %zero, %arg2 = %init2) : (i32, i32) -> (i32, i32) {
2094e98d611SMatthias Kramm    memref.store %arg2, %m0[] {tag_name = "a"} : memref<i32>
2104e98d611SMatthias Kramm    scf.condition(%cond) {tag = "condition"} %arg1, %arg2 : i32, i32
2114e98d611SMatthias Kramm  } do {
2124e98d611SMatthias Kramm   ^bb0(%arg1: i32, %arg2: i32):
2134e98d611SMatthias Kramm    memref.store %arg1, %m0[] {tag_name = "c"} : memref<i32>
2144e98d611SMatthias Kramm    %res = arith.addi %arg2, %arg2 : i32
215a9ab845cSSrishti Srivastava    scf.yield %res, %res: i32, i32
2164e98d611SMatthias Kramm  }
2174e98d611SMatthias Kramm  memref.store %1, %m0[] {tag_name = "b"} : memref<i32>
2184e98d611SMatthias Kramm  return
2194e98d611SMatthias Kramm}
2204e98d611SMatthias Kramm
2214e98d611SMatthias Kramm// -----
2224e98d611SMatthias Kramm
2234e98d611SMatthias Kramm// CHECK-LABEL: test_tag: zero
224a9ab845cSSrishti Srivastava// CHECK: result #0: []
225a9ab845cSSrishti Srivastava// CHECK-LABEL: test_tag: one
226a9ab845cSSrishti Srivastava// CHECK: result #0: [a]
227a9ab845cSSrishti Srivastava// CHECK-LABEL: test_tag: condition
228a9ab845cSSrishti Srivastava// CHECK: operand #0: [brancharg0]
229a9ab845cSSrishti Srivastava//
230a9ab845cSSrishti Srivastava// The important thing to note in this test is that the sparse backward dataflow
231a9ab845cSSrishti Srivastava// analysis framework also works on complex region branch ops like this one
232a9ab845cSSrishti Srivastava// where the number of operands in the `scf.yield` op don't match the number of
233a9ab845cSSrishti Srivastava// results in the parent op.
234a9ab845cSSrishti Srivastavafunc.func @test_complex_while(%m0: memref<i32>, %cond: i1) {
235a9ab845cSSrishti Srivastava  %zero = arith.constant {tag = "zero"} 0 : i32
236a9ab845cSSrishti Srivastava  %one = arith.constant {tag = "one"} 1 : i32
237a9ab845cSSrishti Srivastava  %0 = scf.while (%arg1 = %zero, %arg2 = %one) : (i32, i32) -> (i32) {
238a9ab845cSSrishti Srivastava    scf.condition(%cond) {tag = "condition"} %arg2 : i32
239a9ab845cSSrishti Srivastava  } do {
240a9ab845cSSrishti Srivastava   ^bb0(%arg1: i32):
241a9ab845cSSrishti Srivastava    scf.yield %arg1, %arg1: i32, i32
242a9ab845cSSrishti Srivastava  }
243a9ab845cSSrishti Srivastava  memref.store %0, %m0[] {tag_name = "a"} : memref<i32>
244a9ab845cSSrishti Srivastava  return
245a9ab845cSSrishti Srivastava}
246a9ab845cSSrishti Srivastava
247a9ab845cSSrishti Srivastava// -----
248a9ab845cSSrishti Srivastava
249a9ab845cSSrishti Srivastava// CHECK-LABEL: test_tag: zero
2504e98d611SMatthias Kramm// CHECK: result #0: [brancharg0]
2514e98d611SMatthias Kramm// CHECK-LABEL: test_tag: ten
2524e98d611SMatthias Kramm// CHECK: result #0: [brancharg1]
2534e98d611SMatthias Kramm// CHECK-LABEL: test_tag: one
2544e98d611SMatthias Kramm// CHECK: result #0: [brancharg2]
2554e98d611SMatthias Kramm// CHECK-LABEL: test_tag: x
2564e98d611SMatthias Kramm// CHECK: result #0: [a]
2574e98d611SMatthias Krammfunc.func @test_for(%m0: memref<i32>) {
2584e98d611SMatthias Kramm  %zero = arith.constant {tag = "zero"} 0 : index
2594e98d611SMatthias Kramm  %ten = arith.constant {tag = "ten"} 10 : index
2604e98d611SMatthias Kramm  %one = arith.constant {tag = "one"} 1 : index
2614e98d611SMatthias Kramm  %x = arith.constant {tag = "x"} 0 : i32
2624e98d611SMatthias Kramm  %0 = scf.for %i = %zero to %ten step %one iter_args(%ix = %x) -> (i32) {
2634e98d611SMatthias Kramm    scf.yield %ix : i32
2644e98d611SMatthias Kramm  }
2654e98d611SMatthias Kramm  memref.store %0, %m0[] {tag_name = "a"} : memref<i32>
2664e98d611SMatthias Kramm  return
2674e98d611SMatthias Kramm}
2684e98d611SMatthias Kramm
2694e98d611SMatthias Kramm// -----
2704e98d611SMatthias Kramm
2714e98d611SMatthias Kramm// CHECK-LABEL: test_tag: default_a
272*32a4e3fcSOleksandr "Alex" Zinenko// CHECK:       result #0: [a]
2734e98d611SMatthias Kramm// CHECK-LABEL: test_tag: default_b
274*32a4e3fcSOleksandr "Alex" Zinenko// CHECK:       result #0: [b]
2754e98d611SMatthias Kramm// CHECK-LABEL: test_tag: 1a
276*32a4e3fcSOleksandr "Alex" Zinenko// CHECK:       result #0: [a]
2774e98d611SMatthias Kramm// CHECK-LABEL: test_tag: 1b
278*32a4e3fcSOleksandr "Alex" Zinenko// CHECK:       result #0: [b]
2794e98d611SMatthias Kramm// CHECK-LABEL: test_tag: 2a
280*32a4e3fcSOleksandr "Alex" Zinenko// CHECK:       result #0: [a]
2814e98d611SMatthias Kramm// CHECK-LABEL: test_tag: 2b
282*32a4e3fcSOleksandr "Alex" Zinenko// CHECK:       result #0: [b]
2834e98d611SMatthias Kramm// CHECK-LABEL: test_tag: switch
284*32a4e3fcSOleksandr "Alex" Zinenko// CHECK:       operand #0: [brancharg0]
2854e98d611SMatthias Krammfunc.func @test_switch(%arg0 : index, %m0: memref<i32>) {
2864e98d611SMatthias Kramm  %0, %1 = scf.index_switch %arg0 {tag="switch"} -> i32, i32
2874e98d611SMatthias Kramm  case 1 {
2884e98d611SMatthias Kramm    %2 = arith.constant {tag="1a"} 10 : i32
2894e98d611SMatthias Kramm    %3 = arith.constant {tag="1b"} 100 : i32
2904e98d611SMatthias Kramm    scf.yield %2, %3 : i32, i32
2914e98d611SMatthias Kramm  }
2924e98d611SMatthias Kramm  case 2 {
2934e98d611SMatthias Kramm    %4 = arith.constant {tag="2a"} 20 : i32
2944e98d611SMatthias Kramm    %5 = arith.constant {tag="2b"} 200 : i32
2954e98d611SMatthias Kramm    scf.yield %4, %5 : i32, i32
2964e98d611SMatthias Kramm  }
2974e98d611SMatthias Kramm  default {
2984e98d611SMatthias Kramm    %6 = arith.constant {tag="default_a"} 30 : i32
2994e98d611SMatthias Kramm    %7 = arith.constant {tag="default_b"} 300 : i32
3004e98d611SMatthias Kramm    scf.yield %6, %7 : i32, i32
3014e98d611SMatthias Kramm  }
3024e98d611SMatthias Kramm  memref.store %0, %m0[] {tag_name = "a"} : memref<i32>
3034e98d611SMatthias Kramm  memref.store %1, %m0[] {tag_name = "b"} : memref<i32>
3044e98d611SMatthias Kramm  return
3054e98d611SMatthias Kramm}
3064ef085c5SXiang Li
3074ef085c5SXiang Li// -----
3084ef085c5SXiang Li
309*32a4e3fcSOleksandr "Alex" Zinenko// The point of this test is to ensure the analysis doesn't crash in presence of
310*32a4e3fcSOleksandr "Alex" Zinenko// external functions.
311*32a4e3fcSOleksandr "Alex" Zinenko
3124ef085c5SXiang Li// CHECK-LABEL: llvm.func @decl(i64)
3134ef085c5SXiang Li// CHECK-LABEL: llvm.func @func(%arg0: i64) {
3144ef085c5SXiang Li// CHECK-NEXT:  llvm.call @decl(%arg0) : (i64) -> ()
3154ef085c5SXiang Li// CHECK-NEXT:  llvm.return
3164ef085c5SXiang Li
3174ef085c5SXiang Lillvm.func @decl(i64)
3184ef085c5SXiang Li
3194ef085c5SXiang Lillvm.func @func(%lb : i64) -> () {
3204ef085c5SXiang Li  llvm.call @decl(%lb) : (i64) -> ()
3214ef085c5SXiang Li  llvm.return
3224ef085c5SXiang Li}
323232f8eadSSrishti Srivastava
324232f8eadSSrishti Srivastava// -----
325232f8eadSSrishti Srivastava
326232f8eadSSrishti Srivastavafunc.func private @callee(%arg0 : i32, %arg1 : i32) -> i32 {
327232f8eadSSrishti Srivastava  func.return %arg0 : i32
328232f8eadSSrishti Srivastava}
329232f8eadSSrishti Srivastava
330232f8eadSSrishti Srivastava// CHECK-LABEL: test_tag: a
331*32a4e3fcSOleksandr "Alex" Zinenko
332*32a4e3fcSOleksandr "Alex" Zinenko// IP:           operand #0: [b]
333*32a4e3fcSOleksandr "Alex" Zinenko// LOCAL:        operand #0: [callarg0]
334*32a4e3fcSOleksandr "Alex" Zinenko// LC_AW:        operand #0: [test.call_on_device]
335*32a4e3fcSOleksandr "Alex" Zinenko
336*32a4e3fcSOleksandr "Alex" Zinenko// IP:           operand #1: []
337*32a4e3fcSOleksandr "Alex" Zinenko// LOCAL:        operand #1: [callarg1]
338*32a4e3fcSOleksandr "Alex" Zinenko// LC_AW:        operand #1: [test.call_on_device]
339*32a4e3fcSOleksandr "Alex" Zinenko
340*32a4e3fcSOleksandr "Alex" Zinenko// IP:           operand #2: [callarg2]
341*32a4e3fcSOleksandr "Alex" Zinenko// LOCAL:        operand #2: [callarg2]
342*32a4e3fcSOleksandr "Alex" Zinenko// LC_AW:        operand #2: [test.call_on_device]
343*32a4e3fcSOleksandr "Alex" Zinenko
344*32a4e3fcSOleksandr "Alex" Zinenko// CHECK:        result #0: [b]
345232f8eadSSrishti Srivastavafunc.func @test_call_on_device(%arg0: i32, %arg1: i32, %device: i32, %m0: memref<i32>) {
346232f8eadSSrishti Srivastava  %0 = test.call_on_device @callee(%arg0, %arg1), %device {tag = "a"} : (i32, i32, i32) -> (i32)
347232f8eadSSrishti Srivastava  memref.store %0, %m0[] {tag_name = "b"} : memref<i32>
348232f8eadSSrishti Srivastava  return
349232f8eadSSrishti Srivastava}
350*32a4e3fcSOleksandr "Alex" Zinenko
351*32a4e3fcSOleksandr "Alex" Zinenko// -----
352*32a4e3fcSOleksandr "Alex" Zinenko
353*32a4e3fcSOleksandr "Alex" Zinenkofunc.func private @external_callee(%arg0: i32) -> i32
354*32a4e3fcSOleksandr "Alex" Zinenko
355*32a4e3fcSOleksandr "Alex" Zinenko// CHECK-LABEL: test_tag: add_external
356*32a4e3fcSOleksandr "Alex" Zinenko// IP:    operand #0: [callarg0]
357*32a4e3fcSOleksandr "Alex" Zinenko// LOCAL: operand #0: [callarg0]
358*32a4e3fcSOleksandr "Alex" Zinenko// LC_AW: operand #0: [func.call]
359*32a4e3fcSOleksandr "Alex" Zinenko// IP_AW: operand #0: [func.call]
360*32a4e3fcSOleksandr "Alex" Zinenko
361*32a4e3fcSOleksandr "Alex" Zinenkofunc.func @test_external_callee(%arg0: i32, %m0: memref<i32>) {
362*32a4e3fcSOleksandr "Alex" Zinenko  %0 = arith.addi %arg0, %arg0 { tag = "add_external"}: i32
363*32a4e3fcSOleksandr "Alex" Zinenko  %1 = func.call @external_callee(%arg0) : (i32) -> i32
364*32a4e3fcSOleksandr "Alex" Zinenko  memref.store %1, %m0[] {tag_name = "a"} : memref<i32>
365*32a4e3fcSOleksandr "Alex" Zinenko  return
366*32a4e3fcSOleksandr "Alex" Zinenko}
367