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