blob: 91cdef2a75bb24a763986ebde9bfcc878da7fd3e [file] [log] [blame]
Roman Lebedev1574e4972018-07-12 17:00:11 +00001; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=i686-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,X86,NOBMI2,X86-NOBMI2,FALLBACK0,X86-FALLBACK0
3; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI2,X64-NOBMI2,FALLBACK0,X64-FALLBACK0
4
5; https://bugs.llvm.org/show_bug.cgi?id=38149
6
7; We are truncating from wider width, and then sign-extending
8; back to the original width. Then we equality-comparing orig and src.
9; If they don't match, then we had signed truncation during truncation.
10
11; This can be expressed in a several ways in IR:
12; trunc + sext + icmp eq <- not canonical
13; shl + ashr + icmp eq
14; add + icmp uge
15; add + icmp ult
16; However only the simplest form (with two shifts) gets lowered best.
17
18; ---------------------------------------------------------------------------- ;
19; shl + ashr + icmp eq
20; ---------------------------------------------------------------------------- ;
21
22define i1 @shifts_eqcmp_i16_i8(i16 %x) nounwind {
23; X86-LABEL: shifts_eqcmp_i16_i8:
24; X86: # %bb.0:
25; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
26; X86-NEXT: movsbl %al, %ecx
27; X86-NEXT: cmpw %ax, %cx
28; X86-NEXT: sete %al
29; X86-NEXT: retl
30;
31; X64-LABEL: shifts_eqcmp_i16_i8:
32; X64: # %bb.0:
33; X64-NEXT: movsbl %dil, %eax
34; X64-NEXT: cmpw %di, %ax
35; X64-NEXT: sete %al
36; X64-NEXT: retq
37 %tmp0 = shl i16 %x, 8 ; 16-8
38 %tmp1 = ashr exact i16 %tmp0, 8 ; 16-8
39 %tmp2 = icmp eq i16 %tmp1, %x
40 ret i1 %tmp2
41}
42
43define i1 @shifts_eqcmp_i32_i16(i32 %x) nounwind {
44; X86-LABEL: shifts_eqcmp_i32_i16:
45; X86: # %bb.0:
46; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
47; X86-NEXT: movswl %ax, %ecx
48; X86-NEXT: cmpl %eax, %ecx
49; X86-NEXT: sete %al
50; X86-NEXT: retl
51;
52; X64-LABEL: shifts_eqcmp_i32_i16:
53; X64: # %bb.0:
54; X64-NEXT: movswl %di, %eax
55; X64-NEXT: cmpl %edi, %eax
56; X64-NEXT: sete %al
57; X64-NEXT: retq
58 %tmp0 = shl i32 %x, 16 ; 32-16
59 %tmp1 = ashr exact i32 %tmp0, 16 ; 32-16
60 %tmp2 = icmp eq i32 %tmp1, %x
61 ret i1 %tmp2
62}
63
64define i1 @shifts_eqcmp_i32_i8(i32 %x) nounwind {
65; X86-LABEL: shifts_eqcmp_i32_i8:
66; X86: # %bb.0:
67; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
68; X86-NEXT: movsbl %al, %ecx
69; X86-NEXT: cmpl %eax, %ecx
70; X86-NEXT: sete %al
71; X86-NEXT: retl
72;
73; X64-LABEL: shifts_eqcmp_i32_i8:
74; X64: # %bb.0:
75; X64-NEXT: movsbl %dil, %eax
76; X64-NEXT: cmpl %edi, %eax
77; X64-NEXT: sete %al
78; X64-NEXT: retq
79 %tmp0 = shl i32 %x, 24 ; 32-8
80 %tmp1 = ashr exact i32 %tmp0, 24 ; 32-8
81 %tmp2 = icmp eq i32 %tmp1, %x
82 ret i1 %tmp2
83}
84
85define i1 @shifts_eqcmp_i64_i32(i64 %x) nounwind {
86; X86-LABEL: shifts_eqcmp_i64_i32:
87; X86: # %bb.0:
88; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
89; X86-NEXT: sarl $31, %eax
90; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
91; X86-NEXT: sete %al
92; X86-NEXT: retl
93;
94; X64-LABEL: shifts_eqcmp_i64_i32:
95; X64: # %bb.0:
96; X64-NEXT: movslq %edi, %rax
97; X64-NEXT: cmpq %rdi, %rax
98; X64-NEXT: sete %al
99; X64-NEXT: retq
100 %tmp0 = shl i64 %x, 32 ; 64-32
101 %tmp1 = ashr exact i64 %tmp0, 32 ; 64-32
102 %tmp2 = icmp eq i64 %tmp1, %x
103 ret i1 %tmp2
104}
105
106define i1 @shifts_eqcmp_i64_i16(i64 %x) nounwind {
107; X86-LABEL: shifts_eqcmp_i64_i16:
108; X86: # %bb.0:
109; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
110; X86-NEXT: movswl %ax, %ecx
111; X86-NEXT: movl %ecx, %edx
112; X86-NEXT: sarl $31, %edx
113; X86-NEXT: xorl %eax, %ecx
114; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx
115; X86-NEXT: orl %ecx, %edx
116; X86-NEXT: sete %al
117; X86-NEXT: retl
118;
119; X64-LABEL: shifts_eqcmp_i64_i16:
120; X64: # %bb.0:
121; X64-NEXT: movswq %di, %rax
122; X64-NEXT: cmpq %rdi, %rax
123; X64-NEXT: sete %al
124; X64-NEXT: retq
125 %tmp0 = shl i64 %x, 48 ; 64-16
126 %tmp1 = ashr exact i64 %tmp0, 48 ; 64-16
127 %tmp2 = icmp eq i64 %tmp1, %x
128 ret i1 %tmp2
129}
130
131define i1 @shifts_eqcmp_i64_i8(i64 %x) nounwind {
132; X86-LABEL: shifts_eqcmp_i64_i8:
133; X86: # %bb.0:
134; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
135; X86-NEXT: movsbl %al, %ecx
136; X86-NEXT: movl %ecx, %edx
137; X86-NEXT: sarl $31, %edx
138; X86-NEXT: xorl %eax, %ecx
139; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx
140; X86-NEXT: orl %ecx, %edx
141; X86-NEXT: sete %al
142; X86-NEXT: retl
143;
144; X64-LABEL: shifts_eqcmp_i64_i8:
145; X64: # %bb.0:
146; X64-NEXT: movsbq %dil, %rax
147; X64-NEXT: cmpq %rdi, %rax
148; X64-NEXT: sete %al
149; X64-NEXT: retq
150 %tmp0 = shl i64 %x, 56 ; 64-8
151 %tmp1 = ashr exact i64 %tmp0, 56 ; 64-8
152 %tmp2 = icmp eq i64 %tmp1, %x
153 ret i1 %tmp2
154}
155
156; ---------------------------------------------------------------------------- ;
157; add + icmp uge
158; ---------------------------------------------------------------------------- ;
159
160define i1 @add_ugecmp_i16_i8(i16 %x) nounwind {
161; X86-LABEL: add_ugecmp_i16_i8:
162; X86: # %bb.0:
163; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
164; X86-NEXT: addl $-128, %eax
165; X86-NEXT: movzwl %ax, %eax
166; X86-NEXT: cmpl $65279, %eax # imm = 0xFEFF
167; X86-NEXT: seta %al
168; X86-NEXT: retl
169;
170; X64-LABEL: add_ugecmp_i16_i8:
171; X64: # %bb.0:
172; X64-NEXT: addl $-128, %edi
173; X64-NEXT: movzwl %di, %eax
174; X64-NEXT: cmpl $65279, %eax # imm = 0xFEFF
175; X64-NEXT: seta %al
176; X64-NEXT: retq
177 %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
178 %tmp1 = icmp uge i16 %tmp0, -256 ; ~0U << 8
179 ret i1 %tmp1
180}
181
182define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {
183; X86-LABEL: add_ugecmp_i32_i16:
184; X86: # %bb.0:
185; X86-NEXT: movl $-32768, %eax # imm = 0x8000
186; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
187; X86-NEXT: cmpl $-65537, %eax # imm = 0xFFFEFFFF
188; X86-NEXT: seta %al
189; X86-NEXT: retl
190;
191; X64-LABEL: add_ugecmp_i32_i16:
192; X64: # %bb.0:
193; X64-NEXT: addl $-32768, %edi # imm = 0x8000
194; X64-NEXT: cmpl $-65537, %edi # imm = 0xFFFEFFFF
195; X64-NEXT: seta %al
196; X64-NEXT: retq
197 %tmp0 = add i32 %x, -32768 ; ~0U << (16-1)
198 %tmp1 = icmp uge i32 %tmp0, -65536 ; ~0U << 16
199 ret i1 %tmp1
200}
201
202define i1 @add_ugecmp_i32_i8(i32 %x) nounwind {
203; X86-LABEL: add_ugecmp_i32_i8:
204; X86: # %bb.0:
205; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
206; X86-NEXT: addl $-128, %eax
207; X86-NEXT: cmpl $-257, %eax # imm = 0xFEFF
208; X86-NEXT: seta %al
209; X86-NEXT: retl
210;
211; X64-LABEL: add_ugecmp_i32_i8:
212; X64: # %bb.0:
213; X64-NEXT: addl $-128, %edi
214; X64-NEXT: cmpl $-257, %edi # imm = 0xFEFF
215; X64-NEXT: seta %al
216; X64-NEXT: retq
217 %tmp0 = add i32 %x, -128 ; ~0U << (8-1)
218 %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8
219 ret i1 %tmp1
220}
221
222define i1 @add_ugecmp_i64_i32(i64 %x) nounwind {
223; X86-LABEL: add_ugecmp_i64_i32:
224; X86: # %bb.0:
225; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
226; X86-NEXT: movl $-2147483648, %ecx # imm = 0x80000000
227; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx
228; X86-NEXT: adcl $-1, %eax
229; X86-NEXT: cmpl $-1, %eax
230; X86-NEXT: sete %al
231; X86-NEXT: retl
232;
233; X64-LABEL: add_ugecmp_i64_i32:
234; X64: # %bb.0:
235; X64-NEXT: addq $-2147483648, %rdi # imm = 0x80000000
236; X64-NEXT: movabsq $-4294967297, %rax # imm = 0xFFFFFFFEFFFFFFFF
237; X64-NEXT: cmpq %rax, %rdi
238; X64-NEXT: seta %al
239; X64-NEXT: retq
240 %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1)
241 %tmp1 = icmp uge i64 %tmp0, -4294967296 ; ~0U << 32
242 ret i1 %tmp1
243}
244
245define i1 @add_ugecmp_i64_i16(i64 %x) nounwind {
246; X86-LABEL: add_ugecmp_i64_i16:
247; X86: # %bb.0:
248; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
249; X86-NEXT: movl $-32768, %ecx # imm = 0x8000
250; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx
251; X86-NEXT: adcl $-1, %eax
252; X86-NEXT: movl $-65537, %edx # imm = 0xFFFEFFFF
253; X86-NEXT: cmpl %ecx, %edx
254; X86-NEXT: movl $-1, %ecx
255; X86-NEXT: sbbl %eax, %ecx
256; X86-NEXT: setb %al
257; X86-NEXT: retl
258;
259; X64-LABEL: add_ugecmp_i64_i16:
260; X64: # %bb.0:
261; X64-NEXT: addq $-32768, %rdi # imm = 0x8000
262; X64-NEXT: cmpq $-65537, %rdi # imm = 0xFFFEFFFF
263; X64-NEXT: seta %al
264; X64-NEXT: retq
265 %tmp0 = add i64 %x, -32768 ; ~0U << (16-1)
266 %tmp1 = icmp uge i64 %tmp0, -65536 ; ~0U << 16
267 ret i1 %tmp1
268}
269
270define i1 @add_ugecmp_i64_i8(i64 %x) nounwind {
271; X86-LABEL: add_ugecmp_i64_i8:
272; X86: # %bb.0:
273; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
274; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
275; X86-NEXT: addl $-128, %eax
276; X86-NEXT: adcl $-1, %ecx
277; X86-NEXT: movl $-257, %edx # imm = 0xFEFF
278; X86-NEXT: cmpl %eax, %edx
279; X86-NEXT: movl $-1, %eax
280; X86-NEXT: sbbl %ecx, %eax
281; X86-NEXT: setb %al
282; X86-NEXT: retl
283;
284; X64-LABEL: add_ugecmp_i64_i8:
285; X64: # %bb.0:
286; X64-NEXT: addq $-128, %rdi
287; X64-NEXT: cmpq $-257, %rdi # imm = 0xFEFF
288; X64-NEXT: seta %al
289; X64-NEXT: retq
290 %tmp0 = add i64 %x, -128 ; ~0U << (8-1)
291 %tmp1 = icmp uge i64 %tmp0, -256 ; ~0U << 8
292 ret i1 %tmp1
293}
294
295; ---------------------------------------------------------------------------- ;
296; add + icmp ult
297; ---------------------------------------------------------------------------- ;
298
299define i1 @add_ultcmp_i16_i8(i16 %x) nounwind {
300; X86-LABEL: add_ultcmp_i16_i8:
301; X86: # %bb.0:
302; X86-NEXT: movl $128, %eax
303; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
304; X86-NEXT: movzwl %ax, %eax
305; X86-NEXT: cmpl $256, %eax # imm = 0x100
306; X86-NEXT: setb %al
307; X86-NEXT: retl
308;
309; X64-LABEL: add_ultcmp_i16_i8:
310; X64: # %bb.0:
311; X64-NEXT: subl $-128, %edi
312; X64-NEXT: movzwl %di, %eax
313; X64-NEXT: cmpl $256, %eax # imm = 0x100
314; X64-NEXT: setb %al
315; X64-NEXT: retq
316 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
317 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
318 ret i1 %tmp1
319}
320
321define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {
322; X86-LABEL: add_ultcmp_i32_i16:
323; X86: # %bb.0:
324; X86-NEXT: movl $32768, %eax # imm = 0x8000
325; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
326; X86-NEXT: cmpl $65536, %eax # imm = 0x10000
327; X86-NEXT: setb %al
328; X86-NEXT: retl
329;
330; X64-LABEL: add_ultcmp_i32_i16:
331; X64: # %bb.0:
332; X64-NEXT: addl $32768, %edi # imm = 0x8000
333; X64-NEXT: cmpl $65536, %edi # imm = 0x10000
334; X64-NEXT: setb %al
335; X64-NEXT: retq
336 %tmp0 = add i32 %x, 32768 ; 1U << (16-1)
337 %tmp1 = icmp ult i32 %tmp0, 65536 ; 1U << 16
338 ret i1 %tmp1
339}
340
341define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {
342; X86-LABEL: add_ultcmp_i32_i8:
343; X86: # %bb.0:
344; X86-NEXT: movl $128, %eax
345; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
346; X86-NEXT: cmpl $256, %eax # imm = 0x100
347; X86-NEXT: setb %al
348; X86-NEXT: retl
349;
350; X64-LABEL: add_ultcmp_i32_i8:
351; X64: # %bb.0:
352; X64-NEXT: subl $-128, %edi
353; X64-NEXT: cmpl $256, %edi # imm = 0x100
354; X64-NEXT: setb %al
355; X64-NEXT: retq
356 %tmp0 = add i32 %x, 128 ; 1U << (8-1)
357 %tmp1 = icmp ult i32 %tmp0, 256 ; 1U << 8
358 ret i1 %tmp1
359}
360
361define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {
362; X86-LABEL: add_ultcmp_i64_i32:
363; X86: # %bb.0:
364; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
365; X86-NEXT: movl $-2147483648, %ecx # imm = 0x80000000
366; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx
367; X86-NEXT: adcl $0, %eax
368; X86-NEXT: sete %al
369; X86-NEXT: retl
370;
371; X64-LABEL: add_ultcmp_i64_i32:
372; X64: # %bb.0:
373; X64-NEXT: subq $-2147483648, %rdi # imm = 0x80000000
374; X64-NEXT: shrq $32, %rdi
375; X64-NEXT: sete %al
376; X64-NEXT: retq
377 %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)
378 %tmp1 = icmp ult i64 %tmp0, 4294967296 ; 1U << 32
379 ret i1 %tmp1
380}
381
382define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {
383; X86-LABEL: add_ultcmp_i64_i16:
384; X86: # %bb.0:
385; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
386; X86-NEXT: movl $32768, %ecx # imm = 0x8000
387; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx
388; X86-NEXT: adcl $0, %eax
389; X86-NEXT: cmpl $65536, %ecx # imm = 0x10000
390; X86-NEXT: sbbl $0, %eax
391; X86-NEXT: setb %al
392; X86-NEXT: retl
393;
394; X64-LABEL: add_ultcmp_i64_i16:
395; X64: # %bb.0:
396; X64-NEXT: addq $32768, %rdi # imm = 0x8000
397; X64-NEXT: cmpq $65536, %rdi # imm = 0x10000
398; X64-NEXT: setb %al
399; X64-NEXT: retq
400 %tmp0 = add i64 %x, 32768 ; 1U << (16-1)
401 %tmp1 = icmp ult i64 %tmp0, 65536 ; 1U << 16
402 ret i1 %tmp1
403}
404
405define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {
406; X86-LABEL: add_ultcmp_i64_i8:
407; X86: # %bb.0:
408; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
409; X86-NEXT: movl $128, %ecx
410; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx
411; X86-NEXT: adcl $0, %eax
412; X86-NEXT: cmpl $256, %ecx # imm = 0x100
413; X86-NEXT: sbbl $0, %eax
414; X86-NEXT: setb %al
415; X86-NEXT: retl
416;
417; X64-LABEL: add_ultcmp_i64_i8:
418; X64: # %bb.0:
419; X64-NEXT: subq $-128, %rdi
420; X64-NEXT: cmpq $256, %rdi # imm = 0x100
421; X64-NEXT: setb %al
422; X64-NEXT: retq
423 %tmp0 = add i64 %x, 128 ; 1U << (8-1)
424 %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8
425 ret i1 %tmp1
426}
Roman Lebedevb64e74f2018-07-13 16:14:37 +0000427
428; Negative tests
429; ---------------------------------------------------------------------------- ;
430
431; Adding not a constant
432define i1 @add_ultcmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
433; X86-LABEL: add_ultcmp_bad_i16_i8_add:
434; X86: # %bb.0:
435; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
436; X86-NEXT: addw {{[0-9]+}}(%esp), %ax
437; X86-NEXT: movzwl %ax, %eax
438; X86-NEXT: cmpl $256, %eax # imm = 0x100
439; X86-NEXT: setb %al
440; X86-NEXT: retl
441;
442; X64-LABEL: add_ultcmp_bad_i16_i8_add:
443; X64: # %bb.0:
444; X64-NEXT: addl %esi, %edi
445; X64-NEXT: movzwl %di, %eax
446; X64-NEXT: cmpl $256, %eax # imm = 0x100
447; X64-NEXT: setb %al
448; X64-NEXT: retq
449 %tmp0 = add i16 %x, %y
450 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
451 ret i1 %tmp1
452}
453
454; Comparing not with a constant
455define i1 @add_ultcmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
456; X86-LABEL: add_ultcmp_bad_i16_i8_cmp:
457; X86: # %bb.0:
458; X86-NEXT: movl $128, %eax
459; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
460; X86-NEXT: cmpw {{[0-9]+}}(%esp), %ax
461; X86-NEXT: setb %al
462; X86-NEXT: retl
463;
464; X64-LABEL: add_ultcmp_bad_i16_i8_cmp:
465; X64: # %bb.0:
466; X64-NEXT: subl $-128, %edi
467; X64-NEXT: cmpw %si, %di
468; X64-NEXT: setb %al
469; X64-NEXT: retq
470 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
471 %tmp1 = icmp ult i16 %tmp0, %y
472 ret i1 %tmp1
473}
474
475; Second constant is not larger than the first one
476define i1 @add_ultcmp_bad_i8_i16(i16 %x) nounwind {
477; X86-LABEL: add_ultcmp_bad_i8_i16:
478; X86: # %bb.0:
479; X86-NEXT: movw $128, %ax
480; X86-NEXT: addw {{[0-9]+}}(%esp), %ax
481; X86-NEXT: setb %al
482; X86-NEXT: retl
483;
484; X64-LABEL: add_ultcmp_bad_i8_i16:
485; X64: # %bb.0:
486; X64-NEXT: addw $128, %di
487; X64-NEXT: setb %al
488; X64-NEXT: retq
489 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
490 %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1)
491 ret i1 %tmp1
492}
493
494; First constant is not power of two
495define i1 @add_ultcmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
496; X86-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
497; X86: # %bb.0:
498; X86-NEXT: movl $192, %eax
499; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
500; X86-NEXT: movzwl %ax, %eax
501; X86-NEXT: cmpl $256, %eax # imm = 0x100
502; X86-NEXT: setb %al
503; X86-NEXT: retl
504;
505; X64-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
506; X64: # %bb.0:
507; X64-NEXT: addl $192, %edi
508; X64-NEXT: movzwl %di, %eax
509; X64-NEXT: cmpl $256, %eax # imm = 0x100
510; X64-NEXT: setb %al
511; X64-NEXT: retq
512 %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
513 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
514 ret i1 %tmp1
515}
516
517; Second constant is not power of two
518define i1 @add_ultcmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
519; X86-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
520; X86: # %bb.0:
521; X86-NEXT: movl $128, %eax
522; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
523; X86-NEXT: movzwl %ax, %eax
524; X86-NEXT: cmpl $768, %eax # imm = 0x300
525; X86-NEXT: setb %al
526; X86-NEXT: retl
527;
528; X64-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
529; X64: # %bb.0:
530; X64-NEXT: subl $-128, %edi
531; X64-NEXT: movzwl %di, %eax
532; X64-NEXT: cmpl $768, %eax # imm = 0x300
533; X64-NEXT: setb %al
534; X64-NEXT: retq
535 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
536 %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
537 ret i1 %tmp1
538}
539
540; Magic check fails, 64 << 1 != 256
541define i1 @add_ultcmp_bad_i16_i8_magic(i16 %x) nounwind {
542; X86-LABEL: add_ultcmp_bad_i16_i8_magic:
543; X86: # %bb.0:
544; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
545; X86-NEXT: addl $64, %eax
546; X86-NEXT: movzwl %ax, %eax
547; X86-NEXT: cmpl $256, %eax # imm = 0x100
548; X86-NEXT: setb %al
549; X86-NEXT: retl
550;
551; X64-LABEL: add_ultcmp_bad_i16_i8_magic:
552; X64: # %bb.0:
553; X64-NEXT: addl $64, %edi
554; X64-NEXT: movzwl %di, %eax
555; X64-NEXT: cmpl $256, %eax # imm = 0x100
556; X64-NEXT: setb %al
557; X64-NEXT: retq
558 %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
559 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
560 ret i1 %tmp1
561}
562
563; Bad 'destination type'
564define i1 @add_ultcmp_bad_i16_i4(i16 %x) nounwind {
565; X86-LABEL: add_ultcmp_bad_i16_i4:
566; X86: # %bb.0:
567; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
568; X86-NEXT: addl $8, %eax
569; X86-NEXT: movzwl %ax, %eax
570; X86-NEXT: cmpl $16, %eax
571; X86-NEXT: setb %al
572; X86-NEXT: retl
573;
574; X64-LABEL: add_ultcmp_bad_i16_i4:
575; X64: # %bb.0:
576; X64-NEXT: addl $8, %edi
577; X64-NEXT: movzwl %di, %eax
578; X64-NEXT: cmpl $16, %eax
579; X64-NEXT: setb %al
580; X64-NEXT: retq
581 %tmp0 = add i16 %x, 8 ; 1U << (4-1)
582 %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4
583 ret i1 %tmp1
584}
585
586; Bad storage type
587define i1 @add_ultcmp_bad_i24_i8(i24 %x) nounwind {
588; X86-LABEL: add_ultcmp_bad_i24_i8:
589; X86: # %bb.0:
590; X86-NEXT: movl $128, %eax
591; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
592; X86-NEXT: andl $16777215, %eax # imm = 0xFFFFFF
593; X86-NEXT: cmpl $256, %eax # imm = 0x100
594; X86-NEXT: setb %al
595; X86-NEXT: retl
596;
597; X64-LABEL: add_ultcmp_bad_i24_i8:
598; X64: # %bb.0:
599; X64-NEXT: subl $-128, %edi
600; X64-NEXT: andl $16777215, %edi # imm = 0xFFFFFF
601; X64-NEXT: cmpl $256, %edi # imm = 0x100
602; X64-NEXT: setb %al
603; X64-NEXT: retq
604 %tmp0 = add i24 %x, 128 ; 1U << (8-1)
605 %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8
606 ret i1 %tmp1
607}