1// RUN: mlir-opt --test-print-callgraph --split-input-file %s 2>&1 | FileCheck %s 2 3// CHECK: Testing : "Normal function call" 4module attributes {"test.name" = "Normal function call"} { 5 // CHECK-LABEL: ---- CallGraph ---- 6 // CHECK: - Node : 'llvm.func' {{.*}} sym_name = "foo" 7 // CHECK-NEXT: -- Call-Edge : 'llvm.func' {{.*}} sym_name = "bar" 8 9 // CHECK: - Node : 'llvm.func' {{.*}} sym_name = "bar" 10 // CHECK-NEXT: -- Call-Edge : 'llvm.func' {{.*}} sym_name = "foo" 11 12 // CHECK: - Node : 'llvm.func' {{.*}} sym_name = "entry" 13 // CHECK-DAG: -- Call-Edge : 'llvm.func' {{.*}} sym_name = "foo" 14 // CHECK-DAG: -- Call-Edge : 'llvm.func' {{.*}} sym_name = "bar" 15 16 // CHECK-LABEL: -- SCCs -- 17 // CHECK: - SCC : 18 // CHECK-DAG: -- Node :'llvm.func' {{.*}} sym_name = "foo" 19 // CHECK-DAG: -- Node :'llvm.func' {{.*}} sym_name = "bar" 20 21 // CHECK: - SCC : 22 // CHECK-DAG: -- Node :'llvm.func' {{.*}} sym_name = "entry" 23 24 llvm.func @foo(%arg0: i32) -> i32 { 25 %0 = llvm.mlir.constant(2 : i32) : i32 26 %1 = llvm.sub %arg0, %0 : i32 27 %2 = llvm.call @bar(%arg0, %1) : (i32, i32) -> i32 28 llvm.return %2 : i32 29 } 30 llvm.func @bar(%arg0: i32, %arg1: i32) -> i32 { 31 %0 = llvm.add %arg0, %arg1 : i32 32 %1 = llvm.call @foo(%0) : (i32) -> i32 33 llvm.return %1 : i32 34 } 35 llvm.func @entry(%arg0: i32) -> i32 { 36 %0 = llvm.mlir.constant(2 : i32) : i32 37 %1 = llvm.mlir.constant(0 : i32) : i32 38 %2 = llvm.icmp "sgt" %arg0, %1 : i32 39 llvm.cond_br %2, ^bb1, ^bb2 40 ^bb1: // pred: ^bb0 41 %3 = llvm.call @foo(%arg0) : (i32) -> i32 42 llvm.br ^bb3(%3 : i32) 43 ^bb2: // pred: ^bb0 44 %4 = llvm.add %arg0, %0 : i32 45 %5 = llvm.call @bar(%arg0, %4) : (i32, i32) -> i32 46 llvm.br ^bb3(%5 : i32) 47 ^bb3(%6: i32): // 2 preds: ^bb1, ^bb2 48 llvm.return %6 : i32 49 } 50} 51 52// ----- 53 54// CHECK: Testing : "Invoke call" 55module attributes {"test.name" = "Invoke call"} { 56 // CHECK-LABEL: ---- CallGraph ---- 57 // CHECK: - Node : 'llvm.func' {{.*}} sym_name = "invokeLandingpad" 58 // CHECK-DAG: -- Call-Edge : <Unknown-Callee-Node> 59 60 // CHECK: -- SCCs -- 61 llvm.mlir.global external constant @_ZTIi() : !llvm.ptr 62 llvm.func @foo(%arg0: i32) -> !llvm.struct<(i32, f64, i32)> 63 llvm.func @bar(!llvm.ptr, !llvm.ptr, !llvm.ptr) 64 llvm.func @__gxx_personality_v0(...) -> i32 65 66 llvm.func @invokeLandingpad() -> i32 attributes { personality = @__gxx_personality_v0 } { 67 %0 = llvm.mlir.constant(0 : i32) : i32 68 %1 = llvm.mlir.constant(3 : i32) : i32 69 %2 = llvm.mlir.constant("\01") : !llvm.array<1 x i8> 70 %3 = llvm.mlir.zero : !llvm.ptr 71 %4 = llvm.mlir.zero : !llvm.ptr 72 %5 = llvm.mlir.addressof @_ZTIi : !llvm.ptr 73 %6 = llvm.mlir.constant(1 : i32) : i32 74 %7 = llvm.alloca %6 x i8 : (i32) -> !llvm.ptr 75 %8 = llvm.invoke @foo(%6) to ^bb2 unwind ^bb1 : (i32) -> !llvm.struct<(i32, f64, i32)> 76 77 ^bb1: 78 %10 = llvm.landingpad cleanup (catch %3 : !llvm.ptr) (catch %5 : !llvm.ptr) (filter %2 : !llvm.array<1 x i8>) : !llvm.struct<(ptr, i32)> 79 %11 = llvm.intr.eh.typeid.for %5 : (!llvm.ptr) -> i32 80 llvm.resume %10 : !llvm.struct<(ptr, i32)> 81 82 ^bb2: 83 llvm.return %6 : i32 84 85 ^bb3: 86 llvm.invoke @bar(%7, %5, %4) to ^bb2 unwind ^bb1 : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> () 87 88 ^bb4: 89 llvm.return %0 : i32 90 } 91} 92