Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / eq-of-parts.ll
blob217e37b85933949fa4e706de2528b1b0dde4d1c8
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 ; Combine equality comparisons of adjacent extracted integers parts into
5 ; a comparison of a larger part. Start with some examples...
7 declare void @use.i32(i32)
8 declare void @use.i8(i8)
9 declare void @use.i1(i1)
11 define 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]]
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
30 define 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]]
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
55 define 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]]
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
84 define 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]]
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
107 ; Test commuted variants of eq_21.
109 define 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]]
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
132 define 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]]
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
155 define 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]]
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
178 ; Test vector variant.
180 define <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:%.*]], <i32 8, i32 8>
183 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
184 ; CHECK-NEXT:    [[TMP3:%.*]] = lshr <2 x i32> [[Y:%.*]], <i32 8, 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]]
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
203 ; Test irregular bit widths. This also tests the case where
204 ; all the involved bit widths and offsets are different.
206 define 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]]
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
229 ; Test variants with extra uses.
231 define 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]]
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
262 define 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]]
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
293 define 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]]
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
324 define 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]]
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
355 ; Logical and instead of bitwise and.
357 define 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]]
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
380 ; Negative tests.
382 define 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]]
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
411 define 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]]
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
440 define 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]]
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
469 define 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]]
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
498 define 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]]
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
527 define 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]]
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
556 define 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]]
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
585 define 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]]
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
605 define 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]]
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
634 define 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]]
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
664 ; Now the same thing again, but for or ne instead of and eq.
667 define 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]]
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
686 define 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]]
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
711 define 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]]
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
740 define 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]]
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
763 ; Test commuted variants of ne_21.
765 define 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]]
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
788 define 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]]
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
811 define 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]]
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
834 ; Test vector variant.
836 define <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:%.*]], <i32 8, i32 8>
839 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
840 ; CHECK-NEXT:    [[TMP3:%.*]] = lshr <2 x i32> [[Y:%.*]], <i32 8, 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]]
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
859 ; Test irregular bit widths. This also tests the case where
860 ; all the involved bit widths or offsets are different.
862 define 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]]
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
885 ; Test variants with extra uses.
887 define 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]]
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
918 define 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]]
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
949 define 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]]
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
980 define 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]]
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
1011 ; Logical or instead of bitwise or.
1013 define 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]]
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
1036 ; Negative tests.
1038 define 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]]
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
1067 define 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]]
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
1096 define 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]]
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
1125 define 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]]
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
1154 define 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]]
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
1183 define 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]]
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
1212 define 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]]
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
1241 define 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]]
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
1261 define 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]]
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
1290 define 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]]
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
1319 define 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]]
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
1333 define 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]]
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
1352 define 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]]
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
1371 define 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]]
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
1385 define 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]]
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
1404 define 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]]
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
1423 define 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]]
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