blob: c455f3c4c8aa1b89485b3016b8ddbb37eb348760 [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
Roman Lebedev75c29612018-08-31 08:52:03 +000014; add + icmp uge/ugt
Roman Lebedev5317e882018-07-18 16:19:06 +000015; add + icmp ult/ule
Roman Lebedev1574e4972018-07-12 17:00:11 +000016; 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:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000163; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
164; X86-NEXT: movsbl %al, %ecx
165; X86-NEXT: cmpw %ax, %cx
166; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000167; X86-NEXT: retl
168;
169; X64-LABEL: add_ugecmp_i16_i8:
170; X64: # %bb.0:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000171; X64-NEXT: movsbl %dil, %eax
172; X64-NEXT: cmpw %di, %ax
173; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000174; X64-NEXT: retq
175 %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
176 %tmp1 = icmp uge i16 %tmp0, -256 ; ~0U << 8
177 ret i1 %tmp1
178}
179
180define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {
181; X86-LABEL: add_ugecmp_i32_i16:
182; X86: # %bb.0:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000183; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
184; X86-NEXT: movswl %ax, %ecx
185; X86-NEXT: cmpl %eax, %ecx
186; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000187; X86-NEXT: retl
188;
189; X64-LABEL: add_ugecmp_i32_i16:
190; X64: # %bb.0:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000191; X64-NEXT: movswl %di, %eax
192; X64-NEXT: cmpl %edi, %eax
193; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000194; X64-NEXT: retq
195 %tmp0 = add i32 %x, -32768 ; ~0U << (16-1)
196 %tmp1 = icmp uge i32 %tmp0, -65536 ; ~0U << 16
197 ret i1 %tmp1
198}
199
200define i1 @add_ugecmp_i32_i8(i32 %x) nounwind {
201; X86-LABEL: add_ugecmp_i32_i8:
202; X86: # %bb.0:
203; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevd7a62442018-09-02 13:56:22 +0000204; X86-NEXT: movsbl %al, %ecx
205; X86-NEXT: cmpl %eax, %ecx
206; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000207; X86-NEXT: retl
208;
209; X64-LABEL: add_ugecmp_i32_i8:
210; X64: # %bb.0:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000211; X64-NEXT: movsbl %dil, %eax
212; X64-NEXT: cmpl %edi, %eax
213; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000214; X64-NEXT: retq
215 %tmp0 = add i32 %x, -128 ; ~0U << (8-1)
216 %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8
217 ret i1 %tmp1
218}
219
220define i1 @add_ugecmp_i64_i32(i64 %x) nounwind {
221; X86-LABEL: add_ugecmp_i64_i32:
222; X86: # %bb.0:
223; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevd7a62442018-09-02 13:56:22 +0000224; X86-NEXT: sarl $31, %eax
225; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
Roman Lebedev1574e4972018-07-12 17:00:11 +0000226; X86-NEXT: sete %al
227; X86-NEXT: retl
228;
229; X64-LABEL: add_ugecmp_i64_i32:
230; X64: # %bb.0:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000231; X64-NEXT: movslq %edi, %rax
232; X64-NEXT: cmpq %rdi, %rax
233; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000234; X64-NEXT: retq
235 %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1)
236 %tmp1 = icmp uge i64 %tmp0, -4294967296 ; ~0U << 32
237 ret i1 %tmp1
238}
239
240define i1 @add_ugecmp_i64_i16(i64 %x) nounwind {
241; X86-LABEL: add_ugecmp_i64_i16:
242; X86: # %bb.0:
243; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevd7a62442018-09-02 13:56:22 +0000244; X86-NEXT: movswl %ax, %ecx
245; X86-NEXT: xorl %ecx, %eax
246; X86-NEXT: sarl $31, %ecx
247; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
248; X86-NEXT: orl %eax, %ecx
249; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000250; X86-NEXT: retl
251;
252; X64-LABEL: add_ugecmp_i64_i16:
253; X64: # %bb.0:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000254; X64-NEXT: movswq %di, %rax
255; X64-NEXT: cmpq %rdi, %rax
256; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000257; X64-NEXT: retq
258 %tmp0 = add i64 %x, -32768 ; ~0U << (16-1)
259 %tmp1 = icmp uge i64 %tmp0, -65536 ; ~0U << 16
260 ret i1 %tmp1
261}
262
263define i1 @add_ugecmp_i64_i8(i64 %x) nounwind {
264; X86-LABEL: add_ugecmp_i64_i8:
265; X86: # %bb.0:
266; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevd7a62442018-09-02 13:56:22 +0000267; X86-NEXT: movsbl %al, %ecx
268; X86-NEXT: xorl %ecx, %eax
269; X86-NEXT: sarl $31, %ecx
270; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
271; X86-NEXT: orl %eax, %ecx
272; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000273; X86-NEXT: retl
274;
275; X64-LABEL: add_ugecmp_i64_i8:
276; X64: # %bb.0:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000277; X64-NEXT: movsbq %dil, %rax
278; X64-NEXT: cmpq %rdi, %rax
279; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000280; X64-NEXT: retq
281 %tmp0 = add i64 %x, -128 ; ~0U << (8-1)
282 %tmp1 = icmp uge i64 %tmp0, -256 ; ~0U << 8
283 ret i1 %tmp1
284}
285
Roman Lebedev75c29612018-08-31 08:52:03 +0000286; Slightly more canonical variant
287define i1 @add_ugtcmp_i16_i8(i16 %x) nounwind {
288; X86-LABEL: add_ugtcmp_i16_i8:
289; X86: # %bb.0:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000290; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
291; X86-NEXT: movsbl %al, %ecx
292; X86-NEXT: cmpw %ax, %cx
293; X86-NEXT: sete %al
Roman Lebedev75c29612018-08-31 08:52:03 +0000294; X86-NEXT: retl
295;
296; X64-LABEL: add_ugtcmp_i16_i8:
297; X64: # %bb.0:
Roman Lebedevd7a62442018-09-02 13:56:22 +0000298; X64-NEXT: movsbl %dil, %eax
299; X64-NEXT: cmpw %di, %ax
300; X64-NEXT: sete %al
Roman Lebedev75c29612018-08-31 08:52:03 +0000301; X64-NEXT: retq
302 %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
303 %tmp1 = icmp ugt i16 %tmp0, -257 ; ~0U << 8 - 1
304 ret i1 %tmp1
305}
306
Roman Lebedev1574e4972018-07-12 17:00:11 +0000307; ---------------------------------------------------------------------------- ;
308; add + icmp ult
309; ---------------------------------------------------------------------------- ;
310
311define i1 @add_ultcmp_i16_i8(i16 %x) nounwind {
312; X86-LABEL: add_ultcmp_i16_i8:
313; X86: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000314; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
315; X86-NEXT: movsbl %al, %ecx
316; X86-NEXT: cmpw %ax, %cx
317; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000318; X86-NEXT: retl
319;
320; X64-LABEL: add_ultcmp_i16_i8:
321; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000322; X64-NEXT: movsbl %dil, %eax
323; X64-NEXT: cmpw %di, %ax
324; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000325; X64-NEXT: retq
326 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
327 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
328 ret i1 %tmp1
329}
330
331define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {
332; X86-LABEL: add_ultcmp_i32_i16:
333; X86: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000334; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
335; X86-NEXT: movswl %ax, %ecx
336; X86-NEXT: cmpl %eax, %ecx
337; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000338; X86-NEXT: retl
339;
340; X64-LABEL: add_ultcmp_i32_i16:
341; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000342; X64-NEXT: movswl %di, %eax
343; X64-NEXT: cmpl %edi, %eax
344; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000345; X64-NEXT: retq
346 %tmp0 = add i32 %x, 32768 ; 1U << (16-1)
347 %tmp1 = icmp ult i32 %tmp0, 65536 ; 1U << 16
348 ret i1 %tmp1
349}
350
351define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {
352; X86-LABEL: add_ultcmp_i32_i8:
353; X86: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000354; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
355; X86-NEXT: movsbl %al, %ecx
356; X86-NEXT: cmpl %eax, %ecx
357; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000358; X86-NEXT: retl
359;
360; X64-LABEL: add_ultcmp_i32_i8:
361; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000362; X64-NEXT: movsbl %dil, %eax
363; X64-NEXT: cmpl %edi, %eax
364; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000365; X64-NEXT: retq
366 %tmp0 = add i32 %x, 128 ; 1U << (8-1)
367 %tmp1 = icmp ult i32 %tmp0, 256 ; 1U << 8
368 ret i1 %tmp1
369}
370
371define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {
372; X86-LABEL: add_ultcmp_i64_i32:
373; X86: # %bb.0:
374; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevde506632018-07-16 12:44:10 +0000375; X86-NEXT: sarl $31, %eax
376; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
Roman Lebedev1574e4972018-07-12 17:00:11 +0000377; X86-NEXT: sete %al
378; X86-NEXT: retl
379;
380; X64-LABEL: add_ultcmp_i64_i32:
381; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000382; X64-NEXT: movslq %edi, %rax
383; X64-NEXT: cmpq %rdi, %rax
Roman Lebedev1574e4972018-07-12 17:00:11 +0000384; X64-NEXT: sete %al
385; X64-NEXT: retq
386 %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)
387 %tmp1 = icmp ult i64 %tmp0, 4294967296 ; 1U << 32
388 ret i1 %tmp1
389}
390
391define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {
392; X86-LABEL: add_ultcmp_i64_i16:
393; X86: # %bb.0:
394; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevde506632018-07-16 12:44:10 +0000395; X86-NEXT: movswl %ax, %ecx
396; X86-NEXT: xorl %ecx, %eax
397; X86-NEXT: sarl $31, %ecx
398; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
399; X86-NEXT: orl %eax, %ecx
400; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000401; X86-NEXT: retl
402;
403; X64-LABEL: add_ultcmp_i64_i16:
404; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000405; X64-NEXT: movswq %di, %rax
406; X64-NEXT: cmpq %rdi, %rax
407; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000408; X64-NEXT: retq
409 %tmp0 = add i64 %x, 32768 ; 1U << (16-1)
410 %tmp1 = icmp ult i64 %tmp0, 65536 ; 1U << 16
411 ret i1 %tmp1
412}
413
414define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {
415; X86-LABEL: add_ultcmp_i64_i8:
416; X86: # %bb.0:
417; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
Roman Lebedevde506632018-07-16 12:44:10 +0000418; X86-NEXT: movsbl %al, %ecx
419; X86-NEXT: xorl %ecx, %eax
420; X86-NEXT: sarl $31, %ecx
421; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
422; X86-NEXT: orl %eax, %ecx
423; X86-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000424; X86-NEXT: retl
425;
426; X64-LABEL: add_ultcmp_i64_i8:
427; X64: # %bb.0:
Roman Lebedevde506632018-07-16 12:44:10 +0000428; X64-NEXT: movsbq %dil, %rax
429; X64-NEXT: cmpq %rdi, %rax
430; X64-NEXT: sete %al
Roman Lebedev1574e4972018-07-12 17:00:11 +0000431; X64-NEXT: retq
432 %tmp0 = add i64 %x, 128 ; 1U << (8-1)
433 %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8
434 ret i1 %tmp1
435}
Roman Lebedevb64e74f2018-07-13 16:14:37 +0000436
Roman Lebedev5317e882018-07-18 16:19:06 +0000437; Slightly more canonical variant
438define i1 @add_ulecmp_i16_i8(i16 %x) nounwind {
439; X86-LABEL: add_ulecmp_i16_i8:
440; X86: # %bb.0:
441; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
442; X86-NEXT: movsbl %al, %ecx
443; X86-NEXT: cmpw %ax, %cx
444; X86-NEXT: sete %al
445; X86-NEXT: retl
446;
447; X64-LABEL: add_ulecmp_i16_i8:
448; X64: # %bb.0:
449; X64-NEXT: movsbl %dil, %eax
450; X64-NEXT: cmpw %di, %ax
451; X64-NEXT: sete %al
452; X64-NEXT: retq
453 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
454 %tmp1 = icmp ule i16 %tmp0, 255 ; (1U << 8) - 1
455 ret i1 %tmp1
456}
457
Roman Lebedevb64e74f2018-07-13 16:14:37 +0000458; Negative tests
459; ---------------------------------------------------------------------------- ;
460
461; Adding not a constant
462define i1 @add_ultcmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
463; X86-LABEL: add_ultcmp_bad_i16_i8_add:
464; X86: # %bb.0:
465; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
466; X86-NEXT: addw {{[0-9]+}}(%esp), %ax
467; X86-NEXT: movzwl %ax, %eax
468; X86-NEXT: cmpl $256, %eax # imm = 0x100
469; X86-NEXT: setb %al
470; X86-NEXT: retl
471;
472; X64-LABEL: add_ultcmp_bad_i16_i8_add:
473; X64: # %bb.0:
474; X64-NEXT: addl %esi, %edi
475; X64-NEXT: movzwl %di, %eax
476; X64-NEXT: cmpl $256, %eax # imm = 0x100
477; X64-NEXT: setb %al
478; X64-NEXT: retq
479 %tmp0 = add i16 %x, %y
480 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
481 ret i1 %tmp1
482}
483
484; Comparing not with a constant
485define i1 @add_ultcmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
486; X86-LABEL: add_ultcmp_bad_i16_i8_cmp:
487; X86: # %bb.0:
488; X86-NEXT: movl $128, %eax
489; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
490; X86-NEXT: cmpw {{[0-9]+}}(%esp), %ax
491; X86-NEXT: setb %al
492; X86-NEXT: retl
493;
494; X64-LABEL: add_ultcmp_bad_i16_i8_cmp:
495; X64: # %bb.0:
496; X64-NEXT: subl $-128, %edi
497; X64-NEXT: cmpw %si, %di
498; X64-NEXT: setb %al
499; X64-NEXT: retq
500 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
501 %tmp1 = icmp ult i16 %tmp0, %y
502 ret i1 %tmp1
503}
504
505; Second constant is not larger than the first one
506define i1 @add_ultcmp_bad_i8_i16(i16 %x) nounwind {
507; X86-LABEL: add_ultcmp_bad_i8_i16:
508; X86: # %bb.0:
509; X86-NEXT: movw $128, %ax
510; X86-NEXT: addw {{[0-9]+}}(%esp), %ax
511; X86-NEXT: setb %al
512; X86-NEXT: retl
513;
514; X64-LABEL: add_ultcmp_bad_i8_i16:
515; X64: # %bb.0:
516; X64-NEXT: addw $128, %di
517; X64-NEXT: setb %al
518; X64-NEXT: retq
519 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
520 %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1)
521 ret i1 %tmp1
522}
523
524; First constant is not power of two
525define i1 @add_ultcmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
526; X86-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
527; X86: # %bb.0:
528; X86-NEXT: movl $192, %eax
529; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
530; X86-NEXT: movzwl %ax, %eax
531; X86-NEXT: cmpl $256, %eax # imm = 0x100
532; X86-NEXT: setb %al
533; X86-NEXT: retl
534;
535; X64-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
536; X64: # %bb.0:
537; X64-NEXT: addl $192, %edi
538; X64-NEXT: movzwl %di, %eax
539; X64-NEXT: cmpl $256, %eax # imm = 0x100
540; X64-NEXT: setb %al
541; X64-NEXT: retq
542 %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
543 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
544 ret i1 %tmp1
545}
546
547; Second constant is not power of two
548define i1 @add_ultcmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
549; X86-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
550; X86: # %bb.0:
551; X86-NEXT: movl $128, %eax
552; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
553; X86-NEXT: movzwl %ax, %eax
554; X86-NEXT: cmpl $768, %eax # imm = 0x300
555; X86-NEXT: setb %al
556; X86-NEXT: retl
557;
558; X64-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
559; X64: # %bb.0:
560; X64-NEXT: subl $-128, %edi
561; X64-NEXT: movzwl %di, %eax
562; X64-NEXT: cmpl $768, %eax # imm = 0x300
563; X64-NEXT: setb %al
564; X64-NEXT: retq
565 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
566 %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
567 ret i1 %tmp1
568}
569
570; Magic check fails, 64 << 1 != 256
571define i1 @add_ultcmp_bad_i16_i8_magic(i16 %x) nounwind {
572; X86-LABEL: add_ultcmp_bad_i16_i8_magic:
573; X86: # %bb.0:
574; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
575; X86-NEXT: addl $64, %eax
576; X86-NEXT: movzwl %ax, %eax
577; X86-NEXT: cmpl $256, %eax # imm = 0x100
578; X86-NEXT: setb %al
579; X86-NEXT: retl
580;
581; X64-LABEL: add_ultcmp_bad_i16_i8_magic:
582; X64: # %bb.0:
583; X64-NEXT: addl $64, %edi
584; X64-NEXT: movzwl %di, %eax
585; X64-NEXT: cmpl $256, %eax # imm = 0x100
586; X64-NEXT: setb %al
587; X64-NEXT: retq
588 %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
589 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
590 ret i1 %tmp1
591}
592
593; Bad 'destination type'
594define i1 @add_ultcmp_bad_i16_i4(i16 %x) nounwind {
595; X86-LABEL: add_ultcmp_bad_i16_i4:
596; X86: # %bb.0:
597; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
598; X86-NEXT: addl $8, %eax
Craig Topper0ed892d2018-10-05 18:13:36 +0000599; X86-NEXT: cmpw $16, %ax
Roman Lebedevb64e74f2018-07-13 16:14:37 +0000600; X86-NEXT: setb %al
601; X86-NEXT: retl
602;
603; X64-LABEL: add_ultcmp_bad_i16_i4:
604; X64: # %bb.0:
605; X64-NEXT: addl $8, %edi
Craig Topper0ed892d2018-10-05 18:13:36 +0000606; X64-NEXT: cmpw $16, %di
Roman Lebedevb64e74f2018-07-13 16:14:37 +0000607; X64-NEXT: setb %al
608; X64-NEXT: retq
609 %tmp0 = add i16 %x, 8 ; 1U << (4-1)
610 %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4
611 ret i1 %tmp1
612}
613
614; Bad storage type
615define i1 @add_ultcmp_bad_i24_i8(i24 %x) nounwind {
616; X86-LABEL: add_ultcmp_bad_i24_i8:
617; X86: # %bb.0:
618; X86-NEXT: movl $128, %eax
619; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
620; X86-NEXT: andl $16777215, %eax # imm = 0xFFFFFF
621; X86-NEXT: cmpl $256, %eax # imm = 0x100
622; X86-NEXT: setb %al
623; X86-NEXT: retl
624;
625; X64-LABEL: add_ultcmp_bad_i24_i8:
626; X64: # %bb.0:
627; X64-NEXT: subl $-128, %edi
628; X64-NEXT: andl $16777215, %edi # imm = 0xFFFFFF
629; X64-NEXT: cmpl $256, %edi # imm = 0x100
630; X64-NEXT: setb %al
631; X64-NEXT: retq
632 %tmp0 = add i24 %x, 128 ; 1U << (8-1)
633 %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8
634 ret i1 %tmp1
635}
Roman Lebedev5317e882018-07-18 16:19:06 +0000636
637define i1 @add_ulecmp_bad_i16_i8(i16 %x) nounwind {
638; CHECK-LABEL: add_ulecmp_bad_i16_i8:
639; CHECK: # %bb.0:
640; CHECK-NEXT: movb $1, %al
641; CHECK-NEXT: ret{{[l|q]}}
642 %tmp0 = add i16 %x, 128 ; 1U << (8-1)
643 %tmp1 = icmp ule i16 %tmp0, -1 ; when we +1 it, it will wrap to 0
644 ret i1 %tmp1
645}