1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define i8 @shl_and_and(i8 %x, i8 %y) {
5 ; CHECK-LABEL: @shl_and_and(
6 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]
7 ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 4
8 ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[TMP2]], 80
9 ; CHECK-NEXT: ret i8 [[BW1]]
11 %shift1 = shl i8 %x, 4
12 %shift2 = shl i8 %y, 4
13 %bw2 = and i8 %shift2, 88
14 %bw1 = and i8 %shift1, %bw2
18 define i8 @shl_and_and_fail(i8 %x, i8 %y) {
19 ; CHECK-LABEL: @shl_and_and_fail(
20 ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 4
21 ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 5
22 ; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 64
23 ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]]
24 ; CHECK-NEXT: ret i8 [[BW1]]
26 %shift1 = shl i8 %x, 4
27 %shift2 = shl i8 %y, 5
28 %bw2 = and i8 %shift2, 88
29 %bw1 = and i8 %shift1, %bw2
33 define i8 @shl_add_add(i8 %x, i8 %y) {
34 ; CHECK-LABEL: @shl_add_add(
35 ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]
36 ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 2
37 ; CHECK-NEXT: [[BW1:%.*]] = add i8 [[TMP2]], 48
38 ; CHECK-NEXT: ret i8 [[BW1]]
40 %shift1 = shl i8 %x, 2
41 %shift2 = shl i8 %y, 2
42 %bw2 = add i8 %shift2, 48
43 %bw1 = add i8 %shift1, %bw2
47 define i8 @shl_add_add_fail(i8 %x, i8 %y) {
48 ; CHECK-LABEL: @shl_add_add_fail(
49 ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 2
50 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 2
51 ; CHECK-NEXT: [[BW2:%.*]] = add nuw nsw i8 [[SHIFT2]], 48
52 ; CHECK-NEXT: [[BW1:%.*]] = add nuw i8 [[SHIFT1]], [[BW2]]
53 ; CHECK-NEXT: ret i8 [[BW1]]
55 %shift1 = lshr i8 %x, 2
56 %shift2 = lshr i8 %y, 2
57 %bw2 = add i8 %shift2, 48
58 %bw1 = add i8 %shift1, %bw2
62 define i8 @shl_and_and_fail2(i8 %x, i8 %y) {
63 ; CHECK-LABEL: @shl_and_and_fail2(
64 ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 4, [[X:%.*]]
65 ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 4, [[Y:%.*]]
66 ; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 88
67 ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]]
68 ; CHECK-NEXT: ret i8 [[BW1]]
70 %shift1 = shl i8 4, %x
71 %shift2 = shl i8 4, %y
72 %bw2 = and i8 %shift2, 88
73 %bw1 = and i8 %shift1, %bw2
77 define <2 x i8> @lshr_and_or(<2 x i8> %x, <2 x i8> %y) {
78 ; CHECK-LABEL: @lshr_and_or(
79 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -64, i8 96>
80 ; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i8> [[Y:%.*]], [[TMP1]]
81 ; CHECK-NEXT: [[BW1:%.*]] = lshr <2 x i8> [[TMP2]], <i8 4, i8 5>
82 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
84 %shift1 = lshr <2 x i8> %x, <i8 4, i8 5>
85 %shift2 = lshr <2 x i8> %y, <i8 4, i8 5>
86 %bw2 = and <2 x i8> %shift1, <i8 44, i8 99>
87 %bw1 = or <2 x i8> %shift2, %bw2
91 define <2 x i8> @lshr_and_or_fail(<2 x i8> %x, <2 x i8> %y) {
92 ; CHECK-LABEL: @lshr_and_or_fail(
93 ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 5>
94 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], <i8 5, i8 4>
95 ; CHECK-NEXT: [[BW2:%.*]] = and <2 x i8> [[SHIFT2]], <i8 44, i8 99>
96 ; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[SHIFT1]], [[BW2]]
97 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
99 %shift1 = lshr <2 x i8> %x, <i8 4, i8 5>
100 %shift2 = lshr <2 x i8> %y, <i8 5, i8 4>
101 %bw2 = and <2 x i8> %shift2, <i8 44, i8 99>
102 %bw1 = or <2 x i8> %shift1, %bw2
106 define i8 @shl_and_xor(i8 %x, i8 %y) {
107 ; CHECK-LABEL: @shl_and_xor(
108 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 10
109 ; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[Y:%.*]], [[TMP1]]
110 ; CHECK-NEXT: [[BW1:%.*]] = shl i8 [[TMP2]], 1
111 ; CHECK-NEXT: ret i8 [[BW1]]
113 %shift1 = shl i8 %x, 1
114 %shift2 = shl i8 %y, 1
115 %bw2 = and i8 %shift1, 20
116 %bw1 = xor i8 %shift2, %bw2
120 define i8 @shl_and_add(i8 %x, i8 %y) {
121 ; CHECK-LABEL: @shl_and_add(
122 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], 59
123 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X:%.*]], [[TMP1]]
124 ; CHECK-NEXT: [[BW1:%.*]] = shl i8 [[TMP2]], 1
125 ; CHECK-NEXT: ret i8 [[BW1]]
127 %shift1 = shl i8 %x, 1
128 %shift2 = shl i8 %y, 1
129 %bw2 = and i8 %shift2, 119
130 %bw1 = add i8 %shift1, %bw2
134 define i8 @shl_xor_add_fail(i8 %x, i8 %y) {
135 ; CHECK-LABEL: @shl_xor_add_fail(
136 ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 1
137 ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 1
138 ; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], 119
139 ; CHECK-NEXT: [[BW1:%.*]] = add i8 [[SHIFT1]], [[BW2]]
140 ; CHECK-NEXT: ret i8 [[BW1]]
142 %shift1 = shl i8 %x, 1
143 %shift2 = shl i8 %y, 1
144 %bw2 = xor i8 %shift2, 119
145 %bw1 = add i8 %shift1, %bw2
149 define i8 @lshr_or_and(i8 %x, i8 %y) {
150 ; CHECK-LABEL: @lshr_or_and(
151 ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], -64
152 ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[Y:%.*]], [[TMP1]]
153 ; CHECK-NEXT: [[BW1:%.*]] = lshr i8 [[TMP2]], 5
154 ; CHECK-NEXT: ret i8 [[BW1]]
156 %shift1 = lshr i8 %x, 5
157 %shift2 = lshr i8 %y, 5
158 %bw2 = or i8 %shift1, 198
159 %bw1 = and i8 %bw2, %shift2
163 define i8 @lshr_or_or_fail(i8 %x, i8 %y) {
164 ; CHECK-LABEL: @lshr_or_or_fail(
165 ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
166 ; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 5
167 ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[TMP2]], -58
168 ; CHECK-NEXT: ret i8 [[BW1]]
170 %shift1 = lshr i8 %x, 5
171 %shift2 = lshr i8 %y, 5
172 %bw2 = or i8 %shift2, 198
173 %bw1 = or i8 %shift1, %bw2
177 define <2 x i8> @shl_xor_and(<2 x i8> %x, <2 x i8> %y) {
178 ; CHECK-LABEL: @shl_xor_and(
179 ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[Y:%.*]], <i8 11, i8 poison>
180 ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[X:%.*]], [[TMP1]]
181 ; CHECK-NEXT: [[BW1:%.*]] = shl <2 x i8> [[TMP2]], <i8 2, i8 poison>
182 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
184 %shift1 = shl <2 x i8> %x, <i8 2, i8 poison>
185 %shift2 = shl <2 x i8> %y, <i8 2, i8 poison>
186 %bw2 = xor <2 x i8> %shift2, <i8 44, i8 poison>
187 %bw1 = and <2 x i8> %bw2, %shift1
191 define <2 x i8> @shl_xor_and_fail(<2 x i8> %x, <2 x i8> %y) {
192 ; CHECK-LABEL: @shl_xor_and_fail(
193 ; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 2, i8 poison>
194 ; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], <i8 poison, i8 2>
195 ; CHECK-NEXT: [[BW2:%.*]] = xor <2 x i8> [[SHIFT2]], <i8 44, i8 poison>
196 ; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[SHIFT1]], [[BW2]]
197 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
199 %shift1 = shl <2 x i8> %x, <i8 2, i8 poison>
200 %shift2 = shl <2 x i8> %y, <i8 poison, i8 2>
201 %bw2 = xor <2 x i8> %shift2, <i8 44, i8 poison>
202 %bw1 = and <2 x i8> %shift1, %bw2
206 define i8 @lshr_or_or_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) {
207 ; CHECK-LABEL: @lshr_or_or_no_const(
208 ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
209 ; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SH:%.*]]
210 ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[TMP2]], [[MASK:%.*]]
211 ; CHECK-NEXT: ret i8 [[BW1]]
213 %shift1 = lshr i8 %x, %sh
214 %shift2 = lshr i8 %y, %sh
215 %bw2 = or i8 %shift2, %mask
216 %bw1 = or i8 %shift1, %bw2
220 define i8 @lshr_or_or_no_const_fail(i8 %x, i8 %y, i8 %sh, i8 %mask) {
221 ; CHECK-LABEL: @lshr_or_or_no_const_fail(
222 ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], [[SH:%.*]]
223 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], [[SH]]
224 ; CHECK-NEXT: [[BW2:%.*]] = or i8 [[SHIFT2]], [[MASK:%.*]]
225 ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]]
226 ; CHECK-NEXT: ret i8 [[BW1]]
228 %shift1 = shl i8 %x, %sh
229 %shift2 = lshr i8 %y, %sh
230 %bw2 = or i8 %shift2, %mask
231 %bw1 = or i8 %shift1, %bw2
235 define i8 @shl_xor_xor_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) {
236 ; CHECK-LABEL: @shl_xor_xor_no_const(
237 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]
238 ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SH:%.*]]
239 ; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP2]], [[MASK:%.*]]
240 ; CHECK-NEXT: ret i8 [[BW1]]
242 %shift1 = shl i8 %x, %sh
243 %shift2 = shl i8 %y, %sh
244 %bw2 = xor i8 %shift2, %mask
245 %bw1 = xor i8 %shift1, %bw2
249 define i8 @shl_xor_and_no_const_fail(i8 %x, i8 %y, i8 %sh, i8 %mask) {
250 ; CHECK-LABEL: @shl_xor_and_no_const_fail(
251 ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], [[SH:%.*]]
252 ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], [[SH]]
253 ; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], [[MASK:%.*]]
254 ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]]
255 ; CHECK-NEXT: ret i8 [[BW1]]
257 %shift1 = shl i8 %x, %sh
258 %shift2 = shl i8 %y, %sh
259 %bw2 = xor i8 %shift2, %mask
260 %bw1 = and i8 %shift1, %bw2
264 define <2 x i8> @shl_and_and_no_const(<2 x i8> %x, <2 x i8> %y, <2 x i8> %sh, <2 x i8> %mask) {
265 ; CHECK-LABEL: @shl_and_and_no_const(
266 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[Y:%.*]], [[X:%.*]]
267 ; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[TMP1]], [[SH:%.*]]
268 ; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[TMP2]], [[MASK:%.*]]
269 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
271 %shift1 = shl <2 x i8> %x, %sh
272 %shift2 = shl <2 x i8> %y, %sh
273 %bw2 = and <2 x i8> %shift2, %mask
274 %bw1 = and <2 x i8> %shift1, %bw2
278 define i8 @shl_add_add_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) {
279 ; CHECK-LABEL: @shl_add_add_no_const(
280 ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]
281 ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SH:%.*]]
282 ; CHECK-NEXT: [[BW1:%.*]] = add i8 [[TMP2]], [[MASK:%.*]]
283 ; CHECK-NEXT: ret i8 [[BW1]]
285 %shift1 = shl i8 %x, %sh
286 %shift2 = shl i8 %y, %sh
287 %bw2 = add i8 %shift2, %mask
288 %bw1 = add i8 %shift1, %bw2
292 define i8 @lshr_add_add_no_const_fail(i8 %x, i8 %y, i8 %sh, i8 %mask) {
293 ; CHECK-LABEL: @lshr_add_add_no_const_fail(
294 ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], [[SH:%.*]]
295 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], [[SH]]
296 ; CHECK-NEXT: [[BW2:%.*]] = add i8 [[SHIFT2]], [[MASK:%.*]]
297 ; CHECK-NEXT: [[BW1:%.*]] = add i8 [[SHIFT1]], [[BW2]]
298 ; CHECK-NEXT: ret i8 [[BW1]]
300 %shift1 = lshr i8 %x, %sh
301 %shift2 = lshr i8 %y, %sh
302 %bw2 = add i8 %shift2, %mask
303 %bw1 = add i8 %shift1, %bw2
307 define <2 x i8> @lshr_add_and(<2 x i8> %x, <2 x i8> %y) {
308 ; CHECK-LABEL: @lshr_add_and(
309 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[Y:%.*]], <i8 -8, i8 16>
310 ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[X:%.*]], [[TMP1]]
311 ; CHECK-NEXT: [[BW1:%.*]] = lshr <2 x i8> [[TMP2]], <i8 3, i8 4>
312 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
314 %shift1 = lshr <2 x i8> %x, <i8 3, i8 4>
315 %shift2 = lshr <2 x i8> %y, <i8 3, i8 4>
316 %bw2 = add <2 x i8> %shift2, <i8 255, i8 1>
317 %bw1 = and <2 x i8> %shift1, %bw2
321 define <2 x i8> @lshr_add_or_fail_dif_masks(<2 x i8> %x, <2 x i8> %y) {
322 ; CHECK-LABEL: @lshr_add_or_fail_dif_masks(
323 ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 3, i8 4>
324 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], <i8 poison, i8 3>
325 ; CHECK-NEXT: [[BW2:%.*]] = add nsw <2 x i8> [[SHIFT2]], <i8 -1, i8 1>
326 ; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[SHIFT1]], [[BW2]]
327 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
329 %shift1 = lshr <2 x i8> %x, <i8 3, i8 4>
330 %shift2 = lshr <2 x i8> %y, <i8 poison, i8 3>
331 %bw2 = add <2 x i8> %shift2, <i8 255, i8 1>
332 %bw1 = and <2 x i8> %shift1, %bw2
336 define <2 x i8> @shl_or_or_good_mask(<2 x i8> %x, <2 x i8> %y) {
337 ; CHECK-LABEL: @shl_or_or_good_mask(
338 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[Y:%.*]], [[X:%.*]]
339 ; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[TMP1]], splat (i8 1)
340 ; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[TMP2]], <i8 18, i8 24>
341 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
343 %shift1 = shl <2 x i8> %x, <i8 1, i8 1>
344 %shift2 = shl <2 x i8> %y, <i8 1, i8 1>
345 %bw2 = or <2 x i8> %shift2, <i8 18, i8 24>
346 %bw1 = or <2 x i8> %shift1, %bw2
350 define <2 x i8> @shl_or_or_fail_bad_mask(<2 x i8> %x, <2 x i8> %y) {
351 ; CHECK-LABEL: @shl_or_or_fail_bad_mask(
352 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[Y:%.*]], [[X:%.*]]
353 ; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[TMP1]], splat (i8 1)
354 ; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[TMP2]], <i8 19, i8 24>
355 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
357 %shift1 = shl <2 x i8> %x, <i8 1, i8 1>
358 %shift2 = shl <2 x i8> %y, <i8 1, i8 1>
359 %bw2 = or <2 x i8> %shift2, <i8 19, i8 24>
360 %bw1 = or <2 x i8> %shift1, %bw2
364 define i8 @lshr_xor_or_good_mask(i8 %x, i8 %y) {
365 ; CHECK-LABEL: @lshr_xor_or_good_mask(
366 ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
367 ; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 4
368 ; CHECK-NEXT: [[BW1:%.*]] = or disjoint i8 [[TMP2]], 48
369 ; CHECK-NEXT: ret i8 [[BW1]]
371 %shift1 = lshr i8 %x, 4
372 %shift2 = lshr i8 %y, 4
373 %bw2 = xor i8 %shift2, 48
374 %bw1 = or i8 %shift1, %bw2
378 define i8 @lshr_xor_or_fail_bad_mask(i8 %x, i8 %y) {
379 ; CHECK-LABEL: @lshr_xor_or_fail_bad_mask(
380 ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 6
381 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 6
382 ; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], -127
383 ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]]
384 ; CHECK-NEXT: ret i8 [[BW1]]
386 %shift1 = lshr i8 %x, 6
387 %shift2 = lshr i8 %y, 6
388 %bw2 = xor i8 %shift2, 129
389 %bw1 = or i8 %shift1, %bw2
393 define <2 x i8> @lshr_or_xor_good_mask(<2 x i8> %x, <2 x i8> %y) {
394 ; CHECK-LABEL: @lshr_or_xor_good_mask(
395 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[Y:%.*]], <i8 -64, i8 64>
396 ; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i8> [[X:%.*]], [[TMP1]]
397 ; CHECK-NEXT: [[BW1:%.*]] = lshr <2 x i8> [[TMP2]], splat (i8 6)
398 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
400 %shift1 = lshr <2 x i8> %x, <i8 6, i8 6>
401 %shift2 = lshr <2 x i8> %y, <i8 6, i8 6>
402 %bw2 = or <2 x i8> %shift2, <i8 3, i8 1>
403 %bw1 = xor <2 x i8> %shift1, %bw2
407 define <2 x i8> @lshr_or_xor_fail_bad_mask(<2 x i8> %x, <2 x i8> %y) {
408 ; CHECK-LABEL: @lshr_or_xor_fail_bad_mask(
409 ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], splat (i8 6)
410 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], splat (i8 6)
411 ; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[SHIFT2]], <i8 7, i8 1>
412 ; CHECK-NEXT: [[BW1:%.*]] = xor <2 x i8> [[SHIFT1]], [[BW2]]
413 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
415 %shift1 = lshr <2 x i8> %x, <i8 6, i8 6>
416 %shift2 = lshr <2 x i8> %y, <i8 6, i8 6>
417 %bw2 = or <2 x i8> %shift2, <i8 7, i8 1>
418 %bw1 = xor <2 x i8> %shift1, %bw2
422 define i8 @shl_xor_xor_good_mask(i8 %x, i8 %y) {
423 ; CHECK-LABEL: @shl_xor_xor_good_mask(
424 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]
425 ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 1
426 ; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP2]], 88
427 ; CHECK-NEXT: ret i8 [[BW1]]
429 %shift1 = shl i8 %x, 1
430 %shift2 = shl i8 %y, 1
431 %bw2 = xor i8 %shift2, 88
432 %bw1 = xor i8 %shift1, %bw2
436 define i8 @shl_xor_xor_bad_mask_distribute(i8 %x, i8 %y) {
437 ; CHECK-LABEL: @shl_xor_xor_bad_mask_distribute(
438 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]
439 ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 1
440 ; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP2]], -68
441 ; CHECK-NEXT: ret i8 [[BW1]]
443 %shift1 = shl i8 %x, 1
444 %shift2 = shl i8 %y, 1
445 %bw2 = xor i8 %shift2, 188
446 %bw1 = xor i8 %shift1, %bw2
450 define i8 @shl_add_and(i8 %x, i8 %y) {
451 ; CHECK-LABEL: @shl_add_and(
452 ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], 61
453 ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
454 ; CHECK-NEXT: [[BW1:%.*]] = shl i8 [[TMP2]], 1
455 ; CHECK-NEXT: ret i8 [[BW1]]
457 %shift1 = shl i8 %x, 1
458 %shift2 = shl i8 %y, 1
459 %bw2 = add i8 %shift2, 123
460 %bw1 = and i8 %shift1, %bw2
464 define i8 @lshr_and_add_fail(i8 %x, i8 %y) {
465 ; CHECK-LABEL: @lshr_and_add_fail(
466 ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 1
467 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1
468 ; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 123
469 ; CHECK-NEXT: [[BW1:%.*]] = add nuw i8 [[SHIFT1]], [[BW2]]
470 ; CHECK-NEXT: ret i8 [[BW1]]
472 %shift1 = lshr i8 %x, 1
473 %shift2 = lshr i8 %y, 1
474 %bw2 = and i8 %shift2, 123
475 %bw1 = add i8 %shift1, %bw2
479 define i8 @lshr_add_or_fail(i8 %x, i8 %y) {
480 ; CHECK-LABEL: @lshr_add_or_fail(
481 ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 1
482 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1
483 ; CHECK-NEXT: [[BW2:%.*]] = add nuw i8 [[SHIFT2]], 123
484 ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]]
485 ; CHECK-NEXT: ret i8 [[BW1]]
487 %shift1 = lshr i8 %x, 1
488 %shift2 = lshr i8 %y, 1
489 %bw2 = add i8 %shift2, 123
490 %bw1 = or i8 %shift1, %bw2
494 define i8 @lshr_add_xor_fail(i8 %x, i8 %y) {
495 ; CHECK-LABEL: @lshr_add_xor_fail(
496 ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 1
497 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1
498 ; CHECK-NEXT: [[BW2:%.*]] = add nuw i8 [[SHIFT2]], 123
499 ; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[SHIFT1]], [[BW2]]
500 ; CHECK-NEXT: ret i8 [[BW1]]
502 %shift1 = lshr i8 %x, 1
503 %shift2 = lshr i8 %y, 1
504 %bw2 = add i8 %shift2, 123
505 %bw1 = xor i8 %shift1, %bw2
509 define <2 x i8> @lshr_and_add(<2 x i8> %x, <2 x i8> %y) {
510 ; CHECK-LABEL: @lshr_and_add(
511 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 11, i8 3>
512 ; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[Y:%.*]], [[TMP1]]
513 ; CHECK-NEXT: [[BW1:%.*]] = shl <2 x i8> [[TMP2]], <i8 4, i8 5>
514 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
516 %shift1 = shl <2 x i8> %x, <i8 4, i8 5>
517 %shift2 = shl <2 x i8> %y, <i8 4, i8 5>
518 %bw2 = and <2 x i8> %shift1, <i8 189, i8 123>
519 %bw1 = add <2 x i8> %shift2, %bw2
523 define <2 x i8> @lshr_or_add_fail(<2 x i8> %x, <2 x i8> %y) {
524 ; CHECK-LABEL: @lshr_or_add_fail(
525 ; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 4, i8 5>
526 ; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], <i8 4, i8 5>
527 ; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[SHIFT1]], <i8 -67, i8 123>
528 ; CHECK-NEXT: [[BW1:%.*]] = add <2 x i8> [[SHIFT2]], [[BW2]]
529 ; CHECK-NEXT: ret <2 x i8> [[BW1]]
531 %shift1 = shl <2 x i8> %x, <i8 4, i8 5>
532 %shift2 = shl <2 x i8> %y, <i8 4, i8 5>
533 %bw2 = or <2 x i8> %shift1, <i8 189, i8 123>
534 %bw1 = add <2 x i8> %shift2, %bw2
538 define i8 @shl_add_and_fail_mismatch_shift(i8 %x, i8 %y) {
539 ; CHECK-LABEL: @shl_add_and_fail_mismatch_shift(
540 ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 1
541 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1
542 ; CHECK-NEXT: [[BW2:%.*]] = add nuw i8 [[SHIFT2]], 123
543 ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]]
544 ; CHECK-NEXT: ret i8 [[BW1]]
546 %shift1 = shl i8 %x, 1
547 %shift2 = lshr i8 %y, 1
548 %bw2 = add i8 %shift2, 123
549 %bw1 = and i8 %shift1, %bw2
553 ; Fold (-x >> y) & ((x >> y) ^ -1) -> (-x & ~x) >> y
555 define i8 @and_ashr_not(i8 %x, i8 %y, i8 %shamt) {
556 ; CHECK-LABEL: @and_ashr_not(
557 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1
558 ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
559 ; CHECK-NEXT: [[AND:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]]
560 ; CHECK-NEXT: ret i8 [[AND]]
562 %x.shift = ashr i8 %x, %shamt
563 %y.shift = ashr i8 %y, %shamt
564 %y.shift.not = xor i8 %y.shift, -1
565 %and = and i8 %x.shift, %y.shift.not
569 define i8 @and_ashr_not_commuted(i8 %x, i8 %y, i8 %shamt) {
570 ; CHECK-LABEL: @and_ashr_not_commuted(
571 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1
572 ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
573 ; CHECK-NEXT: [[AND:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]]
574 ; CHECK-NEXT: ret i8 [[AND]]
576 %x.shift = ashr i8 %x, %shamt
577 %y.shift = ashr i8 %y, %shamt
578 %y.shift.not = xor i8 %y.shift, -1
579 %and = and i8 %y.shift.not, %x.shift
583 ; Negative test: lshr instead of ashr
585 define i8 @and_ashr_not_fail_lshr_ashr(i8 %x, i8 %y, i8 %shamt) {
586 ; CHECK-LABEL: @and_ashr_not_fail_lshr_ashr(
587 ; CHECK-NEXT: [[X_SHIFT:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]]
588 ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]]
589 ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1
590 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X_SHIFT]], [[Y_SHIFT_NOT]]
591 ; CHECK-NEXT: ret i8 [[AND]]
593 %x.shift = lshr i8 %x, %shamt
594 %y.shift = ashr i8 %y, %shamt
595 %y.shift.not = xor i8 %y.shift, -1
596 %and = and i8 %x.shift, %y.shift.not
600 ; Negative test: lshr instead of ashr
602 define i8 @and_ashr_not_fail_ashr_lshr(i8 %x, i8 %y, i8 %shamt) {
603 ; CHECK-LABEL: @and_ashr_not_fail_ashr_lshr(
604 ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
605 ; CHECK-NEXT: [[Y_SHIFT:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]]
606 ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1
607 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X_SHIFT]], [[Y_SHIFT_NOT]]
608 ; CHECK-NEXT: ret i8 [[AND]]
610 %x.shift = ashr i8 %x, %shamt
611 %y.shift = lshr i8 %y, %shamt
612 %y.shift.not = xor i8 %y.shift, -1
613 %and = and i8 %x.shift, %y.shift.not
617 ; Negative test: invalid xor constant
619 define i8 @and_ashr_not_fail_invalid_xor_constant(i8 %x, i8 %y, i8 %shamt) {
620 ; CHECK-LABEL: @and_ashr_not_fail_invalid_xor_constant(
621 ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
622 ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]]
623 ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -2
624 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X_SHIFT]], [[Y_SHIFT_NOT]]
625 ; CHECK-NEXT: ret i8 [[AND]]
627 %x.shift = ashr i8 %x, %shamt
628 %y.shift = ashr i8 %y, %shamt
629 %y.shift.not = xor i8 %y.shift, -2
630 %and = and i8 %x.shift, %y.shift.not
634 define <4 x i8> @and_ashr_not_vec(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
635 ; CHECK-LABEL: @and_ashr_not_vec(
636 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1)
637 ; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[X:%.*]], [[TMP1]]
638 ; CHECK-NEXT: [[AND:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]]
639 ; CHECK-NEXT: ret <4 x i8> [[AND]]
641 %x.shift = ashr <4 x i8> %x, %shamt
642 %y.shift = ashr <4 x i8> %y, %shamt
643 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1>
644 %and = and <4 x i8> %x.shift, %y.shift.not
648 define <4 x i8> @and_ashr_not_vec_commuted(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
649 ; CHECK-LABEL: @and_ashr_not_vec_commuted(
650 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1)
651 ; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[X:%.*]], [[TMP1]]
652 ; CHECK-NEXT: [[AND:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]]
653 ; CHECK-NEXT: ret <4 x i8> [[AND]]
655 %x.shift = ashr <4 x i8> %x, %shamt
656 %y.shift = ashr <4 x i8> %y, %shamt
657 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1>
658 %and = and <4 x i8> %y.shift.not, %x.shift
662 define <4 x i8> @and_ashr_not_vec_poison_1(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
663 ; CHECK-LABEL: @and_ashr_not_vec_poison_1(
664 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1)
665 ; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[X:%.*]], [[TMP1]]
666 ; CHECK-NEXT: [[AND:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]]
667 ; CHECK-NEXT: ret <4 x i8> [[AND]]
669 %x.shift = ashr <4 x i8> %x, %shamt
670 %y.shift = ashr <4 x i8> %y, %shamt
671 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 poison, i8 poison, i8 poison>
672 %and = and <4 x i8> %x.shift, %y.shift.not
676 define <4 x i8> @and_ashr_not_vec_poison_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
677 ; CHECK-LABEL: @and_ashr_not_vec_poison_2(
678 ; CHECK-NEXT: ret <4 x i8> poison
680 %x.shift = ashr <4 x i8> %x, %shamt
681 %y.shift = ashr <4 x i8> %y, %shamt
682 %y.shift.not = xor <4 x i8> %y.shift, <i8 poison, i8 poison, i8 poison, i8 poison>
683 %and = and <4 x i8> %x.shift, %y.shift.not
687 ; Fold (-x >> y) | ((x >> y) ^ -1) -> (-x | ~x) >> y
689 define i8 @or_ashr_not(i8 %x, i8 %y, i8 %shamt) {
690 ; CHECK-LABEL: @or_ashr_not(
691 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1
692 ; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[X:%.*]], [[TMP1]]
693 ; CHECK-NEXT: [[OR:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]]
694 ; CHECK-NEXT: ret i8 [[OR]]
696 %x.shift = ashr i8 %x, %shamt
697 %y.shift = ashr i8 %y, %shamt
698 %y.shift.not = xor i8 %y.shift, -1
699 %or = or i8 %x.shift, %y.shift.not
703 define i8 @or_ashr_not_commuted(i8 %x, i8 %y, i8 %shamt) {
704 ; CHECK-LABEL: @or_ashr_not_commuted(
705 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1
706 ; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[X:%.*]], [[TMP1]]
707 ; CHECK-NEXT: [[OR:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]]
708 ; CHECK-NEXT: ret i8 [[OR]]
710 %x.shift = ashr i8 %x, %shamt
711 %y.shift = ashr i8 %y, %shamt
712 %y.shift.not = xor i8 %y.shift, -1
713 %or = or i8 %y.shift.not, %x.shift
717 ; Negative test: lshr instead of ashr
719 define i8 @or_ashr_not_fail_lshr_ashr(i8 %x, i8 %y, i8 %shamt) {
720 ; CHECK-LABEL: @or_ashr_not_fail_lshr_ashr(
721 ; CHECK-NEXT: [[X_SHIFT:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]]
722 ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]]
723 ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1
724 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X_SHIFT]], [[Y_SHIFT_NOT]]
725 ; CHECK-NEXT: ret i8 [[OR]]
727 %x.shift = lshr i8 %x, %shamt
728 %y.shift = ashr i8 %y, %shamt
729 %y.shift.not = xor i8 %y.shift, -1
730 %or = or i8 %x.shift, %y.shift.not
734 ; Negative test: lshr instead of ashr
736 define i8 @or_ashr_not_fail_ashr_lshr(i8 %x, i8 %y, i8 %shamt) {
737 ; CHECK-LABEL: @or_ashr_not_fail_ashr_lshr(
738 ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
739 ; CHECK-NEXT: [[Y_SHIFT:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]]
740 ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1
741 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X_SHIFT]], [[Y_SHIFT_NOT]]
742 ; CHECK-NEXT: ret i8 [[OR]]
744 %x.shift = ashr i8 %x, %shamt
745 %y.shift = lshr i8 %y, %shamt
746 %y.shift.not = xor i8 %y.shift, -1
747 %or = or i8 %x.shift, %y.shift.not
751 ; Negative test: invalid xor constant
753 define i8 @or_ashr_not_fail_invalid_xor_constant(i8 %x, i8 %y, i8 %shamt) {
754 ; CHECK-LABEL: @or_ashr_not_fail_invalid_xor_constant(
755 ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
756 ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]]
757 ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -2
758 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X_SHIFT]], [[Y_SHIFT_NOT]]
759 ; CHECK-NEXT: ret i8 [[OR]]
761 %x.shift = ashr i8 %x, %shamt
762 %y.shift = ashr i8 %y, %shamt
763 %y.shift.not = xor i8 %y.shift, -2
764 %or = or i8 %x.shift, %y.shift.not
768 define <4 x i8> @or_ashr_not_vec(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
769 ; CHECK-LABEL: @or_ashr_not_vec(
770 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1)
771 ; CHECK-NEXT: [[TMP2:%.*]] = or <4 x i8> [[X:%.*]], [[TMP1]]
772 ; CHECK-NEXT: [[OR:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]]
773 ; CHECK-NEXT: ret <4 x i8> [[OR]]
775 %x.shift = ashr <4 x i8> %x, %shamt
776 %y.shift = ashr <4 x i8> %y, %shamt
777 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1>
778 %or = or <4 x i8> %x.shift, %y.shift.not
782 define <4 x i8> @or_ashr_not_vec_commuted(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
783 ; CHECK-LABEL: @or_ashr_not_vec_commuted(
784 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1)
785 ; CHECK-NEXT: [[TMP2:%.*]] = or <4 x i8> [[X:%.*]], [[TMP1]]
786 ; CHECK-NEXT: [[OR:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]]
787 ; CHECK-NEXT: ret <4 x i8> [[OR]]
789 %x.shift = ashr <4 x i8> %x, %shamt
790 %y.shift = ashr <4 x i8> %y, %shamt
791 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1>
792 %or = or <4 x i8> %y.shift.not, %x.shift
796 define <4 x i8> @or_ashr_not_vec_poison_1(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
797 ; CHECK-LABEL: @or_ashr_not_vec_poison_1(
798 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1)
799 ; CHECK-NEXT: [[TMP2:%.*]] = or <4 x i8> [[X:%.*]], [[TMP1]]
800 ; CHECK-NEXT: [[OR:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]]
801 ; CHECK-NEXT: ret <4 x i8> [[OR]]
803 %x.shift = ashr <4 x i8> %x, %shamt
804 %y.shift = ashr <4 x i8> %y, %shamt
805 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 poison, i8 poison, i8 poison>
806 %or = or <4 x i8> %x.shift, %y.shift.not
810 define <4 x i8> @or_ashr_not_vec_poison_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
811 ; CHECK-LABEL: @or_ashr_not_vec_poison_2(
812 ; CHECK-NEXT: ret <4 x i8> poison
814 %x.shift = ashr <4 x i8> %x, %shamt
815 %y.shift = ashr <4 x i8> %y, %shamt
816 %y.shift.not = xor <4 x i8> %y.shift, <i8 poison, i8 poison, i8 poison, i8 poison>
817 %or = or <4 x i8> %x.shift, %y.shift.not
821 ; Fold (-x >> y) ^ ((x >> y) ^ -1) -> (-x ^ ~x) >> y
823 define i8 @xor_ashr_not(i8 %x, i8 %y, i8 %shamt) {
824 ; CHECK-LABEL: @xor_ashr_not(
825 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]
826 ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr i8 [[TMP1]], [[SHAMT:%.*]]
827 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[DOTNOT]], -1
828 ; CHECK-NEXT: ret i8 [[XOR]]
830 %x.shift = ashr i8 %x, %shamt
831 %y.shift = ashr i8 %y, %shamt
832 %y.shift.not = xor i8 %y.shift, -1
833 %xor = xor i8 %x.shift, %y.shift.not
837 define i8 @xor_ashr_not_commuted(i8 %x, i8 %y, i8 %shamt) {
838 ; CHECK-LABEL: @xor_ashr_not_commuted(
839 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]
840 ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr i8 [[TMP1]], [[SHAMT:%.*]]
841 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[DOTNOT]], -1
842 ; CHECK-NEXT: ret i8 [[XOR]]
844 %x.shift = ashr i8 %x, %shamt
845 %y.shift = ashr i8 %y, %shamt
846 %y.shift.not = xor i8 %y.shift, -1
847 %xor = xor i8 %y.shift.not, %x.shift
851 ; Negative test: lshr instead of ashr
853 define i8 @xor_ashr_not_fail_lshr_ashr(i8 %x, i8 %y, i8 %shamt) {
854 ; CHECK-LABEL: @xor_ashr_not_fail_lshr_ashr(
855 ; CHECK-NEXT: [[X_SHIFT:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]]
856 ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]]
857 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y_SHIFT]], [[X_SHIFT]]
858 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -1
859 ; CHECK-NEXT: ret i8 [[XOR]]
861 %x.shift = lshr i8 %x, %shamt
862 %y.shift = ashr i8 %y, %shamt
863 %y.shift.not = xor i8 %y.shift, -1
864 %xor = xor i8 %x.shift, %y.shift.not
868 ; Negative test: lshr instead of ashr
870 define i8 @xor_ashr_not_fail_ashr_lshr(i8 %x, i8 %y, i8 %shamt) {
871 ; CHECK-LABEL: @xor_ashr_not_fail_ashr_lshr(
872 ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
873 ; CHECK-NEXT: [[Y_SHIFT:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]]
874 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y_SHIFT]], [[X_SHIFT]]
875 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -1
876 ; CHECK-NEXT: ret i8 [[XOR]]
878 %x.shift = ashr i8 %x, %shamt
879 %y.shift = lshr i8 %y, %shamt
880 %y.shift.not = xor i8 %y.shift, -1
881 %xor = xor i8 %x.shift, %y.shift.not
885 ; Negative test: invalid xor constant
887 define i8 @xor_ashr_not_fail_invalid_xor_constant(i8 %x, i8 %y, i8 %shamt) {
888 ; CHECK-LABEL: @xor_ashr_not_fail_invalid_xor_constant(
889 ; CHECK-NEXT: [[Y_SHIFT1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]
890 ; CHECK-NEXT: [[TMP1:%.*]] = ashr i8 [[Y_SHIFT1]], [[SHAMT:%.*]]
891 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -2
892 ; CHECK-NEXT: ret i8 [[XOR]]
894 %x.shift = ashr i8 %x, %shamt
895 %y.shift = ashr i8 %y, %shamt
896 %y.shift.not = xor i8 %y.shift, -2
897 %xor = xor i8 %x.shift, %y.shift.not
901 define <4 x i8> @xor_ashr_not_vec(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
902 ; CHECK-LABEL: @xor_ashr_not_vec(
903 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], [[X:%.*]]
904 ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i8> [[TMP1]], [[SHAMT:%.*]]
905 ; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i8> [[DOTNOT]], splat (i8 -1)
906 ; CHECK-NEXT: ret <4 x i8> [[XOR]]
908 %x.shift = ashr <4 x i8> %x, %shamt
909 %y.shift = ashr <4 x i8> %y, %shamt
910 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1>
911 %xor = xor <4 x i8> %x.shift, %y.shift.not
915 define <4 x i8> @xor_ashr_not_vec_commuted(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
916 ; CHECK-LABEL: @xor_ashr_not_vec_commuted(
917 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], [[X:%.*]]
918 ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i8> [[TMP1]], [[SHAMT:%.*]]
919 ; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i8> [[DOTNOT]], splat (i8 -1)
920 ; CHECK-NEXT: ret <4 x i8> [[XOR]]
922 %x.shift = ashr <4 x i8> %x, %shamt
923 %y.shift = ashr <4 x i8> %y, %shamt
924 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1>
925 %xor = xor <4 x i8> %y.shift.not, %x.shift
929 define <4 x i8> @xor_ashr_not_vec_poison_1(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
930 ; CHECK-LABEL: @xor_ashr_not_vec_poison_1(
931 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], [[X:%.*]]
932 ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i8> [[TMP1]], [[SHAMT:%.*]]
933 ; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i8> [[DOTNOT]], splat (i8 -1)
934 ; CHECK-NEXT: ret <4 x i8> [[XOR]]
936 %x.shift = ashr <4 x i8> %x, %shamt
937 %y.shift = ashr <4 x i8> %y, %shamt
938 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 poison, i8 poison, i8 poison>
939 %xor = xor <4 x i8> %x.shift, %y.shift.not
943 define <4 x i8> @xor_ashr_not_vec_poison_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) {
944 ; CHECK-LABEL: @xor_ashr_not_vec_poison_2(
945 ; CHECK-NEXT: ret <4 x i8> poison
947 %x.shift = ashr <4 x i8> %x, %shamt
948 %y.shift = ashr <4 x i8> %y, %shamt
949 %y.shift.not = xor <4 x i8> %y.shift, <i8 poison, i8 poison, i8 poison, i8 poison>
950 %xor = xor <4 x i8> %x.shift, %y.shift.not
954 ; Negative test: invalid binop
956 define i8 @binop_ashr_not_fail_invalid_binop(i8 %x, i8 %y, i8 %shamt) {
957 ; CHECK-LABEL: @binop_ashr_not_fail_invalid_binop(
958 ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
959 ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]]
960 ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1
961 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_SHIFT]], [[Y_SHIFT_NOT]]
962 ; CHECK-NEXT: ret i8 [[ADD]]
964 %x.shift = ashr i8 %x, %shamt
965 %y.shift = ashr i8 %y, %shamt
966 %y.shift.not = xor i8 %y.shift, -1
967 %add = add i8 %x.shift, %y.shift.not