[AMDGPU] Mark AGPR tuple implicit in the first instr of AGPR spills. (#115285)
[llvm-project.git] / llvm / test / Transforms / InstCombine / binop-and-shifts.ll
blob75bdf66ab64284050e3ddb43b38860c2ca7672dc
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
15   ret i8 %bw1
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
30   ret i8 %bw1
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
44   ret i8 %bw1
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
59   ret i8 %bw1
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
74   ret i8 %bw1
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
88   ret <2 x i8> %bw1
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
103   ret <2 x i8> %bw1
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
117   ret i8 %bw1
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
131   ret i8 %bw1
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
146   ret i8 %bw1
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
160   ret i8 %bw1
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
174   ret i8 %bw1
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
188   ret <2 x i8> %bw1
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
203   ret <2 x i8> %bw1
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
217   ret i8 %bw1
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
232   ret i8 %bw1
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
246   ret i8 %bw1
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
261   ret i8 %bw1
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
275   ret <2 x i8> %bw1
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
289   ret i8 %bw1
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
304   ret i8 %bw1
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
318   ret <2 x i8> %bw1
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
333   ret <2 x i8> %bw1
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
347   ret <2 x i8> %bw1
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
361   ret <2 x i8> %bw1
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
375   ret i8 %bw1
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
390   ret i8 %bw1
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
404   ret <2 x i8> %bw1
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
419   ret <2 x i8> %bw1
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
433   ret i8 %bw1
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
447   ret i8 %bw1
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
461   ret i8 %bw1
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
476   ret i8 %bw1
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
491   ret i8 %bw1
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
506   ret i8 %bw1
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
520   ret <2 x i8> %bw1
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
535   ret <2 x i8> %bw1
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
550   ret i8 %bw1
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
566   ret i8 %and
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
580   ret i8 %and
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
597   ret i8 %and
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
614   ret i8 %and
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
631   ret i8 %and
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
645   ret <4 x i8> %and
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
659   ret <4 x i8> %and
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
673   ret <4 x i8> %and
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
684   ret <4 x i8> %and
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
700   ret i8 %or
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
714   ret i8 %or
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
731   ret i8 %or
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
748   ret i8 %or
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
765   ret i8 %or
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
779   ret <4 x i8> %or
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
793   ret <4 x i8> %or
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
807   ret <4 x i8> %or
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
818   ret <4 x i8> %or
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
834   ret i8 %xor
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
848   ret i8 %xor
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
865   ret i8 %xor
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
882   ret i8 %xor
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
898   ret i8 %xor
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
912   ret <4 x i8> %xor
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
926   ret <4 x i8> %xor
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
940   ret <4 x i8> %xor
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
951   ret <4 x i8> %xor
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
968   ret i8 %add