xref: /llvm-project/llvm/test/Transforms/InstCombine/icmp-trunc.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S -data-layout="n8:16:32:64" | FileCheck %s --check-prefixes=CHECK,DL64
3; RUN: opt < %s -passes=instcombine -S -data-layout="n8"          | FileCheck %s --check-prefixes=CHECK,DL8
4
5declare void @use(i8)
6
7define i1 @ult_2(i32 %x) {
8; CHECK-LABEL: @ult_2(
9; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 254
10; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 0
11; CHECK-NEXT:    ret i1 [[R]]
12;
13  %t = trunc i32 %x to i8
14  %r = icmp ult i8 %t, 2
15  ret i1 %r
16}
17
18define <2 x i1> @ult_16_splat(<2 x i16> %x) {
19; CHECK-LABEL: @ult_16_splat(
20; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], splat (i16 2032)
21; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i16> [[TMP1]], zeroinitializer
22; CHECK-NEXT:    ret <2 x i1> [[R]]
23;
24  %t = trunc <2 x i16> %x to <2 x i11>
25  %r = icmp ult <2 x i11> %t, <i11 16, i11 16>
26  ret <2 x i1> %r
27}
28
29; negative test - need power-of-2 constant
30
31define i1 @ult_3(i32 %x) {
32; CHECK-LABEL: @ult_3(
33; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
34; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T]], 3
35; CHECK-NEXT:    ret i1 [[R]]
36;
37  %t = trunc i32 %x to i8
38  %r = icmp ult i8 %t, 3
39  ret i1 %r
40}
41
42; negative test - no extra use allowed
43
44define i1 @ult_2_use(i32 %x) {
45; CHECK-LABEL: @ult_2_use(
46; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
47; CHECK-NEXT:    call void @use(i8 [[T]])
48; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T]], 2
49; CHECK-NEXT:    ret i1 [[R]]
50;
51  %t = trunc i32 %x to i8
52  call void @use(i8 %t)
53  %r = icmp ult i8 %t, 2
54  ret i1 %r
55}
56
57@a = internal unnamed_addr constant [3 x i32] [i32 0, i32 0, i32 1], align 4
58
59define i1 @PR52260(i32 %x) {
60; CHECK-LABEL: @PR52260(
61; CHECK-NEXT:    ret i1 true
62;
63  %idxprom = sext i32 %x to i64
64  %idx = getelementptr inbounds [3 x i32], ptr @a, i64 0, i64 %idxprom
65  %t1 = load i32, ptr %idx, align 4
66  %conv1 = lshr i32 %t1, 1
67  %t2 = trunc i32 %conv1 to i8
68  %conv2 = and i8 %t2, 127
69  %tobool = icmp eq i8 %conv2, 0
70  ret i1 %tobool
71}
72
73define i1 @ult_192(i32 %x) {
74; CHECK-LABEL: @ult_192(
75; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 192
76; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 192
77; CHECK-NEXT:    ret i1 [[R]]
78;
79  %t = trunc i32 %x to i8
80  %r = icmp ult i8 %t, 192 ; 0b1100_0000
81  ret i1 %r
82}
83
84define <2 x i1> @ult_2044_splat(<2 x i16> %x) {
85; CHECK-LABEL: @ult_2044_splat(
86; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], splat (i16 2044)
87; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i16> [[TMP1]], splat (i16 2044)
88; CHECK-NEXT:    ret <2 x i1> [[R]]
89;
90  %t = trunc <2 x i16> %x to <2 x i11>
91  %r = icmp ult <2 x i11> %t, <i11 2044, i11 2044> ; 0b111_1111_1100
92  ret <2 x i1> %r
93}
94
95; negative test - need high-bit-mask constant
96
97define i1 @ult_96(i32 %x) {
98; CHECK-LABEL: @ult_96(
99; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
100; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T]], 96
101; CHECK-NEXT:    ret i1 [[R]]
102;
103  %t = trunc i32 %x to i8
104  %r = icmp ult i8 %t, 96  ; 0b0110_0000
105  ret i1 %r
106}
107
108; negative test - no extra use allowed
109
110define i1 @ult_192_use(i32 %x) {
111; CHECK-LABEL: @ult_192_use(
112; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
113; CHECK-NEXT:    call void @use(i8 [[T]])
114; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T]], -64
115; CHECK-NEXT:    ret i1 [[R]]
116;
117  %t = trunc i32 %x to i8
118  call void @use(i8 %t)
119  %r = icmp ult i8 %t, 192
120  ret i1 %r
121}
122
123define i1 @ugt_3(i32 %x) {
124; CHECK-LABEL: @ugt_3(
125; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 252
126; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 0
127; CHECK-NEXT:    ret i1 [[R]]
128;
129  %t = trunc i32 %x to i8
130  %r = icmp ugt i8 %t, 3
131  ret i1 %r
132}
133
134define <2 x i1> @ugt_7_splat(<2 x i16> %x) {
135; CHECK-LABEL: @ugt_7_splat(
136; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], splat (i16 2040)
137; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i16> [[TMP1]], zeroinitializer
138; CHECK-NEXT:    ret <2 x i1> [[R]]
139;
140  %t = trunc <2 x i16> %x to <2 x i11>
141  %r = icmp ugt <2 x i11> %t, <i11 7, i11 7>
142  ret <2 x i1> %r
143}
144
145; negative test - need low-bit-mask constant
146
147define i1 @ugt_4(i32 %x) {
148; CHECK-LABEL: @ugt_4(
149; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
150; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[T]], 4
151; CHECK-NEXT:    ret i1 [[R]]
152;
153  %t = trunc i32 %x to i8
154  %r = icmp ugt i8 %t, 4
155  ret i1 %r
156}
157
158; negative test - no extra use allowed
159
160define i1 @ugt_3_use(i32 %x) {
161; CHECK-LABEL: @ugt_3_use(
162; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
163; CHECK-NEXT:    call void @use(i8 [[T]])
164; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[T]], 3
165; CHECK-NEXT:    ret i1 [[R]]
166;
167  %t = trunc i32 %x to i8
168  call void @use(i8 %t)
169  %r = icmp ugt i8 %t, 3
170  ret i1 %r
171}
172
173define i1 @ugt_253(i32 %x) {
174; CHECK-LABEL: @ugt_253(
175; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 254
176; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 254
177; CHECK-NEXT:    ret i1 [[R]]
178;
179  %t = trunc i32 %x to i8
180  %r = icmp ugt i8 %t, 253
181  ret i1 %r
182}
183
184define <2 x i1> @ugt_2043_splat(<2 x i16> %x) {
185; CHECK-LABEL: @ugt_2043_splat(
186; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], splat (i16 2044)
187; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i16> [[TMP1]], splat (i16 2044)
188; CHECK-NEXT:    ret <2 x i1> [[R]]
189;
190  %t = trunc <2 x i16> %x to <2 x i11>
191  %r = icmp ugt <2 x i11> %t, <i11 2043, i11 2043> ; 0b111_1111_101
192  ret <2 x i1> %r
193}
194
195; negative test - need not-of-power-of-2 constant
196
197define i1 @ugt_252(i32 %x) {
198; CHECK-LABEL: @ugt_252(
199; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
200; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[T]], -4
201; CHECK-NEXT:    ret i1 [[R]]
202;
203  %t = trunc i32 %x to i8
204  %r = icmp ugt i8 %t, 252
205  ret i1 %r
206}
207
208; negative test - no extra use allowed
209
210define i1 @ugt_253_use(i32 %x) {
211; CHECK-LABEL: @ugt_253_use(
212; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
213; CHECK-NEXT:    call void @use(i8 [[T]])
214; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[T]], -3
215; CHECK-NEXT:    ret i1 [[R]]
216;
217  %t = trunc i32 %x to i8
218  call void @use(i8 %t)
219  %r = icmp ugt i8 %t, 253
220  ret i1 %r
221}
222
223define i1 @slt_0(i32 %x) {
224; CHECK-LABEL: @slt_0(
225; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 128
226; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 0
227; CHECK-NEXT:    ret i1 [[R]]
228;
229  %t = trunc i32 %x to i8
230  %r = icmp slt i8 %t, 0
231  ret i1 %r
232}
233
234define <2 x i1> @slt_0_splat(<2 x i16> %x) {
235; CHECK-LABEL: @slt_0_splat(
236; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], splat (i16 1024)
237; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i16> [[TMP1]], zeroinitializer
238; CHECK-NEXT:    ret <2 x i1> [[R]]
239;
240  %t = trunc <2 x i16> %x to <2 x i11>
241  %r = icmp slt <2 x i11> %t, zeroinitializer
242  ret <2 x i1> %r
243}
244
245define i1 @slt_1(i32 %x) {
246; CHECK-LABEL: @slt_1(
247; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
248; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[T]], 1
249; CHECK-NEXT:    ret i1 [[R]]
250;
251  %t = trunc i32 %x to i8
252  %r = icmp slt i8 %t, 1
253  ret i1 %r
254}
255
256define i1 @slt_0_use(i32 %x) {
257; CHECK-LABEL: @slt_0_use(
258; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
259; CHECK-NEXT:    call void @use(i8 [[T]])
260; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[T]], 0
261; CHECK-NEXT:    ret i1 [[R]]
262;
263  %t = trunc i32 %x to i8
264  call void @use(i8 %t)
265  %r = icmp slt i8 %t, 0
266  ret i1 %r
267}
268
269define i1 @sgt_n1(i32 %x) {
270; CHECK-LABEL: @sgt_n1(
271; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 128
272; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 0
273; CHECK-NEXT:    ret i1 [[R]]
274;
275  %t = trunc i32 %x to i8
276  %r = icmp sgt i8 %t, -1
277  ret i1 %r
278}
279
280define <2 x i1> @sgt_n1_splat(<2 x i16> %x) {
281; CHECK-LABEL: @sgt_n1_splat(
282; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], splat (i16 1024)
283; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i16> [[TMP1]], zeroinitializer
284; CHECK-NEXT:    ret <2 x i1> [[R]]
285;
286  %t = trunc <2 x i16> %x to <2 x i11>
287  %r = icmp sgt <2 x i11> %t, <i11 -1, i11 -1>
288  ret <2 x i1> %r
289}
290
291define i1 @sgt_0(i32 %x) {
292; CHECK-LABEL: @sgt_0(
293; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
294; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[T]], 0
295; CHECK-NEXT:    ret i1 [[R]]
296;
297  %t = trunc i32 %x to i8
298  %r = icmp sgt i8 %t, 0
299  ret i1 %r
300}
301
302define i1 @sgt_n1_use(i32 %x) {
303; CHECK-LABEL: @sgt_n1_use(
304; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
305; CHECK-NEXT:    call void @use(i8 [[T]])
306; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[T]], -1
307; CHECK-NEXT:    ret i1 [[R]]
308;
309  %t = trunc i32 %x to i8
310  call void @use(i8 %t)
311  %r = icmp sgt i8 %t, -1
312  ret i1 %r
313}
314
315define i1 @trunc_eq_i32_i8(i32 %x) {
316; DL64-LABEL: @trunc_eq_i32_i8(
317; DL64-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 255
318; DL64-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 42
319; DL64-NEXT:    ret i1 [[R]]
320;
321; DL8-LABEL: @trunc_eq_i32_i8(
322; DL8-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
323; DL8-NEXT:    [[R:%.*]] = icmp eq i8 [[T]], 42
324; DL8-NEXT:    ret i1 [[R]]
325;
326  %t = trunc i32 %x to i8
327  %r = icmp eq i8 %t, 42
328  ret i1 %r
329}
330
331define <2 x i1> @trunc_eq_v2i32_v2i8(<2 x i32> %x) {
332; CHECK-LABEL: @trunc_eq_v2i32_v2i8(
333; CHECK-NEXT:    [[T:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
334; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[T]], splat (i8 42)
335; CHECK-NEXT:    ret <2 x i1> [[R]]
336;
337  %t = trunc <2 x i32> %x to <2 x i8>
338  %r = icmp eq <2 x i8> %t, <i8 42, i8 42>
339  ret <2 x i1> %r
340}
341
342define i1 @trunc_ne_i64_i10(i64 %x) {
343; DL64-LABEL: @trunc_ne_i64_i10(
344; DL64-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 1023
345; DL64-NEXT:    [[R:%.*]] = icmp eq i64 [[TMP1]], 42
346; DL64-NEXT:    ret i1 [[R]]
347;
348; DL8-LABEL: @trunc_ne_i64_i10(
349; DL8-NEXT:    [[T:%.*]] = trunc i64 [[X:%.*]] to i10
350; DL8-NEXT:    [[R:%.*]] = icmp eq i10 [[T]], 42
351; DL8-NEXT:    ret i1 [[R]]
352;
353  %t = trunc i64 %x to i10
354  %r = icmp eq i10 %t, 42
355  ret i1 %r
356}
357
358define i1 @shl1_trunc_eq0(i32 %a) {
359; CHECK-LABEL: @shl1_trunc_eq0(
360; CHECK-NEXT:    [[R:%.*]] = icmp ugt i32 [[A:%.*]], 15
361; CHECK-NEXT:    ret i1 [[R]]
362;
363  %shl = shl i32 1, %a
364  %t = trunc i32 %shl to i16
365  %r = icmp eq i16 %t, 0
366  ret i1 %r
367}
368
369define <2 x i1> @shl1_trunc_ne0(<2 x i8> %a) {
370; CHECK-LABEL: @shl1_trunc_ne0(
371; CHECK-NEXT:    [[R:%.*]] = icmp ult <2 x i8> [[A:%.*]], splat (i8 5)
372; CHECK-NEXT:    ret <2 x i1> [[R]]
373;
374  %shl = shl <2 x i8> <i8 1, i8 poison>, %a
375  %t = trunc <2 x i8> %shl to <2 x i5>
376  %r = icmp ne <2 x i5> %t, zeroinitializer
377  ret <2 x i1> %r
378}
379
380define i1 @shl1_trunc_eq0_use1(i8 %a) {
381; CHECK-LABEL: @shl1_trunc_eq0_use1(
382; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 1, [[A:%.*]]
383; CHECK-NEXT:    call void @use(i8 [[SHL]])
384; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[A]], 5
385; CHECK-NEXT:    ret i1 [[R]]
386;
387  %shl = shl i8 1, %a
388  call void @use(i8 %shl)
389  %t = trunc i8 %shl to i6
390  %r = icmp eq i6 %t, 0
391  ret i1 %r
392}
393
394define i1 @shl1_trunc_ne0_use2(i37 %a) {
395; CHECK-LABEL: @shl1_trunc_ne0_use2(
396; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i37 1, [[A:%.*]]
397; CHECK-NEXT:    [[T:%.*]] = trunc i37 [[SHL]] to i8
398; CHECK-NEXT:    call void @use(i8 [[T]])
399; CHECK-NEXT:    [[R:%.*]] = icmp ult i37 [[A]], 8
400; CHECK-NEXT:    ret i1 [[R]]
401;
402  %shl = shl i37 1, %a
403  %t = trunc i37 %shl to i8
404  call void @use(i8 %t)
405  %r = icmp ne i8 %t, 0
406  ret i1 %r
407}
408
409; TODO: A > 4
410
411define i1 @shl2_trunc_eq0(i9 %a) {
412; CHECK-LABEL: @shl2_trunc_eq0(
413; CHECK-NEXT:    [[SHL:%.*]] = shl i9 2, [[A:%.*]]
414; CHECK-NEXT:    [[T:%.*]] = trunc i9 [[SHL]] to i6
415; CHECK-NEXT:    [[R:%.*]] = icmp eq i6 [[T]], 0
416; CHECK-NEXT:    ret i1 [[R]]
417;
418  %shl = shl i9 2, %a
419  %t = trunc i9 %shl to i6
420  %r = icmp eq i6 %t, 0
421  ret i1 %r
422}
423
424define i1 @shl2_trunc_ne0(i9 %a) {
425; CHECK-LABEL: @shl2_trunc_ne0(
426; CHECK-NEXT:    [[SHL:%.*]] = shl i9 2, [[A:%.*]]
427; CHECK-NEXT:    [[T:%.*]] = trunc i9 [[SHL]] to i6
428; CHECK-NEXT:    [[R:%.*]] = icmp ne i6 [[T]], 0
429; CHECK-NEXT:    ret i1 [[R]]
430;
431  %shl = shl i9 2, %a
432  %t = trunc i9 %shl to i6
433  %r = icmp ne i6 %t, 0
434  ret i1 %r
435}
436
437define i1 @shl3_trunc_eq0(i9 %a) {
438; CHECK-LABEL: @shl3_trunc_eq0(
439; CHECK-NEXT:    [[SHL:%.*]] = shl i9 3, [[A:%.*]]
440; CHECK-NEXT:    [[T:%.*]] = trunc i9 [[SHL]] to i6
441; CHECK-NEXT:    [[R:%.*]] = icmp eq i6 [[T]], 0
442; CHECK-NEXT:    ret i1 [[R]]
443;
444  %shl = shl i9 3, %a
445  %t = trunc i9 %shl to i6
446  %r = icmp eq i6 %t, 0
447  ret i1 %r
448}
449
450define <2 x i1> @shl4_trunc_ne0(<2 x i8> %a) {
451; CHECK-LABEL: @shl4_trunc_ne0(
452; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i8> <i8 4, i8 poison>, [[A:%.*]]
453; CHECK-NEXT:    [[T:%.*]] = trunc <2 x i8> [[SHL]] to <2 x i5>
454; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i5> [[T]], zeroinitializer
455; CHECK-NEXT:    ret <2 x i1> [[R]]
456;
457  %shl = shl <2 x i8> <i8 4, i8 poison>, %a
458  %t = trunc <2 x i8> %shl to <2 x i5>
459  %r = icmp ne <2 x i5> %t, zeroinitializer
460  ret <2 x i1> %r
461}
462
463
464; TODO: A < 5
465
466define i1 @shl1_trunc_sgt0(i9 %a) {
467; CHECK-LABEL: @shl1_trunc_sgt0(
468; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i9 1, [[A:%.*]]
469; CHECK-NEXT:    [[T:%.*]] = trunc i9 [[SHL]] to i6
470; CHECK-NEXT:    [[R:%.*]] = icmp sgt i6 [[T]], 0
471; CHECK-NEXT:    ret i1 [[R]]
472;
473  %shl = shl i9 1, %a
474  %t = trunc i9 %shl to i6
475  %r = icmp sgt i6 %t, 0
476  ret i1 %r
477}
478
479define i1 @shl1_trunc_eq1(i64 %a) {
480; CHECK-LABEL: @shl1_trunc_eq1(
481; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i64 1, [[A:%.*]]
482; CHECK-NEXT:    [[T:%.*]] = trunc i64 [[SHL]] to i8
483; CHECK-NEXT:    call void @use(i8 [[T]])
484; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[A]], 0
485; CHECK-NEXT:    ret i1 [[R]]
486;
487  %shl = shl i64 1, %a
488  %t = trunc i64 %shl to i8
489  call void @use(i8 %t)
490  %r = icmp eq i8 %t, 1
491  ret i1 %r
492}
493
494define i1 @shl1_trunc_ne32(i8 %a) {
495; CHECK-LABEL: @shl1_trunc_ne32(
496; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 1, [[A:%.*]]
497; CHECK-NEXT:    call void @use(i8 [[SHL]])
498; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[A]], 5
499; CHECK-NEXT:    ret i1 [[R]]
500;
501  %shl = shl i8 1, %a
502  call void @use(i8 %shl)
503  %t = trunc i8 %shl to i6
504  %r = icmp ne i6 %t, 32
505  ret i1 %r
506}
507
508define i1 @shl2_trunc_eq8_i32(i32 %a) {
509; DL64-LABEL: @shl2_trunc_eq8_i32(
510; DL64-NEXT:    [[SHL:%.*]] = shl i32 2, [[A:%.*]]
511; DL64-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], 65534
512; DL64-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 8
513; DL64-NEXT:    ret i1 [[R]]
514;
515; DL8-LABEL: @shl2_trunc_eq8_i32(
516; DL8-NEXT:    [[SHL:%.*]] = shl i32 2, [[A:%.*]]
517; DL8-NEXT:    [[T:%.*]] = trunc i32 [[SHL]] to i16
518; DL8-NEXT:    [[R:%.*]] = icmp eq i16 [[T]], 8
519; DL8-NEXT:    ret i1 [[R]]
520;
521  %shl = shl i32 2, %a
522  %t = trunc i32 %shl to i16
523  %r = icmp eq i16 %t, 8
524  ret i1 %r
525}
526
527define i1 @shl2_trunc_ne8_i32(i32 %a) {
528; DL64-LABEL: @shl2_trunc_ne8_i32(
529; DL64-NEXT:    [[SHL:%.*]] = shl i32 2, [[A:%.*]]
530; DL64-NEXT:    [[TMP1:%.*]] = and i32 [[SHL]], 65534
531; DL64-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 8
532; DL64-NEXT:    ret i1 [[R]]
533;
534; DL8-LABEL: @shl2_trunc_ne8_i32(
535; DL8-NEXT:    [[SHL:%.*]] = shl i32 2, [[A:%.*]]
536; DL8-NEXT:    [[T:%.*]] = trunc i32 [[SHL]] to i16
537; DL8-NEXT:    [[R:%.*]] = icmp ne i16 [[T]], 8
538; DL8-NEXT:    ret i1 [[R]]
539;
540  %shl = shl i32 2, %a
541  %t = trunc i32 %shl to i16
542  %r = icmp ne i16 %t, 8
543  ret i1 %r
544}
545
546define i1 @shl1_trunc_sgt4(i32 %a) {
547; CHECK-LABEL: @shl1_trunc_sgt4(
548; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 1, [[A:%.*]]
549; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[SHL]] to i16
550; CHECK-NEXT:    [[R:%.*]] = icmp sgt i16 [[T]], 4
551; CHECK-NEXT:    ret i1 [[R]]
552;
553  %shl = shl i32 1, %a
554  %t = trunc i32 %shl to i16
555  %r = icmp sgt i16 %t, 4
556  ret i1 %r
557}
558
559define i1 @eq_nuw(i32 %x) {
560; DL64-LABEL: @eq_nuw(
561; DL64-NEXT:    [[R:%.*]] = icmp eq i32 [[X:%.*]], 123
562; DL64-NEXT:    ret i1 [[R]]
563;
564; DL8-LABEL: @eq_nuw(
565; DL8-NEXT:    [[T:%.*]] = trunc nuw i32 [[X:%.*]] to i8
566; DL8-NEXT:    [[R:%.*]] = icmp eq i8 [[T]], 123
567; DL8-NEXT:    ret i1 [[R]]
568;
569  %t = trunc nuw i32 %x to i8
570  %r = icmp eq i8 %t, 123
571  ret i1 %r
572}
573
574define i1 @ult_nuw(i32 %x) {
575; DL64-LABEL: @ult_nuw(
576; DL64-NEXT:    [[R:%.*]] = icmp ult i32 [[X:%.*]], 45
577; DL64-NEXT:    ret i1 [[R]]
578;
579; DL8-LABEL: @ult_nuw(
580; DL8-NEXT:    [[T:%.*]] = trunc nuw i32 [[X:%.*]] to i8
581; DL8-NEXT:    [[R:%.*]] = icmp ult i8 [[T]], 45
582; DL8-NEXT:    ret i1 [[R]]
583;
584  %t = trunc nuw i32 %x to i8
585  %r = icmp ult i8 %t, 45
586  ret i1 %r
587}
588
589define i1 @ule_nuw(i32 %x) {
590; DL64-LABEL: @ule_nuw(
591; DL64-NEXT:    [[T:%.*]] = trunc nuw i32 [[X:%.*]] to i8
592; DL64-NEXT:    [[R:%.*]] = icmp ult i32 [[X]], 46
593; DL64-NEXT:    call void @use(i8 [[T]])
594; DL64-NEXT:    ret i1 [[R]]
595;
596; DL8-LABEL: @ule_nuw(
597; DL8-NEXT:    [[T:%.*]] = trunc nuw i32 [[X:%.*]] to i8
598; DL8-NEXT:    [[R:%.*]] = icmp ult i8 [[T]], 46
599; DL8-NEXT:    call void @use(i8 [[T]])
600; DL8-NEXT:    ret i1 [[R]]
601;
602  %t = trunc nuw i32 %x to i8
603  %r = icmp ule i8 %t, 45
604  call void @use(i8 %t)
605  ret i1 %r
606}
607
608define i1 @ugt_nuw(i32 %x) {
609; DL64-LABEL: @ugt_nuw(
610; DL64-NEXT:    [[R:%.*]] = icmp ugt i32 [[X:%.*]], 12
611; DL64-NEXT:    ret i1 [[R]]
612;
613; DL8-LABEL: @ugt_nuw(
614; DL8-NEXT:    [[T:%.*]] = trunc nuw i32 [[X:%.*]] to i8
615; DL8-NEXT:    [[R:%.*]] = icmp ugt i8 [[T]], 12
616; DL8-NEXT:    ret i1 [[R]]
617;
618  %t = trunc nuw i32 %x to i8
619  %r = icmp ugt i8 %t, 12
620  ret i1 %r
621}
622
623define i1 @uge_nuw(i32 %x) {
624; DL64-LABEL: @uge_nuw(
625; DL64-NEXT:    [[T:%.*]] = trunc nuw i32 [[X:%.*]] to i8
626; DL64-NEXT:    [[R:%.*]] = icmp ugt i32 [[X]], 98
627; DL64-NEXT:    call void @use(i8 [[T]])
628; DL64-NEXT:    ret i1 [[R]]
629;
630; DL8-LABEL: @uge_nuw(
631; DL8-NEXT:    [[T:%.*]] = trunc nuw i32 [[X:%.*]] to i8
632; DL8-NEXT:    [[R:%.*]] = icmp ugt i8 [[T]], 98
633; DL8-NEXT:    call void @use(i8 [[T]])
634; DL8-NEXT:    ret i1 [[R]]
635;
636  %t = trunc nuw i32 %x to i8
637  %r = icmp uge i8 %t, 99
638  call void @use(i8 %t)
639  ret i1 %r
640}
641
642define i1 @uge_nuw_i48(i48 %x) {
643; CHECK-LABEL: @uge_nuw_i48(
644; CHECK-NEXT:    [[T:%.*]] = trunc nuw i48 [[X:%.*]] to i8
645; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[T]], 98
646; CHECK-NEXT:    call void @use(i8 [[T]])
647; CHECK-NEXT:    ret i1 [[R]]
648;
649  %t = trunc nuw i48 %x to i8
650  %r = icmp uge i8 %t, 99
651  call void @use(i8 %t)
652  ret i1 %r
653}
654
655define i1 @sgt_nuw_fail(i32 %x) {
656; CHECK-LABEL: @sgt_nuw_fail(
657; CHECK-NEXT:    [[T:%.*]] = trunc nuw i32 [[X:%.*]] to i8
658; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[T]], 12
659; CHECK-NEXT:    ret i1 [[R]]
660;
661  %t = trunc nuw i32 %x to i8
662  %r = icmp sgt i8 %t, 12
663  ret i1 %r
664}
665
666define i1 @ne_nsw(i32 %x) {
667; DL64-LABEL: @ne_nsw(
668; DL64-NEXT:    [[R:%.*]] = icmp ne i32 [[X:%.*]], -123
669; DL64-NEXT:    ret i1 [[R]]
670;
671; DL8-LABEL: @ne_nsw(
672; DL8-NEXT:    [[T:%.*]] = trunc nsw i32 [[X:%.*]] to i8
673; DL8-NEXT:    [[R:%.*]] = icmp ne i8 [[T]], -123
674; DL8-NEXT:    ret i1 [[R]]
675;
676  %t = trunc nsw i32 %x to i8
677  %r = icmp ne i8 %t, -123
678  ret i1 %r
679}
680
681define i1 @slt_nsw(i32 %x) {
682; DL64-LABEL: @slt_nsw(
683; DL64-NEXT:    [[R:%.*]] = icmp slt i32 [[X:%.*]], 45
684; DL64-NEXT:    ret i1 [[R]]
685;
686; DL8-LABEL: @slt_nsw(
687; DL8-NEXT:    [[T:%.*]] = trunc nsw i32 [[X:%.*]] to i8
688; DL8-NEXT:    [[R:%.*]] = icmp slt i8 [[T]], 45
689; DL8-NEXT:    ret i1 [[R]]
690;
691  %t = trunc nsw i32 %x to i8
692  %r = icmp slt i8 %t, 45
693  ret i1 %r
694}
695
696define i1 @sle_nsw(i16 %x) {
697; DL64-LABEL: @sle_nsw(
698; DL64-NEXT:    [[T:%.*]] = trunc nsw i16 [[X:%.*]] to i8
699; DL64-NEXT:    [[R:%.*]] = icmp slt i16 [[X]], 46
700; DL64-NEXT:    call void @use(i8 [[T]])
701; DL64-NEXT:    ret i1 [[R]]
702;
703; DL8-LABEL: @sle_nsw(
704; DL8-NEXT:    [[T:%.*]] = trunc nsw i16 [[X:%.*]] to i8
705; DL8-NEXT:    [[R:%.*]] = icmp slt i8 [[T]], 46
706; DL8-NEXT:    call void @use(i8 [[T]])
707; DL8-NEXT:    ret i1 [[R]]
708;
709  %t = trunc nsw i16 %x to i8
710  %r = icmp sle i8 %t, 45
711  call void @use(i8 %t)
712  ret i1 %r
713}
714
715define i1 @sgt_nsw(i32 %x) {
716; DL64-LABEL: @sgt_nsw(
717; DL64-NEXT:    [[R:%.*]] = icmp sgt i32 [[X:%.*]], -12
718; DL64-NEXT:    ret i1 [[R]]
719;
720; DL8-LABEL: @sgt_nsw(
721; DL8-NEXT:    [[T:%.*]] = trunc nsw i32 [[X:%.*]] to i8
722; DL8-NEXT:    [[R:%.*]] = icmp sgt i8 [[T]], -12
723; DL8-NEXT:    ret i1 [[R]]
724;
725  %t = trunc nsw i32 %x to i8
726  %r = icmp sgt i8 %t, -12
727  ret i1 %r
728}
729
730define i1 @sge_nsw(i64 %x) {
731; DL64-LABEL: @sge_nsw(
732; DL64-NEXT:    [[T:%.*]] = trunc nsw i64 [[X:%.*]] to i8
733; DL64-NEXT:    [[R:%.*]] = icmp sgt i64 [[X]], 98
734; DL64-NEXT:    call void @use(i8 [[T]])
735; DL64-NEXT:    ret i1 [[R]]
736;
737; DL8-LABEL: @sge_nsw(
738; DL8-NEXT:    [[T:%.*]] = trunc nsw i64 [[X:%.*]] to i8
739; DL8-NEXT:    [[R:%.*]] = icmp sgt i8 [[T]], 98
740; DL8-NEXT:    call void @use(i8 [[T]])
741; DL8-NEXT:    ret i1 [[R]]
742;
743  %t = trunc nsw i64 %x to i8
744  %r = icmp sge i8 %t, 99
745  call void @use(i8 %t)
746  ret i1 %r
747}
748
749
750
751define i1 @sge_nsw_i48(i48 %x) {
752; CHECK-LABEL: @sge_nsw_i48(
753; CHECK-NEXT:    [[T:%.*]] = trunc nsw i48 [[X:%.*]] to i8
754; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[T]], 98
755; CHECK-NEXT:    call void @use(i8 [[T]])
756; CHECK-NEXT:    ret i1 [[R]]
757;
758  %t = trunc nsw i48 %x to i8
759  %r = icmp sge i8 %t, 99
760  call void @use(i8 %t)
761  ret i1 %r
762}
763
764
765define <2 x i1> @uge_nsw(<2 x i32> %x) {
766; CHECK-LABEL: @uge_nsw(
767; CHECK-NEXT:    [[T:%.*]] = trunc nsw <2 x i32> [[X:%.*]] to <2 x i8>
768; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[T]], splat (i8 -46)
769; CHECK-NEXT:    ret <2 x i1> [[R]]
770;
771  %t = trunc nsw <2 x i32> %x to <2 x i8>
772  %r = icmp uge <2 x i8> %t, <i8 -45, i8 -45>
773  ret <2 x i1> %r
774}
775
776
777define <2 x i1> @uge_nsw_non_splat(<2 x i32> %x) {
778; CHECK-LABEL: @uge_nsw_non_splat(
779; CHECK-NEXT:    [[T:%.*]] = trunc nsw <2 x i32> [[X:%.*]] to <2 x i8>
780; CHECK-NEXT:    [[R:%.*]] = icmp ugt <2 x i8> [[T]], <i8 44, i8 45>
781; CHECK-NEXT:    ret <2 x i1> [[R]]
782;
783  %t = trunc nsw <2 x i32> %x to <2 x i8>
784  %r = icmp uge <2 x i8> %t, <i8 45, i8 46>
785  ret <2 x i1> %r
786}
787
788