1 ; Test handling of call instructions. 2 3 ; RUN: %p2i -i %s --insts --args -allow-externally-defined-symbols \ 4 ; RUN: | FileCheck %s 5 ; RUN: %p2i -i %s --args -notranslate -timing \ 6 ; RUN: -allow-externally-defined-symbols | \ 7 ; RUN: FileCheck --check-prefix=NOIR %s 8 9 define internal i32 @fib(i32 %n) { 10 entry: 11 %cmp = icmp slt i32 %n, 2 12 br i1 %cmp, label %return, label %if.end 13 14 if.end: ; preds = %entry 15 %sub = add i32 %n, -1 16 %call = tail call i32 @fib(i32 %sub) 17 %sub1 = add i32 %n, -2 18 %call2 = tail call i32 @fib(i32 %sub1) 19 %add = add i32 %call2, %call 20 ret i32 %add 21 22 return: ; preds = %entry 23 ret i32 %n 24 } 25 26 ; CHECK: define internal i32 @fib(i32 %n) { 27 ; CHECK-NEXT: entry: 28 ; CHECK-NEXT: %cmp = icmp slt i32 %n, 2 29 ; CHECK-NEXT: br i1 %cmp, label %return, label %if.end 30 ; CHECK-NEXT: if.end: 31 ; CHECK-NEXT: %sub = add i32 %n, -1 32 ; CHECK-NEXT: %call = call i32 @fib(i32 %sub) 33 ; CHECK-NEXT: %sub1 = add i32 %n, -2 34 ; CHECK-NEXT: %call2 = call i32 @fib(i32 %sub1) 35 ; CHECK-NEXT: %add = add i32 %call2, %call 36 ; CHECK-NEXT: ret i32 %add 37 ; CHECK-NEXT: return: 38 ; CHECK-NEXT: ret i32 %n 39 ; CHECK-NEXT: } 40 41 define internal i32 @fact(i32 %n) { 42 entry: 43 %cmp = icmp slt i32 %n, 2 44 br i1 %cmp, label %return, label %if.end 45 46 if.end: ; preds = %entry 47 %sub = add i32 %n, -1 48 %call = tail call i32 @fact(i32 %sub) 49 %mul = mul i32 %call, %n 50 ret i32 %mul 51 52 return: ; preds = %entry 53 ret i32 %n 54 } 55 56 ; CHECK-NEXT: define internal i32 @fact(i32 %n) { 57 ; CHECK-NEXT: entry: 58 ; CHECK-NEXT: %cmp = icmp slt i32 %n, 2 59 ; CHECK-NEXT: br i1 %cmp, label %return, label %if.end 60 ; CHECK-NEXT: if.end: 61 ; CHECK-NEXT: %sub = add i32 %n, -1 62 ; CHECK-NEXT: %call = call i32 @fact(i32 %sub) 63 ; CHECK-NEXT: %mul = mul i32 %call, %n 64 ; CHECK-NEXT: ret i32 %mul 65 ; CHECK-NEXT: return: 66 ; CHECK-NEXT: ret i32 %n 67 ; CHECK-NEXT: } 68 69 define internal i32 @redirect(i32 %n) { 70 entry: 71 %call = tail call i32 @redirect_target(i32 %n) 72 ret i32 %call 73 } 74 75 ; CHECK-NEXT: define internal i32 @redirect(i32 %n) { 76 ; CHECK-NEXT: entry: 77 ; CHECK-NEXT: %call = call i32 @redirect_target(i32 %n) 78 ; CHECK-NEXT: ret i32 %call 79 ; CHECK-NEXT: } 80 81 declare i32 @redirect_target(i32) 82 83 define internal void @call_void(i32 %n) { 84 entry: 85 %cmp2 = icmp sgt i32 %n, 0 86 br i1 %cmp2, label %if.then, label %if.end 87 88 if.then: ; preds = %entry, %if.then 89 %n.tr3 = phi i32 [ %call.i, %if.then ], [ %n, %entry ] 90 %sub = add i32 %n.tr3, -1 91 %call.i = tail call i32 @redirect_target(i32 %sub) 92 %cmp = icmp sgt i32 %call.i, 0 93 br i1 %cmp, label %if.then, label %if.end 94 95 if.end: ; preds = %if.then, %entry 96 ret void 97 } 98 99 ; CHECK-NEXT: define internal void @call_void(i32 %n) { 100 ; CHECK-NEXT: entry: 101 ; CHECK-NEXT: %cmp2 = icmp sgt i32 %n, 0 102 ; CHECK-NEXT: br i1 %cmp2, label %if.then, label %if.end 103 ; CHECK-NEXT: if.then: 104 ; CHECK-NEXT: %n.tr3 = phi i32 [ %call.i, %if.then ], [ %n, %entry ] 105 ; CHECK-NEXT: %sub = add i32 %n.tr3, -1 106 ; CHECK-NEXT: %call.i = call i32 @redirect_target(i32 %sub) 107 ; CHECK-NEXT: %cmp = icmp sgt i32 %call.i, 0 108 ; CHECK-NEXT: br i1 %cmp, label %if.then, label %if.end 109 ; CHECK-NEXT: if.end: 110 ; CHECK-NEXT: ret void 111 ; CHECK-NEXT: } 112 113 ; NOIR: Total across all functions 114