132a4e3fcSOleksandr "Alex" Zinenko// RUN: mlir-opt %s --test-next-access --split-input-file |\ 232a4e3fcSOleksandr "Alex" Zinenko// RUN: FileCheck %s --check-prefixes=CHECK,IP 332a4e3fcSOleksandr "Alex" Zinenko// RUN: mlir-opt %s --test-next-access='interprocedural=false' \ 432a4e3fcSOleksandr "Alex" Zinenko// RUN: --split-input-file |\ 532a4e3fcSOleksandr "Alex" Zinenko// RUN: FileCheck %s --check-prefixes=CHECK,LOCAL 632a4e3fcSOleksandr "Alex" Zinenko// RUN: mlir-opt %s --test-next-access='assume-func-reads=true' \ 732a4e3fcSOleksandr "Alex" Zinenko// RUN: --split-input-file |\ 832a4e3fcSOleksandr "Alex" Zinenko// RUN: FileCheck %s --check-prefixes=CHECK,IP_AR 932a4e3fcSOleksandr "Alex" Zinenko// RUN: mlir-opt %s \ 1032a4e3fcSOleksandr "Alex" Zinenko// RUN: --test-next-access='interprocedural=false assume-func-reads=true' \ 1132a4e3fcSOleksandr "Alex" Zinenko// RUN: --split-input-file | FileCheck %s --check-prefixes=CHECK,LC_AR 1232a4e3fcSOleksandr "Alex" Zinenko 1332a4e3fcSOleksandr "Alex" Zinenko// Check prefixes are as follows: 1432a4e3fcSOleksandr "Alex" Zinenko// 'check': common for all runs; 1532a4e3fcSOleksandr "Alex" Zinenko// 'ip_ar': interpocedural runs assuming calls to external functions read 1632a4e3fcSOleksandr "Alex" Zinenko// all arguments; 1732a4e3fcSOleksandr "Alex" Zinenko// 'ip': interprocedural runs not assuming function calls reading; 1832a4e3fcSOleksandr "Alex" Zinenko// 'local': local (non-interprocedural) analysis not assuming calls reading; 1932a4e3fcSOleksandr "Alex" Zinenko// 'lc_ar': local analysis assuming external calls reading all arguments. 208a918c54SAlex Zinenko 218a918c54SAlex Zinenko// CHECK-LABEL: @trivial 228a918c54SAlex Zinenkofunc.func @trivial(%arg0: memref<f32>, %arg1: f32) -> f32 { 238a918c54SAlex Zinenko // CHECK: name = "store" 248a918c54SAlex Zinenko // CHECK-SAME: next_access = ["unknown", ["load"]] 258a918c54SAlex Zinenko memref.store %arg1, %arg0[] {name = "store"} : memref<f32> 268a918c54SAlex Zinenko // CHECK: name = "load" 278a918c54SAlex Zinenko // CHECK-SAME: next_access = ["unknown"] 288a918c54SAlex Zinenko %0 = memref.load %arg0[] {name = "load"} : memref<f32> 298a918c54SAlex Zinenko return %0 : f32 308a918c54SAlex Zinenko} 318a918c54SAlex Zinenko 328a918c54SAlex Zinenko// CHECK-LABEL: @chain 338a918c54SAlex Zinenkofunc.func @chain(%arg0: memref<f32>, %arg1: f32) -> f32 { 348a918c54SAlex Zinenko // CHECK: name = "store" 358a918c54SAlex Zinenko // CHECK-SAME: next_access = ["unknown", ["load 1"]] 368a918c54SAlex Zinenko memref.store %arg1, %arg0[] {name = "store"} : memref<f32> 378a918c54SAlex Zinenko // CHECK: name = "load 1" 388a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["load 2"]] 398a918c54SAlex Zinenko %0 = memref.load %arg0[] {name = "load 1"} : memref<f32> 408a918c54SAlex Zinenko // CHECK: name = "load 2" 418a918c54SAlex Zinenko // CHECK-SAME: next_access = ["unknown"] 428a918c54SAlex Zinenko %1 = memref.load %arg0[] {name = "load 2"} : memref<f32> 438a918c54SAlex Zinenko %2 = arith.addf %0, %1 : f32 448a918c54SAlex Zinenko return %2 : f32 458a918c54SAlex Zinenko} 468a918c54SAlex Zinenko 478a918c54SAlex Zinenko// CHECK-LABEL: @branch 488a918c54SAlex Zinenkofunc.func @branch(%arg0: memref<f32>, %arg1: f32, %arg2: i1) -> f32 { 498a918c54SAlex Zinenko // CHECK: name = "store" 508a918c54SAlex Zinenko // CHECK-SAME: next_access = ["unknown", ["load 1", "load 2"]] 518a918c54SAlex Zinenko memref.store %arg1, %arg0[] {name = "store"} : memref<f32> 528a918c54SAlex Zinenko cf.cond_br %arg2, ^bb0, ^bb1 538a918c54SAlex Zinenko 548a918c54SAlex Zinenko^bb0: 558a918c54SAlex Zinenko %0 = memref.load %arg0[] {name = "load 1"} : memref<f32> 568a918c54SAlex Zinenko cf.br ^bb2(%0 : f32) 578a918c54SAlex Zinenko 588a918c54SAlex Zinenko^bb1: 598a918c54SAlex Zinenko %1 = memref.load %arg0[] {name = "load 2"} : memref<f32> 608a918c54SAlex Zinenko cf.br ^bb2(%1 : f32) 618a918c54SAlex Zinenko 628a918c54SAlex Zinenko^bb2(%phi: f32): 638a918c54SAlex Zinenko return %phi : f32 648a918c54SAlex Zinenko} 658a918c54SAlex Zinenko 66*f0b0c025Sklensy// CHECK-LABEL: @dead_branch 678a918c54SAlex Zinenkofunc.func @dead_branch(%arg0: memref<f32>, %arg1: f32) -> f32 { 688a918c54SAlex Zinenko // CHECK: name = "store" 698a918c54SAlex Zinenko // CHECK-SAME: next_access = ["unknown", ["load 2"]] 708a918c54SAlex Zinenko memref.store %arg1, %arg0[] {name = "store"} : memref<f32> 718a918c54SAlex Zinenko cf.br ^bb1 728a918c54SAlex Zinenko 738a918c54SAlex Zinenko^bb0: 748a918c54SAlex Zinenko // CHECK: name = "load 1" 758a918c54SAlex Zinenko // CHECK-SAME: next_access = "not computed" 768a918c54SAlex Zinenko %0 = memref.load %arg0[] {name = "load 1"} : memref<f32> 778a918c54SAlex Zinenko cf.br ^bb2(%0 : f32) 788a918c54SAlex Zinenko 798a918c54SAlex Zinenko^bb1: 808a918c54SAlex Zinenko %1 = memref.load %arg0[] {name = "load 2"} : memref<f32> 818a918c54SAlex Zinenko cf.br ^bb2(%1 : f32) 828a918c54SAlex Zinenko 838a918c54SAlex Zinenko^bb2(%phi: f32): 848a918c54SAlex Zinenko return %phi : f32 858a918c54SAlex Zinenko} 868a918c54SAlex Zinenko 878a918c54SAlex Zinenko// CHECK-LABEL: @loop 888a918c54SAlex Zinenkofunc.func @loop(%arg0: memref<?xf32>, %arg1: f32, %arg2: index, %arg3: index, %arg4: index) -> f32 { 898a918c54SAlex Zinenko %c0 = arith.constant 0.0 : f32 908a918c54SAlex Zinenko // CHECK: name = "pre" 918dbddb17SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["outside", "loop"], "unknown"] 928a918c54SAlex Zinenko memref.load %arg0[%arg4] {name = "pre"} : memref<?xf32> 938a918c54SAlex Zinenko %l = scf.for %i = %arg2 to %arg3 step %arg4 iter_args(%ia = %c0) -> (f32) { 948a918c54SAlex Zinenko // CHECK: name = "loop" 958a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["outside", "loop"], "unknown"] 968a918c54SAlex Zinenko %0 = memref.load %arg0[%i] {name = "loop"} : memref<?xf32> 978a918c54SAlex Zinenko %1 = arith.addf %ia, %0 : f32 988a918c54SAlex Zinenko scf.yield %1 : f32 998a918c54SAlex Zinenko } 1008a918c54SAlex Zinenko %v = memref.load %arg0[%arg3] {name = "outside"} : memref<?xf32> 1018a918c54SAlex Zinenko %2 = arith.addf %v, %l : f32 1028a918c54SAlex Zinenko return %2 : f32 1038a918c54SAlex Zinenko} 1048a918c54SAlex Zinenko 1058a918c54SAlex Zinenko// CHECK-LABEL: @conditional 1068a918c54SAlex Zinenkofunc.func @conditional(%cond: i1, %arg0: memref<f32>) { 1078a918c54SAlex Zinenko // CHECK: name = "pre" 1088dbddb17SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post", "then"]] 1098a918c54SAlex Zinenko memref.load %arg0[] {name = "pre"}: memref<f32> 1108a918c54SAlex Zinenko scf.if %cond { 1118a918c54SAlex Zinenko // CHECK: name = "then" 1128a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 1138a918c54SAlex Zinenko memref.load %arg0[] {name = "then"} : memref<f32> 1148a918c54SAlex Zinenko } 1158a918c54SAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 1168a918c54SAlex Zinenko return 1178a918c54SAlex Zinenko} 1188a918c54SAlex Zinenko 1198a918c54SAlex Zinenko// CHECK-LABEL: @two_sided_conditional 1208a918c54SAlex Zinenkofunc.func @two_sided_conditional(%cond: i1, %arg0: memref<f32>) { 1218a918c54SAlex Zinenko // CHECK: name = "pre" 1228a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["then", "else"]] 1238a918c54SAlex Zinenko memref.load %arg0[] {name = "pre"}: memref<f32> 1248a918c54SAlex Zinenko scf.if %cond { 1258a918c54SAlex Zinenko // CHECK: name = "then" 1268a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 1278a918c54SAlex Zinenko memref.load %arg0[] {name = "then"} : memref<f32> 1288a918c54SAlex Zinenko } else { 1298a918c54SAlex Zinenko // CHECK: name = "else" 1308a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 1318a918c54SAlex Zinenko memref.load %arg0[] {name = "else"} : memref<f32> 1328a918c54SAlex Zinenko } 1338a918c54SAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 1348a918c54SAlex Zinenko return 1358a918c54SAlex Zinenko} 1368a918c54SAlex Zinenko 1378a918c54SAlex Zinenko// CHECK-LABEL: @dead_conditional 1388a918c54SAlex Zinenkofunc.func @dead_conditional(%arg0: memref<f32>) { 1398a918c54SAlex Zinenko %false = arith.constant 0 : i1 1408a918c54SAlex Zinenko // CHECK: name = "pre" 1418dbddb17SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 1428a918c54SAlex Zinenko memref.load %arg0[] {name = "pre"}: memref<f32> 1438a918c54SAlex Zinenko scf.if %false { 1448a918c54SAlex Zinenko // CHECK: name = "then" 1458a918c54SAlex Zinenko // CHECK-SAME: next_access = "not computed" 1468a918c54SAlex Zinenko memref.load %arg0[] {name = "then"} : memref<f32> 1478a918c54SAlex Zinenko } 1488a918c54SAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 1498a918c54SAlex Zinenko return 1508a918c54SAlex Zinenko} 1518a918c54SAlex Zinenko 1528a918c54SAlex Zinenko// CHECK-LABEL: @known_conditional 1538a918c54SAlex Zinenkofunc.func @known_conditional(%arg0: memref<f32>) { 1548a918c54SAlex Zinenko %false = arith.constant 0 : i1 1558a918c54SAlex Zinenko // CHECK: name = "pre" 1568a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["else"]] 1578a918c54SAlex Zinenko memref.load %arg0[] {name = "pre"}: memref<f32> 1588a918c54SAlex Zinenko scf.if %false { 1598a918c54SAlex Zinenko // CHECK: name = "then" 1608a918c54SAlex Zinenko // CHECK-SAME: next_access = "not computed" 1618a918c54SAlex Zinenko memref.load %arg0[] {name = "then"} : memref<f32> 1628a918c54SAlex Zinenko } else { 1638a918c54SAlex Zinenko // CHECK: name = "else" 1648a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 1658a918c54SAlex Zinenko memref.load %arg0[] {name = "else"} : memref<f32> 1668a918c54SAlex Zinenko } 1678a918c54SAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 1688a918c54SAlex Zinenko return 1698a918c54SAlex Zinenko} 1708a918c54SAlex Zinenko 1718a918c54SAlex Zinenko// CHECK-LABEL: @loop_cf 1728a918c54SAlex Zinenkofunc.func @loop_cf(%arg0: memref<?xf32>, %arg1: f32, %arg2: index, %arg3: index, %arg4: index) -> f32 { 1738a918c54SAlex Zinenko %cst = arith.constant 0.000000e+00 : f32 1748a918c54SAlex Zinenko // CHECK: name = "pre" 1758a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["loop", "outside"], "unknown"] 1768a918c54SAlex Zinenko %0 = memref.load %arg0[%arg4] {name = "pre"} : memref<?xf32> 1778a918c54SAlex Zinenko cf.br ^bb1(%arg2, %cst : index, f32) 1788a918c54SAlex Zinenko^bb1(%1: index, %2: f32): 1798a918c54SAlex Zinenko %3 = arith.cmpi slt, %1, %arg3 : index 1808a918c54SAlex Zinenko cf.cond_br %3, ^bb2, ^bb3 1818a918c54SAlex Zinenko^bb2: 1828a918c54SAlex Zinenko // CHECK: name = "loop" 1838a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["loop", "outside"], "unknown"] 1848a918c54SAlex Zinenko %4 = memref.load %arg0[%1] {name = "loop"} : memref<?xf32> 1858a918c54SAlex Zinenko %5 = arith.addf %2, %4 : f32 1868a918c54SAlex Zinenko %6 = arith.addi %1, %arg4 : index 1878a918c54SAlex Zinenko cf.br ^bb1(%6, %5 : index, f32) 1888a918c54SAlex Zinenko^bb3: 1898a918c54SAlex Zinenko %7 = memref.load %arg0[%arg3] {name = "outside"} : memref<?xf32> 1908a918c54SAlex Zinenko %8 = arith.addf %7, %2 : f32 1918a918c54SAlex Zinenko return %8 : f32 1928a918c54SAlex Zinenko} 1938a918c54SAlex Zinenko 194*f0b0c025Sklensy// CHECK-LABEL: @conditional_cf 1958a918c54SAlex Zinenkofunc.func @conditional_cf(%arg0: i1, %arg1: memref<f32>) { 1968a918c54SAlex Zinenko // CHECK: name = "pre" 1978a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["then", "post"]] 1988a918c54SAlex Zinenko %0 = memref.load %arg1[] {name = "pre"} : memref<f32> 1998a918c54SAlex Zinenko cf.cond_br %arg0, ^bb1, ^bb2 2008a918c54SAlex Zinenko^bb1: 2018a918c54SAlex Zinenko // CHECK: name = "then" 2028a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 2038a918c54SAlex Zinenko %1 = memref.load %arg1[] {name = "then"} : memref<f32> 2048a918c54SAlex Zinenko cf.br ^bb2 2058a918c54SAlex Zinenko^bb2: 2068a918c54SAlex Zinenko %2 = memref.load %arg1[] {name = "post"} : memref<f32> 2078a918c54SAlex Zinenko return 2088a918c54SAlex Zinenko} 2098a918c54SAlex Zinenko 2108a918c54SAlex Zinenko// CHECK-LABEL: @two_sided_conditional_cf 2118a918c54SAlex Zinenkofunc.func @two_sided_conditional_cf(%arg0: i1, %arg1: memref<f32>) { 2128a918c54SAlex Zinenko // CHECK: name = "pre" 2138a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["then", "else"]] 2148a918c54SAlex Zinenko %0 = memref.load %arg1[] {name = "pre"} : memref<f32> 2158a918c54SAlex Zinenko cf.cond_br %arg0, ^bb1, ^bb2 2168a918c54SAlex Zinenko^bb1: 2178a918c54SAlex Zinenko // CHECK: name = "then" 2188a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 2198a918c54SAlex Zinenko %1 = memref.load %arg1[] {name = "then"} : memref<f32> 2208a918c54SAlex Zinenko cf.br ^bb3 2218a918c54SAlex Zinenko^bb2: 2228a918c54SAlex Zinenko // CHECK: name = "else" 2238a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 2248a918c54SAlex Zinenko %2 = memref.load %arg1[] {name = "else"} : memref<f32> 2258a918c54SAlex Zinenko cf.br ^bb3 2268a918c54SAlex Zinenko^bb3: 2278a918c54SAlex Zinenko %3 = memref.load %arg1[] {name = "post"} : memref<f32> 2288a918c54SAlex Zinenko return 2298a918c54SAlex Zinenko} 2308a918c54SAlex Zinenko 2318a918c54SAlex Zinenko// CHECK-LABEL: @dead_conditional_cf 2328a918c54SAlex Zinenkofunc.func @dead_conditional_cf(%arg0: memref<f32>) { 2338a918c54SAlex Zinenko %false = arith.constant false 2348a918c54SAlex Zinenko // CHECK: name = "pre" 2358a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 2368a918c54SAlex Zinenko %0 = memref.load %arg0[] {name = "pre"} : memref<f32> 2378a918c54SAlex Zinenko cf.cond_br %false, ^bb1, ^bb2 2388a918c54SAlex Zinenko^bb1: 2398a918c54SAlex Zinenko // CHECK: name = "then" 2408a918c54SAlex Zinenko // CHECK-SAME: next_access = "not computed" 2418a918c54SAlex Zinenko %1 = memref.load %arg0[] {name = "then"} : memref<f32> 2428a918c54SAlex Zinenko cf.br ^bb2 2438a918c54SAlex Zinenko^bb2: 2448a918c54SAlex Zinenko %2 = memref.load %arg0[] {name = "post"} : memref<f32> 2458a918c54SAlex Zinenko return 2468a918c54SAlex Zinenko} 2478a918c54SAlex Zinenko 2488a918c54SAlex Zinenko// CHECK-LABEL: @known_conditional_cf 2498a918c54SAlex Zinenkofunc.func @known_conditional_cf(%arg0: memref<f32>) { 2508a918c54SAlex Zinenko %false = arith.constant false 2518a918c54SAlex Zinenko // CHECK: name = "pre" 2528a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["else"]] 2538a918c54SAlex Zinenko %0 = memref.load %arg0[] {name = "pre"} : memref<f32> 2548a918c54SAlex Zinenko cf.cond_br %false, ^bb1, ^bb2 2558a918c54SAlex Zinenko^bb1: 2568a918c54SAlex Zinenko // CHECK: name = "then" 2578a918c54SAlex Zinenko // CHECK-SAME: next_access = "not computed" 2588a918c54SAlex Zinenko %1 = memref.load %arg0[] {name = "then"} : memref<f32> 2598a918c54SAlex Zinenko cf.br ^bb3 2608a918c54SAlex Zinenko^bb2: 2618a918c54SAlex Zinenko // CHECK: name = "else" 2628a918c54SAlex Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 2638a918c54SAlex Zinenko %2 = memref.load %arg0[] {name = "else"} : memref<f32> 2648a918c54SAlex Zinenko cf.br ^bb3 2658a918c54SAlex Zinenko^bb3: 2668a918c54SAlex Zinenko %3 = memref.load %arg0[] {name = "post"} : memref<f32> 2678a918c54SAlex Zinenko return 2688a918c54SAlex Zinenko} 2698a918c54SAlex Zinenko 2708a918c54SAlex Zinenko// ----- 2718a918c54SAlex Zinenko 2728a918c54SAlex Zinenkofunc.func private @callee1(%arg0: memref<f32>) { 27332a4e3fcSOleksandr "Alex" Zinenko // IP: name = "callee1" 27432a4e3fcSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["post"]] 27532a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "callee1" 27632a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 2778a918c54SAlex Zinenko memref.load %arg0[] {name = "callee1"} : memref<f32> 2788a918c54SAlex Zinenko return 2798a918c54SAlex Zinenko} 2808a918c54SAlex Zinenko 2818a918c54SAlex Zinenkofunc.func private @callee2(%arg0: memref<f32>) { 2828a918c54SAlex Zinenko // CHECK: name = "callee2" 2838a918c54SAlex Zinenko // CHECK-SAME: next_access = "not computed" 2848a918c54SAlex Zinenko memref.load %arg0[] {name = "callee2"} : memref<f32> 2858a918c54SAlex Zinenko return 2868a918c54SAlex Zinenko} 2878a918c54SAlex Zinenko 2888a918c54SAlex Zinenko// CHECK-LABEL: @simple_call 2898a918c54SAlex Zinenkofunc.func @simple_call(%arg0: memref<f32>) { 29032a4e3fcSOleksandr "Alex" Zinenko // IP: name = "caller" 29132a4e3fcSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["callee1"]] 29232a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "caller" 29332a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 29432a4e3fcSOleksandr "Alex" Zinenko // LC_AR: name = "caller" 29532a4e3fcSOleksandr "Alex" Zinenko // LC_AR-SAME: next_access = {{\[}}["call"]] 2968a918c54SAlex Zinenko memref.load %arg0[] {name = "caller"} : memref<f32> 29732a4e3fcSOleksandr "Alex" Zinenko func.call @callee1(%arg0) {name = "call"} : (memref<f32>) -> () 2988a918c54SAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 2998a918c54SAlex Zinenko return 3008a918c54SAlex Zinenko} 3018a918c54SAlex Zinenko 3028a918c54SAlex Zinenko// ----- 3038a918c54SAlex Zinenko 3048a918c54SAlex Zinenko// CHECK-LABEL: @infinite_recursive_call 3058a918c54SAlex Zinenkofunc.func @infinite_recursive_call(%arg0: memref<f32>) { 30632a4e3fcSOleksandr "Alex" Zinenko // IP: name = "pre" 30732a4e3fcSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["pre"]] 30832a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "pre" 30932a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 31032a4e3fcSOleksandr "Alex" Zinenko // LC_AR: name = "pre" 31132a4e3fcSOleksandr "Alex" Zinenko // LC_AR-SAME: next_access = {{\[}}["call"]] 3128a918c54SAlex Zinenko memref.load %arg0[] {name = "pre"} : memref<f32> 31332a4e3fcSOleksandr "Alex" Zinenko func.call @infinite_recursive_call(%arg0) {name = "call"} : (memref<f32>) -> () 3148a918c54SAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 3158a918c54SAlex Zinenko return 3168a918c54SAlex Zinenko} 3178a918c54SAlex Zinenko 3188a918c54SAlex Zinenko// ----- 3198a918c54SAlex Zinenko 3208a918c54SAlex Zinenko// CHECK-LABEL: @recursive_call 3218a918c54SAlex Zinenkofunc.func @recursive_call(%arg0: memref<f32>, %cond: i1) { 32232a4e3fcSOleksandr "Alex" Zinenko // IP: name = "pre" 32332a4e3fcSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["post", "pre"]] 32432a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "pre" 32532a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 32632a4e3fcSOleksandr "Alex" Zinenko // LC_AR: name = "pre" 32732a4e3fcSOleksandr "Alex" Zinenko // LC_AR-SAME: next_access = {{\[}}["post", "call"]] 3288a918c54SAlex Zinenko memref.load %arg0[] {name = "pre"} : memref<f32> 3298a918c54SAlex Zinenko scf.if %cond { 33032a4e3fcSOleksandr "Alex" Zinenko func.call @recursive_call(%arg0, %cond) {name = "call"} : (memref<f32>, i1) -> () 3318a918c54SAlex Zinenko } 3328a918c54SAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 3338a918c54SAlex Zinenko return 3348a918c54SAlex Zinenko} 3358a918c54SAlex Zinenko 3368a918c54SAlex Zinenko// ----- 3378a918c54SAlex Zinenko 3388a918c54SAlex Zinenko// CHECK-LABEL: @recursive_call_cf 3398a918c54SAlex Zinenkofunc.func @recursive_call_cf(%arg0: memref<f32>, %cond: i1) { 34032a4e3fcSOleksandr "Alex" Zinenko // IP: name = "pre" 34132a4e3fcSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["pre", "post"]] 34232a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "pre" 34332a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 34432a4e3fcSOleksandr "Alex" Zinenko // LC_AR: name = "pre" 34532a4e3fcSOleksandr "Alex" Zinenko // LC_AR-SAME: next_access = {{\[}}["call", "post"]] 3468a918c54SAlex Zinenko %0 = memref.load %arg0[] {name = "pre"} : memref<f32> 3478a918c54SAlex Zinenko cf.cond_br %cond, ^bb1, ^bb2 3488a918c54SAlex Zinenko^bb1: 34932a4e3fcSOleksandr "Alex" Zinenko call @recursive_call_cf(%arg0, %cond) {name = "call"} : (memref<f32>, i1) -> () 3508a918c54SAlex Zinenko cf.br ^bb2 3518a918c54SAlex Zinenko^bb2: 3528a918c54SAlex Zinenko %2 = memref.load %arg0[] {name = "post"} : memref<f32> 3538a918c54SAlex Zinenko return 3548a918c54SAlex Zinenko} 3558a918c54SAlex Zinenko 3568a918c54SAlex Zinenko// ----- 3578a918c54SAlex Zinenko 3588a918c54SAlex Zinenkofunc.func private @callee1(%arg0: memref<f32>) { 35932a4e3fcSOleksandr "Alex" Zinenko // IP: name = "callee1" 36032a4e3fcSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["post"]] 36132a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "callee1" 36232a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 3638a918c54SAlex Zinenko memref.load %arg0[] {name = "callee1"} : memref<f32> 3648a918c54SAlex Zinenko return 3658a918c54SAlex Zinenko} 3668a918c54SAlex Zinenko 3678a918c54SAlex Zinenkofunc.func private @callee2(%arg0: memref<f32>) { 36832a4e3fcSOleksandr "Alex" Zinenko // IP: name = "callee2" 36932a4e3fcSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["post"]] 37032a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "callee2" 37132a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 3728a918c54SAlex Zinenko memref.load %arg0[] {name = "callee2"} : memref<f32> 3738a918c54SAlex Zinenko return 3748a918c54SAlex Zinenko} 3758a918c54SAlex Zinenko 3768a918c54SAlex Zinenkofunc.func @conditonal_call(%arg0: memref<f32>, %cond: i1) { 37732a4e3fcSOleksandr "Alex" Zinenko // IP: name = "pre" 37832a4e3fcSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["callee1", "callee2"]] 37932a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "pre" 38032a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 38132a4e3fcSOleksandr "Alex" Zinenko // LC_AR: name = "pre" 38232a4e3fcSOleksandr "Alex" Zinenko // LC_AR-SAME: next_access = {{\[}}["call1", "call2"]] 3838a918c54SAlex Zinenko memref.load %arg0[] {name = "pre"} : memref<f32> 3848a918c54SAlex Zinenko scf.if %cond { 38532a4e3fcSOleksandr "Alex" Zinenko func.call @callee1(%arg0) {name = "call1"} : (memref<f32>) -> () 3868a918c54SAlex Zinenko } else { 38732a4e3fcSOleksandr "Alex" Zinenko func.call @callee2(%arg0) {name = "call2"} : (memref<f32>) -> () 3888a918c54SAlex Zinenko } 3898a918c54SAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 3908a918c54SAlex Zinenko return 3918a918c54SAlex Zinenko} 3925d8813deSAlex Zinenko 3935d8813deSAlex Zinenko// ----- 3945d8813deSAlex Zinenko 3955d8813deSAlex Zinenko 3965d8813deSAlex Zinenko// In this test, the "call" operation also accesses %arg0 itself before 3975d8813deSAlex Zinenko// transferring control flow to the callee. Therefore, the order of accesses is 3985d8813deSAlex Zinenko// "caller" -> "call" -> "callee" -> "post" 3995d8813deSAlex Zinenko 4005d8813deSAlex Zinenkofunc.func private @callee(%arg0: memref<f32>) { 40132a4e3fcSOleksandr "Alex" Zinenko // IP: name = "callee" 4024d9d105cSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["post"]] 40332a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "callee" 40432a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 4055d8813deSAlex Zinenko memref.load %arg0[] {name = "callee"} : memref<f32> 4065d8813deSAlex Zinenko return 4075d8813deSAlex Zinenko} 4085d8813deSAlex Zinenko 4095d8813deSAlex Zinenko// CHECK-LABEL: @call_and_store_before 4105d8813deSAlex Zinenkofunc.func @call_and_store_before(%arg0: memref<f32>) { 41132a4e3fcSOleksandr "Alex" Zinenko // IP: name = "caller" 4124d9d105cSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["call"]] 41332a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "caller" 41432a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 41532a4e3fcSOleksandr "Alex" Zinenko // LC_AR: name = "caller" 41632a4e3fcSOleksandr "Alex" Zinenko // LC_AR-SAME: next_access = {{\[}}["call"]] 4175d8813deSAlex Zinenko memref.load %arg0[] {name = "caller"} : memref<f32> 4185d8813deSAlex Zinenko // Note that the access after the entire call is "post". 4195d8813deSAlex Zinenko // CHECK: name = "call" 4204d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["post"], ["post"]] 4215d8813deSAlex Zinenko test.call_and_store @callee(%arg0), %arg0 {name = "call", store_before_call = true} : (memref<f32>, memref<f32>) -> () 4225d8813deSAlex Zinenko // CHECK: name = "post" 4234d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = ["unknown"] 4245d8813deSAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 4255d8813deSAlex Zinenko return 4265d8813deSAlex Zinenko} 4275d8813deSAlex Zinenko 4285d8813deSAlex Zinenko// ----- 4295d8813deSAlex Zinenko 4305d8813deSAlex Zinenko// In this test, the "call" operation also accesses %arg0 itself after getting 4315d8813deSAlex Zinenko// control flow back from the callee. Therefore, the order of accesses is 4325d8813deSAlex Zinenko// "caller" -> "callee" -> "call" -> "post" 4335d8813deSAlex Zinenko 4345d8813deSAlex Zinenkofunc.func private @callee(%arg0: memref<f32>) { 43532a4e3fcSOleksandr "Alex" Zinenko // IP: name = "callee" 4364d9d105cSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["call"]] 43732a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "callee" 43832a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 4395d8813deSAlex Zinenko memref.load %arg0[] {name = "callee"} : memref<f32> 4405d8813deSAlex Zinenko return 4415d8813deSAlex Zinenko} 4425d8813deSAlex Zinenko 4435d8813deSAlex Zinenko// CHECK-LABEL: @call_and_store_after 4445d8813deSAlex Zinenkofunc.func @call_and_store_after(%arg0: memref<f32>) { 44532a4e3fcSOleksandr "Alex" Zinenko // IP: name = "caller" 4464d9d105cSOleksandr "Alex" Zinenko // IP-SAME: next_access = {{\[}}["callee"]] 44732a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "caller" 44832a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 44932a4e3fcSOleksandr "Alex" Zinenko // LC_AR: name = "caller" 45032a4e3fcSOleksandr "Alex" Zinenko // LC_AR-SAME: next_access = {{\[}}["call"]] 4515d8813deSAlex Zinenko memref.load %arg0[] {name = "caller"} : memref<f32> 4525d8813deSAlex Zinenko // CHECK: name = "call" 4534d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["post"], ["post"]] 45432a4e3fcSOleksandr "Alex" Zinenko test.call_and_store @callee(%arg0), %arg0 {name = "call", store_before_call = false} : (memref<f32>, memref<f32>) -> () 4555d8813deSAlex Zinenko // CHECK: name = "post" 4564d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = ["unknown"] 4575d8813deSAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 4585d8813deSAlex Zinenko return 4595d8813deSAlex Zinenko} 4605d8813deSAlex Zinenko 4615d8813deSAlex Zinenko// ----- 4625d8813deSAlex Zinenko 4635d8813deSAlex Zinenko// In this test, the "region" operation also accesses %arg0 itself before 4645d8813deSAlex Zinenko// entering the region. Therefore: 4655d8813deSAlex Zinenko// - the next access of "pre" is the "region" operation itself; 4665d8813deSAlex Zinenko// - at the entry of the block, the next access is "post". 4675d8813deSAlex Zinenko// CHECK-LABEL: @store_with_a_region 4685d8813deSAlex Zinenkofunc.func @store_with_a_region_before(%arg0: memref<f32>) { 4695d8813deSAlex Zinenko // CHECK: name = "pre" 4704d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["region"]] 4715d8813deSAlex Zinenko memref.load %arg0[] {name = "pre"} : memref<f32> 4725d8813deSAlex Zinenko // CHECK: name = "region" 4734d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 4744d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_at_entry_point = {{\[}}{{\[}}["post"]]] 4755d8813deSAlex Zinenko test.store_with_a_region %arg0 attributes { name = "region", store_before_region = true } { 4765d8813deSAlex Zinenko test.store_with_a_region_terminator 4775d8813deSAlex Zinenko } : memref<f32> 4785d8813deSAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 4795d8813deSAlex Zinenko return 4805d8813deSAlex Zinenko} 4815d8813deSAlex Zinenko 4825d8813deSAlex Zinenko// In this test, the "region" operation also accesses %arg0 itself after 4835d8813deSAlex Zinenko// exiting from the region. Therefore: 4845d8813deSAlex Zinenko// - the next access of "pre" is the "region" operation itself; 4855d8813deSAlex Zinenko// - at the entry of the block, the next access is "region". 4865d8813deSAlex Zinenko// CHECK-LABEL: @store_with_a_region 4875d8813deSAlex Zinenkofunc.func @store_with_a_region_after(%arg0: memref<f32>) { 4885d8813deSAlex Zinenko // CHECK: name = "pre" 4894d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["region"]] 4905d8813deSAlex Zinenko memref.load %arg0[] {name = "pre"} : memref<f32> 4915d8813deSAlex Zinenko // CHECK: name = "region" 4924d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 4934d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_at_entry_point = {{\[}}{{\[}}["region"]]] 4945d8813deSAlex Zinenko test.store_with_a_region %arg0 attributes { name = "region", store_before_region = false } { 4955d8813deSAlex Zinenko test.store_with_a_region_terminator 4965d8813deSAlex Zinenko } : memref<f32> 4975d8813deSAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 4985d8813deSAlex Zinenko return 4995d8813deSAlex Zinenko} 5005d8813deSAlex Zinenko 5015d8813deSAlex Zinenko// In this test, the operation with a region stores to %arg0 before going to the 5025d8813deSAlex Zinenko// region. Therefore: 5035d8813deSAlex Zinenko// - the next access of "pre" is the "region" operation itself; 5045d8813deSAlex Zinenko// - the next access of the "region" operation (computed as the next access 5055d8813deSAlex Zinenko// *after* said operation) is the "post" operation; 5065d8813deSAlex Zinenko// - the next access of the "inner" operation is also "post"; 5075d8813deSAlex Zinenko// - the next access at the entry point of the region of the "region" operation 5085d8813deSAlex Zinenko// is the "inner" operation. 5095d8813deSAlex Zinenko// That is, the order of access is: "pre" -> "region" -> "inner" -> "post". 5105d8813deSAlex Zinenko// CHECK-LABEL: @store_with_a_region_before_containing_a_load 5115d8813deSAlex Zinenkofunc.func @store_with_a_region_before_containing_a_load(%arg0: memref<f32>) { 5125d8813deSAlex Zinenko // CHECK: name = "pre" 5134d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["region"]] 5145d8813deSAlex Zinenko memref.load %arg0[] {name = "pre"} : memref<f32> 5155d8813deSAlex Zinenko // CHECK: name = "region" 5164d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 5174d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_at_entry_point = {{\[}}{{\[}}["inner"]]] 5185d8813deSAlex Zinenko test.store_with_a_region %arg0 attributes { name = "region", store_before_region = true } { 5195d8813deSAlex Zinenko // CHECK: name = "inner" 5204d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 5215d8813deSAlex Zinenko memref.load %arg0[] {name = "inner"} : memref<f32> 5225d8813deSAlex Zinenko test.store_with_a_region_terminator 5235d8813deSAlex Zinenko } : memref<f32> 5245d8813deSAlex Zinenko // CHECK: name = "post" 5254d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = ["unknown"] 5265d8813deSAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 5275d8813deSAlex Zinenko return 5285d8813deSAlex Zinenko} 5295d8813deSAlex Zinenko 5305d8813deSAlex Zinenko// In this test, the operation with a region stores to %arg0 after exiting from 5315d8813deSAlex Zinenko// the region. Therefore: 5325d8813deSAlex Zinenko// - the next access of "pre" is "inner"; 5335d8813deSAlex Zinenko// - the next access of the "region" operation (computed as the next access 5345d8813deSAlex Zinenko// *after* said operation) is the "post" operation); 5355d8813deSAlex Zinenko// - the next access at the entry point of the region of the "region" operation 5365d8813deSAlex Zinenko// is the "inner" operation; 5375d8813deSAlex Zinenko// - the next access of the "inner" operation is the "region" operation itself. 5385d8813deSAlex Zinenko// That is, the order of access is "pre" -> "inner" -> "region" -> "post". 5395d8813deSAlex Zinenko// CHECK-LABEL: @store_with_a_region_after_containing_a_load 5405d8813deSAlex Zinenkofunc.func @store_with_a_region_after_containing_a_load(%arg0: memref<f32>) { 5415d8813deSAlex Zinenko // CHECK: name = "pre" 5424d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["inner"]] 5435d8813deSAlex Zinenko memref.load %arg0[] {name = "pre"} : memref<f32> 5445d8813deSAlex Zinenko // CHECK: name = "region" 5454d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["post"]] 5464d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_at_entry_point = {{\[}}{{\[}}["inner"]]] 5475d8813deSAlex Zinenko test.store_with_a_region %arg0 attributes { name = "region", store_before_region = false } { 5485d8813deSAlex Zinenko // CHECK: name = "inner" 5494d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = {{\[}}["region"]] 5505d8813deSAlex Zinenko memref.load %arg0[] {name = "inner"} : memref<f32> 5515d8813deSAlex Zinenko test.store_with_a_region_terminator 5525d8813deSAlex Zinenko } : memref<f32> 5535d8813deSAlex Zinenko // CHECK: name = "post" 5544d9d105cSOleksandr "Alex" Zinenko // CHECK-SAME: next_access = ["unknown"] 5555d8813deSAlex Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 5565d8813deSAlex Zinenko return 5575d8813deSAlex Zinenko} 55832a4e3fcSOleksandr "Alex" Zinenko 55932a4e3fcSOleksandr "Alex" Zinenko// ----- 56032a4e3fcSOleksandr "Alex" Zinenko 56132a4e3fcSOleksandr "Alex" Zinenkofunc.func private @opaque_callee(%arg0: memref<f32>) 56232a4e3fcSOleksandr "Alex" Zinenko 56332a4e3fcSOleksandr "Alex" Zinenko// CHECK-LABEL: @call_opaque_callee 56432a4e3fcSOleksandr "Alex" Zinenkofunc.func @call_opaque_callee(%arg0: memref<f32>) { 56532a4e3fcSOleksandr "Alex" Zinenko // IP: name = "pre" 56632a4e3fcSOleksandr "Alex" Zinenko // IP-SAME: next_access = ["unknown"] 56732a4e3fcSOleksandr "Alex" Zinenko // IP_AR: name = "pre" 56832a4e3fcSOleksandr "Alex" Zinenko // IP_AR-SAME: next_access = {{\[}}["call"]] 56932a4e3fcSOleksandr "Alex" Zinenko // LOCAL: name = "pre" 57032a4e3fcSOleksandr "Alex" Zinenko // LOCAL-SAME: next_access = ["unknown"] 57132a4e3fcSOleksandr "Alex" Zinenko // LC_AR: name = "pre" 57232a4e3fcSOleksandr "Alex" Zinenko // LC_AR-SAME: next_access = {{\[}}["call"]] 57332a4e3fcSOleksandr "Alex" Zinenko memref.load %arg0[] {name = "pre"} : memref<f32> 57432a4e3fcSOleksandr "Alex" Zinenko func.call @opaque_callee(%arg0) {name = "call"} : (memref<f32>) -> () 57532a4e3fcSOleksandr "Alex" Zinenko memref.load %arg0[] {name = "post"} : memref<f32> 57632a4e3fcSOleksandr "Alex" Zinenko return 57732a4e3fcSOleksandr "Alex" Zinenko} 5782bd66425Sdrblallo 5792bd66425Sdrblallo// ----- 5802bd66425Sdrblallo 5812bd66425Sdrblallo// CHECK-LABEL: @indirect_call 5822bd66425Sdrblallofunc.func @indirect_call(%arg0: memref<f32>, %arg1: (memref<f32>) -> ()) { 5832bd66425Sdrblallo // IP: name = "pre" 5842bd66425Sdrblallo // IP-SAME: next_access = ["unknown"] 5852bd66425Sdrblallo // IP_AR: name = "pre" 5862bd66425Sdrblallo // IP_AR-SAME: next_access = ["unknown"] 5872bd66425Sdrblallo // LOCAL: name = "pre" 5882bd66425Sdrblallo // LOCAL-SAME: next_access = ["unknown"] 5892bd66425Sdrblallo // LC_AR: name = "pre" 5902bd66425Sdrblallo // LC_AR-SAME: next_access = {{\[}}["call"]] 5912bd66425Sdrblallo memref.load %arg0[] {name = "pre"} : memref<f32> 5922bd66425Sdrblallo func.call_indirect %arg1(%arg0) {name = "call"} : (memref<f32>) -> () 5932bd66425Sdrblallo memref.load %arg0[] {name = "post"} : memref<f32> 5942bd66425Sdrblallo return 5952bd66425Sdrblallo} 596