xref: /llvm-project/llvm/test/Transforms/InstCombine/eq-of-parts.ll (revision e477989a055f92f6ca63fc8f76929cde81d33e44)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4; Combine equality comparisons of adjacent extracted integers parts into
5; a comparison of a larger part. Start with some examples...
6
7declare void @use.i32(i32)
8declare void @use.i8(i8)
9declare void @use.i1(i1)
10
11define i1 @eq_10(i32 %x, i32 %y) {
12; CHECK-LABEL: @eq_10(
13; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
14; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i16
15; CHECK-NEXT:    [[C_10:%.*]] = icmp eq i16 [[TMP1]], [[TMP2]]
16; CHECK-NEXT:    ret i1 [[C_10]]
17;
18  %x.0 = trunc i32 %x to i8
19  %x.321 = lshr i32 %x, 8
20  %x.1 = trunc i32 %x.321 to i8
21  %y.0 = trunc i32 %y to i8
22  %y.321 = lshr i32 %y, 8
23  %y.1 = trunc i32 %y.321 to i8
24  %c.0 = icmp eq i8 %x.0, %y.0
25  %c.1 = icmp eq i8 %x.1, %y.1
26  %c.10 = and i1 %c.0, %c.1
27  ret i1 %c.10
28}
29
30define i1 @eq_210(i32 %x, i32 %y) {
31; CHECK-LABEL: @eq_210(
32; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i24
33; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i24
34; CHECK-NEXT:    [[C_210:%.*]] = icmp eq i24 [[TMP1]], [[TMP2]]
35; CHECK-NEXT:    ret i1 [[C_210]]
36;
37  %x.0 = trunc i32 %x to i8
38  %x.321 = lshr i32 %x, 8
39  %x.1 = trunc i32 %x.321 to i8
40  %x.32 = lshr i32 %x, 16
41  %x.2 = trunc i32 %x.32 to i8
42  %y.0 = trunc i32 %y to i8
43  %y.321 = lshr i32 %y, 8
44  %y.1 = trunc i32 %y.321 to i8
45  %y.32 = lshr i32 %y, 16
46  %y.2 = trunc i32 %y.32 to i8
47  %c.0 = icmp eq i8 %x.0, %y.0
48  %c.1 = icmp eq i8 %x.1, %y.1
49  %c.2 = icmp eq i8 %x.2, %y.2
50  %c.10 = and i1 %c.0, %c.1
51  %c.210 = and i1 %c.2, %c.10
52  ret i1 %c.210
53}
54
55define i1 @eq_3210(i32 %x, i32 %y) {
56; CHECK-LABEL: @eq_3210(
57; CHECK-NEXT:    [[C_3210:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
58; CHECK-NEXT:    ret i1 [[C_3210]]
59;
60  %x.0 = trunc i32 %x to i8
61  %x.321 = lshr i32 %x, 8
62  %x.1 = trunc i32 %x.321 to i8
63  %x.32 = lshr i32 %x, 16
64  %x.2 = trunc i32 %x.32 to i8
65  %x.3.ext = lshr i32 %x, 24
66  %x.3 = trunc i32 %x.3.ext to i8
67  %y.0 = trunc i32 %y to i8
68  %y.321 = lshr i32 %y, 8
69  %y.1 = trunc i32 %y.321 to i8
70  %y.32 = lshr i32 %y, 16
71  %y.2 = trunc i32 %y.32 to i8
72  %y.3.ext = lshr i32 %y, 24
73  %y.3 = trunc i32 %y.3.ext to i8
74  %c.0 = icmp eq i8 %x.0, %y.0
75  %c.1 = icmp eq i8 %x.1, %y.1
76  %c.2 = icmp eq i8 %x.2, %y.2
77  %c.3 = icmp eq i8 %x.3, %y.3
78  %c.10 = and i1 %c.0, %c.1
79  %c.210 = and i1 %c.2, %c.10
80  %c.3210 = and i1 %c.3, %c.210
81  ret i1 %c.3210
82}
83
84define i1 @eq_21(i32 %x, i32 %y) {
85; CHECK-LABEL: @eq_21(
86; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
87; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
88; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
89; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
90; CHECK-NEXT:    [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
91; CHECK-NEXT:    ret i1 [[C_210]]
92;
93  %x.321 = lshr i32 %x, 8
94  %x.1 = trunc i32 %x.321 to i8
95  %x.32 = lshr i32 %x, 16
96  %x.2 = trunc i32 %x.32 to i8
97  %y.321 = lshr i32 %y, 8
98  %y.1 = trunc i32 %y.321 to i8
99  %y.32 = lshr i32 %y, 16
100  %y.2 = trunc i32 %y.32 to i8
101  %c.1 = icmp eq i8 %x.1, %y.1
102  %c.2 = icmp eq i8 %x.2, %y.2
103  %c.210 = and i1 %c.2, %c.1
104  ret i1 %c.210
105}
106
107; Test commuted variants of eq_21.
108
109define i1 @eq_21_comm_and(i32 %x, i32 %y) {
110; CHECK-LABEL: @eq_21_comm_and(
111; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
112; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
113; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
114; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
115; CHECK-NEXT:    [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
116; CHECK-NEXT:    ret i1 [[C_210]]
117;
118  %x.321 = lshr i32 %x, 8
119  %x.1 = trunc i32 %x.321 to i8
120  %x.32 = lshr i32 %x, 16
121  %x.2 = trunc i32 %x.32 to i8
122  %y.321 = lshr i32 %y, 8
123  %y.1 = trunc i32 %y.321 to i8
124  %y.32 = lshr i32 %y, 16
125  %y.2 = trunc i32 %y.32 to i8
126  %c.1 = icmp eq i8 %x.1, %y.1
127  %c.2 = icmp eq i8 %x.2, %y.2
128  %c.210 = and i1 %c.1, %c.2
129  ret i1 %c.210
130}
131
132define i1 @eq_21_comm_eq(i32 %x, i32 %y) {
133; CHECK-LABEL: @eq_21_comm_eq(
134; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 8
135; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
136; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[X:%.*]], 8
137; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
138; CHECK-NEXT:    [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
139; CHECK-NEXT:    ret i1 [[C_210]]
140;
141  %x.321 = lshr i32 %x, 8
142  %x.1 = trunc i32 %x.321 to i8
143  %x.32 = lshr i32 %x, 16
144  %x.2 = trunc i32 %x.32 to i8
145  %y.321 = lshr i32 %y, 8
146  %y.1 = trunc i32 %y.321 to i8
147  %y.32 = lshr i32 %y, 16
148  %y.2 = trunc i32 %y.32 to i8
149  %c.1 = icmp eq i8 %x.1, %y.1
150  %c.2 = icmp eq i8 %y.2, %x.2
151  %c.210 = and i1 %c.2, %c.1
152  ret i1 %c.210
153}
154
155define i1 @eq_21_comm_eq2(i32 %x, i32 %y) {
156; CHECK-LABEL: @eq_21_comm_eq2(
157; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
158; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
159; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
160; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
161; CHECK-NEXT:    [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
162; CHECK-NEXT:    ret i1 [[C_210]]
163;
164  %x.321 = lshr i32 %x, 8
165  %x.1 = trunc i32 %x.321 to i8
166  %x.32 = lshr i32 %x, 16
167  %x.2 = trunc i32 %x.32 to i8
168  %y.321 = lshr i32 %y, 8
169  %y.1 = trunc i32 %y.321 to i8
170  %y.32 = lshr i32 %y, 16
171  %y.2 = trunc i32 %y.32 to i8
172  %c.1 = icmp eq i8 %y.1, %x.1
173  %c.2 = icmp eq i8 %x.2, %y.2
174  %c.210 = and i1 %c.2, %c.1
175  ret i1 %c.210
176}
177
178; Test vector variant.
179
180define <2x i1> @eq_21_vector(<2x i32> %x, <2x i32> %y) {
181; CHECK-LABEL: @eq_21_vector(
182; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 8)
183; CHECK-NEXT:    [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
184; CHECK-NEXT:    [[TMP3:%.*]] = lshr <2 x i32> [[Y:%.*]], splat (i32 8)
185; CHECK-NEXT:    [[TMP4:%.*]] = trunc <2 x i32> [[TMP3]] to <2 x i16>
186; CHECK-NEXT:    [[C_210:%.*]] = icmp eq <2 x i16> [[TMP2]], [[TMP4]]
187; CHECK-NEXT:    ret <2 x i1> [[C_210]]
188;
189  %x.321 = lshr <2x i32> %x, <i32 8, i32 8>
190  %x.1 = trunc <2x i32> %x.321 to <2x i8>
191  %x.32 = lshr <2x i32> %x, <i32 16, i32 16>
192  %x.2 = trunc <2x i32> %x.32 to <2x i8>
193  %y.321 = lshr <2x i32> %y, <i32 8, i32 8>
194  %y.1 = trunc <2x i32> %y.321 to <2x i8>
195  %y.32 = lshr <2x i32> %y, <i32 16, i32 16>
196  %y.2 = trunc <2x i32> %y.32 to <2x i8>
197  %c.1 = icmp eq <2x i8> %x.1, %y.1
198  %c.2 = icmp eq <2x i8> %x.2, %y.2
199  %c.210 = and <2x i1> %c.2, %c.1
200  ret <2 x i1> %c.210
201}
202
203; Test irregular bit widths. This also tests the case where
204; all the involved bit widths and offsets are different.
205
206define i1 @eq_irregular_bit_widths(i31 %x, i31 %y) {
207; CHECK-LABEL: @eq_irregular_bit_widths(
208; CHECK-NEXT:    [[TMP1:%.*]] = lshr i31 [[X:%.*]], 7
209; CHECK-NEXT:    [[TMP2:%.*]] = trunc i31 [[TMP1]] to i11
210; CHECK-NEXT:    [[TMP3:%.*]] = lshr i31 [[Y:%.*]], 7
211; CHECK-NEXT:    [[TMP4:%.*]] = trunc i31 [[TMP3]] to i11
212; CHECK-NEXT:    [[C_210:%.*]] = icmp eq i11 [[TMP2]], [[TMP4]]
213; CHECK-NEXT:    ret i1 [[C_210]]
214;
215  %x.321 = lshr i31 %x, 7
216  %x.1 = trunc i31 %x.321 to i6
217  %x.32 = lshr i31 %x, 13
218  %x.2 = trunc i31 %x.32 to i5
219  %y.321 = lshr i31 %y, 7
220  %y.1 = trunc i31 %y.321 to i6
221  %y.32 = lshr i31 %y, 13
222  %y.2 = trunc i31 %y.32 to i5
223  %c.1 = icmp eq i6 %x.1, %y.1
224  %c.2 = icmp eq i5 %x.2, %y.2
225  %c.210 = and i1 %c.2, %c.1
226  ret i1 %c.210
227}
228
229; Test variants with extra uses.
230
231define i1 @eq_21_extra_use_lshr(i32 %x, i32 %y) {
232; CHECK-LABEL: @eq_21_extra_use_lshr(
233; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
234; CHECK-NEXT:    call void @use.i32(i32 [[X_321]])
235; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
236; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
237; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
238; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
239; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
240; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
241; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
242; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
243; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
244; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_1]], [[C_2]]
245; CHECK-NEXT:    ret i1 [[C_210]]
246;
247  %x.321 = lshr i32 %x, 8
248  call void @use.i32(i32 %x.321)
249  %x.1 = trunc i32 %x.321 to i8
250  %x.32 = lshr i32 %x, 16
251  %x.2 = trunc i32 %x.32 to i8
252  %y.321 = lshr i32 %y, 8
253  %y.1 = trunc i32 %y.321 to i8
254  %y.32 = lshr i32 %y, 16
255  %y.2 = trunc i32 %y.32 to i8
256  %c.1 = icmp eq i8 %x.1, %y.1
257  %c.2 = icmp eq i8 %x.2, %y.2
258  %c.210 = and i1 %c.1, %c.2
259  ret i1 %c.210
260}
261
262define i1 @eq_21_extra_use_trunc(i32 %x, i32 %y) {
263; CHECK-LABEL: @eq_21_extra_use_trunc(
264; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
265; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
266; CHECK-NEXT:    call void @use.i8(i8 [[X_1]])
267; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
268; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
269; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
270; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
271; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
272; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
273; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
274; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
275; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_1]], [[C_2]]
276; CHECK-NEXT:    ret i1 [[C_210]]
277;
278  %x.321 = lshr i32 %x, 8
279  %x.1 = trunc i32 %x.321 to i8
280  call void @use.i8(i8 %x.1)
281  %x.32 = lshr i32 %x, 16
282  %x.2 = trunc i32 %x.32 to i8
283  %y.321 = lshr i32 %y, 8
284  %y.1 = trunc i32 %y.321 to i8
285  %y.32 = lshr i32 %y, 16
286  %y.2 = trunc i32 %y.32 to i8
287  %c.1 = icmp eq i8 %x.1, %y.1
288  %c.2 = icmp eq i8 %x.2, %y.2
289  %c.210 = and i1 %c.1, %c.2
290  ret i1 %c.210
291}
292
293define i1 @eq_21_extra_use_eq1(i32 %x, i32 %y) {
294; CHECK-LABEL: @eq_21_extra_use_eq1(
295; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
296; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
297; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
298; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
299; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
300; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
301; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
302; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
303; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
304; CHECK-NEXT:    call void @use.i1(i1 [[C_1]])
305; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
306; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_1]], [[C_2]]
307; CHECK-NEXT:    ret i1 [[C_210]]
308;
309  %x.321 = lshr i32 %x, 8
310  %x.1 = trunc i32 %x.321 to i8
311  %x.32 = lshr i32 %x, 16
312  %x.2 = trunc i32 %x.32 to i8
313  %y.321 = lshr i32 %y, 8
314  %y.1 = trunc i32 %y.321 to i8
315  %y.32 = lshr i32 %y, 16
316  %y.2 = trunc i32 %y.32 to i8
317  %c.1 = icmp eq i8 %x.1, %y.1
318  call void @use.i1(i1 %c.1)
319  %c.2 = icmp eq i8 %x.2, %y.2
320  %c.210 = and i1 %c.1, %c.2
321  ret i1 %c.210
322}
323
324define i1 @eq_21_extra_use_eq2(i32 %x, i32 %y) {
325; CHECK-LABEL: @eq_21_extra_use_eq2(
326; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
327; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
328; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
329; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
330; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
331; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
332; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
333; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
334; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
335; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
336; CHECK-NEXT:    call void @use.i1(i1 [[C_2]])
337; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_1]], [[C_2]]
338; CHECK-NEXT:    ret i1 [[C_210]]
339;
340  %x.321 = lshr i32 %x, 8
341  %x.1 = trunc i32 %x.321 to i8
342  %x.32 = lshr i32 %x, 16
343  %x.2 = trunc i32 %x.32 to i8
344  %y.321 = lshr i32 %y, 8
345  %y.1 = trunc i32 %y.321 to i8
346  %y.32 = lshr i32 %y, 16
347  %y.2 = trunc i32 %y.32 to i8
348  %c.1 = icmp eq i8 %x.1, %y.1
349  %c.2 = icmp eq i8 %x.2, %y.2
350  call void @use.i1(i1 %c.2)
351  %c.210 = and i1 %c.1, %c.2
352  ret i1 %c.210
353}
354
355; Logical and instead of bitwise and.
356
357define i1 @eq_21_logical(i32 %x, i32 %y) {
358; CHECK-LABEL: @eq_21_logical(
359; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
360; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
361; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
362; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
363; CHECK-NEXT:    [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
364; CHECK-NEXT:    ret i1 [[C_210]]
365;
366  %x.321 = lshr i32 %x, 8
367  %x.1 = trunc i32 %x.321 to i8
368  %x.32 = lshr i32 %x, 16
369  %x.2 = trunc i32 %x.32 to i8
370  %y.321 = lshr i32 %y, 8
371  %y.1 = trunc i32 %y.321 to i8
372  %y.32 = lshr i32 %y, 16
373  %y.2 = trunc i32 %y.32 to i8
374  %c.1 = icmp eq i8 %x.1, %y.1
375  %c.2 = icmp eq i8 %x.2, %y.2
376  %c.210 = select i1 %c.2, i1 %c.1, i1 false
377  ret i1 %c.210
378}
379
380; Negative tests.
381
382define i1 @eq_21_wrong_op1(i32 %x, i32 %y, i32 %z) {
383; CHECK-LABEL: @eq_21_wrong_op1(
384; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[Z:%.*]], 8
385; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
386; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X:%.*]], 16
387; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
388; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
389; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
390; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
391; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
392; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
393; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
394; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
395; CHECK-NEXT:    ret i1 [[C_210]]
396;
397  %x.321 = lshr i32 %z, 8
398  %x.1 = trunc i32 %x.321 to i8
399  %x.32 = lshr i32 %x, 16
400  %x.2 = trunc i32 %x.32 to i8
401  %y.321 = lshr i32 %y, 8
402  %y.1 = trunc i32 %y.321 to i8
403  %y.32 = lshr i32 %y, 16
404  %y.2 = trunc i32 %y.32 to i8
405  %c.1 = icmp eq i8 %x.1, %y.1
406  %c.2 = icmp eq i8 %x.2, %y.2
407  %c.210 = and i1 %c.2, %c.1
408  ret i1 %c.210
409}
410
411define i1 @eq_21_wrong_op2(i32 %x, i32 %y, i32 %z) {
412; CHECK-LABEL: @eq_21_wrong_op2(
413; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
414; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
415; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[Z:%.*]], 16
416; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
417; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
418; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
419; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
420; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
421; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
422; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
423; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
424; CHECK-NEXT:    ret i1 [[C_210]]
425;
426  %x.321 = lshr i32 %x, 8
427  %x.1 = trunc i32 %x.321 to i8
428  %x.32 = lshr i32 %z, 16
429  %x.2 = trunc i32 %x.32 to i8
430  %y.321 = lshr i32 %y, 8
431  %y.1 = trunc i32 %y.321 to i8
432  %y.32 = lshr i32 %y, 16
433  %y.2 = trunc i32 %y.32 to i8
434  %c.1 = icmp eq i8 %x.1, %y.1
435  %c.2 = icmp eq i8 %x.2, %y.2
436  %c.210 = and i1 %c.2, %c.1
437  ret i1 %c.210
438}
439
440define i1 @eq_21_wrong_op3(i32 %x, i32 %y, i32 %z) {
441; CHECK-LABEL: @eq_21_wrong_op3(
442; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
443; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
444; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
445; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
446; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Z:%.*]], 8
447; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
448; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y:%.*]], 16
449; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
450; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
451; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
452; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
453; CHECK-NEXT:    ret i1 [[C_210]]
454;
455  %x.321 = lshr i32 %x, 8
456  %x.1 = trunc i32 %x.321 to i8
457  %x.32 = lshr i32 %x, 16
458  %x.2 = trunc i32 %x.32 to i8
459  %y.321 = lshr i32 %z, 8
460  %y.1 = trunc i32 %y.321 to i8
461  %y.32 = lshr i32 %y, 16
462  %y.2 = trunc i32 %y.32 to i8
463  %c.1 = icmp eq i8 %x.1, %y.1
464  %c.2 = icmp eq i8 %x.2, %y.2
465  %c.210 = and i1 %c.2, %c.1
466  ret i1 %c.210
467}
468
469define i1 @eq_21_wrong_op4(i32 %x, i32 %y, i32 %z) {
470; CHECK-LABEL: @eq_21_wrong_op4(
471; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
472; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
473; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
474; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
475; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
476; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
477; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Z:%.*]], 16
478; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
479; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
480; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
481; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
482; CHECK-NEXT:    ret i1 [[C_210]]
483;
484  %x.321 = lshr i32 %x, 8
485  %x.1 = trunc i32 %x.321 to i8
486  %x.32 = lshr i32 %x, 16
487  %x.2 = trunc i32 %x.32 to i8
488  %y.321 = lshr i32 %y, 8
489  %y.1 = trunc i32 %y.321 to i8
490  %y.32 = lshr i32 %z, 16
491  %y.2 = trunc i32 %y.32 to i8
492  %c.1 = icmp eq i8 %x.1, %y.1
493  %c.2 = icmp eq i8 %x.2, %y.2
494  %c.210 = and i1 %c.2, %c.1
495  ret i1 %c.210
496}
497
498define i1 @eq_21_wrong_shift1(i32 %x, i32 %y) {
499; CHECK-LABEL: @eq_21_wrong_shift1(
500; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
501; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
502; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
503; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
504; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 7
505; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
506; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
507; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
508; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
509; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
510; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
511; CHECK-NEXT:    ret i1 [[C_210]]
512;
513  %x.321 = lshr i32 %x, 8
514  %x.1 = trunc i32 %x.321 to i8
515  %x.32 = lshr i32 %x, 16
516  %x.2 = trunc i32 %x.32 to i8
517  %y.321 = lshr i32 %y, 7
518  %y.1 = trunc i32 %y.321 to i8
519  %y.32 = lshr i32 %y, 16
520  %y.2 = trunc i32 %y.32 to i8
521  %c.1 = icmp eq i8 %x.1, %y.1
522  %c.2 = icmp eq i8 %x.2, %y.2
523  %c.210 = and i1 %c.2, %c.1
524  ret i1 %c.210
525}
526
527define i1 @eq_21_wrong_shift2(i32 %x, i32 %y) {
528; CHECK-LABEL: @eq_21_wrong_shift2(
529; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
530; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
531; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
532; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
533; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
534; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
535; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 15
536; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
537; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
538; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
539; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
540; CHECK-NEXT:    ret i1 [[C_210]]
541;
542  %x.321 = lshr i32 %x, 8
543  %x.1 = trunc i32 %x.321 to i8
544  %x.32 = lshr i32 %x, 16
545  %x.2 = trunc i32 %x.32 to i8
546  %y.321 = lshr i32 %y, 8
547  %y.1 = trunc i32 %y.321 to i8
548  %y.32 = lshr i32 %y, 15
549  %y.2 = trunc i32 %y.32 to i8
550  %c.1 = icmp eq i8 %x.1, %y.1
551  %c.2 = icmp eq i8 %x.2, %y.2
552  %c.210 = and i1 %c.2, %c.1
553  ret i1 %c.210
554}
555
556define i1 @eq_21_not_adjacent(i32 %x, i32 %y) {
557; CHECK-LABEL: @eq_21_not_adjacent(
558; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
559; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
560; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 17
561; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
562; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
563; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
564; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 17
565; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
566; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
567; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
568; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
569; CHECK-NEXT:    ret i1 [[C_210]]
570;
571  %x.321 = lshr i32 %x, 8
572  %x.1 = trunc i32 %x.321 to i8
573  %x.32 = lshr i32 %x, 17
574  %x.2 = trunc i32 %x.32 to i8
575  %y.321 = lshr i32 %y, 8
576  %y.1 = trunc i32 %y.321 to i8
577  %y.32 = lshr i32 %y, 17
578  %y.2 = trunc i32 %y.32 to i8
579  %c.1 = icmp eq i8 %x.1, %y.1
580  %c.2 = icmp eq i8 %x.2, %y.2
581  %c.210 = and i1 %c.2, %c.1
582  ret i1 %c.210
583}
584
585define i1 @eq_shift_in_zeros(i32 %x, i32 %y) {
586; CHECK-LABEL: @eq_shift_in_zeros(
587; CHECK-NEXT:    [[C_210_UNSHIFTED:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
588; CHECK-NEXT:    [[C_210:%.*]] = icmp ult i32 [[C_210_UNSHIFTED]], 256
589; CHECK-NEXT:    ret i1 [[C_210]]
590;
591  %x.321 = lshr i32 %x, 8
592  %x.1 = trunc i32 %x.321 to i8
593  %x.32 = lshr i32 %x, 16
594  %x.2 = trunc i32 %x.32 to i24
595  %y.321 = lshr i32 %y, 8
596  %y.1 = trunc i32 %y.321 to i8
597  %y.32 = lshr i32 %y, 16
598  %y.2 = trunc i32 %y.32 to i24
599  %c.1 = icmp eq i8 %x.1, %y.1
600  %c.2 = icmp eq i24 %x.2, %y.2
601  %c.210 = and i1 %c.2, %c.1
602  ret i1 %c.210
603}
604
605define i1 @eq_21_wrong_pred1(i32 %x, i32 %y) {
606; CHECK-LABEL: @eq_21_wrong_pred1(
607; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
608; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
609; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
610; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
611; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
612; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
613; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
614; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
615; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
616; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
617; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
618; CHECK-NEXT:    ret i1 [[C_210]]
619;
620  %x.321 = lshr i32 %x, 8
621  %x.1 = trunc i32 %x.321 to i8
622  %x.32 = lshr i32 %x, 16
623  %x.2 = trunc i32 %x.32 to i8
624  %y.321 = lshr i32 %y, 8
625  %y.1 = trunc i32 %y.321 to i8
626  %y.32 = lshr i32 %y, 16
627  %y.2 = trunc i32 %y.32 to i8
628  %c.1 = icmp eq i8 %x.1, %y.1
629  %c.2 = icmp ne i8 %x.2, %y.2
630  %c.210 = and i1 %c.2, %c.1
631  ret i1 %c.210
632}
633
634define i1 @eq_21_wrong_pred2(i32 %x, i32 %y) {
635; CHECK-LABEL: @eq_21_wrong_pred2(
636; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
637; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
638; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
639; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
640; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
641; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
642; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
643; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
644; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
645; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
646; CHECK-NEXT:    [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
647; CHECK-NEXT:    ret i1 [[C_210]]
648;
649  %x.321 = lshr i32 %x, 8
650  %x.1 = trunc i32 %x.321 to i8
651  %x.32 = lshr i32 %x, 16
652  %x.2 = trunc i32 %x.32 to i8
653  %y.321 = lshr i32 %y, 8
654  %y.1 = trunc i32 %y.321 to i8
655  %y.32 = lshr i32 %y, 16
656  %y.2 = trunc i32 %y.32 to i8
657  %c.1 = icmp ne i8 %x.1, %y.1
658  %c.2 = icmp ne i8 %x.2, %y.2
659  %c.210 = and i1 %c.2, %c.1
660  ret i1 %c.210
661}
662
663;
664; Now the same thing again, but for or ne instead of and eq.
665;
666
667define i1 @ne_10(i32 %x, i32 %y) {
668; CHECK-LABEL: @ne_10(
669; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
670; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i16
671; CHECK-NEXT:    [[C_10:%.*]] = icmp ne i16 [[TMP1]], [[TMP2]]
672; CHECK-NEXT:    ret i1 [[C_10]]
673;
674  %x.0 = trunc i32 %x to i8
675  %x.321 = lshr i32 %x, 8
676  %x.1 = trunc i32 %x.321 to i8
677  %y.0 = trunc i32 %y to i8
678  %y.321 = lshr i32 %y, 8
679  %y.1 = trunc i32 %y.321 to i8
680  %c.0 = icmp ne i8 %x.0, %y.0
681  %c.1 = icmp ne i8 %x.1, %y.1
682  %c.10 = or i1 %c.0, %c.1
683  ret i1 %c.10
684}
685
686define i1 @ne_210(i32 %x, i32 %y) {
687; CHECK-LABEL: @ne_210(
688; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i24
689; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i24
690; CHECK-NEXT:    [[C_210:%.*]] = icmp ne i24 [[TMP1]], [[TMP2]]
691; CHECK-NEXT:    ret i1 [[C_210]]
692;
693  %x.0 = trunc i32 %x to i8
694  %x.321 = lshr i32 %x, 8
695  %x.1 = trunc i32 %x.321 to i8
696  %x.32 = lshr i32 %x, 16
697  %x.2 = trunc i32 %x.32 to i8
698  %y.0 = trunc i32 %y to i8
699  %y.321 = lshr i32 %y, 8
700  %y.1 = trunc i32 %y.321 to i8
701  %y.32 = lshr i32 %y, 16
702  %y.2 = trunc i32 %y.32 to i8
703  %c.0 = icmp ne i8 %x.0, %y.0
704  %c.1 = icmp ne i8 %x.1, %y.1
705  %c.2 = icmp ne i8 %x.2, %y.2
706  %c.10 = or i1 %c.0, %c.1
707  %c.210 = or i1 %c.2, %c.10
708  ret i1 %c.210
709}
710
711define i1 @ne_3210(i32 %x, i32 %y) {
712; CHECK-LABEL: @ne_3210(
713; CHECK-NEXT:    [[C_3210:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
714; CHECK-NEXT:    ret i1 [[C_3210]]
715;
716  %x.0 = trunc i32 %x to i8
717  %x.321 = lshr i32 %x, 8
718  %x.1 = trunc i32 %x.321 to i8
719  %x.32 = lshr i32 %x, 16
720  %x.2 = trunc i32 %x.32 to i8
721  %x.3.ext = lshr i32 %x, 24
722  %x.3 = trunc i32 %x.3.ext to i8
723  %y.0 = trunc i32 %y to i8
724  %y.321 = lshr i32 %y, 8
725  %y.1 = trunc i32 %y.321 to i8
726  %y.32 = lshr i32 %y, 16
727  %y.2 = trunc i32 %y.32 to i8
728  %y.3.ext = lshr i32 %y, 24
729  %y.3 = trunc i32 %y.3.ext to i8
730  %c.0 = icmp ne i8 %x.0, %y.0
731  %c.1 = icmp ne i8 %x.1, %y.1
732  %c.2 = icmp ne i8 %x.2, %y.2
733  %c.3 = icmp ne i8 %x.3, %y.3
734  %c.10 = or i1 %c.0, %c.1
735  %c.210 = or i1 %c.2, %c.10
736  %c.3210 = or i1 %c.3, %c.210
737  ret i1 %c.3210
738}
739
740define i1 @ne_21(i32 %x, i32 %y) {
741; CHECK-LABEL: @ne_21(
742; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
743; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
744; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
745; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
746; CHECK-NEXT:    [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
747; CHECK-NEXT:    ret i1 [[C_210]]
748;
749  %x.321 = lshr i32 %x, 8
750  %x.1 = trunc i32 %x.321 to i8
751  %x.32 = lshr i32 %x, 16
752  %x.2 = trunc i32 %x.32 to i8
753  %y.321 = lshr i32 %y, 8
754  %y.1 = trunc i32 %y.321 to i8
755  %y.32 = lshr i32 %y, 16
756  %y.2 = trunc i32 %y.32 to i8
757  %c.1 = icmp ne i8 %x.1, %y.1
758  %c.2 = icmp ne i8 %x.2, %y.2
759  %c.210 = or i1 %c.2, %c.1
760  ret i1 %c.210
761}
762
763; Test commuted variants of ne_21.
764
765define i1 @ne_21_comm_or(i32 %x, i32 %y) {
766; CHECK-LABEL: @ne_21_comm_or(
767; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
768; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
769; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
770; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
771; CHECK-NEXT:    [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
772; CHECK-NEXT:    ret i1 [[C_210]]
773;
774  %x.321 = lshr i32 %x, 8
775  %x.1 = trunc i32 %x.321 to i8
776  %x.32 = lshr i32 %x, 16
777  %x.2 = trunc i32 %x.32 to i8
778  %y.321 = lshr i32 %y, 8
779  %y.1 = trunc i32 %y.321 to i8
780  %y.32 = lshr i32 %y, 16
781  %y.2 = trunc i32 %y.32 to i8
782  %c.1 = icmp ne i8 %x.1, %y.1
783  %c.2 = icmp ne i8 %x.2, %y.2
784  %c.210 = or i1 %c.1, %c.2
785  ret i1 %c.210
786}
787
788define i1 @ne_21_comm_ne(i32 %x, i32 %y) {
789; CHECK-LABEL: @ne_21_comm_ne(
790; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 8
791; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
792; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[X:%.*]], 8
793; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
794; CHECK-NEXT:    [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
795; CHECK-NEXT:    ret i1 [[C_210]]
796;
797  %x.321 = lshr i32 %x, 8
798  %x.1 = trunc i32 %x.321 to i8
799  %x.32 = lshr i32 %x, 16
800  %x.2 = trunc i32 %x.32 to i8
801  %y.321 = lshr i32 %y, 8
802  %y.1 = trunc i32 %y.321 to i8
803  %y.32 = lshr i32 %y, 16
804  %y.2 = trunc i32 %y.32 to i8
805  %c.1 = icmp ne i8 %x.1, %y.1
806  %c.2 = icmp ne i8 %y.2, %x.2
807  %c.210 = or i1 %c.2, %c.1
808  ret i1 %c.210
809}
810
811define i1 @ne_21_comm_ne2(i32 %x, i32 %y) {
812; CHECK-LABEL: @ne_21_comm_ne2(
813; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
814; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
815; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
816; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
817; CHECK-NEXT:    [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
818; CHECK-NEXT:    ret i1 [[C_210]]
819;
820  %x.321 = lshr i32 %x, 8
821  %x.1 = trunc i32 %x.321 to i8
822  %x.32 = lshr i32 %x, 16
823  %x.2 = trunc i32 %x.32 to i8
824  %y.321 = lshr i32 %y, 8
825  %y.1 = trunc i32 %y.321 to i8
826  %y.32 = lshr i32 %y, 16
827  %y.2 = trunc i32 %y.32 to i8
828  %c.1 = icmp ne i8 %y.1, %x.1
829  %c.2 = icmp ne i8 %x.2, %y.2
830  %c.210 = or i1 %c.2, %c.1
831  ret i1 %c.210
832}
833
834; Test vector variant.
835
836define <2x i1> @ne_21_vector(<2x i32> %x, <2x i32> %y) {
837; CHECK-LABEL: @ne_21_vector(
838; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 8)
839; CHECK-NEXT:    [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
840; CHECK-NEXT:    [[TMP3:%.*]] = lshr <2 x i32> [[Y:%.*]], splat (i32 8)
841; CHECK-NEXT:    [[TMP4:%.*]] = trunc <2 x i32> [[TMP3]] to <2 x i16>
842; CHECK-NEXT:    [[C_210:%.*]] = icmp ne <2 x i16> [[TMP2]], [[TMP4]]
843; CHECK-NEXT:    ret <2 x i1> [[C_210]]
844;
845  %x.321 = lshr <2x i32> %x, <i32 8, i32 8>
846  %x.1 = trunc <2x i32> %x.321 to <2x i8>
847  %x.32 = lshr <2x i32> %x, <i32 16, i32 16>
848  %x.2 = trunc <2x i32> %x.32 to <2x i8>
849  %y.321 = lshr <2x i32> %y, <i32 8, i32 8>
850  %y.1 = trunc <2x i32> %y.321 to <2x i8>
851  %y.32 = lshr <2x i32> %y, <i32 16, i32 16>
852  %y.2 = trunc <2x i32> %y.32 to <2x i8>
853  %c.1 = icmp ne <2x i8> %x.1, %y.1
854  %c.2 = icmp ne <2x i8> %x.2, %y.2
855  %c.210 = or <2x i1> %c.2, %c.1
856  ret <2 x i1> %c.210
857}
858
859; Test irregular bit widths. This also tests the case where
860; all the involved bit widths or offsets are different.
861
862define i1 @ne_irregular_bit_widths(i31 %x, i31 %y) {
863; CHECK-LABEL: @ne_irregular_bit_widths(
864; CHECK-NEXT:    [[TMP1:%.*]] = lshr i31 [[X:%.*]], 7
865; CHECK-NEXT:    [[TMP2:%.*]] = trunc i31 [[TMP1]] to i11
866; CHECK-NEXT:    [[TMP3:%.*]] = lshr i31 [[Y:%.*]], 7
867; CHECK-NEXT:    [[TMP4:%.*]] = trunc i31 [[TMP3]] to i11
868; CHECK-NEXT:    [[C_210:%.*]] = icmp ne i11 [[TMP2]], [[TMP4]]
869; CHECK-NEXT:    ret i1 [[C_210]]
870;
871  %x.321 = lshr i31 %x, 7
872  %x.1 = trunc i31 %x.321 to i6
873  %x.32 = lshr i31 %x, 13
874  %x.2 = trunc i31 %x.32 to i5
875  %y.321 = lshr i31 %y, 7
876  %y.1 = trunc i31 %y.321 to i6
877  %y.32 = lshr i31 %y, 13
878  %y.2 = trunc i31 %y.32 to i5
879  %c.1 = icmp ne i6 %x.1, %y.1
880  %c.2 = icmp ne i5 %x.2, %y.2
881  %c.210 = or i1 %c.2, %c.1
882  ret i1 %c.210
883}
884
885; Test variants with extra uses.
886
887define i1 @ne_21_extra_use_lshr(i32 %x, i32 %y) {
888; CHECK-LABEL: @ne_21_extra_use_lshr(
889; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
890; CHECK-NEXT:    call void @use.i32(i32 [[X_321]])
891; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
892; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
893; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
894; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
895; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
896; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
897; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
898; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
899; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
900; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_1]], [[C_2]]
901; CHECK-NEXT:    ret i1 [[C_210]]
902;
903  %x.321 = lshr i32 %x, 8
904  call void @use.i32(i32 %x.321)
905  %x.1 = trunc i32 %x.321 to i8
906  %x.32 = lshr i32 %x, 16
907  %x.2 = trunc i32 %x.32 to i8
908  %y.321 = lshr i32 %y, 8
909  %y.1 = trunc i32 %y.321 to i8
910  %y.32 = lshr i32 %y, 16
911  %y.2 = trunc i32 %y.32 to i8
912  %c.1 = icmp ne i8 %x.1, %y.1
913  %c.2 = icmp ne i8 %x.2, %y.2
914  %c.210 = or i1 %c.1, %c.2
915  ret i1 %c.210
916}
917
918define i1 @ne_21_extra_use_trunc(i32 %x, i32 %y) {
919; CHECK-LABEL: @ne_21_extra_use_trunc(
920; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
921; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
922; CHECK-NEXT:    call void @use.i8(i8 [[X_1]])
923; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
924; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
925; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
926; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
927; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
928; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
929; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
930; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
931; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_1]], [[C_2]]
932; CHECK-NEXT:    ret i1 [[C_210]]
933;
934  %x.321 = lshr i32 %x, 8
935  %x.1 = trunc i32 %x.321 to i8
936  call void @use.i8(i8 %x.1)
937  %x.32 = lshr i32 %x, 16
938  %x.2 = trunc i32 %x.32 to i8
939  %y.321 = lshr i32 %y, 8
940  %y.1 = trunc i32 %y.321 to i8
941  %y.32 = lshr i32 %y, 16
942  %y.2 = trunc i32 %y.32 to i8
943  %c.1 = icmp ne i8 %x.1, %y.1
944  %c.2 = icmp ne i8 %x.2, %y.2
945  %c.210 = or i1 %c.1, %c.2
946  ret i1 %c.210
947}
948
949define i1 @ne_21_extra_use_ne1(i32 %x, i32 %y) {
950; CHECK-LABEL: @ne_21_extra_use_ne1(
951; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
952; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
953; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
954; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
955; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
956; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
957; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
958; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
959; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
960; CHECK-NEXT:    call void @use.i1(i1 [[C_1]])
961; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
962; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_1]], [[C_2]]
963; CHECK-NEXT:    ret i1 [[C_210]]
964;
965  %x.321 = lshr i32 %x, 8
966  %x.1 = trunc i32 %x.321 to i8
967  %x.32 = lshr i32 %x, 16
968  %x.2 = trunc i32 %x.32 to i8
969  %y.321 = lshr i32 %y, 8
970  %y.1 = trunc i32 %y.321 to i8
971  %y.32 = lshr i32 %y, 16
972  %y.2 = trunc i32 %y.32 to i8
973  %c.1 = icmp ne i8 %x.1, %y.1
974  call void @use.i1(i1 %c.1)
975  %c.2 = icmp ne i8 %x.2, %y.2
976  %c.210 = or i1 %c.1, %c.2
977  ret i1 %c.210
978}
979
980define i1 @ne_21_extra_use_ne2(i32 %x, i32 %y) {
981; CHECK-LABEL: @ne_21_extra_use_ne2(
982; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
983; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
984; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
985; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
986; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
987; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
988; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
989; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
990; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
991; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
992; CHECK-NEXT:    call void @use.i1(i1 [[C_2]])
993; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_1]], [[C_2]]
994; CHECK-NEXT:    ret i1 [[C_210]]
995;
996  %x.321 = lshr i32 %x, 8
997  %x.1 = trunc i32 %x.321 to i8
998  %x.32 = lshr i32 %x, 16
999  %x.2 = trunc i32 %x.32 to i8
1000  %y.321 = lshr i32 %y, 8
1001  %y.1 = trunc i32 %y.321 to i8
1002  %y.32 = lshr i32 %y, 16
1003  %y.2 = trunc i32 %y.32 to i8
1004  %c.1 = icmp ne i8 %x.1, %y.1
1005  %c.2 = icmp ne i8 %x.2, %y.2
1006  call void @use.i1(i1 %c.2)
1007  %c.210 = or i1 %c.1, %c.2
1008  ret i1 %c.210
1009}
1010
1011; Logical or instead of bitwise or.
1012
1013define i1 @ne_21_logical(i32 %x, i32 %y) {
1014; CHECK-LABEL: @ne_21_logical(
1015; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
1016; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
1017; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
1018; CHECK-NEXT:    [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
1019; CHECK-NEXT:    [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
1020; CHECK-NEXT:    ret i1 [[C_210]]
1021;
1022  %x.321 = lshr i32 %x, 8
1023  %x.1 = trunc i32 %x.321 to i8
1024  %x.32 = lshr i32 %x, 16
1025  %x.2 = trunc i32 %x.32 to i8
1026  %y.321 = lshr i32 %y, 8
1027  %y.1 = trunc i32 %y.321 to i8
1028  %y.32 = lshr i32 %y, 16
1029  %y.2 = trunc i32 %y.32 to i8
1030  %c.1 = icmp ne i8 %x.1, %y.1
1031  %c.2 = icmp ne i8 %x.2, %y.2
1032  %c.210 = select i1 %c.2, i1 true, i1 %c.1
1033  ret i1 %c.210
1034}
1035
1036; Negative tests.
1037
1038define i1 @ne_21_wrong_op1(i32 %x, i32 %y, i32 %z) {
1039; CHECK-LABEL: @ne_21_wrong_op1(
1040; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[Z:%.*]], 8
1041; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
1042; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X:%.*]], 16
1043; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
1044; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
1045; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
1046; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
1047; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
1048; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
1049; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
1050; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
1051; CHECK-NEXT:    ret i1 [[C_210]]
1052;
1053  %x.321 = lshr i32 %z, 8
1054  %x.1 = trunc i32 %x.321 to i8
1055  %x.32 = lshr i32 %x, 16
1056  %x.2 = trunc i32 %x.32 to i8
1057  %y.321 = lshr i32 %y, 8
1058  %y.1 = trunc i32 %y.321 to i8
1059  %y.32 = lshr i32 %y, 16
1060  %y.2 = trunc i32 %y.32 to i8
1061  %c.1 = icmp ne i8 %x.1, %y.1
1062  %c.2 = icmp ne i8 %x.2, %y.2
1063  %c.210 = or i1 %c.2, %c.1
1064  ret i1 %c.210
1065}
1066
1067define i1 @ne_21_wrong_op2(i32 %x, i32 %y, i32 %z) {
1068; CHECK-LABEL: @ne_21_wrong_op2(
1069; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
1070; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
1071; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[Z:%.*]], 16
1072; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
1073; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
1074; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
1075; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
1076; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
1077; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
1078; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
1079; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
1080; CHECK-NEXT:    ret i1 [[C_210]]
1081;
1082  %x.321 = lshr i32 %x, 8
1083  %x.1 = trunc i32 %x.321 to i8
1084  %x.32 = lshr i32 %z, 16
1085  %x.2 = trunc i32 %x.32 to i8
1086  %y.321 = lshr i32 %y, 8
1087  %y.1 = trunc i32 %y.321 to i8
1088  %y.32 = lshr i32 %y, 16
1089  %y.2 = trunc i32 %y.32 to i8
1090  %c.1 = icmp ne i8 %x.1, %y.1
1091  %c.2 = icmp ne i8 %x.2, %y.2
1092  %c.210 = or i1 %c.2, %c.1
1093  ret i1 %c.210
1094}
1095
1096define i1 @ne_21_wrong_op3(i32 %x, i32 %y, i32 %z) {
1097; CHECK-LABEL: @ne_21_wrong_op3(
1098; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
1099; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
1100; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
1101; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
1102; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Z:%.*]], 8
1103; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
1104; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y:%.*]], 16
1105; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
1106; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
1107; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
1108; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
1109; CHECK-NEXT:    ret i1 [[C_210]]
1110;
1111  %x.321 = lshr i32 %x, 8
1112  %x.1 = trunc i32 %x.321 to i8
1113  %x.32 = lshr i32 %x, 16
1114  %x.2 = trunc i32 %x.32 to i8
1115  %y.321 = lshr i32 %z, 8
1116  %y.1 = trunc i32 %y.321 to i8
1117  %y.32 = lshr i32 %y, 16
1118  %y.2 = trunc i32 %y.32 to i8
1119  %c.1 = icmp ne i8 %x.1, %y.1
1120  %c.2 = icmp ne i8 %x.2, %y.2
1121  %c.210 = or i1 %c.2, %c.1
1122  ret i1 %c.210
1123}
1124
1125define i1 @ne_21_wrong_op4(i32 %x, i32 %y, i32 %z) {
1126; CHECK-LABEL: @ne_21_wrong_op4(
1127; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
1128; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
1129; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
1130; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
1131; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
1132; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
1133; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Z:%.*]], 16
1134; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
1135; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
1136; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
1137; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
1138; CHECK-NEXT:    ret i1 [[C_210]]
1139;
1140  %x.321 = lshr i32 %x, 8
1141  %x.1 = trunc i32 %x.321 to i8
1142  %x.32 = lshr i32 %x, 16
1143  %x.2 = trunc i32 %x.32 to i8
1144  %y.321 = lshr i32 %y, 8
1145  %y.1 = trunc i32 %y.321 to i8
1146  %y.32 = lshr i32 %z, 16
1147  %y.2 = trunc i32 %y.32 to i8
1148  %c.1 = icmp ne i8 %x.1, %y.1
1149  %c.2 = icmp ne i8 %x.2, %y.2
1150  %c.210 = or i1 %c.2, %c.1
1151  ret i1 %c.210
1152}
1153
1154define i1 @ne_21_wrong_shift1(i32 %x, i32 %y) {
1155; CHECK-LABEL: @ne_21_wrong_shift1(
1156; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
1157; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
1158; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
1159; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
1160; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 7
1161; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
1162; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
1163; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
1164; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
1165; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
1166; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
1167; CHECK-NEXT:    ret i1 [[C_210]]
1168;
1169  %x.321 = lshr i32 %x, 8
1170  %x.1 = trunc i32 %x.321 to i8
1171  %x.32 = lshr i32 %x, 16
1172  %x.2 = trunc i32 %x.32 to i8
1173  %y.321 = lshr i32 %y, 7
1174  %y.1 = trunc i32 %y.321 to i8
1175  %y.32 = lshr i32 %y, 16
1176  %y.2 = trunc i32 %y.32 to i8
1177  %c.1 = icmp ne i8 %x.1, %y.1
1178  %c.2 = icmp ne i8 %x.2, %y.2
1179  %c.210 = or i1 %c.2, %c.1
1180  ret i1 %c.210
1181}
1182
1183define i1 @ne_21_wrong_shift2(i32 %x, i32 %y) {
1184; CHECK-LABEL: @ne_21_wrong_shift2(
1185; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
1186; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
1187; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
1188; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
1189; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
1190; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
1191; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 15
1192; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
1193; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
1194; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
1195; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
1196; CHECK-NEXT:    ret i1 [[C_210]]
1197;
1198  %x.321 = lshr i32 %x, 8
1199  %x.1 = trunc i32 %x.321 to i8
1200  %x.32 = lshr i32 %x, 16
1201  %x.2 = trunc i32 %x.32 to i8
1202  %y.321 = lshr i32 %y, 8
1203  %y.1 = trunc i32 %y.321 to i8
1204  %y.32 = lshr i32 %y, 15
1205  %y.2 = trunc i32 %y.32 to i8
1206  %c.1 = icmp ne i8 %x.1, %y.1
1207  %c.2 = icmp ne i8 %x.2, %y.2
1208  %c.210 = or i1 %c.2, %c.1
1209  ret i1 %c.210
1210}
1211
1212define i1 @ne_21_not_adjacent(i32 %x, i32 %y) {
1213; CHECK-LABEL: @ne_21_not_adjacent(
1214; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
1215; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
1216; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 17
1217; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
1218; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
1219; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
1220; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 17
1221; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
1222; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
1223; CHECK-NEXT:    [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
1224; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
1225; CHECK-NEXT:    ret i1 [[C_210]]
1226;
1227  %x.321 = lshr i32 %x, 8
1228  %x.1 = trunc i32 %x.321 to i8
1229  %x.32 = lshr i32 %x, 17
1230  %x.2 = trunc i32 %x.32 to i8
1231  %y.321 = lshr i32 %y, 8
1232  %y.1 = trunc i32 %y.321 to i8
1233  %y.32 = lshr i32 %y, 17
1234  %y.2 = trunc i32 %y.32 to i8
1235  %c.1 = icmp ne i8 %x.1, %y.1
1236  %c.2 = icmp ne i8 %x.2, %y.2
1237  %c.210 = or i1 %c.2, %c.1
1238  ret i1 %c.210
1239}
1240
1241define i1 @ne_shift_in_zeros(i32 %x, i32 %y) {
1242; CHECK-LABEL: @ne_shift_in_zeros(
1243; CHECK-NEXT:    [[C_210_UNSHIFTED:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
1244; CHECK-NEXT:    [[C_210:%.*]] = icmp ugt i32 [[C_210_UNSHIFTED]], 255
1245; CHECK-NEXT:    ret i1 [[C_210]]
1246;
1247  %x.321 = lshr i32 %x, 8
1248  %x.1 = trunc i32 %x.321 to i8
1249  %x.32 = lshr i32 %x, 16
1250  %x.2 = trunc i32 %x.32 to i24
1251  %y.321 = lshr i32 %y, 8
1252  %y.1 = trunc i32 %y.321 to i8
1253  %y.32 = lshr i32 %y, 16
1254  %y.2 = trunc i32 %y.32 to i24
1255  %c.1 = icmp ne i8 %x.1, %y.1
1256  %c.2 = icmp ne i24 %x.2, %y.2
1257  %c.210 = or i1 %c.2, %c.1
1258  ret i1 %c.210
1259}
1260
1261define i1 @ne_21_wrong_pred1(i32 %x, i32 %y) {
1262; CHECK-LABEL: @ne_21_wrong_pred1(
1263; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
1264; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
1265; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
1266; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
1267; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
1268; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
1269; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
1270; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
1271; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
1272; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
1273; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
1274; CHECK-NEXT:    ret i1 [[C_210]]
1275;
1276  %x.321 = lshr i32 %x, 8
1277  %x.1 = trunc i32 %x.321 to i8
1278  %x.32 = lshr i32 %x, 16
1279  %x.2 = trunc i32 %x.32 to i8
1280  %y.321 = lshr i32 %y, 8
1281  %y.1 = trunc i32 %y.321 to i8
1282  %y.32 = lshr i32 %y, 16
1283  %y.2 = trunc i32 %y.32 to i8
1284  %c.1 = icmp ne i8 %x.1, %y.1
1285  %c.2 = icmp eq i8 %x.2, %y.2
1286  %c.210 = or i1 %c.2, %c.1
1287  ret i1 %c.210
1288}
1289
1290define i1 @ne_21_wrong_pred2(i32 %x, i32 %y) {
1291; CHECK-LABEL: @ne_21_wrong_pred2(
1292; CHECK-NEXT:    [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
1293; CHECK-NEXT:    [[X_1:%.*]] = trunc i32 [[X_321]] to i8
1294; CHECK-NEXT:    [[X_32:%.*]] = lshr i32 [[X]], 16
1295; CHECK-NEXT:    [[X_2:%.*]] = trunc i32 [[X_32]] to i8
1296; CHECK-NEXT:    [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
1297; CHECK-NEXT:    [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
1298; CHECK-NEXT:    [[Y_32:%.*]] = lshr i32 [[Y]], 16
1299; CHECK-NEXT:    [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
1300; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
1301; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
1302; CHECK-NEXT:    [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
1303; CHECK-NEXT:    ret i1 [[C_210]]
1304;
1305  %x.321 = lshr i32 %x, 8
1306  %x.1 = trunc i32 %x.321 to i8
1307  %x.32 = lshr i32 %x, 16
1308  %x.2 = trunc i32 %x.32 to i8
1309  %y.321 = lshr i32 %y, 8
1310  %y.1 = trunc i32 %y.321 to i8
1311  %y.32 = lshr i32 %y, 16
1312  %y.2 = trunc i32 %y.32 to i8
1313  %c.1 = icmp eq i8 %x.1, %y.1
1314  %c.2 = icmp eq i8 %x.2, %y.2
1315  %c.210 = or i1 %c.2, %c.1
1316  ret i1 %c.210
1317}
1318
1319define i1 @eq_optimized_highbits_cmp(i32 %x, i32 %y) {
1320; CHECK-LABEL: @eq_optimized_highbits_cmp(
1321; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[Y:%.*]], [[X:%.*]]
1322; CHECK-NEXT:    ret i1 [[R]]
1323;
1324  %xor = xor i32 %y, %x
1325  %cmp_hi = icmp ult i32 %xor, 33554432
1326  %tx = trunc i32 %x to i25
1327  %ty = trunc i32 %y to i25
1328  %cmp_lo = icmp eq i25 %tx, %ty
1329  %r = and i1 %cmp_hi, %cmp_lo
1330  ret i1 %r
1331}
1332
1333define i1 @eq_optimized_highbits_cmp_todo_overlapping(i32 %x, i32 %y) {
1334; CHECK-LABEL: @eq_optimized_highbits_cmp_todo_overlapping(
1335; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1336; CHECK-NEXT:    [[CMP_HI:%.*]] = icmp ult i32 [[XOR]], 16777216
1337; CHECK-NEXT:    [[TX:%.*]] = trunc i32 [[X]] to i25
1338; CHECK-NEXT:    [[TY:%.*]] = trunc i32 [[Y]] to i25
1339; CHECK-NEXT:    [[CMP_LO:%.*]] = icmp eq i25 [[TX]], [[TY]]
1340; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP_HI]], [[CMP_LO]]
1341; CHECK-NEXT:    ret i1 [[R]]
1342;
1343  %xor = xor i32 %y, %x
1344  %cmp_hi = icmp ult i32 %xor, 16777216
1345  %tx = trunc i32 %x to i25
1346  %ty = trunc i32 %y to i25
1347  %cmp_lo = icmp eq i25 %tx, %ty
1348  %r = and i1 %cmp_hi, %cmp_lo
1349  ret i1 %r
1350}
1351
1352define i1 @eq_optimized_highbits_cmp_fail_not_pow2(i32 %x, i32 %y) {
1353; CHECK-LABEL: @eq_optimized_highbits_cmp_fail_not_pow2(
1354; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1355; CHECK-NEXT:    [[CMP_HI:%.*]] = icmp ult i32 [[XOR]], 16777215
1356; CHECK-NEXT:    [[TX:%.*]] = trunc i32 [[X]] to i24
1357; CHECK-NEXT:    [[TY:%.*]] = trunc i32 [[Y]] to i24
1358; CHECK-NEXT:    [[CMP_LO:%.*]] = icmp eq i24 [[TX]], [[TY]]
1359; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP_HI]], [[CMP_LO]]
1360; CHECK-NEXT:    ret i1 [[R]]
1361;
1362  %xor = xor i32 %y, %x
1363  %cmp_hi = icmp ult i32 %xor, 16777215
1364  %tx = trunc i32 %x to i24
1365  %ty = trunc i32 %y to i24
1366  %cmp_lo = icmp eq i24 %tx, %ty
1367  %r = and i1 %cmp_hi, %cmp_lo
1368  ret i1 %r
1369}
1370
1371define i1 @ne_optimized_highbits_cmp(i32 %x, i32 %y) {
1372; CHECK-LABEL: @ne_optimized_highbits_cmp(
1373; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[Y:%.*]], [[X:%.*]]
1374; CHECK-NEXT:    ret i1 [[R]]
1375;
1376  %xor = xor i32 %y, %x
1377  %cmp_hi = icmp ugt i32 %xor, 16777215
1378  %tx = trunc i32 %x to i24
1379  %ty = trunc i32 %y to i24
1380  %cmp_lo = icmp ne i24 %tx, %ty
1381  %r = or i1 %cmp_hi, %cmp_lo
1382  ret i1 %r
1383}
1384
1385define i1 @ne_optimized_highbits_cmp_fail_not_mask(i32 %x, i32 %y) {
1386; CHECK-LABEL: @ne_optimized_highbits_cmp_fail_not_mask(
1387; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1388; CHECK-NEXT:    [[CMP_HI:%.*]] = icmp ugt i32 [[XOR]], 16777216
1389; CHECK-NEXT:    [[TX:%.*]] = trunc i32 [[X]] to i24
1390; CHECK-NEXT:    [[TY:%.*]] = trunc i32 [[Y]] to i24
1391; CHECK-NEXT:    [[CMP_LO:%.*]] = icmp ne i24 [[TX]], [[TY]]
1392; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP_HI]], [[CMP_LO]]
1393; CHECK-NEXT:    ret i1 [[R]]
1394;
1395  %xor = xor i32 %y, %x
1396  %cmp_hi = icmp ugt i32 %xor, 16777216
1397  %tx = trunc i32 %x to i24
1398  %ty = trunc i32 %y to i24
1399  %cmp_lo = icmp ne i24 %tx, %ty
1400  %r = or i1 %cmp_hi, %cmp_lo
1401  ret i1 %r
1402}
1403
1404define i1 @ne_optimized_highbits_cmp_fail_no_combined_int(i32 %x, i32 %y) {
1405; CHECK-LABEL: @ne_optimized_highbits_cmp_fail_no_combined_int(
1406; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1407; CHECK-NEXT:    [[CMP_HI:%.*]] = icmp ugt i32 [[XOR]], 16777215
1408; CHECK-NEXT:    [[TX:%.*]] = trunc i32 [[X]] to i23
1409; CHECK-NEXT:    [[TY:%.*]] = trunc i32 [[Y]] to i23
1410; CHECK-NEXT:    [[CMP_LO:%.*]] = icmp ne i23 [[TX]], [[TY]]
1411; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP_HI]], [[CMP_LO]]
1412; CHECK-NEXT:    ret i1 [[R]]
1413;
1414  %xor = xor i32 %y, %x
1415  %cmp_hi = icmp ugt i32 %xor, 16777215
1416  %tx = trunc i32 %x to i23
1417  %ty = trunc i32 %y to i23
1418  %cmp_lo = icmp ne i23 %tx, %ty
1419  %r = or i1 %cmp_hi, %cmp_lo
1420  ret i1 %r
1421}
1422
1423define i1 @ne_optimized_highbits_cmp_todo_overlapping(i32 %x, i32 %y) {
1424; CHECK-LABEL: @ne_optimized_highbits_cmp_todo_overlapping(
1425; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1426; CHECK-NEXT:    [[CMP_HI:%.*]] = icmp ugt i32 [[XOR]], 8388607
1427; CHECK-NEXT:    [[TX:%.*]] = trunc i32 [[X]] to i24
1428; CHECK-NEXT:    [[TY:%.*]] = trunc i32 [[Y]] to i24
1429; CHECK-NEXT:    [[CMP_LO:%.*]] = icmp ne i24 [[TX]], [[TY]]
1430; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP_HI]], [[CMP_LO]]
1431; CHECK-NEXT:    ret i1 [[R]]
1432;
1433  %xor = xor i32 %y, %x
1434  %cmp_hi = icmp ugt i32 %xor, 8388607
1435  %tx = trunc i32 %x to i24
1436  %ty = trunc i32 %y to i24
1437  %cmp_lo = icmp ne i24 %tx, %ty
1438  %r = or i1 %cmp_hi, %cmp_lo
1439  ret i1 %r
1440}
1441
1442define i1 @and_trunc_i1(i8 %a1, i8 %a2) {
1443; CHECK-LABEL: @and_trunc_i1(
1444; CHECK-NEXT:    [[AND:%.*]] = icmp eq i8 [[A1:%.*]], [[A2:%.*]]
1445; CHECK-NEXT:    ret i1 [[AND]]
1446;
1447  %xor = xor i8 %a1, %a2
1448  %cmp = icmp ult i8 %xor, 2
1449  %lobit = trunc i8 %xor to i1
1450  %lobit.inv = xor i1 %lobit, true
1451  %and = and i1 %cmp, %lobit.inv
1452  ret i1 %and
1453}
1454
1455define i1 @and_trunc_i1_wrong_const(i8 %a1, i8 %a2) {
1456; CHECK-LABEL: @and_trunc_i1_wrong_const(
1457; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[A1:%.*]], [[A2:%.*]]
1458; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[XOR]], 4
1459; CHECK-NEXT:    [[LOBIT:%.*]] = trunc i8 [[XOR]] to i1
1460; CHECK-NEXT:    [[LOBIT_INV:%.*]] = xor i1 [[LOBIT]], true
1461; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[LOBIT_INV]]
1462; CHECK-NEXT:    ret i1 [[AND]]
1463;
1464  %xor = xor i8 %a1, %a2
1465  %cmp = icmp ult i8 %xor, 4
1466  %lobit = trunc i8 %xor to i1
1467  %lobit.inv = xor i1 %lobit, true
1468  %and = and i1 %cmp, %lobit.inv
1469  ret i1 %and
1470}
1471
1472define i1 @and_trunc_i1_wrong_operands(i8 %a1, i8 %a2, i8 %a3) {
1473; CHECK-LABEL: @and_trunc_i1_wrong_operands(
1474; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[A1:%.*]], [[A2:%.*]]
1475; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[XOR]], 2
1476; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[A1]], [[A3:%.*]]
1477; CHECK-NEXT:    [[LOBIT:%.*]] = trunc i8 [[XOR2]] to i1
1478; CHECK-NEXT:    [[LOBIT_INV:%.*]] = xor i1 [[LOBIT]], true
1479; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[LOBIT_INV]]
1480; CHECK-NEXT:    ret i1 [[AND]]
1481;
1482  %xor = xor i8 %a1, %a2
1483  %cmp = icmp ult i8 %xor, 2
1484  %xor2 = xor i8 %a1, %a3
1485  %lobit = trunc i8 %xor2 to i1
1486  %lobit.inv = xor i1 %lobit, true
1487  %and = and i1 %cmp, %lobit.inv
1488  ret i1 %and
1489}
1490
1491define i1 @or_trunc_i1(i64 %a1, i64 %a2) {
1492; CHECK-LABEL: @or_trunc_i1(
1493; CHECK-NEXT:    [[OR:%.*]] = icmp ne i64 [[A2:%.*]], [[A1:%.*]]
1494; CHECK-NEXT:    ret i1 [[OR]]
1495;
1496  %xor = xor i64 %a2, %a1
1497  %cmp = icmp ugt i64 %xor, 1
1498  %trunc = trunc i64 %xor to i1
1499  %or = or i1 %cmp, %trunc
1500  ret i1 %or
1501}
1502
1503define i1 @or_trunc_i1_wrong_const(i64 %a1, i64 %a2) {
1504; CHECK-LABEL: @or_trunc_i1_wrong_const(
1505; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[A2:%.*]], [[A1:%.*]]
1506; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[XOR]], 2
1507; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[XOR]] to i1
1508; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP]], [[TRUNC]]
1509; CHECK-NEXT:    ret i1 [[OR]]
1510;
1511  %xor = xor i64 %a2, %a1
1512  %cmp = icmp ugt i64 %xor, 2
1513  %trunc = trunc i64 %xor to i1
1514  %or = or i1 %cmp, %trunc
1515  ret i1 %or
1516}
1517
1518define i1 @or_trunc_i1_wrong_operands(i64 %a1, i64 %a2, i64 %a3) {
1519; CHECK-LABEL: @or_trunc_i1_wrong_operands(
1520; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[A2:%.*]], [[A1:%.*]]
1521; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[XOR]], 1
1522; CHECK-NEXT:    [[XOR2:%.*]] = xor i64 [[A3:%.*]], [[A1]]
1523; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[XOR2]] to i1
1524; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP]], [[TRUNC]]
1525; CHECK-NEXT:    ret i1 [[OR]]
1526;
1527  %xor = xor i64 %a2, %a1
1528  %cmp = icmp ugt i64 %xor, 1
1529  %xor2 = xor i64 %a3, %a1
1530  %trunc = trunc i64 %xor2 to i1
1531  %or = or i1 %cmp, %trunc
1532  ret i1 %or
1533}
1534
1535define i1 @jv_identical(i64 %arg1, i64 %arg2) {
1536; CHECK-LABEL: @jv_identical(
1537; CHECK-NEXT:    [[ARG1_TRUNC:%.*]] = trunc i64 [[ARG1:%.*]] to i8
1538; CHECK-NEXT:    [[ARG2_TRUNC:%.*]] = trunc i64 [[ARG2:%.*]] to i8
1539; CHECK-NEXT:    [[EQ1:%.*]] = icmp eq i8 [[ARG1_TRUNC]], [[ARG2_TRUNC]]
1540; CHECK-NEXT:    [[DOTUNSHIFTED:%.*]] = xor i64 [[ARG2]], [[ARG1]]
1541; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[DOTUNSHIFTED]], 65536
1542; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[EQ1]], [[TMP1]]
1543; CHECK-NEXT:    ret i1 [[AND2]]
1544;
1545  %arg1.trunc = trunc i64 %arg1 to i8
1546  %arg1.shift = lshr i64 %arg1, 16
1547  %arg1.shift.trunc = trunc i64 %arg1.shift to i16
1548  %arg2.trunc = trunc i64 %arg2 to i8
1549  %arg2.shift = lshr i64 %arg2, 16
1550  %arg2.shift.trunc = trunc i64 %arg2.shift to i16
1551  %eq1 = icmp eq i8 %arg1.trunc, %arg2.trunc
1552  %eq2 = icmp eq i16 %arg1.shift.trunc, %arg2.shift.trunc
1553  %and1 = and i1 %eq1, %eq2
1554  %xor = xor i64 %arg2, %arg1
1555  %cmp = icmp ult i64 %xor, 4294967296
1556  %and2 = and i1 %cmp, %and1
1557  ret i1 %and2
1558}
1559