1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=-cmov | FileCheck %s --check-prefixes=ALL,I386,I386-NOCMOV
3 ; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefixes=ALL,I386,I386-CMOV
4 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=-cmov | FileCheck %s --check-prefixes=ALL,I686,I686-NOCMOV
5 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefixes=ALL,I686,I686-CMOV
6 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=-cmov | FileCheck %s --check-prefixes=ALL,X86_64,X86_64-NOCMOV
7 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefixes=ALL,X86_64,X86_64-CMOV
9 ; Values don't come from regs. All good.
11 define i8 @t0(i32 %a1_wide_orig, i32 %a2_wide_orig, i32 %inc) nounwind {
12 ; I386-NOCMOV-LABEL: t0:
13 ; I386-NOCMOV: # %bb.0:
14 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
15 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
16 ; I386-NOCMOV-NEXT: addl %ecx, %eax
17 ; I386-NOCMOV-NEXT: addl {{[0-9]+}}(%esp), %ecx
18 ; I386-NOCMOV-NEXT: cmpb %cl, %al
19 ; I386-NOCMOV-NEXT: jge .LBB0_2
20 ; I386-NOCMOV-NEXT: # %bb.1:
21 ; I386-NOCMOV-NEXT: movl %ecx, %eax
22 ; I386-NOCMOV-NEXT: .LBB0_2:
23 ; I386-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
24 ; I386-NOCMOV-NEXT: retl
26 ; I386-CMOV-LABEL: t0:
28 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
29 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
30 ; I386-CMOV-NEXT: addl %eax, %ecx
31 ; I386-CMOV-NEXT: addl {{[0-9]+}}(%esp), %eax
32 ; I386-CMOV-NEXT: cmpb %al, %cl
33 ; I386-CMOV-NEXT: cmovgel %ecx, %eax
34 ; I386-CMOV-NEXT: # kill: def $al killed $al killed $eax
35 ; I386-CMOV-NEXT: retl
37 ; I686-NOCMOV-LABEL: t0:
38 ; I686-NOCMOV: # %bb.0:
39 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
40 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
41 ; I686-NOCMOV-NEXT: addl %ecx, %eax
42 ; I686-NOCMOV-NEXT: addl {{[0-9]+}}(%esp), %ecx
43 ; I686-NOCMOV-NEXT: cmpb %cl, %al
44 ; I686-NOCMOV-NEXT: jge .LBB0_2
45 ; I686-NOCMOV-NEXT: # %bb.1:
46 ; I686-NOCMOV-NEXT: movl %ecx, %eax
47 ; I686-NOCMOV-NEXT: .LBB0_2:
48 ; I686-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
49 ; I686-NOCMOV-NEXT: retl
51 ; I686-CMOV-LABEL: t0:
53 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
54 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
55 ; I686-CMOV-NEXT: addl %eax, %ecx
56 ; I686-CMOV-NEXT: addl {{[0-9]+}}(%esp), %eax
57 ; I686-CMOV-NEXT: cmpb %al, %cl
58 ; I686-CMOV-NEXT: cmovgel %ecx, %eax
59 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
60 ; I686-CMOV-NEXT: retl
64 ; X86_64-NEXT: movl %esi, %eax
65 ; X86_64-NEXT: addl %edx, %edi
66 ; X86_64-NEXT: addl %edx, %eax
67 ; X86_64-NEXT: cmpb %al, %dil
68 ; X86_64-NEXT: cmovgel %edi, %eax
69 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
71 %a1_wide = add i32 %a1_wide_orig, %inc
72 %a2_wide = add i32 %a2_wide_orig, %inc
73 %a1 = trunc i32 %a1_wide to i8
74 %a2 = trunc i32 %a2_wide to i8
75 %t1 = icmp sgt i8 %a1, %a2
76 %t2 = select i1 %t1, i8 %a1, i8 %a2
80 ; Values don't come from regs, but there is only one truncation.
82 define i8 @neg_only_one_truncation(i32 %a1_wide_orig, i8 %a2_orig, i32 %inc) nounwind {
83 ; I386-NOCMOV-LABEL: neg_only_one_truncation:
84 ; I386-NOCMOV: # %bb.0:
85 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
86 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
87 ; I386-NOCMOV-NEXT: addl %ecx, %eax
88 ; I386-NOCMOV-NEXT: addb {{[0-9]+}}(%esp), %cl
89 ; I386-NOCMOV-NEXT: cmpb %cl, %al
90 ; I386-NOCMOV-NEXT: jge .LBB1_2
91 ; I386-NOCMOV-NEXT: # %bb.1:
92 ; I386-NOCMOV-NEXT: movl %ecx, %eax
93 ; I386-NOCMOV-NEXT: .LBB1_2:
94 ; I386-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
95 ; I386-NOCMOV-NEXT: retl
97 ; I386-CMOV-LABEL: neg_only_one_truncation:
99 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
100 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
101 ; I386-CMOV-NEXT: addl %eax, %ecx
102 ; I386-CMOV-NEXT: addb {{[0-9]+}}(%esp), %al
103 ; I386-CMOV-NEXT: cmpb %al, %cl
104 ; I386-CMOV-NEXT: movzbl %al, %eax
105 ; I386-CMOV-NEXT: cmovgel %ecx, %eax
106 ; I386-CMOV-NEXT: # kill: def $al killed $al killed $eax
107 ; I386-CMOV-NEXT: retl
109 ; I686-NOCMOV-LABEL: neg_only_one_truncation:
110 ; I686-NOCMOV: # %bb.0:
111 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
112 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
113 ; I686-NOCMOV-NEXT: addl %ecx, %eax
114 ; I686-NOCMOV-NEXT: addb {{[0-9]+}}(%esp), %cl
115 ; I686-NOCMOV-NEXT: cmpb %cl, %al
116 ; I686-NOCMOV-NEXT: jge .LBB1_2
117 ; I686-NOCMOV-NEXT: # %bb.1:
118 ; I686-NOCMOV-NEXT: movl %ecx, %eax
119 ; I686-NOCMOV-NEXT: .LBB1_2:
120 ; I686-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
121 ; I686-NOCMOV-NEXT: retl
123 ; I686-CMOV-LABEL: neg_only_one_truncation:
124 ; I686-CMOV: # %bb.0:
125 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
126 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
127 ; I686-CMOV-NEXT: addl %eax, %ecx
128 ; I686-CMOV-NEXT: addb {{[0-9]+}}(%esp), %al
129 ; I686-CMOV-NEXT: cmpb %al, %cl
130 ; I686-CMOV-NEXT: movzbl %al, %eax
131 ; I686-CMOV-NEXT: cmovgel %ecx, %eax
132 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
133 ; I686-CMOV-NEXT: retl
135 ; X86_64-LABEL: neg_only_one_truncation:
137 ; X86_64-NEXT: addl %edx, %edi
138 ; X86_64-NEXT: addb %sil, %dl
139 ; X86_64-NEXT: cmpb %dl, %dil
140 ; X86_64-NEXT: movzbl %dl, %eax
141 ; X86_64-NEXT: cmovgel %edi, %eax
142 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
144 %a1_wide = add i32 %a1_wide_orig, %inc
145 %inc_short = trunc i32 %inc to i8
146 %a2 = add i8 %a2_orig, %inc_short
147 %a1 = trunc i32 %a1_wide to i8
148 %t1 = icmp sgt i8 %a1, %a2
149 %t2 = select i1 %t1, i8 %a1, i8 %a2
153 ; Values don't come from regs, but truncation from different types.
155 define i8 @neg_type_mismatch(i32 %a1_wide_orig, i16 %a2_wide_orig, i32 %inc) nounwind {
156 ; I386-NOCMOV-LABEL: neg_type_mismatch:
157 ; I386-NOCMOV: # %bb.0:
158 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
159 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
160 ; I386-NOCMOV-NEXT: addl %ecx, %eax
161 ; I386-NOCMOV-NEXT: addw {{[0-9]+}}(%esp), %cx
162 ; I386-NOCMOV-NEXT: cmpb %cl, %al
163 ; I386-NOCMOV-NEXT: jge .LBB2_2
164 ; I386-NOCMOV-NEXT: # %bb.1:
165 ; I386-NOCMOV-NEXT: movl %ecx, %eax
166 ; I386-NOCMOV-NEXT: .LBB2_2:
167 ; I386-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
168 ; I386-NOCMOV-NEXT: retl
170 ; I386-CMOV-LABEL: neg_type_mismatch:
171 ; I386-CMOV: # %bb.0:
172 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
173 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
174 ; I386-CMOV-NEXT: addl %eax, %ecx
175 ; I386-CMOV-NEXT: addw {{[0-9]+}}(%esp), %ax
176 ; I386-CMOV-NEXT: cmpb %al, %cl
177 ; I386-CMOV-NEXT: cmovgel %ecx, %eax
178 ; I386-CMOV-NEXT: # kill: def $al killed $al killed $eax
179 ; I386-CMOV-NEXT: retl
181 ; I686-NOCMOV-LABEL: neg_type_mismatch:
182 ; I686-NOCMOV: # %bb.0:
183 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
184 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
185 ; I686-NOCMOV-NEXT: addl %ecx, %eax
186 ; I686-NOCMOV-NEXT: addw {{[0-9]+}}(%esp), %cx
187 ; I686-NOCMOV-NEXT: cmpb %cl, %al
188 ; I686-NOCMOV-NEXT: jge .LBB2_2
189 ; I686-NOCMOV-NEXT: # %bb.1:
190 ; I686-NOCMOV-NEXT: movl %ecx, %eax
191 ; I686-NOCMOV-NEXT: .LBB2_2:
192 ; I686-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
193 ; I686-NOCMOV-NEXT: retl
195 ; I686-CMOV-LABEL: neg_type_mismatch:
196 ; I686-CMOV: # %bb.0:
197 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
198 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
199 ; I686-CMOV-NEXT: addl %eax, %ecx
200 ; I686-CMOV-NEXT: addw {{[0-9]+}}(%esp), %ax
201 ; I686-CMOV-NEXT: cmpb %al, %cl
202 ; I686-CMOV-NEXT: cmovgel %ecx, %eax
203 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
204 ; I686-CMOV-NEXT: retl
206 ; X86_64-LABEL: neg_type_mismatch:
208 ; X86_64-NEXT: movl %esi, %eax
209 ; X86_64-NEXT: addl %edx, %edi
210 ; X86_64-NEXT: addl %edx, %eax
211 ; X86_64-NEXT: cmpb %al, %dil
212 ; X86_64-NEXT: cmovgel %edi, %eax
213 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
215 %a1_wide = add i32 %a1_wide_orig, %inc
216 %inc_short = trunc i32 %inc to i16
217 %a2_wide = add i16 %a2_wide_orig, %inc_short
218 %a1 = trunc i32 %a1_wide to i8
219 %a2 = trunc i16 %a2_wide to i8
220 %t1 = icmp sgt i8 %a1, %a2
221 %t2 = select i1 %t1, i8 %a1, i8 %a2
225 ; One value come from regs
227 define i8 @negative_CopyFromReg(i32 %a1_wide, i32 %a2_wide_orig, i32 %inc) nounwind {
228 ; I386-NOCMOV-LABEL: negative_CopyFromReg:
229 ; I386-NOCMOV: # %bb.0:
230 ; I386-NOCMOV-NEXT: movb {{[0-9]+}}(%esp), %al
231 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
232 ; I386-NOCMOV-NEXT: addl {{[0-9]+}}(%esp), %ecx
233 ; I386-NOCMOV-NEXT: cmpb %cl, %al
234 ; I386-NOCMOV-NEXT: jge .LBB3_2
235 ; I386-NOCMOV-NEXT: # %bb.1:
236 ; I386-NOCMOV-NEXT: movl %ecx, %eax
237 ; I386-NOCMOV-NEXT: .LBB3_2:
238 ; I386-NOCMOV-NEXT: retl
240 ; I386-CMOV-LABEL: negative_CopyFromReg:
241 ; I386-CMOV: # %bb.0:
242 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
243 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
244 ; I386-CMOV-NEXT: addl {{[0-9]+}}(%esp), %eax
245 ; I386-CMOV-NEXT: cmpb %al, %cl
246 ; I386-CMOV-NEXT: cmovgel %ecx, %eax
247 ; I386-CMOV-NEXT: # kill: def $al killed $al killed $eax
248 ; I386-CMOV-NEXT: retl
250 ; I686-NOCMOV-LABEL: negative_CopyFromReg:
251 ; I686-NOCMOV: # %bb.0:
252 ; I686-NOCMOV-NEXT: movb {{[0-9]+}}(%esp), %al
253 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
254 ; I686-NOCMOV-NEXT: addl {{[0-9]+}}(%esp), %ecx
255 ; I686-NOCMOV-NEXT: cmpb %cl, %al
256 ; I686-NOCMOV-NEXT: jge .LBB3_2
257 ; I686-NOCMOV-NEXT: # %bb.1:
258 ; I686-NOCMOV-NEXT: movl %ecx, %eax
259 ; I686-NOCMOV-NEXT: .LBB3_2:
260 ; I686-NOCMOV-NEXT: retl
262 ; I686-CMOV-LABEL: negative_CopyFromReg:
263 ; I686-CMOV: # %bb.0:
264 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
265 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
266 ; I686-CMOV-NEXT: addl {{[0-9]+}}(%esp), %eax
267 ; I686-CMOV-NEXT: cmpb %al, %cl
268 ; I686-CMOV-NEXT: cmovgel %ecx, %eax
269 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
270 ; I686-CMOV-NEXT: retl
272 ; X86_64-LABEL: negative_CopyFromReg:
274 ; X86_64-NEXT: movl %esi, %eax
275 ; X86_64-NEXT: addl %edx, %eax
276 ; X86_64-NEXT: cmpb %al, %dil
277 ; X86_64-NEXT: cmovgel %edi, %eax
278 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
280 %a2_wide = add i32 %a2_wide_orig, %inc
281 %a1 = trunc i32 %a1_wide to i8
282 %a2 = trunc i32 %a2_wide to i8
283 %t1 = icmp sgt i8 %a1, %a2
284 %t2 = select i1 %t1, i8 %a1, i8 %a2
288 ; Both values come from regs
290 define i8 @negative_CopyFromRegs(i32 %a1_wide, i32 %a2_wide) nounwind {
291 ; I386-NOCMOV-LABEL: negative_CopyFromRegs:
292 ; I386-NOCMOV: # %bb.0:
293 ; I386-NOCMOV-NEXT: movb {{[0-9]+}}(%esp), %cl
294 ; I386-NOCMOV-NEXT: movb {{[0-9]+}}(%esp), %al
295 ; I386-NOCMOV-NEXT: cmpb %cl, %al
296 ; I386-NOCMOV-NEXT: jge .LBB4_2
297 ; I386-NOCMOV-NEXT: # %bb.1:
298 ; I386-NOCMOV-NEXT: movl %ecx, %eax
299 ; I386-NOCMOV-NEXT: .LBB4_2:
300 ; I386-NOCMOV-NEXT: retl
302 ; I386-CMOV-LABEL: negative_CopyFromRegs:
303 ; I386-CMOV: # %bb.0:
304 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
305 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
306 ; I386-CMOV-NEXT: cmpb %al, %cl
307 ; I386-CMOV-NEXT: cmovgel %ecx, %eax
308 ; I386-CMOV-NEXT: # kill: def $al killed $al killed $eax
309 ; I386-CMOV-NEXT: retl
311 ; I686-NOCMOV-LABEL: negative_CopyFromRegs:
312 ; I686-NOCMOV: # %bb.0:
313 ; I686-NOCMOV-NEXT: movb {{[0-9]+}}(%esp), %cl
314 ; I686-NOCMOV-NEXT: movb {{[0-9]+}}(%esp), %al
315 ; I686-NOCMOV-NEXT: cmpb %cl, %al
316 ; I686-NOCMOV-NEXT: jge .LBB4_2
317 ; I686-NOCMOV-NEXT: # %bb.1:
318 ; I686-NOCMOV-NEXT: movl %ecx, %eax
319 ; I686-NOCMOV-NEXT: .LBB4_2:
320 ; I686-NOCMOV-NEXT: retl
322 ; I686-CMOV-LABEL: negative_CopyFromRegs:
323 ; I686-CMOV: # %bb.0:
324 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
325 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
326 ; I686-CMOV-NEXT: cmpb %al, %cl
327 ; I686-CMOV-NEXT: cmovgel %ecx, %eax
328 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
329 ; I686-CMOV-NEXT: retl
331 ; X86_64-LABEL: negative_CopyFromRegs:
333 ; X86_64-NEXT: movl %esi, %eax
334 ; X86_64-NEXT: cmpb %al, %dil
335 ; X86_64-NEXT: cmovgel %edi, %eax
336 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
338 %a1 = trunc i32 %a1_wide to i8
339 %a2 = trunc i32 %a2_wide to i8
340 %t1 = icmp sgt i8 %a1, %a2
341 %t2 = select i1 %t1, i8 %a1, i8 %a2