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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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