[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / X86 / 8bit_cmov_of_trunc_promotion.ll
blobc8235e8d096551e5f760c834eec143d9e22014cf
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:
27 ; I386-CMOV:       # %bb.0:
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:
52 ; I686-CMOV:       # %bb.0:
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
62 ; X86_64-LABEL: t0:
63 ; X86_64:       # %bb.0:
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
70 ; X86_64-NEXT:    retq
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
77   ret i8 %t2
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:
98 ; I386-CMOV:       # %bb.0:
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:
136 ; X86_64:       # %bb.0:
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
143 ; X86_64-NEXT:    retq
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
150   ret i8 %t2
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:
207 ; X86_64:       # %bb.0:
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
214 ; X86_64-NEXT:    retq
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
222   ret i8 %t2
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:
273 ; X86_64:       # %bb.0:
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
279 ; X86_64-NEXT:    retq
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
285   ret i8 %t2
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:
332 ; X86_64:       # %bb.0:
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
337 ; X86_64-NEXT:    retq
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
342   ret i8 %t2