blob: f18307fbbc74785cb53f95562b70c81ca643d6aa [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:
Roman Lebedevde506632018-07-16 12:44:10 +0000302; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
303; X86-NEXT: movsbl %al, %ecx
304; X86-NEXT: cmpw %ax, %cx
305; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000306; X86-NEXT: retl
307;
308; X64-LABEL: add_ultcmp_i16_i8:
309; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000310; X64-NEXT: movsbl %dil, %eax
311; X64-NEXT: cmpw %di, %ax
312; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000313; X64-NEXT: retq
314 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
315 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
316 ret i1 %tmp1
317}
318
319define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {
320; X86-LABEL: add_ultcmp_i32_i16:
321; X86: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000322; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
323; X86-NEXT: movswl %ax, %ecx
324; X86-NEXT: cmpl %eax, %ecx
325; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000326; X86-NEXT: retl
327;
328; X64-LABEL: add_ultcmp_i32_i16:
329; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000330; X64-NEXT: movswl %di, %eax
331; X64-NEXT: cmpl %edi, %eax
332; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000333; X64-NEXT: retq
334 %tmp0 = add i32 %x, 32768 ; 1U << (16-1)
335 %tmp1 = icmp ult i32 %tmp0, 65536 ; 1U << 16
336 ret i1 %tmp1
337}
338
339define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {
340; X86-LABEL: add_ultcmp_i32_i8:
341; X86: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000342; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
343; X86-NEXT: movsbl %al, %ecx
344; X86-NEXT: cmpl %eax, %ecx
345; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000346; X86-NEXT: retl
347;
348; X64-LABEL: add_ultcmp_i32_i8:
349; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000350; X64-NEXT: movsbl %dil, %eax
351; X64-NEXT: cmpl %edi, %eax
352; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000353; X64-NEXT: retq
354 %tmp0 = add i32 %x, 128 ; 1U << (8-1)
355 %tmp1 = icmp ult i32 %tmp0, 256 ; 1U << 8
356 ret i1 %tmp1
357}
358
359define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {
360; X86-LABEL: add_ultcmp_i64_i32:
361; X86: # %bb.0:
362; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevde506632018-07-16 12:44:10 +0000363; X86-NEXT: sarl $31, %eax
364; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
Roman Lebedev1574e4972018-07-12 17:00:11 +0000365; X86-NEXT: sete %al
366; X86-NEXT: retl
367;
368; X64-LABEL: add_ultcmp_i64_i32:
369; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000370; X64-NEXT: movslq %edi, %rax
371; X64-NEXT: cmpq %rdi, %rax
Roman Lebedev1574e4972018-07-12 17:00:11 +0000372; X64-NEXT: sete %al
373; X64-NEXT: retq
374 %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)
375 %tmp1 = icmp ult i64 %tmp0, 4294967296 ; 1U << 32
376 ret i1 %tmp1
377}
378
379define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {
380; X86-LABEL: add_ultcmp_i64_i16:
381; X86: # %bb.0:
382; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevde506632018-07-16 12:44:10 +0000383; X86-NEXT: movswl %ax, %ecx
384; X86-NEXT: xorl %ecx, %eax
385; X86-NEXT: sarl $31, %ecx
386; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
387; X86-NEXT: orl %eax, %ecx
388; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000389; X86-NEXT: retl
390;
391; X64-LABEL: add_ultcmp_i64_i16:
392; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000393; X64-NEXT: movswq %di, %rax
394; X64-NEXT: cmpq %rdi, %rax
395; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000396; X64-NEXT: retq
397 %tmp0 = add i64 %x, 32768 ; 1U << (16-1)
398 %tmp1 = icmp ult i64 %tmp0, 65536 ; 1U << 16
399 ret i1 %tmp1
400}
401
402define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {
403; X86-LABEL: add_ultcmp_i64_i8:
404; X86: # %bb.0:
405; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevde506632018-07-16 12:44:10 +0000406; X86-NEXT: movsbl %al, %ecx
407; X86-NEXT: xorl %ecx, %eax
408; X86-NEXT: sarl $31, %ecx
409; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
410; X86-NEXT: orl %eax, %ecx
411; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000412; X86-NEXT: retl
413;
414; X64-LABEL: add_ultcmp_i64_i8:
415; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000416; X64-NEXT: movsbq %dil, %rax
417; X64-NEXT: cmpq %rdi, %rax
418; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000419; X64-NEXT: retq
420 %tmp0 = add i64 %x, 128 ; 1U << (8-1)
421 %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8
422 ret i1 %tmp1
423}
Roman Lebedevb64e74f2018-07-13 16:14:37 +0000424
425; Negative tests
426; ---------------------------------------------------------------------------- ;
427
428; Adding not a constant
429define i1 @add_ultcmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
430; X86-LABEL: add_ultcmp_bad_i16_i8_add:
431; X86: # %bb.0:
432; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
433; X86-NEXT: addw {{[0-9]+}}(%esp), %ax
434; X86-NEXT: movzwl %ax, %eax
435; X86-NEXT: cmpl $256, %eax # imm = 0x100
436; X86-NEXT: setb %al
437; X86-NEXT: retl
438;
439; X64-LABEL: add_ultcmp_bad_i16_i8_add:
440; X64: # %bb.0:
441; X64-NEXT: addl %esi, %edi
442; X64-NEXT: movzwl %di, %eax
443; X64-NEXT: cmpl $256, %eax # imm = 0x100
444; X64-NEXT: setb %al
445; X64-NEXT: retq
446 %tmp0 = add i16 %x, %y
447 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
448 ret i1 %tmp1
449}
450
451; Comparing not with a constant
452define i1 @add_ultcmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
453; X86-LABEL: add_ultcmp_bad_i16_i8_cmp:
454; X86: # %bb.0:
455; X86-NEXT: movl $128, %eax
456; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
457; X86-NEXT: cmpw {{[0-9]+}}(%esp), %ax
458; X86-NEXT: setb %al
459; X86-NEXT: retl
460;
461; X64-LABEL: add_ultcmp_bad_i16_i8_cmp:
462; X64: # %bb.0:
463; X64-NEXT: subl $-128, %edi
464; X64-NEXT: cmpw %si, %di
465; X64-NEXT: setb %al
466; X64-NEXT: retq
467 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
468 %tmp1 = icmp ult i16 %tmp0, %y
469 ret i1 %tmp1
470}
471
472; Second constant is not larger than the first one
473define i1 @add_ultcmp_bad_i8_i16(i16 %x) nounwind {
474; X86-LABEL: add_ultcmp_bad_i8_i16:
475; X86: # %bb.0:
476; X86-NEXT: movw $128, %ax
477; X86-NEXT: addw {{[0-9]+}}(%esp), %ax
478; X86-NEXT: setb %al
479; X86-NEXT: retl
480;
481; X64-LABEL: add_ultcmp_bad_i8_i16:
482; X64: # %bb.0:
483; X64-NEXT: addw $128, %di
484; X64-NEXT: setb %al
485; X64-NEXT: retq
486 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
487 %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1)
488 ret i1 %tmp1
489}
490
491; First constant is not power of two
492define i1 @add_ultcmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
493; X86-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
494; X86: # %bb.0:
495; X86-NEXT: movl $192, %eax
496; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
497; X86-NEXT: movzwl %ax, %eax
498; X86-NEXT: cmpl $256, %eax # imm = 0x100
499; X86-NEXT: setb %al
500; X86-NEXT: retl
501;
502; X64-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
503; X64: # %bb.0:
504; X64-NEXT: addl $192, %edi
505; X64-NEXT: movzwl %di, %eax
506; X64-NEXT: cmpl $256, %eax # imm = 0x100
507; X64-NEXT: setb %al
508; X64-NEXT: retq
509 %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
510 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
511 ret i1 %tmp1
512}
513
514; Second constant is not power of two
515define i1 @add_ultcmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
516; X86-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
517; X86: # %bb.0:
518; X86-NEXT: movl $128, %eax
519; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
520; X86-NEXT: movzwl %ax, %eax
521; X86-NEXT: cmpl $768, %eax # imm = 0x300
522; X86-NEXT: setb %al
523; X86-NEXT: retl
524;
525; X64-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
526; X64: # %bb.0:
527; X64-NEXT: subl $-128, %edi
528; X64-NEXT: movzwl %di, %eax
529; X64-NEXT: cmpl $768, %eax # imm = 0x300
530; X64-NEXT: setb %al
531; X64-NEXT: retq
532 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
533 %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
534 ret i1 %tmp1
535}
536
537; Magic check fails, 64 << 1 != 256
538define i1 @add_ultcmp_bad_i16_i8_magic(i16 %x) nounwind {
539; X86-LABEL: add_ultcmp_bad_i16_i8_magic:
540; X86: # %bb.0:
541; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
542; X86-NEXT: addl $64, %eax
543; X86-NEXT: movzwl %ax, %eax
544; X86-NEXT: cmpl $256, %eax # imm = 0x100
545; X86-NEXT: setb %al
546; X86-NEXT: retl
547;
548; X64-LABEL: add_ultcmp_bad_i16_i8_magic:
549; X64: # %bb.0:
550; X64-NEXT: addl $64, %edi
551; X64-NEXT: movzwl %di, %eax
552; X64-NEXT: cmpl $256, %eax # imm = 0x100
553; X64-NEXT: setb %al
554; X64-NEXT: retq
555 %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
556 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
557 ret i1 %tmp1
558}
559
560; Bad 'destination type'
561define i1 @add_ultcmp_bad_i16_i4(i16 %x) nounwind {
562; X86-LABEL: add_ultcmp_bad_i16_i4:
563; X86: # %bb.0:
564; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
565; X86-NEXT: addl $8, %eax
566; X86-NEXT: movzwl %ax, %eax
567; X86-NEXT: cmpl $16, %eax
568; X86-NEXT: setb %al
569; X86-NEXT: retl
570;
571; X64-LABEL: add_ultcmp_bad_i16_i4:
572; X64: # %bb.0:
573; X64-NEXT: addl $8, %edi
574; X64-NEXT: movzwl %di, %eax
575; X64-NEXT: cmpl $16, %eax
576; X64-NEXT: setb %al
577; X64-NEXT: retq
578 %tmp0 = add i16 %x, 8 ; 1U << (4-1)
579 %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4
580 ret i1 %tmp1
581}
582
583; Bad storage type
584define i1 @add_ultcmp_bad_i24_i8(i24 %x) nounwind {
585; X86-LABEL: add_ultcmp_bad_i24_i8:
586; X86: # %bb.0:
587; X86-NEXT: movl $128, %eax
588; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
589; X86-NEXT: andl $16777215, %eax # imm = 0xFFFFFF
590; X86-NEXT: cmpl $256, %eax # imm = 0x100
591; X86-NEXT: setb %al
592; X86-NEXT: retl
593;
594; X64-LABEL: add_ultcmp_bad_i24_i8:
595; X64: # %bb.0:
596; X64-NEXT: subl $-128, %edi
597; X64-NEXT: andl $16777215, %edi # imm = 0xFFFFFF
598; X64-NEXT: cmpl $256, %edi # imm = 0x100
599; X64-NEXT: setb %al
600; X64-NEXT: retq
601 %tmp0 = add i24 %x, 128 ; 1U << (8-1)
602 %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8
603 ret i1 %tmp1
604}