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 9define internal i32 @fib(i32 %n) { 10entry: 11 %cmp = icmp slt i32 %n, 2 12 br i1 %cmp, label %return, label %if.end 13 14if.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 22return: ; 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 41define internal i32 @fact(i32 %n) { 42entry: 43 %cmp = icmp slt i32 %n, 2 44 br i1 %cmp, label %return, label %if.end 45 46if.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 52return: ; 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 69define internal i32 @redirect(i32 %n) { 70entry: 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 81declare i32 @redirect_target(i32) 82 83define internal void @call_void(i32 %n) { 84entry: 85 %cmp2 = icmp sgt i32 %n, 0 86 br i1 %cmp2, label %if.then, label %if.end 87 88if.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 95if.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