Revert 374373: [Codegen] Alter the default promotion for saturating adds and subs
[llvm-core.git] / test / CodeGen / AArch64 / shift-amount-mod.ll
blob6b8d19c83be52570a0105fe2b17fe543b21df1ad
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
4 ;==============================================================================;
5 ; the shift amount is negated (shiftbitwidth - shiftamt)
6 ;==============================================================================;
8 ; shift left
9 ;------------------------------------------------------------------------------;
11 define i32 @reg32_shl_by_negated(i32 %val, i32 %shamt) nounwind {
12 ; CHECK-LABEL: reg32_shl_by_negated:
13 ; CHECK:       // %bb.0:
14 ; CHECK-NEXT:    neg w8, w1
15 ; CHECK-NEXT:    lsl w0, w0, w8
16 ; CHECK-NEXT:    ret
17   %negshamt = sub i32 32, %shamt
18   %shifted = shl i32 %val, %negshamt
19   ret i32 %shifted
21 define i32 @load32_shl_by_negated(i32* %valptr, i32 %shamt) nounwind {
22 ; CHECK-LABEL: load32_shl_by_negated:
23 ; CHECK:       // %bb.0:
24 ; CHECK-NEXT:    ldr w8, [x0]
25 ; CHECK-NEXT:    neg w9, w1
26 ; CHECK-NEXT:    lsl w0, w8, w9
27 ; CHECK-NEXT:    ret
28   %val = load i32, i32* %valptr
29   %negshamt = sub i32 32, %shamt
30   %shifted = shl i32 %val, %negshamt
31   ret i32 %shifted
33 define void @store32_shl_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
34 ; CHECK-LABEL: store32_shl_by_negated:
35 ; CHECK:       // %bb.0:
36 ; CHECK-NEXT:    neg w8, w2
37 ; CHECK-NEXT:    lsl w8, w0, w8
38 ; CHECK-NEXT:    str w8, [x1]
39 ; CHECK-NEXT:    ret
40   %negshamt = sub i32 32, %shamt
41   %shifted = shl i32 %val, %negshamt
42   store i32 %shifted, i32* %dstptr
43   ret void
45 define void @modify32_shl_by_negated(i32* %valptr, i32 %shamt) nounwind {
46 ; CHECK-LABEL: modify32_shl_by_negated:
47 ; CHECK:       // %bb.0:
48 ; CHECK-NEXT:    ldr w8, [x0]
49 ; CHECK-NEXT:    neg w9, w1
50 ; CHECK-NEXT:    lsl w8, w8, w9
51 ; CHECK-NEXT:    str w8, [x0]
52 ; CHECK-NEXT:    ret
53   %val = load i32, i32* %valptr
54   %negshamt = sub i32 32, %shamt
55   %shifted = shl i32 %val, %negshamt
56   store i32 %shifted, i32* %valptr
57   ret void
60 define i64 @reg64_shl_by_negated(i64 %val, i64 %shamt) nounwind {
61 ; CHECK-LABEL: reg64_shl_by_negated:
62 ; CHECK:       // %bb.0:
63 ; CHECK-NEXT:    neg x8, x1
64 ; CHECK-NEXT:    lsl x0, x0, x8
65 ; CHECK-NEXT:    ret
66   %negshamt = sub i64 64, %shamt
67   %shifted = shl i64 %val, %negshamt
68   ret i64 %shifted
70 define i64 @load64_shl_by_negated(i64* %valptr, i64 %shamt) nounwind {
71 ; CHECK-LABEL: load64_shl_by_negated:
72 ; CHECK:       // %bb.0:
73 ; CHECK-NEXT:    ldr x8, [x0]
74 ; CHECK-NEXT:    neg x9, x1
75 ; CHECK-NEXT:    lsl x0, x8, x9
76 ; CHECK-NEXT:    ret
77   %val = load i64, i64* %valptr
78   %negshamt = sub i64 64, %shamt
79   %shifted = shl i64 %val, %negshamt
80   ret i64 %shifted
82 define void @store64_shl_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
83 ; CHECK-LABEL: store64_shl_by_negated:
84 ; CHECK:       // %bb.0:
85 ; CHECK-NEXT:    neg x8, x2
86 ; CHECK-NEXT:    lsl x8, x0, x8
87 ; CHECK-NEXT:    str x8, [x1]
88 ; CHECK-NEXT:    ret
89   %negshamt = sub i64 64, %shamt
90   %shifted = shl i64 %val, %negshamt
91   store i64 %shifted, i64* %dstptr
92   ret void
94 define void @modify64_shl_by_negated(i64* %valptr, i64 %shamt) nounwind {
95 ; CHECK-LABEL: modify64_shl_by_negated:
96 ; CHECK:       // %bb.0:
97 ; CHECK-NEXT:    ldr x8, [x0]
98 ; CHECK-NEXT:    neg x9, x1
99 ; CHECK-NEXT:    lsl x8, x8, x9
100 ; CHECK-NEXT:    str x8, [x0]
101 ; CHECK-NEXT:    ret
102   %val = load i64, i64* %valptr
103   %negshamt = sub i64 64, %shamt
104   %shifted = shl i64 %val, %negshamt
105   store i64 %shifted, i64* %valptr
106   ret void
109 ; logical shift right
110 ;------------------------------------------------------------------------------;
112 define i32 @reg32_lshr_by_negated(i32 %val, i32 %shamt) nounwind {
113 ; CHECK-LABEL: reg32_lshr_by_negated:
114 ; CHECK:       // %bb.0:
115 ; CHECK-NEXT:    neg w8, w1
116 ; CHECK-NEXT:    lsr w0, w0, w8
117 ; CHECK-NEXT:    ret
118   %negshamt = sub i32 32, %shamt
119   %shifted = lshr i32 %val, %negshamt
120   ret i32 %shifted
122 define i32 @load32_lshr_by_negated(i32* %valptr, i32 %shamt) nounwind {
123 ; CHECK-LABEL: load32_lshr_by_negated:
124 ; CHECK:       // %bb.0:
125 ; CHECK-NEXT:    ldr w8, [x0]
126 ; CHECK-NEXT:    neg w9, w1
127 ; CHECK-NEXT:    lsr w0, w8, w9
128 ; CHECK-NEXT:    ret
129   %val = load i32, i32* %valptr
130   %negshamt = sub i32 32, %shamt
131   %shifted = lshr i32 %val, %negshamt
132   ret i32 %shifted
134 define void @store32_lshr_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
135 ; CHECK-LABEL: store32_lshr_by_negated:
136 ; CHECK:       // %bb.0:
137 ; CHECK-NEXT:    neg w8, w2
138 ; CHECK-NEXT:    lsr w8, w0, w8
139 ; CHECK-NEXT:    str w8, [x1]
140 ; CHECK-NEXT:    ret
141   %negshamt = sub i32 32, %shamt
142   %shifted = lshr i32 %val, %negshamt
143   store i32 %shifted, i32* %dstptr
144   ret void
146 define void @modify32_lshr_by_negated(i32* %valptr, i32 %shamt) nounwind {
147 ; CHECK-LABEL: modify32_lshr_by_negated:
148 ; CHECK:       // %bb.0:
149 ; CHECK-NEXT:    ldr w8, [x0]
150 ; CHECK-NEXT:    neg w9, w1
151 ; CHECK-NEXT:    lsr w8, w8, w9
152 ; CHECK-NEXT:    str w8, [x0]
153 ; CHECK-NEXT:    ret
154   %val = load i32, i32* %valptr
155   %negshamt = sub i32 32, %shamt
156   %shifted = lshr i32 %val, %negshamt
157   store i32 %shifted, i32* %valptr
158   ret void
161 define i64 @reg64_lshr_by_negated(i64 %val, i64 %shamt) nounwind {
162 ; CHECK-LABEL: reg64_lshr_by_negated:
163 ; CHECK:       // %bb.0:
164 ; CHECK-NEXT:    neg x8, x1
165 ; CHECK-NEXT:    lsr x0, x0, x8
166 ; CHECK-NEXT:    ret
167   %negshamt = sub i64 64, %shamt
168   %shifted = lshr i64 %val, %negshamt
169   ret i64 %shifted
171 define i64 @load64_lshr_by_negated(i64* %valptr, i64 %shamt) nounwind {
172 ; CHECK-LABEL: load64_lshr_by_negated:
173 ; CHECK:       // %bb.0:
174 ; CHECK-NEXT:    ldr x8, [x0]
175 ; CHECK-NEXT:    neg x9, x1
176 ; CHECK-NEXT:    lsr x0, x8, x9
177 ; CHECK-NEXT:    ret
178   %val = load i64, i64* %valptr
179   %negshamt = sub i64 64, %shamt
180   %shifted = lshr i64 %val, %negshamt
181   ret i64 %shifted
183 define void @store64_lshr_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
184 ; CHECK-LABEL: store64_lshr_by_negated:
185 ; CHECK:       // %bb.0:
186 ; CHECK-NEXT:    neg x8, x2
187 ; CHECK-NEXT:    lsr x8, x0, x8
188 ; CHECK-NEXT:    str x8, [x1]
189 ; CHECK-NEXT:    ret
190   %negshamt = sub i64 64, %shamt
191   %shifted = lshr i64 %val, %negshamt
192   store i64 %shifted, i64* %dstptr
193   ret void
195 define void @modify64_lshr_by_negated(i64* %valptr, i64 %shamt) nounwind {
196 ; CHECK-LABEL: modify64_lshr_by_negated:
197 ; CHECK:       // %bb.0:
198 ; CHECK-NEXT:    ldr x8, [x0]
199 ; CHECK-NEXT:    neg x9, x1
200 ; CHECK-NEXT:    lsr x8, x8, x9
201 ; CHECK-NEXT:    str x8, [x0]
202 ; CHECK-NEXT:    ret
203   %val = load i64, i64* %valptr
204   %negshamt = sub i64 64, %shamt
205   %shifted = lshr i64 %val, %negshamt
206   store i64 %shifted, i64* %valptr
207   ret void
210 ; arithmetic shift right
211 ;------------------------------------------------------------------------------;
213 define i32 @reg32_ashr_by_negated(i32 %val, i32 %shamt) nounwind {
214 ; CHECK-LABEL: reg32_ashr_by_negated:
215 ; CHECK:       // %bb.0:
216 ; CHECK-NEXT:    neg w8, w1
217 ; CHECK-NEXT:    asr w0, w0, w8
218 ; CHECK-NEXT:    ret
219   %negshamt = sub i32 32, %shamt
220   %shifted = ashr i32 %val, %negshamt
221   ret i32 %shifted
223 define i32 @load32_ashr_by_negated(i32* %valptr, i32 %shamt) nounwind {
224 ; CHECK-LABEL: load32_ashr_by_negated:
225 ; CHECK:       // %bb.0:
226 ; CHECK-NEXT:    ldr w8, [x0]
227 ; CHECK-NEXT:    neg w9, w1
228 ; CHECK-NEXT:    asr w0, w8, w9
229 ; CHECK-NEXT:    ret
230   %val = load i32, i32* %valptr
231   %negshamt = sub i32 32, %shamt
232   %shifted = ashr i32 %val, %negshamt
233   ret i32 %shifted
235 define void @store32_ashr_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
236 ; CHECK-LABEL: store32_ashr_by_negated:
237 ; CHECK:       // %bb.0:
238 ; CHECK-NEXT:    neg w8, w2
239 ; CHECK-NEXT:    asr w8, w0, w8
240 ; CHECK-NEXT:    str w8, [x1]
241 ; CHECK-NEXT:    ret
242   %negshamt = sub i32 32, %shamt
243   %shifted = ashr i32 %val, %negshamt
244   store i32 %shifted, i32* %dstptr
245   ret void
247 define void @modify32_ashr_by_negated(i32* %valptr, i32 %shamt) nounwind {
248 ; CHECK-LABEL: modify32_ashr_by_negated:
249 ; CHECK:       // %bb.0:
250 ; CHECK-NEXT:    ldr w8, [x0]
251 ; CHECK-NEXT:    neg w9, w1
252 ; CHECK-NEXT:    asr w8, w8, w9
253 ; CHECK-NEXT:    str w8, [x0]
254 ; CHECK-NEXT:    ret
255   %val = load i32, i32* %valptr
256   %negshamt = sub i32 32, %shamt
257   %shifted = ashr i32 %val, %negshamt
258   store i32 %shifted, i32* %valptr
259   ret void
262 define i64 @reg64_ashr_by_negated(i64 %val, i64 %shamt) nounwind {
263 ; CHECK-LABEL: reg64_ashr_by_negated:
264 ; CHECK:       // %bb.0:
265 ; CHECK-NEXT:    neg x8, x1
266 ; CHECK-NEXT:    asr x0, x0, x8
267 ; CHECK-NEXT:    ret
268   %negshamt = sub i64 64, %shamt
269   %shifted = ashr i64 %val, %negshamt
270   ret i64 %shifted
272 define i64 @load64_ashr_by_negated(i64* %valptr, i64 %shamt) nounwind {
273 ; CHECK-LABEL: load64_ashr_by_negated:
274 ; CHECK:       // %bb.0:
275 ; CHECK-NEXT:    ldr x8, [x0]
276 ; CHECK-NEXT:    neg x9, x1
277 ; CHECK-NEXT:    asr x0, x8, x9
278 ; CHECK-NEXT:    ret
279   %val = load i64, i64* %valptr
280   %negshamt = sub i64 64, %shamt
281   %shifted = ashr i64 %val, %negshamt
282   ret i64 %shifted
284 define void @store64_ashr_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
285 ; CHECK-LABEL: store64_ashr_by_negated:
286 ; CHECK:       // %bb.0:
287 ; CHECK-NEXT:    neg x8, x2
288 ; CHECK-NEXT:    asr x8, x0, x8
289 ; CHECK-NEXT:    str x8, [x1]
290 ; CHECK-NEXT:    ret
291   %negshamt = sub i64 64, %shamt
292   %shifted = ashr i64 %val, %negshamt
293   store i64 %shifted, i64* %dstptr
294   ret void
296 define void @modify64_ashr_by_negated(i64* %valptr, i64 %shamt) nounwind {
297 ; CHECK-LABEL: modify64_ashr_by_negated:
298 ; CHECK:       // %bb.0:
299 ; CHECK-NEXT:    ldr x8, [x0]
300 ; CHECK-NEXT:    neg x9, x1
301 ; CHECK-NEXT:    asr x8, x8, x9
302 ; CHECK-NEXT:    str x8, [x0]
303 ; CHECK-NEXT:    ret
304   %val = load i64, i64* %valptr
305   %negshamt = sub i64 64, %shamt
306   %shifted = ashr i64 %val, %negshamt
307   store i64 %shifted, i64* %valptr
308   ret void
311 ;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
312 ; next let's only test simple reg pattern, and only lshr.
313 ;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
315 ;==============================================================================;
316 ; subtraction from negated shift amount
318 define i32 @reg32_lshr_by_sub_from_negated(i32 %val, i32 %a, i32 %b) nounwind {
319 ; CHECK-LABEL: reg32_lshr_by_sub_from_negated:
320 ; CHECK:       // %bb.0:
321 ; CHECK-NEXT:    add w8, w1, w2
322 ; CHECK-NEXT:    neg w8, w8
323 ; CHECK-NEXT:    lsr w0, w0, w8
324 ; CHECK-NEXT:    ret
325   %nega = sub i32 32, %a
326   %negasubb = sub i32 %nega, %b
327   %shifted = lshr i32 %val, %negasubb
328   ret i32 %shifted
330 define i64 @reg64_lshr_by_sub_from_negated(i64 %val, i64 %a, i64 %b) nounwind {
331 ; CHECK-LABEL: reg64_lshr_by_sub_from_negated:
332 ; CHECK:       // %bb.0:
333 ; CHECK-NEXT:    add x8, x1, x2
334 ; CHECK-NEXT:    neg x8, x8
335 ; CHECK-NEXT:    lsr x0, x0, x8
336 ; CHECK-NEXT:    ret
337   %nega = sub i64 64, %a
338   %negasubb = sub i64 %nega, %b
339   %shifted = lshr i64 %val, %negasubb
340   ret i64 %shifted
343 ;==============================================================================;
344 ; subtraction of negated shift amount
346 define i32 @reg32_lshr_by_sub_of_negated(i32 %val, i32 %a, i32 %b) nounwind {
347 ; CHECK-LABEL: reg32_lshr_by_sub_of_negated:
348 ; CHECK:       // %bb.0:
349 ; CHECK-NEXT:    add w8, w1, w2
350 ; CHECK-NEXT:    lsr w0, w0, w8
351 ; CHECK-NEXT:    ret
352   %nega = sub i32 32, %a
353   %negasubb = sub i32 %b, %nega
354   %shifted = lshr i32 %val, %negasubb
355   ret i32 %shifted
357 define i64 @reg64_lshr_by_sub_of_negated(i64 %val, i64 %a, i64 %b) nounwind {
358 ; CHECK-LABEL: reg64_lshr_by_sub_of_negated:
359 ; CHECK:       // %bb.0:
360 ; CHECK-NEXT:    add x8, x1, x2
361 ; CHECK-NEXT:    lsr x0, x0, x8
362 ; CHECK-NEXT:    ret
363   %nega = sub i64 64, %a
364   %negasubb = sub i64 %b, %nega
365   %shifted = lshr i64 %val, %negasubb
366   ret i64 %shifted
369 ;==============================================================================;
370 ; add to negated shift amount
373 define i32 @reg32_lshr_by_add_to_negated(i32 %val, i32 %a, i32 %b) nounwind {
374 ; CHECK-LABEL: reg32_lshr_by_add_to_negated:
375 ; CHECK:       // %bb.0:
376 ; CHECK-NEXT:    sub w8, w2, w1
377 ; CHECK-NEXT:    lsr w0, w0, w8
378 ; CHECK-NEXT:    ret
379   %nega = sub i32 32, %a
380   %negasubb = add i32 %nega, %b
381   %shifted = lshr i32 %val, %negasubb
382   ret i32 %shifted
384 define i64 @reg64_lshr_by_add_to_negated(i64 %val, i64 %a, i64 %b) nounwind {
385 ; CHECK-LABEL: reg64_lshr_by_add_to_negated:
386 ; CHECK:       // %bb.0:
387 ; CHECK-NEXT:    sub x8, x2, x1
388 ; CHECK-NEXT:    lsr x0, x0, x8
389 ; CHECK-NEXT:    ret
390   %nega = sub i64 64, %a
391   %negasubb = add i64 %nega, %b
392   %shifted = lshr i64 %val, %negasubb
393   ret i64 %shifted
396 ;==============================================================================;
397 ; subtraction of negated shift amounts
399 define i32 @reg32_lshr_by_sub_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
400 ; CHECK-LABEL: reg32_lshr_by_sub_of_negated_amts:
401 ; CHECK:       // %bb.0:
402 ; CHECK-NEXT:    sub w8, w2, w1
403 ; CHECK-NEXT:    lsr w0, w0, w8
404 ; CHECK-NEXT:    ret
405   %nega = sub i32 32, %a
406   %negb = sub i32 32, %b
407   %negasubnegb = sub i32 %nega, %negb
408   %shifted = lshr i32 %val, %negasubnegb
409   ret i32 %shifted
411 define i64 @reg64_lshr_by_sub_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
412 ; CHECK-LABEL: reg64_lshr_by_sub_of_negated_amts:
413 ; CHECK:       // %bb.0:
414 ; CHECK-NEXT:    sub x8, x2, x1
415 ; CHECK-NEXT:    lsr x0, x0, x8
416 ; CHECK-NEXT:    ret
417   %nega = sub i64 64, %a
418   %negb = sub i64 64, %b
419   %negasubnegb = sub i64 %nega, %negb
420   %shifted = lshr i64 %val, %negasubnegb
421   ret i64 %shifted
424 ;==============================================================================;
425 ; addition of negated shift amounts
427 define i32 @reg32_lshr_by_add_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
428 ; CHECK-LABEL: reg32_lshr_by_add_of_negated_amts:
429 ; CHECK:       // %bb.0:
430 ; CHECK-NEXT:    add w8, w1, w2
431 ; CHECK-NEXT:    neg w8, w8
432 ; CHECK-NEXT:    lsr w0, w0, w8
433 ; CHECK-NEXT:    ret
434   %nega = sub i32 32, %a
435   %negb = sub i32 32, %b
436   %negasubnegb = add i32 %nega, %negb
437   %shifted = lshr i32 %val, %negasubnegb
438   ret i32 %shifted
440 define i64 @reg64_lshr_by_add_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
441 ; CHECK-LABEL: reg64_lshr_by_add_of_negated_amts:
442 ; CHECK:       // %bb.0:
443 ; CHECK-NEXT:    add x8, x1, x2
444 ; CHECK-NEXT:    neg x8, x8
445 ; CHECK-NEXT:    lsr x0, x0, x8
446 ; CHECK-NEXT:    ret
447   %nega = sub i64 64, %a
448   %negb = sub i64 64, %b
449   %negasubnegb = add i64 %nega, %negb
450   %shifted = lshr i64 %val, %negasubnegb
451   ret i64 %shifted
454 ;==============================================================================;
455 ; and patterns with an actual negation+addition
457 define i32 @reg32_lshr_by_negated_unfolded(i32 %val, i32 %shamt) nounwind {
458 ; CHECK-LABEL: reg32_lshr_by_negated_unfolded:
459 ; CHECK:       // %bb.0:
460 ; CHECK-NEXT:    neg w8, w1
461 ; CHECK-NEXT:    lsr w0, w0, w8
462 ; CHECK-NEXT:    ret
463   %negshamt = sub i32 0, %shamt
464   %negaaddbitwidth = add i32 %negshamt, 32
465   %shifted = lshr i32 %val, %negaaddbitwidth
466   ret i32 %shifted
468 define i64 @reg64_lshr_by_negated_unfolded(i64 %val, i64 %shamt) nounwind {
469 ; CHECK-LABEL: reg64_lshr_by_negated_unfolded:
470 ; CHECK:       // %bb.0:
471 ; CHECK-NEXT:    neg x8, x1
472 ; CHECK-NEXT:    lsr x0, x0, x8
473 ; CHECK-NEXT:    ret
474   %negshamt = sub i64 0, %shamt
475   %negaaddbitwidth = add i64 %negshamt, 64
476   %shifted = lshr i64 %val, %negaaddbitwidth
477   ret i64 %shifted
480 define i32 @reg32_lshr_by_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
481 ; CHECK-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
482 ; CHECK:       // %bb.0:
483 ; CHECK-NEXT:    add w8, w1, w2
484 ; CHECK-NEXT:    neg w8, w8
485 ; CHECK-NEXT:    lsr w0, w0, w8
486 ; CHECK-NEXT:    ret
487   %nega = sub i32 0, %a
488   %negaaddbitwidth = add i32 %nega, 32
489   %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
490   %shifted = lshr i32 %val, %negaaddbitwidthsubb
491   ret i32 %shifted
493 define i64 @reg64_lshr_by_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
494 ; CHECK-LABEL: reg64_lshr_by_negated_unfolded_sub_b:
495 ; CHECK:       // %bb.0:
496 ; CHECK-NEXT:    add x8, x1, x2
497 ; CHECK-NEXT:    neg x8, x8
498 ; CHECK-NEXT:    lsr x0, x0, x8
499 ; CHECK-NEXT:    ret
500   %nega = sub i64 0, %a
501   %negaaddbitwidth = add i64 %nega, 64
502   %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
503   %shifted = lshr i64 %val, %negaaddbitwidthsubb
504   ret i64 %shifted
507 define i32 @reg32_lshr_by_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
508 ; CHECK-LABEL: reg32_lshr_by_b_sub_negated_unfolded:
509 ; CHECK:       // %bb.0:
510 ; CHECK-NEXT:    add w8, w2, w1
511 ; CHECK-NEXT:    lsr w0, w0, w8
512 ; CHECK-NEXT:    ret
513   %nega = sub i32 0, %a
514   %negaaddbitwidth = add i32 %nega, 32
515   %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
516   %shifted = lshr i32 %val, %negaaddbitwidthsubb
517   ret i32 %shifted
519 define i64 @reg64_lshr_by_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
520 ; CHECK-LABEL: reg64_lshr_by_b_sub_negated_unfolded:
521 ; CHECK:       // %bb.0:
522 ; CHECK-NEXT:    add x8, x2, x1
523 ; CHECK-NEXT:    lsr x0, x0, x8
524 ; CHECK-NEXT:    ret
525   %nega = sub i64 0, %a
526   %negaaddbitwidth = add i64 %nega, 64
527   %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
528   %shifted = lshr i64 %val, %negaaddbitwidthsubb
529   ret i64 %shifted
532 define i32 @reg32_lshr_by_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
533 ; CHECK-LABEL: reg32_lshr_by_negated_unfolded_add_b:
534 ; CHECK:       // %bb.0:
535 ; CHECK-NEXT:    sub w8, w2, w1
536 ; CHECK-NEXT:    lsr w0, w0, w8
537 ; CHECK-NEXT:    ret
538   %nega = sub i32 0, %a
539   %negaaddbitwidth = add i32 %nega, 32
540   %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
541   %shifted = lshr i32 %val, %negaaddbitwidthaddb
542   ret i32 %shifted
544 define i64 @reg64_lshr_by_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
545 ; CHECK-LABEL: reg64_lshr_by_negated_unfolded_add_b:
546 ; CHECK:       // %bb.0:
547 ; CHECK-NEXT:    sub x8, x2, x1
548 ; CHECK-NEXT:    lsr x0, x0, x8
549 ; CHECK-NEXT:    ret
550   %nega = sub i64 0, %a
551   %negaaddbitwidth = add i64 %nega, 64
552   %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
553   %shifted = lshr i64 %val, %negaaddbitwidthaddb
554   ret i64 %shifted
557 ;==============================================================================;
558 ; and patterns with an actual negation+mask
560 define i32 @reg32_lshr_by_masked_negated_unfolded(i32 %val, i32 %shamt) nounwind {
561 ; CHECK-LABEL: reg32_lshr_by_masked_negated_unfolded:
562 ; CHECK:       // %bb.0:
563 ; CHECK-NEXT:    neg w8, w1
564 ; CHECK-NEXT:    lsr w0, w0, w8
565 ; CHECK-NEXT:    ret
566   %negshamt = sub i32 0, %shamt
567   %negaaddbitwidth = and i32 %negshamt, 31
568   %shifted = lshr i32 %val, %negaaddbitwidth
569   ret i32 %shifted
571 define i64 @reg64_lshr_by_masked_negated_unfolded(i64 %val, i64 %shamt) nounwind {
572 ; CHECK-LABEL: reg64_lshr_by_masked_negated_unfolded:
573 ; CHECK:       // %bb.0:
574 ; CHECK-NEXT:    neg w8, w1
575 ; CHECK-NEXT:    lsr x0, x0, x8
576 ; CHECK-NEXT:    ret
577   %negshamt = sub i64 0, %shamt
578   %negaaddbitwidth = and i64 %negshamt, 63
579   %shifted = lshr i64 %val, %negaaddbitwidth
580   ret i64 %shifted
583 define i32 @reg32_lshr_by_masked_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
584 ; CHECK-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b:
585 ; CHECK:       // %bb.0:
586 ; CHECK-NEXT:    neg w8, w1
587 ; CHECK-NEXT:    and w8, w8, #0x1f
588 ; CHECK-NEXT:    sub w8, w8, w2
589 ; CHECK-NEXT:    lsr w0, w0, w8
590 ; CHECK-NEXT:    ret
591   %nega = sub i32 0, %a
592   %negaaddbitwidth = and i32 %nega, 31
593   %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
594   %shifted = lshr i32 %val, %negaaddbitwidthsubb
595   ret i32 %shifted
597 define i64 @reg64_lshr_by_masked_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
598 ; CHECK-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b:
599 ; CHECK:       // %bb.0:
600 ; CHECK-NEXT:    neg w8, w1
601 ; CHECK-NEXT:    and x8, x8, #0x3f
602 ; CHECK-NEXT:    sub x8, x8, x2
603 ; CHECK-NEXT:    lsr x0, x0, x8
604 ; CHECK-NEXT:    ret
605   %nega = sub i64 0, %a
606   %negaaddbitwidth = and i64 %nega, 63
607   %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
608   %shifted = lshr i64 %val, %negaaddbitwidthsubb
609   ret i64 %shifted
612 define i32 @reg32_lshr_by_masked_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
613 ; CHECK-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded:
614 ; CHECK:       // %bb.0:
615 ; CHECK-NEXT:    neg w8, w1
616 ; CHECK-NEXT:    and w8, w8, #0x1f
617 ; CHECK-NEXT:    sub w8, w2, w8
618 ; CHECK-NEXT:    lsr w0, w0, w8
619 ; CHECK-NEXT:    ret
620   %nega = sub i32 0, %a
621   %negaaddbitwidth = and i32 %nega, 31
622   %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
623   %shifted = lshr i32 %val, %negaaddbitwidthsubb
624   ret i32 %shifted
626 define i64 @reg64_lshr_by_masked_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
627 ; CHECK-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded:
628 ; CHECK:       // %bb.0:
629 ; CHECK-NEXT:    neg w8, w1
630 ; CHECK-NEXT:    and x8, x8, #0x3f
631 ; CHECK-NEXT:    sub x8, x2, x8
632 ; CHECK-NEXT:    lsr x0, x0, x8
633 ; CHECK-NEXT:    ret
634   %nega = sub i64 0, %a
635   %negaaddbitwidth = and i64 %nega, 63
636   %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
637   %shifted = lshr i64 %val, %negaaddbitwidthsubb
638   ret i64 %shifted
641 define i32 @reg32_lshr_by_masked_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
642 ; CHECK-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b:
643 ; CHECK:       // %bb.0:
644 ; CHECK-NEXT:    neg w8, w1
645 ; CHECK-NEXT:    and w8, w8, #0x1f
646 ; CHECK-NEXT:    add w8, w8, w2
647 ; CHECK-NEXT:    lsr w0, w0, w8
648 ; CHECK-NEXT:    ret
649   %nega = sub i32 0, %a
650   %negaaddbitwidth = and i32 %nega, 31
651   %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
652   %shifted = lshr i32 %val, %negaaddbitwidthaddb
653   ret i32 %shifted
655 define i64 @reg64_lshr_by_masked_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
656 ; CHECK-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b:
657 ; CHECK:       // %bb.0:
658 ; CHECK-NEXT:    neg w8, w1
659 ; CHECK-NEXT:    and x8, x8, #0x3f
660 ; CHECK-NEXT:    add x8, x8, x2
661 ; CHECK-NEXT:    lsr x0, x0, x8
662 ; CHECK-NEXT:    ret
663   %nega = sub i64 0, %a
664   %negaaddbitwidth = and i64 %nega, 63
665   %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
666   %shifted = lshr i64 %val, %negaaddbitwidthaddb
667   ret i64 %shifted