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-prefix=I386-NOCMOV
3 ; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefix=I386-CMOV
4 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=-cmov | FileCheck %s --check-prefix=I686-NOCMOV
5 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefix=I686-CMOV
6 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=-cmov | FileCheck %s --check-prefix=X86_64
7 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefix=X86_64
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: jg .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: cmovgl %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: jg .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: cmovgl %ecx, %eax
59 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
60 ; I686-CMOV-NEXT: retl
64 ; X86_64-NEXT: # kill: def $edx killed $edx def $rdx
65 ; X86_64-NEXT: # kill: def $esi killed $esi def $rsi
66 ; X86_64-NEXT: # kill: def $edi killed $edi def $rdi
67 ; X86_64-NEXT: leal (%rdi,%rdx), %ecx
68 ; X86_64-NEXT: leal (%rsi,%rdx), %eax
69 ; X86_64-NEXT: cmpb %al, %cl
70 ; X86_64-NEXT: cmovgl %ecx, %eax
71 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
73 %a1_wide = add i32 %a1_wide_orig, %inc
74 %a2_wide = add i32 %a2_wide_orig, %inc
75 %a1 = trunc i32 %a1_wide to i8
76 %a2 = trunc i32 %a2_wide to i8
77 %t1 = icmp sgt i8 %a1, %a2
78 %t2 = select i1 %t1, i8 %a1, i8 %a2
82 ; Values don't come from regs, but there is only one truncation.
84 define i8 @neg_only_one_truncation(i32 %a1_wide_orig, i8 %a2_orig, i32 %inc) nounwind {
85 ; I386-NOCMOV-LABEL: neg_only_one_truncation:
86 ; I386-NOCMOV: # %bb.0:
87 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
88 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
89 ; I386-NOCMOV-NEXT: addl %ecx, %eax
90 ; I386-NOCMOV-NEXT: addb {{[0-9]+}}(%esp), %cl
91 ; I386-NOCMOV-NEXT: cmpb %cl, %al
92 ; I386-NOCMOV-NEXT: jg .LBB1_2
93 ; I386-NOCMOV-NEXT: # %bb.1:
94 ; I386-NOCMOV-NEXT: movl %ecx, %eax
95 ; I386-NOCMOV-NEXT: .LBB1_2:
96 ; I386-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
97 ; I386-NOCMOV-NEXT: retl
99 ; I386-CMOV-LABEL: neg_only_one_truncation:
100 ; I386-CMOV: # %bb.0:
101 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
102 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
103 ; I386-CMOV-NEXT: addl %eax, %ecx
104 ; I386-CMOV-NEXT: addb {{[0-9]+}}(%esp), %al
105 ; I386-CMOV-NEXT: cmpb %al, %cl
106 ; I386-CMOV-NEXT: movzbl %al, %eax
107 ; I386-CMOV-NEXT: cmovgl %ecx, %eax
108 ; I386-CMOV-NEXT: # kill: def $al killed $al killed $eax
109 ; I386-CMOV-NEXT: retl
111 ; I686-NOCMOV-LABEL: neg_only_one_truncation:
112 ; I686-NOCMOV: # %bb.0:
113 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
114 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
115 ; I686-NOCMOV-NEXT: addl %ecx, %eax
116 ; I686-NOCMOV-NEXT: addb {{[0-9]+}}(%esp), %cl
117 ; I686-NOCMOV-NEXT: cmpb %cl, %al
118 ; I686-NOCMOV-NEXT: jg .LBB1_2
119 ; I686-NOCMOV-NEXT: # %bb.1:
120 ; I686-NOCMOV-NEXT: movl %ecx, %eax
121 ; I686-NOCMOV-NEXT: .LBB1_2:
122 ; I686-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
123 ; I686-NOCMOV-NEXT: retl
125 ; I686-CMOV-LABEL: neg_only_one_truncation:
126 ; I686-CMOV: # %bb.0:
127 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
128 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
129 ; I686-CMOV-NEXT: addl %eax, %ecx
130 ; I686-CMOV-NEXT: addb {{[0-9]+}}(%esp), %al
131 ; I686-CMOV-NEXT: cmpb %al, %cl
132 ; I686-CMOV-NEXT: movzbl %al, %eax
133 ; I686-CMOV-NEXT: cmovgl %ecx, %eax
134 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
135 ; I686-CMOV-NEXT: retl
137 ; X86_64-LABEL: neg_only_one_truncation:
139 ; X86_64-NEXT: # kill: def $edx killed $edx def $rdx
140 ; X86_64-NEXT: # kill: def $edi killed $edi def $rdi
141 ; X86_64-NEXT: leal (%rdi,%rdx), %ecx
142 ; X86_64-NEXT: addb %sil, %dl
143 ; X86_64-NEXT: cmpb %dl, %cl
144 ; X86_64-NEXT: movzbl %dl, %eax
145 ; X86_64-NEXT: cmovgl %ecx, %eax
146 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
148 %a1_wide = add i32 %a1_wide_orig, %inc
149 %inc_short = trunc i32 %inc to i8
150 %a2 = add i8 %a2_orig, %inc_short
151 %a1 = trunc i32 %a1_wide to i8
152 %t1 = icmp sgt i8 %a1, %a2
153 %t2 = select i1 %t1, i8 %a1, i8 %a2
157 ; Values don't come from regs, but truncation from different types.
159 define i8 @neg_type_mismatch(i32 %a1_wide_orig, i16 %a2_wide_orig, i32 %inc) nounwind {
160 ; I386-NOCMOV-LABEL: neg_type_mismatch:
161 ; I386-NOCMOV: # %bb.0:
162 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
163 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
164 ; I386-NOCMOV-NEXT: addl %ecx, %eax
165 ; I386-NOCMOV-NEXT: addw {{[0-9]+}}(%esp), %cx
166 ; I386-NOCMOV-NEXT: cmpb %cl, %al
167 ; I386-NOCMOV-NEXT: jg .LBB2_2
168 ; I386-NOCMOV-NEXT: # %bb.1:
169 ; I386-NOCMOV-NEXT: movl %ecx, %eax
170 ; I386-NOCMOV-NEXT: .LBB2_2:
171 ; I386-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
172 ; I386-NOCMOV-NEXT: retl
174 ; I386-CMOV-LABEL: neg_type_mismatch:
175 ; I386-CMOV: # %bb.0:
176 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
177 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
178 ; I386-CMOV-NEXT: addl %eax, %ecx
179 ; I386-CMOV-NEXT: addw {{[0-9]+}}(%esp), %ax
180 ; I386-CMOV-NEXT: cmpb %al, %cl
181 ; I386-CMOV-NEXT: cmovgl %ecx, %eax
182 ; I386-CMOV-NEXT: # kill: def $al killed $al killed $eax
183 ; I386-CMOV-NEXT: retl
185 ; I686-NOCMOV-LABEL: neg_type_mismatch:
186 ; I686-NOCMOV: # %bb.0:
187 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
188 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
189 ; I686-NOCMOV-NEXT: addl %ecx, %eax
190 ; I686-NOCMOV-NEXT: addw {{[0-9]+}}(%esp), %cx
191 ; I686-NOCMOV-NEXT: cmpb %cl, %al
192 ; I686-NOCMOV-NEXT: jg .LBB2_2
193 ; I686-NOCMOV-NEXT: # %bb.1:
194 ; I686-NOCMOV-NEXT: movl %ecx, %eax
195 ; I686-NOCMOV-NEXT: .LBB2_2:
196 ; I686-NOCMOV-NEXT: # kill: def $al killed $al killed $eax
197 ; I686-NOCMOV-NEXT: retl
199 ; I686-CMOV-LABEL: neg_type_mismatch:
200 ; I686-CMOV: # %bb.0:
201 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
202 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
203 ; I686-CMOV-NEXT: addl %eax, %ecx
204 ; I686-CMOV-NEXT: addw {{[0-9]+}}(%esp), %ax
205 ; I686-CMOV-NEXT: cmpb %al, %cl
206 ; I686-CMOV-NEXT: cmovgl %ecx, %eax
207 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
208 ; I686-CMOV-NEXT: retl
210 ; X86_64-LABEL: neg_type_mismatch:
212 ; X86_64-NEXT: # kill: def $edx killed $edx def $rdx
213 ; X86_64-NEXT: # kill: def $esi killed $esi def $rsi
214 ; X86_64-NEXT: # kill: def $edi killed $edi def $rdi
215 ; X86_64-NEXT: leal (%rdi,%rdx), %ecx
216 ; X86_64-NEXT: leal (%rsi,%rdx), %eax
217 ; X86_64-NEXT: cmpb %al, %cl
218 ; X86_64-NEXT: cmovgl %ecx, %eax
219 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
221 %a1_wide = add i32 %a1_wide_orig, %inc
222 %inc_short = trunc i32 %inc to i16
223 %a2_wide = add i16 %a2_wide_orig, %inc_short
224 %a1 = trunc i32 %a1_wide to i8
225 %a2 = trunc i16 %a2_wide to i8
226 %t1 = icmp sgt i8 %a1, %a2
227 %t2 = select i1 %t1, i8 %a1, i8 %a2
231 ; One value come from regs
233 define i8 @negative_CopyFromReg(i32 %a1_wide, i32 %a2_wide_orig, i32 %inc) nounwind {
234 ; I386-NOCMOV-LABEL: negative_CopyFromReg:
235 ; I386-NOCMOV: # %bb.0:
236 ; I386-NOCMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax
237 ; I386-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
238 ; I386-NOCMOV-NEXT: addl {{[0-9]+}}(%esp), %ecx
239 ; I386-NOCMOV-NEXT: cmpb %cl, %al
240 ; I386-NOCMOV-NEXT: jg .LBB3_2
241 ; I386-NOCMOV-NEXT: # %bb.1:
242 ; I386-NOCMOV-NEXT: movl %ecx, %eax
243 ; I386-NOCMOV-NEXT: .LBB3_2:
244 ; I386-NOCMOV-NEXT: retl
246 ; I386-CMOV-LABEL: negative_CopyFromReg:
247 ; I386-CMOV: # %bb.0:
248 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
249 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
250 ; I386-CMOV-NEXT: addl {{[0-9]+}}(%esp), %eax
251 ; I386-CMOV-NEXT: cmpb %al, %cl
252 ; I386-CMOV-NEXT: cmovgl %ecx, %eax
253 ; I386-CMOV-NEXT: # kill: def $al killed $al killed $eax
254 ; I386-CMOV-NEXT: retl
256 ; I686-NOCMOV-LABEL: negative_CopyFromReg:
257 ; I686-NOCMOV: # %bb.0:
258 ; I686-NOCMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax
259 ; I686-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
260 ; I686-NOCMOV-NEXT: addl {{[0-9]+}}(%esp), %ecx
261 ; I686-NOCMOV-NEXT: cmpb %cl, %al
262 ; I686-NOCMOV-NEXT: jg .LBB3_2
263 ; I686-NOCMOV-NEXT: # %bb.1:
264 ; I686-NOCMOV-NEXT: movl %ecx, %eax
265 ; I686-NOCMOV-NEXT: .LBB3_2:
266 ; I686-NOCMOV-NEXT: retl
268 ; I686-CMOV-LABEL: negative_CopyFromReg:
269 ; I686-CMOV: # %bb.0:
270 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
271 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
272 ; I686-CMOV-NEXT: addl {{[0-9]+}}(%esp), %eax
273 ; I686-CMOV-NEXT: cmpb %al, %cl
274 ; I686-CMOV-NEXT: cmovgl %ecx, %eax
275 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
276 ; I686-CMOV-NEXT: retl
278 ; X86_64-LABEL: negative_CopyFromReg:
280 ; X86_64-NEXT: # kill: def $edx killed $edx def $rdx
281 ; X86_64-NEXT: # kill: def $esi killed $esi def $rsi
282 ; X86_64-NEXT: leal (%rsi,%rdx), %eax
283 ; X86_64-NEXT: cmpb %al, %dil
284 ; X86_64-NEXT: cmovgl %edi, %eax
285 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
287 %a2_wide = add i32 %a2_wide_orig, %inc
288 %a1 = trunc i32 %a1_wide to i8
289 %a2 = trunc i32 %a2_wide to i8
290 %t1 = icmp sgt i8 %a1, %a2
291 %t2 = select i1 %t1, i8 %a1, i8 %a2
295 ; Both values come from regs
297 define i8 @negative_CopyFromRegs(i32 %a1_wide, i32 %a2_wide) nounwind {
298 ; I386-NOCMOV-LABEL: negative_CopyFromRegs:
299 ; I386-NOCMOV: # %bb.0:
300 ; I386-NOCMOV-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
301 ; I386-NOCMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax
302 ; I386-NOCMOV-NEXT: cmpb %cl, %al
303 ; I386-NOCMOV-NEXT: jg .LBB4_2
304 ; I386-NOCMOV-NEXT: # %bb.1:
305 ; I386-NOCMOV-NEXT: movl %ecx, %eax
306 ; I386-NOCMOV-NEXT: .LBB4_2:
307 ; I386-NOCMOV-NEXT: retl
309 ; I386-CMOV-LABEL: negative_CopyFromRegs:
310 ; I386-CMOV: # %bb.0:
311 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
312 ; I386-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
313 ; I386-CMOV-NEXT: cmpb %al, %cl
314 ; I386-CMOV-NEXT: cmovgl %ecx, %eax
315 ; I386-CMOV-NEXT: # kill: def $al killed $al killed $eax
316 ; I386-CMOV-NEXT: retl
318 ; I686-NOCMOV-LABEL: negative_CopyFromRegs:
319 ; I686-NOCMOV: # %bb.0:
320 ; I686-NOCMOV-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
321 ; I686-NOCMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax
322 ; I686-NOCMOV-NEXT: cmpb %cl, %al
323 ; I686-NOCMOV-NEXT: jg .LBB4_2
324 ; I686-NOCMOV-NEXT: # %bb.1:
325 ; I686-NOCMOV-NEXT: movl %ecx, %eax
326 ; I686-NOCMOV-NEXT: .LBB4_2:
327 ; I686-NOCMOV-NEXT: retl
329 ; I686-CMOV-LABEL: negative_CopyFromRegs:
330 ; I686-CMOV: # %bb.0:
331 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
332 ; I686-CMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
333 ; I686-CMOV-NEXT: cmpb %al, %cl
334 ; I686-CMOV-NEXT: cmovgl %ecx, %eax
335 ; I686-CMOV-NEXT: # kill: def $al killed $al killed $eax
336 ; I686-CMOV-NEXT: retl
338 ; X86_64-LABEL: negative_CopyFromRegs:
340 ; X86_64-NEXT: movl %esi, %eax
341 ; X86_64-NEXT: cmpb %al, %dil
342 ; X86_64-NEXT: cmovgl %edi, %eax
343 ; X86_64-NEXT: # kill: def $al killed $al killed $eax
345 %a1 = trunc i32 %a1_wide to i8
346 %a2 = trunc i32 %a2_wide to i8
347 %t1 = icmp sgt i8 %a1, %a2
348 %t2 = select i1 %t1, i8 %a1, i8 %a2