OLD | NEW |
1 ; This tests the optimization where producers and consumers of i1 (bool) | 1 ; This tests the optimization where producers and consumers of i1 (bool) |
2 ; variables are combined to implicitly use flags instead of explicitly using | 2 ; variables are combined to implicitly use flags instead of explicitly using |
3 ; stack or register variables. | 3 ; stack or register variables. |
4 | 4 |
5 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 | FileCheck %s | 5 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 | FileCheck %s |
6 | 6 |
7 declare void @use_value(i32) | 7 declare void @use_value(i32) |
8 | 8 |
9 ; Basic cmp/branch folding. | 9 ; Basic cmp/branch folding. |
10 define i32 @fold_cmp_br(i32 %arg1, i32 %arg2) { | 10 define i32 @fold_cmp_br(i32 %arg1, i32 %arg2) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 ; Basic cmp/select folding. | 84 ; Basic cmp/select folding. |
85 define i32 @fold_cmp_select(i32 %arg1, i32 %arg2) { | 85 define i32 @fold_cmp_select(i32 %arg1, i32 %arg2) { |
86 entry: | 86 entry: |
87 %cmp1 = icmp slt i32 %arg1, %arg2 | 87 %cmp1 = icmp slt i32 %arg1, %arg2 |
88 %result = select i1 %cmp1, i32 %arg1, i32 %arg2 | 88 %result = select i1 %cmp1, i32 %arg1, i32 %arg2 |
89 ret i32 %result | 89 ret i32 %result |
90 } | 90 } |
91 | 91 |
92 ; CHECK-LABEL: fold_cmp_select | 92 ; CHECK-LABEL: fold_cmp_select |
93 ; CHECK: cmp | 93 ; CHECK: cmp |
94 ; CHECK: jl | 94 ; CHECK: cmovl |
95 ; CHECK: mov | |
96 | 95 |
97 | 96 |
98 ; 64-bit cmp/select folding. | 97 ; 64-bit cmp/select folding. |
99 define i64 @fold_cmp_select_64(i64 %arg1, i64 %arg2) { | 98 define i64 @fold_cmp_select_64(i64 %arg1, i64 %arg2) { |
100 entry: | 99 entry: |
101 %arg1_trunc = trunc i64 %arg1 to i32 | 100 %arg1_trunc = trunc i64 %arg1 to i32 |
102 %arg2_trunc = trunc i64 %arg2 to i32 | 101 %arg2_trunc = trunc i64 %arg2 to i32 |
103 %cmp1 = icmp slt i32 %arg1_trunc, %arg2_trunc | 102 %cmp1 = icmp slt i32 %arg1_trunc, %arg2_trunc |
104 %result = select i1 %cmp1, i64 %arg1, i64 %arg2 | 103 %result = select i1 %cmp1, i64 %arg1, i64 %arg2 |
105 ret i64 %result | 104 ret i64 %result |
106 } | 105 } |
107 | 106 |
108 ; CHECK-LABEL: fold_cmp_select_64 | 107 ; CHECK-LABEL: fold_cmp_select_64 |
109 ; CHECK: cmp | 108 ; CHECK: cmp |
110 ; CHECK: jl | 109 ; CHECK: cmovl |
111 ; CHECK: mov | 110 ; CHECK: cmovl |
112 ; CHECK: mov | |
113 | 111 |
114 | 112 |
115 ; Cmp/select folding with intervening instructions. | 113 ; Cmp/select folding with intervening instructions. |
116 define i32 @fold_cmp_select_intervening_insts(i32 %arg1, i32 %arg2) { | 114 define i32 @fold_cmp_select_intervening_insts(i32 %arg1, i32 %arg2) { |
117 entry: | 115 entry: |
118 %cmp1 = icmp slt i32 %arg1, %arg2 | 116 %cmp1 = icmp slt i32 %arg1, %arg2 |
119 call void @use_value(i32 %arg1) | 117 call void @use_value(i32 %arg1) |
120 %result = select i1 %cmp1, i32 %arg1, i32 %arg2 | 118 %result = select i1 %cmp1, i32 %arg1, i32 %arg2 |
121 ret i32 %result | 119 ret i32 %result |
122 } | 120 } |
123 | 121 |
124 ; CHECK-LABEL: fold_cmp_select_intervening_insts | 122 ; CHECK-LABEL: fold_cmp_select_intervening_insts |
125 ; CHECK-NOT: cmp | 123 ; CHECK-NOT: cmp |
126 ; CHECK: call | 124 ; CHECK: call |
127 ; CHECK: cmp | 125 ; CHECK: cmp |
128 ; CHECK: jl | 126 ; CHECK: cmovl |
129 ; CHECK: mov | |
130 | 127 |
131 | 128 |
132 ; Cmp/multi-select folding. | 129 ; Cmp/multi-select folding. |
133 define i32 @fold_cmp_select_multi(i32 %arg1, i32 %arg2) { | 130 define i32 @fold_cmp_select_multi(i32 %arg1, i32 %arg2) { |
134 entry: | 131 entry: |
135 %cmp1 = icmp slt i32 %arg1, %arg2 | 132 %cmp1 = icmp slt i32 %arg1, %arg2 |
136 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 | 133 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 |
137 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 | 134 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 |
138 %c = select i1 %cmp1, i32 123, i32 %arg1 | 135 %c = select i1 %cmp1, i32 123, i32 %arg1 |
139 %partial = add i32 %a, %b | 136 %partial = add i32 %a, %b |
140 %result = add i32 %partial, %c | 137 %result = add i32 %partial, %c |
141 ret i32 %result | 138 ret i32 %result |
142 } | 139 } |
143 | 140 |
144 ; CHECK-LABEL: fold_cmp_select_multi | 141 ; CHECK-LABEL: fold_cmp_select_multi |
145 ; CHECK: cmp | 142 ; CHECK: cmp |
146 ; CHECK: jl | 143 ; CHECK: cmovl |
147 ; CHECK: cmp | 144 ; CHECK: cmp |
148 ; CHECK: jl | 145 ; CHECK: cmovl |
149 ; CHECK: cmp | 146 ; CHECK: cmp |
150 ; CHECK: jl | 147 ; CHECK: cmovge |
151 ; CHECK: add | 148 ; CHECK: add |
152 ; CHECK: add | 149 ; CHECK: add |
153 | 150 |
154 | 151 |
155 ; Cmp/multi-select non-folding because of live-out. | 152 ; Cmp/multi-select non-folding because of live-out. |
156 define i32 @no_fold_cmp_select_multi_liveout(i32 %arg1, i32 %arg2) { | 153 define i32 @no_fold_cmp_select_multi_liveout(i32 %arg1, i32 %arg2) { |
157 entry: | 154 entry: |
158 %cmp1 = icmp slt i32 %arg1, %arg2 | 155 %cmp1 = icmp slt i32 %arg1, %arg2 |
159 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 | 156 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 |
160 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 | 157 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 |
161 br label %next | 158 br label %next |
162 next: | 159 next: |
163 %c = select i1 %cmp1, i32 123, i32 %arg1 | 160 %c = select i1 %cmp1, i32 123, i32 %arg1 |
164 %partial = add i32 %a, %b | 161 %partial = add i32 %a, %b |
165 %result = add i32 %partial, %c | 162 %result = add i32 %partial, %c |
166 ret i32 %result | 163 ret i32 %result |
167 } | 164 } |
168 | 165 |
169 ; CHECK-LABEL: no_fold_cmp_select_multi_liveout | 166 ; CHECK-LABEL: no_fold_cmp_select_multi_liveout |
170 ; CHECK: set | 167 ; CHECK: set |
171 ; CHECK: cmp | 168 ; CHECK: cmp |
172 ; CHECK: jne | 169 ; CHECK: cmovne |
173 ; CHECK: cmp | 170 ; CHECK: cmp |
174 ; CHECK: jne | 171 ; CHECK: cmovne |
175 ; CHECK: cmp | 172 ; CHECK: cmp |
176 ; CHECK: jne | 173 ; CHECK: cmove |
177 ; CHECK: add | 174 ; CHECK: add |
178 ; CHECK: add | 175 ; CHECK: add |
179 | 176 |
180 | 177 |
181 ; Cmp/multi-select non-folding because of extra non-whitelisted uses. | 178 ; Cmp/multi-select non-folding because of extra non-whitelisted uses. |
182 define i32 @no_fold_cmp_select_multi_non_whitelist(i32 %arg1, i32 %arg2) { | 179 define i32 @no_fold_cmp_select_multi_non_whitelist(i32 %arg1, i32 %arg2) { |
183 entry: | 180 entry: |
184 %cmp1 = icmp slt i32 %arg1, %arg2 | 181 %cmp1 = icmp slt i32 %arg1, %arg2 |
185 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 | 182 %a = select i1 %cmp1, i32 %arg1, i32 %arg2 |
186 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 | 183 %b = select i1 %cmp1, i32 %arg2, i32 %arg1 |
187 %c = select i1 %cmp1, i32 123, i32 %arg1 | 184 %c = select i1 %cmp1, i32 123, i32 %arg1 |
188 %ext = zext i1 %cmp1 to i32 | 185 %ext = zext i1 %cmp1 to i32 |
189 %partial1 = add i32 %a, %b | 186 %partial1 = add i32 %a, %b |
190 %partial2 = add i32 %partial1, %c | 187 %partial2 = add i32 %partial1, %c |
191 %result = add i32 %partial2, %ext | 188 %result = add i32 %partial2, %ext |
192 ret i32 %result | 189 ret i32 %result |
193 } | 190 } |
194 | 191 |
195 ; CHECK-LABEL: no_fold_cmp_select_multi_non_whitelist | 192 ; CHECK-LABEL: no_fold_cmp_select_multi_non_whitelist |
196 ; CHECK: set | 193 ; CHECK: set |
197 ; CHECK: cmp | 194 ; CHECK: cmp |
198 ; CHECK: jne | 195 ; CHECK: cmovne |
199 ; CHECK: cmp | 196 ; CHECK: cmp |
200 ; CHECK: jne | 197 ; CHECK: cmovne |
201 ; CHECK: cmp | 198 ; CHECK: cmp |
202 ; CHECK: jne | 199 ; CHECK: cmove |
203 ; CHECK: movzx | 200 ; CHECK: movzx |
204 ; CHECK: add | 201 ; CHECK: add |
205 ; CHECK: add | 202 ; CHECK: add |
206 ; CHECK: add | 203 ; CHECK: add |
OLD | NEW |