OLD | NEW |
---|---|
(Empty) | |
1 ; This tests the optimization where producers and consumers of i1 (bool) | |
2 ; variables are combined to implicitly use flags instead of explicitly using | |
3 ; stack or register variables. | |
4 | |
5 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 | FileCheck %s | |
6 | |
7 declare void @use_value(i32) | |
8 | |
9 ; Basic cmp/branch folding. | |
10 define i32 @fold_cmp_br(i32 %arg1, i32 %arg2) { | |
11 entry: | |
12 %cmp1 = icmp slt i32 %arg1, %arg2 | |
13 br i1 %cmp1, label %branch1, label %branch2 | |
14 branch1: | |
15 ret i32 1 | |
16 branch2: | |
17 ret i32 2 | |
18 } | |
19 | |
20 ; CHECK-LABEL: fold_cmp_br | |
21 ; CHECK: cmp | |
22 ; CHECK: jge | |
23 | |
24 | |
25 ; Cmp/branch folding with intervening instructions. | |
26 define i32 @fold_cmp_br_intervening_insts(i32 %arg1, i32 %arg2) { | |
27 entry: | |
28 %cmp1 = icmp slt i32 %arg1, %arg2 | |
29 call void @use_value(i32 %arg1) | |
30 br i1 %cmp1, label %branch1, label %branch2 | |
31 branch1: | |
32 ret i32 1 | |
33 branch2: | |
34 ret i32 2 | |
35 } | |
36 | |
37 ; CHECK-LABEL: fold_cmp_br_intervening_insts | |
38 ; CHECK: call | |
39 ; CHECK: cmp | |
40 ; CHECK: jge | |
41 | |
42 | |
43 ; Cmp/branch non-folding because of live-out. | |
44 define i32 @no_fold_cmp_br_liveout(i32 %arg1, i32 %arg2) { | |
45 entry: | |
46 %cmp1 = icmp slt i32 %arg1, %arg2 | |
47 br label %next | |
48 next: | |
49 br i1 %cmp1, label %branch1, label %branch2 | |
50 branch1: | |
51 ret i32 1 | |
52 branch2: | |
53 ret i32 2 | |
54 } | |
55 | |
56 ; CHECK-LABEL: no_fold_cmp_br_liveout | |
57 ; CHECK: cmp | |
58 ; CHECK: set | |
59 ; CHECK: cmp | |
60 ; CHECK: je | |
61 | |
62 | |
63 ; Cmp/branch non-folding because of extra non-whitelisted uses. | |
64 define i32 @no_fold_cmp_br_non_whitelist(i32 %arg1, i32 %arg2) { | |
65 entry: | |
66 %cmp1 = icmp slt i32 %arg1, %arg2 | |
67 %result = zext i1 %cmp1 to i32 | |
68 br i1 %cmp1, label %branch1, label %branch2 | |
69 branch1: | |
70 ret i32 %result | |
71 branch2: | |
72 ret i32 2 | |
73 } | |
74 | |
75 ; CHECK-LABEL: no_fold_cmp_br_non_whitelist | |
76 ; CHECK: cmp | |
77 ; CHECK: set | |
78 ; CHECK: movzx | |
79 ; CHECK: cmp | |
80 ; CHECK: je | |
81 | |
82 | |
83 ; Basic cmp/select folding. | |
84 define i32 @fold_cmp_select(i32 %arg1, i32 %arg2) { | |
85 entry: | |
86 %cmp1 = icmp slt i32 %arg1, %arg2 | |
87 %result = select i1 %cmp1, i32 %arg1, i32 %arg2 | |
88 ret i32 %result | |
89 } | |
90 | |
91 ; CHECK-LABEL: fold_cmp_select | |
92 ; CHECK: cmp | |
93 ; CHECK: jl | |
94 ; CHECK: mov | |
95 | |
96 | |
97 ; 64-bit cmp/select folding. | |
98 define i64 @fold_cmp_select_64(i64 %arg1, i64 %arg2) { | |
99 entry: | |
100 %arg1_trunc = trunc i64 %arg1 to i32 | |
101 %arg2_trunc = trunc i64 %arg2 to i32 | |
102 %cmp1 = icmp slt i32 %arg1_trunc, %arg2_trunc | |
103 %result = select i1 %cmp1, i64 %arg1, i64 %arg2 | |
104 ret i64 %result | |
105 } | |
106 | |
107 ; CHECK-LABEL: fold_cmp_select_64 | |
108 ; CHECK: cmp | |
109 ; CHECK: jl | |
110 ; CHECK: mov | |
111 ; CHECK: mov | |
112 | |
113 | |
114 ; Cmp/select folding with intervening instructions. | |
115 define i32 @fold_cmp_select_intervening_insts(i32 %arg1, i32 %arg2) { | |
116 entry: | |
117 %cmp1 = icmp slt i32 %arg1, %arg2 | |
118 call void @use_value(i32 %arg1) | |
119 %result = select i1 %cmp1, i32 %arg1, i32 %arg2 | |
120 ret i32 %result | |
121 } | |
122 | |
123 ; CHECK-LABEL: fold_cmp_select_intervening_insts | |
124 ; CHECK: call | |
jvoung (off chromium)
2015/05/15 21:48:20
Maybe show the ; CHECK-NOT: cmp
before the call,
Jim Stichnoth
2015/05/16 17:32:51
Done. (in both "intervening" tests)
| |
125 ; CHECK: cmp | |
126 ; CHECK: jl | |
127 ; CHECK: mov | |
128 | |
129 | |
130 ; Cmp/multi-select folding. | |
131 define i32 @fold_cmp_select_multi(i32 %arg1, i32 %arg2) { | |
132 entry: | |
133 %cmp1 = icmp slt i32 %arg1, %arg2 | |
134 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 | |
135 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 | |
136 %c = select i1 %cmp1, i32 123, i32 %arg1 | |
137 %partial = add i32 %a, %b | |
138 %result = add i32 %partial, %c | |
139 ret i32 %result | |
140 } | |
141 | |
142 ; CHECK-LABEL: fold_cmp_select_multi | |
143 ; CHECK: cmp | |
144 ; CHECK: jl | |
145 ; CHECK: cmp | |
146 ; CHECK: jl | |
147 ; CHECK: cmp | |
148 ; CHECK: jl | |
149 ; CHECK: add | |
150 ; CHECK: add | |
151 | |
152 | |
153 ; Cmp/multi-select non-folding because of live-out. | |
154 define i32 @no_fold_cmp_select_multi_liveout(i32 %arg1, i32 %arg2) { | |
155 entry: | |
156 %cmp1 = icmp slt i32 %arg1, %arg2 | |
157 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 | |
158 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 | |
159 br label %next | |
160 next: | |
161 %c = select i1 %cmp1, i32 123, i32 %arg1 | |
162 %partial = add i32 %a, %b | |
163 %result = add i32 %partial, %c | |
164 ret i32 %result | |
165 } | |
166 | |
167 ; CHECK-LABEL: no_fold_cmp_select_multi_liveout | |
168 ; CHECK: set | |
169 ; CHECK: cmp | |
170 ; CHECK: jne | |
171 ; CHECK: cmp | |
172 ; CHECK: jne | |
173 ; CHECK: cmp | |
174 ; CHECK: jne | |
175 ; CHECK: add | |
176 ; CHECK: add | |
177 | |
178 | |
179 ; Cmp/multi-select non-folding because of extra non-whitelisted uses. | |
180 define i32 @no_fold_cmp_select_multi_non_whitelist(i32 %arg1, i32 %arg2) { | |
181 entry: | |
182 %cmp1 = icmp slt i32 %arg1, %arg2 | |
183 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 | |
184 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 | |
185 %c = select i1 %cmp1, i32 123, i32 %arg1 | |
186 %ext = zext i1 %cmp1 to i32 | |
187 %partial1 = add i32 %a, %b | |
188 %partial2 = add i32 %partial1, %c | |
189 %result = add i32 %partial2, %ext | |
190 ret i32 %result | |
191 } | |
192 | |
193 ; CHECK-LABEL: no_fold_cmp_select_multi_non_whitelist | |
194 ; CHECK: set | |
195 ; CHECK: cmp | |
196 ; CHECK: jne | |
197 ; CHECK: cmp | |
198 ; CHECK: jne | |
199 ; CHECK: cmp | |
200 ; CHECK: jne | |
201 ; CHECK: movzx | |
202 ; CHECK: add | |
203 ; CHECK: add | |
204 ; CHECK: add | |
OLD | NEW |