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