[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / X86 / shift-amount-mod.ll
blob70fa32027c787219336cc75872b6a25211fbd081
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown-unknown   | FileCheck %s --check-prefixes=ALL,X32
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=ALL,X64
5 ;==============================================================================;
6 ; the shift amount is negated (shiftbitwidth - shiftamt)
7 ;==============================================================================;
9 ; shift left
10 ;------------------------------------------------------------------------------;
12 define i32 @reg32_shl_by_negated(i32 %val, i32 %shamt) nounwind {
13 ; X32-LABEL: reg32_shl_by_negated:
14 ; X32:       # %bb.0:
15 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
16 ; X32-NEXT:    xorl %ecx, %ecx
17 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
18 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
19 ; X32-NEXT:    shll %cl, %eax
20 ; X32-NEXT:    retl
22 ; X64-LABEL: reg32_shl_by_negated:
23 ; X64:       # %bb.0:
24 ; X64-NEXT:    movl %esi, %ecx
25 ; X64-NEXT:    movl %edi, %eax
26 ; X64-NEXT:    negb %cl
27 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
28 ; X64-NEXT:    shll %cl, %eax
29 ; X64-NEXT:    retq
30   %negshamt = sub i32 32, %shamt
31   %shifted = shl i32 %val, %negshamt
32   ret i32 %shifted
34 define i32 @load32_shl_by_negated(i32* %valptr, i32 %shamt) nounwind {
35 ; X32-LABEL: load32_shl_by_negated:
36 ; X32:       # %bb.0:
37 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
38 ; X32-NEXT:    movl (%eax), %eax
39 ; X32-NEXT:    xorl %ecx, %ecx
40 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
41 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
42 ; X32-NEXT:    shll %cl, %eax
43 ; X32-NEXT:    retl
45 ; X64-LABEL: load32_shl_by_negated:
46 ; X64:       # %bb.0:
47 ; X64-NEXT:    movl %esi, %ecx
48 ; X64-NEXT:    movl (%rdi), %eax
49 ; X64-NEXT:    negb %cl
50 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
51 ; X64-NEXT:    shll %cl, %eax
52 ; X64-NEXT:    retq
53   %val = load i32, i32* %valptr
54   %negshamt = sub i32 32, %shamt
55   %shifted = shl i32 %val, %negshamt
56   ret i32 %shifted
58 define void @store32_shl_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
59 ; X32-LABEL: store32_shl_by_negated:
60 ; X32:       # %bb.0:
61 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
62 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
63 ; X32-NEXT:    xorl %ecx, %ecx
64 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
65 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
66 ; X32-NEXT:    shll %cl, %edx
67 ; X32-NEXT:    movl %edx, (%eax)
68 ; X32-NEXT:    retl
70 ; X64-LABEL: store32_shl_by_negated:
71 ; X64:       # %bb.0:
72 ; X64-NEXT:    movl %edx, %ecx
73 ; X64-NEXT:    negb %cl
74 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
75 ; X64-NEXT:    shll %cl, %edi
76 ; X64-NEXT:    movl %edi, (%rsi)
77 ; X64-NEXT:    retq
78   %negshamt = sub i32 32, %shamt
79   %shifted = shl i32 %val, %negshamt
80   store i32 %shifted, i32* %dstptr
81   ret void
83 define void @modify32_shl_by_negated(i32* %valptr, i32 %shamt) nounwind {
84 ; X32-LABEL: modify32_shl_by_negated:
85 ; X32:       # %bb.0:
86 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
87 ; X32-NEXT:    movb $32, %cl
88 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
89 ; X32-NEXT:    shll %cl, (%eax)
90 ; X32-NEXT:    retl
92 ; X64-LABEL: modify32_shl_by_negated:
93 ; X64:       # %bb.0:
94 ; X64-NEXT:    movb $32, %cl
95 ; X64-NEXT:    subb %sil, %cl
96 ; X64-NEXT:    shll %cl, (%rdi)
97 ; X64-NEXT:    retq
98   %val = load i32, i32* %valptr
99   %negshamt = sub i32 32, %shamt
100   %shifted = shl i32 %val, %negshamt
101   store i32 %shifted, i32* %valptr
102   ret void
105 define i64 @reg64_shl_by_negated(i64 %val, i64 %shamt) nounwind {
106 ; X32-LABEL: reg64_shl_by_negated:
107 ; X32:       # %bb.0:
108 ; X32-NEXT:    pushl %esi
109 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
110 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
111 ; X32-NEXT:    movb $64, %cl
112 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
113 ; X32-NEXT:    movl %esi, %eax
114 ; X32-NEXT:    shll %cl, %eax
115 ; X32-NEXT:    shldl %cl, %esi, %edx
116 ; X32-NEXT:    testb $32, %cl
117 ; X32-NEXT:    je .LBB4_2
118 ; X32-NEXT:  # %bb.1:
119 ; X32-NEXT:    movl %eax, %edx
120 ; X32-NEXT:    xorl %eax, %eax
121 ; X32-NEXT:  .LBB4_2:
122 ; X32-NEXT:    popl %esi
123 ; X32-NEXT:    retl
125 ; X64-LABEL: reg64_shl_by_negated:
126 ; X64:       # %bb.0:
127 ; X64-NEXT:    movq %rsi, %rcx
128 ; X64-NEXT:    movq %rdi, %rax
129 ; X64-NEXT:    negb %cl
130 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
131 ; X64-NEXT:    shlq %cl, %rax
132 ; X64-NEXT:    retq
133   %negshamt = sub i64 64, %shamt
134   %shifted = shl i64 %val, %negshamt
135   ret i64 %shifted
137 define i64 @load64_shl_by_negated(i64* %valptr, i64 %shamt) nounwind {
138 ; X32-LABEL: load64_shl_by_negated:
139 ; X32:       # %bb.0:
140 ; X32-NEXT:    pushl %esi
141 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
142 ; X32-NEXT:    movl (%eax), %esi
143 ; X32-NEXT:    movl 4(%eax), %edx
144 ; X32-NEXT:    movb $64, %cl
145 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
146 ; X32-NEXT:    movl %esi, %eax
147 ; X32-NEXT:    shll %cl, %eax
148 ; X32-NEXT:    shldl %cl, %esi, %edx
149 ; X32-NEXT:    testb $32, %cl
150 ; X32-NEXT:    je .LBB5_2
151 ; X32-NEXT:  # %bb.1:
152 ; X32-NEXT:    movl %eax, %edx
153 ; X32-NEXT:    xorl %eax, %eax
154 ; X32-NEXT:  .LBB5_2:
155 ; X32-NEXT:    popl %esi
156 ; X32-NEXT:    retl
158 ; X64-LABEL: load64_shl_by_negated:
159 ; X64:       # %bb.0:
160 ; X64-NEXT:    movq %rsi, %rcx
161 ; X64-NEXT:    movq (%rdi), %rax
162 ; X64-NEXT:    negb %cl
163 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
164 ; X64-NEXT:    shlq %cl, %rax
165 ; X64-NEXT:    retq
166   %val = load i64, i64* %valptr
167   %negshamt = sub i64 64, %shamt
168   %shifted = shl i64 %val, %negshamt
169   ret i64 %shifted
171 define void @store64_shl_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
172 ; X32-LABEL: store64_shl_by_negated:
173 ; X32:       # %bb.0:
174 ; X32-NEXT:    pushl %edi
175 ; X32-NEXT:    pushl %esi
176 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
177 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edi
178 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
179 ; X32-NEXT:    movb $64, %cl
180 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
181 ; X32-NEXT:    movl %edi, %esi
182 ; X32-NEXT:    shll %cl, %esi
183 ; X32-NEXT:    shldl %cl, %edi, %edx
184 ; X32-NEXT:    testb $32, %cl
185 ; X32-NEXT:    je .LBB6_2
186 ; X32-NEXT:  # %bb.1:
187 ; X32-NEXT:    movl %esi, %edx
188 ; X32-NEXT:    xorl %esi, %esi
189 ; X32-NEXT:  .LBB6_2:
190 ; X32-NEXT:    movl %edx, 4(%eax)
191 ; X32-NEXT:    movl %esi, (%eax)
192 ; X32-NEXT:    popl %esi
193 ; X32-NEXT:    popl %edi
194 ; X32-NEXT:    retl
196 ; X64-LABEL: store64_shl_by_negated:
197 ; X64:       # %bb.0:
198 ; X64-NEXT:    movq %rdx, %rcx
199 ; X64-NEXT:    negb %cl
200 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
201 ; X64-NEXT:    shlq %cl, %rdi
202 ; X64-NEXT:    movq %rdi, (%rsi)
203 ; X64-NEXT:    retq
204   %negshamt = sub i64 64, %shamt
205   %shifted = shl i64 %val, %negshamt
206   store i64 %shifted, i64* %dstptr
207   ret void
209 define void @modify64_shl_by_negated(i64* %valptr, i64 %shamt) nounwind {
210 ; X32-LABEL: modify64_shl_by_negated:
211 ; X32:       # %bb.0:
212 ; X32-NEXT:    pushl %edi
213 ; X32-NEXT:    pushl %esi
214 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
215 ; X32-NEXT:    movl (%eax), %edi
216 ; X32-NEXT:    movl 4(%eax), %edx
217 ; X32-NEXT:    movb $64, %cl
218 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
219 ; X32-NEXT:    movl %edi, %esi
220 ; X32-NEXT:    shll %cl, %esi
221 ; X32-NEXT:    shldl %cl, %edi, %edx
222 ; X32-NEXT:    testb $32, %cl
223 ; X32-NEXT:    je .LBB7_2
224 ; X32-NEXT:  # %bb.1:
225 ; X32-NEXT:    movl %esi, %edx
226 ; X32-NEXT:    xorl %esi, %esi
227 ; X32-NEXT:  .LBB7_2:
228 ; X32-NEXT:    movl %esi, (%eax)
229 ; X32-NEXT:    movl %edx, 4(%eax)
230 ; X32-NEXT:    popl %esi
231 ; X32-NEXT:    popl %edi
232 ; X32-NEXT:    retl
234 ; X64-LABEL: modify64_shl_by_negated:
235 ; X64:       # %bb.0:
236 ; X64-NEXT:    movb $64, %cl
237 ; X64-NEXT:    subb %sil, %cl
238 ; X64-NEXT:    shlq %cl, (%rdi)
239 ; X64-NEXT:    retq
240   %val = load i64, i64* %valptr
241   %negshamt = sub i64 64, %shamt
242   %shifted = shl i64 %val, %negshamt
243   store i64 %shifted, i64* %valptr
244   ret void
247 ; logical shift right
248 ;------------------------------------------------------------------------------;
250 define i32 @reg32_lshr_by_negated(i32 %val, i32 %shamt) nounwind {
251 ; X32-LABEL: reg32_lshr_by_negated:
252 ; X32:       # %bb.0:
253 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
254 ; X32-NEXT:    xorl %ecx, %ecx
255 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
256 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
257 ; X32-NEXT:    shrl %cl, %eax
258 ; X32-NEXT:    retl
260 ; X64-LABEL: reg32_lshr_by_negated:
261 ; X64:       # %bb.0:
262 ; X64-NEXT:    movl %esi, %ecx
263 ; X64-NEXT:    movl %edi, %eax
264 ; X64-NEXT:    negb %cl
265 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
266 ; X64-NEXT:    shrl %cl, %eax
267 ; X64-NEXT:    retq
268   %negshamt = sub i32 32, %shamt
269   %shifted = lshr i32 %val, %negshamt
270   ret i32 %shifted
272 define i32 @load32_lshr_by_negated(i32* %valptr, i32 %shamt) nounwind {
273 ; X32-LABEL: load32_lshr_by_negated:
274 ; X32:       # %bb.0:
275 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
276 ; X32-NEXT:    movl (%eax), %eax
277 ; X32-NEXT:    xorl %ecx, %ecx
278 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
279 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
280 ; X32-NEXT:    shrl %cl, %eax
281 ; X32-NEXT:    retl
283 ; X64-LABEL: load32_lshr_by_negated:
284 ; X64:       # %bb.0:
285 ; X64-NEXT:    movl %esi, %ecx
286 ; X64-NEXT:    movl (%rdi), %eax
287 ; X64-NEXT:    negb %cl
288 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
289 ; X64-NEXT:    shrl %cl, %eax
290 ; X64-NEXT:    retq
291   %val = load i32, i32* %valptr
292   %negshamt = sub i32 32, %shamt
293   %shifted = lshr i32 %val, %negshamt
294   ret i32 %shifted
296 define void @store32_lshr_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
297 ; X32-LABEL: store32_lshr_by_negated:
298 ; X32:       # %bb.0:
299 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
300 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
301 ; X32-NEXT:    xorl %ecx, %ecx
302 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
303 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
304 ; X32-NEXT:    shrl %cl, %edx
305 ; X32-NEXT:    movl %edx, (%eax)
306 ; X32-NEXT:    retl
308 ; X64-LABEL: store32_lshr_by_negated:
309 ; X64:       # %bb.0:
310 ; X64-NEXT:    movl %edx, %ecx
311 ; X64-NEXT:    negb %cl
312 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
313 ; X64-NEXT:    shrl %cl, %edi
314 ; X64-NEXT:    movl %edi, (%rsi)
315 ; X64-NEXT:    retq
316   %negshamt = sub i32 32, %shamt
317   %shifted = lshr i32 %val, %negshamt
318   store i32 %shifted, i32* %dstptr
319   ret void
321 define void @modify32_lshr_by_negated(i32* %valptr, i32 %shamt) nounwind {
322 ; X32-LABEL: modify32_lshr_by_negated:
323 ; X32:       # %bb.0:
324 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
325 ; X32-NEXT:    movb $32, %cl
326 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
327 ; X32-NEXT:    shrl %cl, (%eax)
328 ; X32-NEXT:    retl
330 ; X64-LABEL: modify32_lshr_by_negated:
331 ; X64:       # %bb.0:
332 ; X64-NEXT:    movb $32, %cl
333 ; X64-NEXT:    subb %sil, %cl
334 ; X64-NEXT:    shrl %cl, (%rdi)
335 ; X64-NEXT:    retq
336   %val = load i32, i32* %valptr
337   %negshamt = sub i32 32, %shamt
338   %shifted = lshr i32 %val, %negshamt
339   store i32 %shifted, i32* %valptr
340   ret void
343 define i64 @reg64_lshr_by_negated(i64 %val, i64 %shamt) nounwind {
344 ; X32-LABEL: reg64_lshr_by_negated:
345 ; X32:       # %bb.0:
346 ; X32-NEXT:    pushl %esi
347 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
348 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
349 ; X32-NEXT:    movb $64, %cl
350 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
351 ; X32-NEXT:    movl %esi, %edx
352 ; X32-NEXT:    shrl %cl, %edx
353 ; X32-NEXT:    shrdl %cl, %esi, %eax
354 ; X32-NEXT:    testb $32, %cl
355 ; X32-NEXT:    je .LBB12_2
356 ; X32-NEXT:  # %bb.1:
357 ; X32-NEXT:    movl %edx, %eax
358 ; X32-NEXT:    xorl %edx, %edx
359 ; X32-NEXT:  .LBB12_2:
360 ; X32-NEXT:    popl %esi
361 ; X32-NEXT:    retl
363 ; X64-LABEL: reg64_lshr_by_negated:
364 ; X64:       # %bb.0:
365 ; X64-NEXT:    movq %rsi, %rcx
366 ; X64-NEXT:    movq %rdi, %rax
367 ; X64-NEXT:    negb %cl
368 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
369 ; X64-NEXT:    shrq %cl, %rax
370 ; X64-NEXT:    retq
371   %negshamt = sub i64 64, %shamt
372   %shifted = lshr i64 %val, %negshamt
373   ret i64 %shifted
375 define i64 @load64_lshr_by_negated(i64* %valptr, i64 %shamt) nounwind {
376 ; X32-LABEL: load64_lshr_by_negated:
377 ; X32:       # %bb.0:
378 ; X32-NEXT:    pushl %esi
379 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
380 ; X32-NEXT:    movl (%ecx), %eax
381 ; X32-NEXT:    movl 4(%ecx), %esi
382 ; X32-NEXT:    movb $64, %cl
383 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
384 ; X32-NEXT:    movl %esi, %edx
385 ; X32-NEXT:    shrl %cl, %edx
386 ; X32-NEXT:    shrdl %cl, %esi, %eax
387 ; X32-NEXT:    testb $32, %cl
388 ; X32-NEXT:    je .LBB13_2
389 ; X32-NEXT:  # %bb.1:
390 ; X32-NEXT:    movl %edx, %eax
391 ; X32-NEXT:    xorl %edx, %edx
392 ; X32-NEXT:  .LBB13_2:
393 ; X32-NEXT:    popl %esi
394 ; X32-NEXT:    retl
396 ; X64-LABEL: load64_lshr_by_negated:
397 ; X64:       # %bb.0:
398 ; X64-NEXT:    movq %rsi, %rcx
399 ; X64-NEXT:    movq (%rdi), %rax
400 ; X64-NEXT:    negb %cl
401 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
402 ; X64-NEXT:    shrq %cl, %rax
403 ; X64-NEXT:    retq
404   %val = load i64, i64* %valptr
405   %negshamt = sub i64 64, %shamt
406   %shifted = lshr i64 %val, %negshamt
407   ret i64 %shifted
409 define void @store64_lshr_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
410 ; X32-LABEL: store64_lshr_by_negated:
411 ; X32:       # %bb.0:
412 ; X32-NEXT:    pushl %edi
413 ; X32-NEXT:    pushl %esi
414 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
415 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
416 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edi
417 ; X32-NEXT:    movb $64, %cl
418 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
419 ; X32-NEXT:    movl %edi, %esi
420 ; X32-NEXT:    shrl %cl, %esi
421 ; X32-NEXT:    shrdl %cl, %edi, %edx
422 ; X32-NEXT:    testb $32, %cl
423 ; X32-NEXT:    je .LBB14_2
424 ; X32-NEXT:  # %bb.1:
425 ; X32-NEXT:    movl %esi, %edx
426 ; X32-NEXT:    xorl %esi, %esi
427 ; X32-NEXT:  .LBB14_2:
428 ; X32-NEXT:    movl %esi, 4(%eax)
429 ; X32-NEXT:    movl %edx, (%eax)
430 ; X32-NEXT:    popl %esi
431 ; X32-NEXT:    popl %edi
432 ; X32-NEXT:    retl
434 ; X64-LABEL: store64_lshr_by_negated:
435 ; X64:       # %bb.0:
436 ; X64-NEXT:    movq %rdx, %rcx
437 ; X64-NEXT:    negb %cl
438 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
439 ; X64-NEXT:    shrq %cl, %rdi
440 ; X64-NEXT:    movq %rdi, (%rsi)
441 ; X64-NEXT:    retq
442   %negshamt = sub i64 64, %shamt
443   %shifted = lshr i64 %val, %negshamt
444   store i64 %shifted, i64* %dstptr
445   ret void
447 define void @modify64_lshr_by_negated(i64* %valptr, i64 %shamt) nounwind {
448 ; X32-LABEL: modify64_lshr_by_negated:
449 ; X32:       # %bb.0:
450 ; X32-NEXT:    pushl %edi
451 ; X32-NEXT:    pushl %esi
452 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
453 ; X32-NEXT:    movl (%eax), %edx
454 ; X32-NEXT:    movl 4(%eax), %edi
455 ; X32-NEXT:    movb $64, %cl
456 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
457 ; X32-NEXT:    movl %edi, %esi
458 ; X32-NEXT:    shrl %cl, %esi
459 ; X32-NEXT:    shrdl %cl, %edi, %edx
460 ; X32-NEXT:    testb $32, %cl
461 ; X32-NEXT:    je .LBB15_2
462 ; X32-NEXT:  # %bb.1:
463 ; X32-NEXT:    movl %esi, %edx
464 ; X32-NEXT:    xorl %esi, %esi
465 ; X32-NEXT:  .LBB15_2:
466 ; X32-NEXT:    movl %edx, (%eax)
467 ; X32-NEXT:    movl %esi, 4(%eax)
468 ; X32-NEXT:    popl %esi
469 ; X32-NEXT:    popl %edi
470 ; X32-NEXT:    retl
472 ; X64-LABEL: modify64_lshr_by_negated:
473 ; X64:       # %bb.0:
474 ; X64-NEXT:    movb $64, %cl
475 ; X64-NEXT:    subb %sil, %cl
476 ; X64-NEXT:    shrq %cl, (%rdi)
477 ; X64-NEXT:    retq
478   %val = load i64, i64* %valptr
479   %negshamt = sub i64 64, %shamt
480   %shifted = lshr i64 %val, %negshamt
481   store i64 %shifted, i64* %valptr
482   ret void
485 ; arithmetic shift right
486 ;------------------------------------------------------------------------------;
488 define i32 @reg32_ashr_by_negated(i32 %val, i32 %shamt) nounwind {
489 ; X32-LABEL: reg32_ashr_by_negated:
490 ; X32:       # %bb.0:
491 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
492 ; X32-NEXT:    xorl %ecx, %ecx
493 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
494 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
495 ; X32-NEXT:    sarl %cl, %eax
496 ; X32-NEXT:    retl
498 ; X64-LABEL: reg32_ashr_by_negated:
499 ; X64:       # %bb.0:
500 ; X64-NEXT:    movl %esi, %ecx
501 ; X64-NEXT:    movl %edi, %eax
502 ; X64-NEXT:    negb %cl
503 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
504 ; X64-NEXT:    sarl %cl, %eax
505 ; X64-NEXT:    retq
506   %negshamt = sub i32 32, %shamt
507   %shifted = ashr i32 %val, %negshamt
508   ret i32 %shifted
510 define i32 @load32_ashr_by_negated(i32* %valptr, i32 %shamt) nounwind {
511 ; X32-LABEL: load32_ashr_by_negated:
512 ; X32:       # %bb.0:
513 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
514 ; X32-NEXT:    movl (%eax), %eax
515 ; X32-NEXT:    xorl %ecx, %ecx
516 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
517 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
518 ; X32-NEXT:    sarl %cl, %eax
519 ; X32-NEXT:    retl
521 ; X64-LABEL: load32_ashr_by_negated:
522 ; X64:       # %bb.0:
523 ; X64-NEXT:    movl %esi, %ecx
524 ; X64-NEXT:    movl (%rdi), %eax
525 ; X64-NEXT:    negb %cl
526 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
527 ; X64-NEXT:    sarl %cl, %eax
528 ; X64-NEXT:    retq
529   %val = load i32, i32* %valptr
530   %negshamt = sub i32 32, %shamt
531   %shifted = ashr i32 %val, %negshamt
532   ret i32 %shifted
534 define void @store32_ashr_by_negated(i32 %val, i32* %dstptr, i32 %shamt) nounwind {
535 ; X32-LABEL: store32_ashr_by_negated:
536 ; X32:       # %bb.0:
537 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
538 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
539 ; X32-NEXT:    xorl %ecx, %ecx
540 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
541 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
542 ; X32-NEXT:    sarl %cl, %edx
543 ; X32-NEXT:    movl %edx, (%eax)
544 ; X32-NEXT:    retl
546 ; X64-LABEL: store32_ashr_by_negated:
547 ; X64:       # %bb.0:
548 ; X64-NEXT:    movl %edx, %ecx
549 ; X64-NEXT:    negb %cl
550 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
551 ; X64-NEXT:    sarl %cl, %edi
552 ; X64-NEXT:    movl %edi, (%rsi)
553 ; X64-NEXT:    retq
554   %negshamt = sub i32 32, %shamt
555   %shifted = ashr i32 %val, %negshamt
556   store i32 %shifted, i32* %dstptr
557   ret void
559 define void @modify32_ashr_by_negated(i32* %valptr, i32 %shamt) nounwind {
560 ; X32-LABEL: modify32_ashr_by_negated:
561 ; X32:       # %bb.0:
562 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
563 ; X32-NEXT:    movb $32, %cl
564 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
565 ; X32-NEXT:    sarl %cl, (%eax)
566 ; X32-NEXT:    retl
568 ; X64-LABEL: modify32_ashr_by_negated:
569 ; X64:       # %bb.0:
570 ; X64-NEXT:    movb $32, %cl
571 ; X64-NEXT:    subb %sil, %cl
572 ; X64-NEXT:    sarl %cl, (%rdi)
573 ; X64-NEXT:    retq
574   %val = load i32, i32* %valptr
575   %negshamt = sub i32 32, %shamt
576   %shifted = ashr i32 %val, %negshamt
577   store i32 %shifted, i32* %valptr
578   ret void
581 define i64 @reg64_ashr_by_negated(i64 %val, i64 %shamt) nounwind {
582 ; X32-LABEL: reg64_ashr_by_negated:
583 ; X32:       # %bb.0:
584 ; X32-NEXT:    pushl %esi
585 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
586 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
587 ; X32-NEXT:    movb $64, %cl
588 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
589 ; X32-NEXT:    movl %esi, %edx
590 ; X32-NEXT:    sarl %cl, %edx
591 ; X32-NEXT:    shrdl %cl, %esi, %eax
592 ; X32-NEXT:    testb $32, %cl
593 ; X32-NEXT:    je .LBB20_2
594 ; X32-NEXT:  # %bb.1:
595 ; X32-NEXT:    sarl $31, %esi
596 ; X32-NEXT:    movl %edx, %eax
597 ; X32-NEXT:    movl %esi, %edx
598 ; X32-NEXT:  .LBB20_2:
599 ; X32-NEXT:    popl %esi
600 ; X32-NEXT:    retl
602 ; X64-LABEL: reg64_ashr_by_negated:
603 ; X64:       # %bb.0:
604 ; X64-NEXT:    movq %rsi, %rcx
605 ; X64-NEXT:    movq %rdi, %rax
606 ; X64-NEXT:    negb %cl
607 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
608 ; X64-NEXT:    sarq %cl, %rax
609 ; X64-NEXT:    retq
610   %negshamt = sub i64 64, %shamt
611   %shifted = ashr i64 %val, %negshamt
612   ret i64 %shifted
614 define i64 @load64_ashr_by_negated(i64* %valptr, i64 %shamt) nounwind {
615 ; X32-LABEL: load64_ashr_by_negated:
616 ; X32:       # %bb.0:
617 ; X32-NEXT:    pushl %esi
618 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
619 ; X32-NEXT:    movl (%ecx), %eax
620 ; X32-NEXT:    movl 4(%ecx), %esi
621 ; X32-NEXT:    movb $64, %cl
622 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
623 ; X32-NEXT:    movl %esi, %edx
624 ; X32-NEXT:    sarl %cl, %edx
625 ; X32-NEXT:    shrdl %cl, %esi, %eax
626 ; X32-NEXT:    testb $32, %cl
627 ; X32-NEXT:    je .LBB21_2
628 ; X32-NEXT:  # %bb.1:
629 ; X32-NEXT:    sarl $31, %esi
630 ; X32-NEXT:    movl %edx, %eax
631 ; X32-NEXT:    movl %esi, %edx
632 ; X32-NEXT:  .LBB21_2:
633 ; X32-NEXT:    popl %esi
634 ; X32-NEXT:    retl
636 ; X64-LABEL: load64_ashr_by_negated:
637 ; X64:       # %bb.0:
638 ; X64-NEXT:    movq %rsi, %rcx
639 ; X64-NEXT:    movq (%rdi), %rax
640 ; X64-NEXT:    negb %cl
641 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
642 ; X64-NEXT:    sarq %cl, %rax
643 ; X64-NEXT:    retq
644   %val = load i64, i64* %valptr
645   %negshamt = sub i64 64, %shamt
646   %shifted = ashr i64 %val, %negshamt
647   ret i64 %shifted
649 define void @store64_ashr_by_negated(i64 %val, i64* %dstptr, i64 %shamt) nounwind {
650 ; X32-LABEL: store64_ashr_by_negated:
651 ; X32:       # %bb.0:
652 ; X32-NEXT:    pushl %edi
653 ; X32-NEXT:    pushl %esi
654 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
655 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
656 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edi
657 ; X32-NEXT:    movb $64, %cl
658 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
659 ; X32-NEXT:    movl %edi, %esi
660 ; X32-NEXT:    sarl %cl, %esi
661 ; X32-NEXT:    shrdl %cl, %edi, %edx
662 ; X32-NEXT:    testb $32, %cl
663 ; X32-NEXT:    je .LBB22_2
664 ; X32-NEXT:  # %bb.1:
665 ; X32-NEXT:    sarl $31, %edi
666 ; X32-NEXT:    movl %esi, %edx
667 ; X32-NEXT:    movl %edi, %esi
668 ; X32-NEXT:  .LBB22_2:
669 ; X32-NEXT:    movl %esi, 4(%eax)
670 ; X32-NEXT:    movl %edx, (%eax)
671 ; X32-NEXT:    popl %esi
672 ; X32-NEXT:    popl %edi
673 ; X32-NEXT:    retl
675 ; X64-LABEL: store64_ashr_by_negated:
676 ; X64:       # %bb.0:
677 ; X64-NEXT:    movq %rdx, %rcx
678 ; X64-NEXT:    negb %cl
679 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
680 ; X64-NEXT:    sarq %cl, %rdi
681 ; X64-NEXT:    movq %rdi, (%rsi)
682 ; X64-NEXT:    retq
683   %negshamt = sub i64 64, %shamt
684   %shifted = ashr i64 %val, %negshamt
685   store i64 %shifted, i64* %dstptr
686   ret void
688 define void @modify64_ashr_by_negated(i64* %valptr, i64 %shamt) nounwind {
689 ; X32-LABEL: modify64_ashr_by_negated:
690 ; X32:       # %bb.0:
691 ; X32-NEXT:    pushl %edi
692 ; X32-NEXT:    pushl %esi
693 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
694 ; X32-NEXT:    movl (%eax), %edx
695 ; X32-NEXT:    movl 4(%eax), %edi
696 ; X32-NEXT:    movb $64, %cl
697 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
698 ; X32-NEXT:    movl %edi, %esi
699 ; X32-NEXT:    sarl %cl, %esi
700 ; X32-NEXT:    shrdl %cl, %edi, %edx
701 ; X32-NEXT:    testb $32, %cl
702 ; X32-NEXT:    je .LBB23_2
703 ; X32-NEXT:  # %bb.1:
704 ; X32-NEXT:    sarl $31, %edi
705 ; X32-NEXT:    movl %esi, %edx
706 ; X32-NEXT:    movl %edi, %esi
707 ; X32-NEXT:  .LBB23_2:
708 ; X32-NEXT:    movl %edx, (%eax)
709 ; X32-NEXT:    movl %esi, 4(%eax)
710 ; X32-NEXT:    popl %esi
711 ; X32-NEXT:    popl %edi
712 ; X32-NEXT:    retl
714 ; X64-LABEL: modify64_ashr_by_negated:
715 ; X64:       # %bb.0:
716 ; X64-NEXT:    movb $64, %cl
717 ; X64-NEXT:    subb %sil, %cl
718 ; X64-NEXT:    sarq %cl, (%rdi)
719 ; X64-NEXT:    retq
720   %val = load i64, i64* %valptr
721   %negshamt = sub i64 64, %shamt
722   %shifted = ashr i64 %val, %negshamt
723   store i64 %shifted, i64* %valptr
724   ret void
727 ;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
728 ; next let's only test simple reg pattern, and only lshr.
729 ;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
731 ;==============================================================================;
732 ; subtraction from negated shift amount
734 define i32 @reg32_lshr_by_sub_from_negated(i32 %val, i32 %a, i32 %b) nounwind {
735 ; X32-LABEL: reg32_lshr_by_sub_from_negated:
736 ; X32:       # %bb.0:
737 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
738 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
739 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
740 ; X32-NEXT:    negb %cl
741 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
742 ; X32-NEXT:    shrl %cl, %eax
743 ; X32-NEXT:    retl
745 ; X64-LABEL: reg32_lshr_by_sub_from_negated:
746 ; X64:       # %bb.0:
747 ; X64-NEXT:    # kill: def $edx killed $edx def $rdx
748 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
749 ; X64-NEXT:    movl %edi, %eax
750 ; X64-NEXT:    leal (%rsi,%rdx), %ecx
751 ; X64-NEXT:    negb %cl
752 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
753 ; X64-NEXT:    shrl %cl, %eax
754 ; X64-NEXT:    retq
755   %nega = sub i32 32, %a
756   %negasubb = sub i32 %nega, %b
757   %shifted = lshr i32 %val, %negasubb
758   ret i32 %shifted
760 define i64 @reg64_lshr_by_sub_from_negated(i64 %val, i64 %a, i64 %b) nounwind {
761 ; X32-LABEL: reg64_lshr_by_sub_from_negated:
762 ; X32:       # %bb.0:
763 ; X32-NEXT:    pushl %esi
764 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
765 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
766 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
767 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
768 ; X32-NEXT:    movb $64, %cl
769 ; X32-NEXT:    subb %dl, %cl
770 ; X32-NEXT:    movl %esi, %edx
771 ; X32-NEXT:    shrl %cl, %edx
772 ; X32-NEXT:    shrdl %cl, %esi, %eax
773 ; X32-NEXT:    testb $32, %cl
774 ; X32-NEXT:    je .LBB25_2
775 ; X32-NEXT:  # %bb.1:
776 ; X32-NEXT:    movl %edx, %eax
777 ; X32-NEXT:    xorl %edx, %edx
778 ; X32-NEXT:  .LBB25_2:
779 ; X32-NEXT:    popl %esi
780 ; X32-NEXT:    retl
782 ; X64-LABEL: reg64_lshr_by_sub_from_negated:
783 ; X64:       # %bb.0:
784 ; X64-NEXT:    movq %rdi, %rax
785 ; X64-NEXT:    leal (%rdx,%rsi), %ecx
786 ; X64-NEXT:    negb %cl
787 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
788 ; X64-NEXT:    shrq %cl, %rax
789 ; X64-NEXT:    retq
790   %nega = sub i64 64, %a
791   %negasubb = sub i64 %nega, %b
792   %shifted = lshr i64 %val, %negasubb
793   ret i64 %shifted
796 ;==============================================================================;
797 ; subtraction of negated shift amount
799 define i32 @reg32_lshr_by_sub_of_negated(i32 %val, i32 %a, i32 %b) nounwind {
800 ; X32-LABEL: reg32_lshr_by_sub_of_negated:
801 ; X32:       # %bb.0:
802 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
803 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
804 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
805 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
806 ; X32-NEXT:    shrl %cl, %eax
807 ; X32-NEXT:    retl
809 ; X64-LABEL: reg32_lshr_by_sub_of_negated:
810 ; X64:       # %bb.0:
811 ; X64-NEXT:    # kill: def $edx killed $edx def $rdx
812 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
813 ; X64-NEXT:    movl %edi, %eax
814 ; X64-NEXT:    leal (%rsi,%rdx), %ecx
815 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
816 ; X64-NEXT:    shrl %cl, %eax
817 ; X64-NEXT:    retq
818   %nega = sub i32 32, %a
819   %negasubb = sub i32 %b, %nega
820   %shifted = lshr i32 %val, %negasubb
821   ret i32 %shifted
823 define i64 @reg64_lshr_by_sub_of_negated(i64 %val, i64 %a, i64 %b) nounwind {
824 ; X32-LABEL: reg64_lshr_by_sub_of_negated:
825 ; X32:       # %bb.0:
826 ; X32-NEXT:    pushl %esi
827 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
828 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
829 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
830 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
831 ; X32-NEXT:    addb $-64, %cl
832 ; X32-NEXT:    movl %esi, %edx
833 ; X32-NEXT:    shrl %cl, %edx
834 ; X32-NEXT:    shrdl %cl, %esi, %eax
835 ; X32-NEXT:    testb $32, %cl
836 ; X32-NEXT:    je .LBB27_2
837 ; X32-NEXT:  # %bb.1:
838 ; X32-NEXT:    movl %edx, %eax
839 ; X32-NEXT:    xorl %edx, %edx
840 ; X32-NEXT:  .LBB27_2:
841 ; X32-NEXT:    popl %esi
842 ; X32-NEXT:    retl
844 ; X64-LABEL: reg64_lshr_by_sub_of_negated:
845 ; X64:       # %bb.0:
846 ; X64-NEXT:    movq %rdi, %rax
847 ; X64-NEXT:    leal (%rdx,%rsi), %ecx
848 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
849 ; X64-NEXT:    shrq %cl, %rax
850 ; X64-NEXT:    retq
851   %nega = sub i64 64, %a
852   %negasubb = sub i64 %b, %nega
853   %shifted = lshr i64 %val, %negasubb
854   ret i64 %shifted
857 ;==============================================================================;
858 ; add to negated shift amount
861 define i32 @reg32_lshr_by_add_to_negated(i32 %val, i32 %a, i32 %b) nounwind {
862 ; X32-LABEL: reg32_lshr_by_add_to_negated:
863 ; X32:       # %bb.0:
864 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
865 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
866 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
867 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
868 ; X32-NEXT:    shrl %cl, %eax
869 ; X32-NEXT:    retl
871 ; X64-LABEL: reg32_lshr_by_add_to_negated:
872 ; X64:       # %bb.0:
873 ; X64-NEXT:    movl %edx, %ecx
874 ; X64-NEXT:    movl %edi, %eax
875 ; X64-NEXT:    subl %esi, %ecx
876 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
877 ; X64-NEXT:    shrl %cl, %eax
878 ; X64-NEXT:    retq
879   %nega = sub i32 32, %a
880   %negasubb = add i32 %nega, %b
881   %shifted = lshr i32 %val, %negasubb
882   ret i32 %shifted
884 define i64 @reg64_lshr_by_add_to_negated(i64 %val, i64 %a, i64 %b) nounwind {
885 ; X32-LABEL: reg64_lshr_by_add_to_negated:
886 ; X32:       # %bb.0:
887 ; X32-NEXT:    pushl %esi
888 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
889 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
890 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
891 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
892 ; X32-NEXT:    addb $64, %cl
893 ; X32-NEXT:    movl %esi, %edx
894 ; X32-NEXT:    shrl %cl, %edx
895 ; X32-NEXT:    shrdl %cl, %esi, %eax
896 ; X32-NEXT:    testb $32, %cl
897 ; X32-NEXT:    je .LBB29_2
898 ; X32-NEXT:  # %bb.1:
899 ; X32-NEXT:    movl %edx, %eax
900 ; X32-NEXT:    xorl %edx, %edx
901 ; X32-NEXT:  .LBB29_2:
902 ; X32-NEXT:    popl %esi
903 ; X32-NEXT:    retl
905 ; X64-LABEL: reg64_lshr_by_add_to_negated:
906 ; X64:       # %bb.0:
907 ; X64-NEXT:    movq %rdx, %rcx
908 ; X64-NEXT:    movq %rdi, %rax
909 ; X64-NEXT:    subl %esi, %ecx
910 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
911 ; X64-NEXT:    shrq %cl, %rax
912 ; X64-NEXT:    retq
913   %nega = sub i64 64, %a
914   %negasubb = add i64 %nega, %b
915   %shifted = lshr i64 %val, %negasubb
916   ret i64 %shifted
919 ;==============================================================================;
920 ; subtraction of negated shift amounts
922 define i32 @reg32_lshr_by_sub_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
923 ; X32-LABEL: reg32_lshr_by_sub_of_negated_amts:
924 ; X32:       # %bb.0:
925 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
926 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
927 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
928 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
929 ; X32-NEXT:    shrl %cl, %eax
930 ; X32-NEXT:    retl
932 ; X64-LABEL: reg32_lshr_by_sub_of_negated_amts:
933 ; X64:       # %bb.0:
934 ; X64-NEXT:    movl %edx, %ecx
935 ; X64-NEXT:    movl %edi, %eax
936 ; X64-NEXT:    subl %esi, %ecx
937 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
938 ; X64-NEXT:    shrl %cl, %eax
939 ; X64-NEXT:    retq
940   %nega = sub i32 32, %a
941   %negb = sub i32 32, %b
942   %negasubnegb = sub i32 %nega, %negb
943   %shifted = lshr i32 %val, %negasubnegb
944   ret i32 %shifted
946 define i64 @reg64_lshr_by_sub_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
947 ; X32-LABEL: reg64_lshr_by_sub_of_negated_amts:
948 ; X32:       # %bb.0:
949 ; X32-NEXT:    pushl %esi
950 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
951 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
952 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
953 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
954 ; X32-NEXT:    movl %esi, %edx
955 ; X32-NEXT:    shrl %cl, %edx
956 ; X32-NEXT:    shrdl %cl, %esi, %eax
957 ; X32-NEXT:    testb $32, %cl
958 ; X32-NEXT:    je .LBB31_2
959 ; X32-NEXT:  # %bb.1:
960 ; X32-NEXT:    movl %edx, %eax
961 ; X32-NEXT:    xorl %edx, %edx
962 ; X32-NEXT:  .LBB31_2:
963 ; X32-NEXT:    popl %esi
964 ; X32-NEXT:    retl
966 ; X64-LABEL: reg64_lshr_by_sub_of_negated_amts:
967 ; X64:       # %bb.0:
968 ; X64-NEXT:    movq %rdx, %rcx
969 ; X64-NEXT:    movq %rdi, %rax
970 ; X64-NEXT:    subl %esi, %ecx
971 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
972 ; X64-NEXT:    shrq %cl, %rax
973 ; X64-NEXT:    retq
974   %nega = sub i64 64, %a
975   %negb = sub i64 64, %b
976   %negasubnegb = sub i64 %nega, %negb
977   %shifted = lshr i64 %val, %negasubnegb
978   ret i64 %shifted
981 ;==============================================================================;
982 ; addition of negated shift amounts
984 define i32 @reg32_lshr_by_add_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
985 ; X32-LABEL: reg32_lshr_by_add_of_negated_amts:
986 ; X32:       # %bb.0:
987 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
988 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
989 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
990 ; X32-NEXT:    negb %cl
991 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
992 ; X32-NEXT:    shrl %cl, %eax
993 ; X32-NEXT:    retl
995 ; X64-LABEL: reg32_lshr_by_add_of_negated_amts:
996 ; X64:       # %bb.0:
997 ; X64-NEXT:    # kill: def $edx killed $edx def $rdx
998 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
999 ; X64-NEXT:    movl %edi, %eax
1000 ; X64-NEXT:    leal (%rsi,%rdx), %ecx
1001 ; X64-NEXT:    negb %cl
1002 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1003 ; X64-NEXT:    shrl %cl, %eax
1004 ; X64-NEXT:    retq
1005   %nega = sub i32 32, %a
1006   %negb = sub i32 32, %b
1007   %negasubnegb = add i32 %nega, %negb
1008   %shifted = lshr i32 %val, %negasubnegb
1009   ret i32 %shifted
1011 define i64 @reg64_lshr_by_add_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
1012 ; X32-LABEL: reg64_lshr_by_add_of_negated_amts:
1013 ; X32:       # %bb.0:
1014 ; X32-NEXT:    pushl %esi
1015 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1016 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1017 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
1018 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
1019 ; X32-NEXT:    movb $-128, %cl
1020 ; X32-NEXT:    subb %dl, %cl
1021 ; X32-NEXT:    movl %esi, %edx
1022 ; X32-NEXT:    shrl %cl, %edx
1023 ; X32-NEXT:    shrdl %cl, %esi, %eax
1024 ; X32-NEXT:    testb $32, %cl
1025 ; X32-NEXT:    je .LBB33_2
1026 ; X32-NEXT:  # %bb.1:
1027 ; X32-NEXT:    movl %edx, %eax
1028 ; X32-NEXT:    xorl %edx, %edx
1029 ; X32-NEXT:  .LBB33_2:
1030 ; X32-NEXT:    popl %esi
1031 ; X32-NEXT:    retl
1033 ; X64-LABEL: reg64_lshr_by_add_of_negated_amts:
1034 ; X64:       # %bb.0:
1035 ; X64-NEXT:    movq %rdi, %rax
1036 ; X64-NEXT:    leal (%rdx,%rsi), %ecx
1037 ; X64-NEXT:    negb %cl
1038 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1039 ; X64-NEXT:    shrq %cl, %rax
1040 ; X64-NEXT:    retq
1041   %nega = sub i64 64, %a
1042   %negb = sub i64 64, %b
1043   %negasubnegb = add i64 %nega, %negb
1044   %shifted = lshr i64 %val, %negasubnegb
1045   ret i64 %shifted
1048 ;==============================================================================;
1049 ; and patterns with an actual negation+addition
1051 define i32 @reg32_lshr_by_negated_unfolded(i32 %val, i32 %shamt) nounwind {
1052 ; X32-LABEL: reg32_lshr_by_negated_unfolded:
1053 ; X32:       # %bb.0:
1054 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1055 ; X32-NEXT:    xorl %ecx, %ecx
1056 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
1057 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
1058 ; X32-NEXT:    shrl %cl, %eax
1059 ; X32-NEXT:    retl
1061 ; X64-LABEL: reg32_lshr_by_negated_unfolded:
1062 ; X64:       # %bb.0:
1063 ; X64-NEXT:    movl %esi, %ecx
1064 ; X64-NEXT:    movl %edi, %eax
1065 ; X64-NEXT:    negb %cl
1066 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1067 ; X64-NEXT:    shrl %cl, %eax
1068 ; X64-NEXT:    retq
1069   %negshamt = sub i32 0, %shamt
1070   %negaaddbitwidth = add i32 %negshamt, 32
1071   %shifted = lshr i32 %val, %negaaddbitwidth
1072   ret i32 %shifted
1074 define i64 @reg64_lshr_by_negated_unfolded(i64 %val, i64 %shamt) nounwind {
1075 ; X32-LABEL: reg64_lshr_by_negated_unfolded:
1076 ; X32:       # %bb.0:
1077 ; X32-NEXT:    pushl %esi
1078 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1079 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1080 ; X32-NEXT:    movb $64, %cl
1081 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
1082 ; X32-NEXT:    movl %esi, %edx
1083 ; X32-NEXT:    shrl %cl, %edx
1084 ; X32-NEXT:    shrdl %cl, %esi, %eax
1085 ; X32-NEXT:    testb $32, %cl
1086 ; X32-NEXT:    je .LBB35_2
1087 ; X32-NEXT:  # %bb.1:
1088 ; X32-NEXT:    movl %edx, %eax
1089 ; X32-NEXT:    xorl %edx, %edx
1090 ; X32-NEXT:  .LBB35_2:
1091 ; X32-NEXT:    popl %esi
1092 ; X32-NEXT:    retl
1094 ; X64-LABEL: reg64_lshr_by_negated_unfolded:
1095 ; X64:       # %bb.0:
1096 ; X64-NEXT:    movq %rsi, %rcx
1097 ; X64-NEXT:    movq %rdi, %rax
1098 ; X64-NEXT:    negb %cl
1099 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
1100 ; X64-NEXT:    shrq %cl, %rax
1101 ; X64-NEXT:    retq
1102   %negshamt = sub i64 0, %shamt
1103   %negaaddbitwidth = add i64 %negshamt, 64
1104   %shifted = lshr i64 %val, %negaaddbitwidth
1105   ret i64 %shifted
1108 define i32 @reg32_lshr_by_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
1109 ; X32-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
1110 ; X32:       # %bb.0:
1111 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1112 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1113 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
1114 ; X32-NEXT:    negb %cl
1115 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
1116 ; X32-NEXT:    shrl %cl, %eax
1117 ; X32-NEXT:    retl
1119 ; X64-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
1120 ; X64:       # %bb.0:
1121 ; X64-NEXT:    # kill: def $edx killed $edx def $rdx
1122 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
1123 ; X64-NEXT:    movl %edi, %eax
1124 ; X64-NEXT:    leal (%rsi,%rdx), %ecx
1125 ; X64-NEXT:    negb %cl
1126 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1127 ; X64-NEXT:    shrl %cl, %eax
1128 ; X64-NEXT:    retq
1129   %nega = sub i32 0, %a
1130   %negaaddbitwidth = add i32 %nega, 32
1131   %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
1132   %shifted = lshr i32 %val, %negaaddbitwidthsubb
1133   ret i32 %shifted
1135 define i64 @reg64_lshr_by_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
1136 ; X32-LABEL: reg64_lshr_by_negated_unfolded_sub_b:
1137 ; X32:       # %bb.0:
1138 ; X32-NEXT:    pushl %esi
1139 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1140 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1141 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
1142 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
1143 ; X32-NEXT:    movb $64, %cl
1144 ; X32-NEXT:    subb %dl, %cl
1145 ; X32-NEXT:    movl %esi, %edx
1146 ; X32-NEXT:    shrl %cl, %edx
1147 ; X32-NEXT:    shrdl %cl, %esi, %eax
1148 ; X32-NEXT:    testb $32, %cl
1149 ; X32-NEXT:    je .LBB37_2
1150 ; X32-NEXT:  # %bb.1:
1151 ; X32-NEXT:    movl %edx, %eax
1152 ; X32-NEXT:    xorl %edx, %edx
1153 ; X32-NEXT:  .LBB37_2:
1154 ; X32-NEXT:    popl %esi
1155 ; X32-NEXT:    retl
1157 ; X64-LABEL: reg64_lshr_by_negated_unfolded_sub_b:
1158 ; X64:       # %bb.0:
1159 ; X64-NEXT:    movq %rdi, %rax
1160 ; X64-NEXT:    leal (%rdx,%rsi), %ecx
1161 ; X64-NEXT:    negb %cl
1162 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1163 ; X64-NEXT:    shrq %cl, %rax
1164 ; X64-NEXT:    retq
1165   %nega = sub i64 0, %a
1166   %negaaddbitwidth = add i64 %nega, 64
1167   %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
1168   %shifted = lshr i64 %val, %negaaddbitwidthsubb
1169   ret i64 %shifted
1172 define i32 @reg32_lshr_by_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
1173 ; X32-LABEL: reg32_lshr_by_b_sub_negated_unfolded:
1174 ; X32:       # %bb.0:
1175 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1176 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1177 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
1178 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
1179 ; X32-NEXT:    shrl %cl, %eax
1180 ; X32-NEXT:    retl
1182 ; X64-LABEL: reg32_lshr_by_b_sub_negated_unfolded:
1183 ; X64:       # %bb.0:
1184 ; X64-NEXT:    # kill: def $edx killed $edx def $rdx
1185 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
1186 ; X64-NEXT:    movl %edi, %eax
1187 ; X64-NEXT:    leal (%rsi,%rdx), %ecx
1188 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1189 ; X64-NEXT:    shrl %cl, %eax
1190 ; X64-NEXT:    retq
1191   %nega = sub i32 0, %a
1192   %negaaddbitwidth = add i32 %nega, 32
1193   %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
1194   %shifted = lshr i32 %val, %negaaddbitwidthsubb
1195   ret i32 %shifted
1197 define i64 @reg64_lshr_by_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
1198 ; X32-LABEL: reg64_lshr_by_b_sub_negated_unfolded:
1199 ; X32:       # %bb.0:
1200 ; X32-NEXT:    pushl %esi
1201 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1202 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1203 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1204 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
1205 ; X32-NEXT:    addb $-64, %cl
1206 ; X32-NEXT:    movl %esi, %edx
1207 ; X32-NEXT:    shrl %cl, %edx
1208 ; X32-NEXT:    shrdl %cl, %esi, %eax
1209 ; X32-NEXT:    testb $32, %cl
1210 ; X32-NEXT:    je .LBB39_2
1211 ; X32-NEXT:  # %bb.1:
1212 ; X32-NEXT:    movl %edx, %eax
1213 ; X32-NEXT:    xorl %edx, %edx
1214 ; X32-NEXT:  .LBB39_2:
1215 ; X32-NEXT:    popl %esi
1216 ; X32-NEXT:    retl
1218 ; X64-LABEL: reg64_lshr_by_b_sub_negated_unfolded:
1219 ; X64:       # %bb.0:
1220 ; X64-NEXT:    movq %rdi, %rax
1221 ; X64-NEXT:    leal (%rdx,%rsi), %ecx
1222 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1223 ; X64-NEXT:    shrq %cl, %rax
1224 ; X64-NEXT:    retq
1225   %nega = sub i64 0, %a
1226   %negaaddbitwidth = add i64 %nega, 64
1227   %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
1228   %shifted = lshr i64 %val, %negaaddbitwidthsubb
1229   ret i64 %shifted
1232 define i32 @reg32_lshr_by_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
1233 ; X32-LABEL: reg32_lshr_by_negated_unfolded_add_b:
1234 ; X32:       # %bb.0:
1235 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1236 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1237 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
1238 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
1239 ; X32-NEXT:    shrl %cl, %eax
1240 ; X32-NEXT:    retl
1242 ; X64-LABEL: reg32_lshr_by_negated_unfolded_add_b:
1243 ; X64:       # %bb.0:
1244 ; X64-NEXT:    movl %edx, %ecx
1245 ; X64-NEXT:    movl %edi, %eax
1246 ; X64-NEXT:    subl %esi, %ecx
1247 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1248 ; X64-NEXT:    shrl %cl, %eax
1249 ; X64-NEXT:    retq
1250   %nega = sub i32 0, %a
1251   %negaaddbitwidth = add i32 %nega, 32
1252   %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
1253   %shifted = lshr i32 %val, %negaaddbitwidthaddb
1254   ret i32 %shifted
1256 define i64 @reg64_lshr_by_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
1257 ; X32-LABEL: reg64_lshr_by_negated_unfolded_add_b:
1258 ; X32:       # %bb.0:
1259 ; X32-NEXT:    pushl %esi
1260 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1261 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1262 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1263 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
1264 ; X32-NEXT:    addb $64, %cl
1265 ; X32-NEXT:    movl %esi, %edx
1266 ; X32-NEXT:    shrl %cl, %edx
1267 ; X32-NEXT:    shrdl %cl, %esi, %eax
1268 ; X32-NEXT:    testb $32, %cl
1269 ; X32-NEXT:    je .LBB41_2
1270 ; X32-NEXT:  # %bb.1:
1271 ; X32-NEXT:    movl %edx, %eax
1272 ; X32-NEXT:    xorl %edx, %edx
1273 ; X32-NEXT:  .LBB41_2:
1274 ; X32-NEXT:    popl %esi
1275 ; X32-NEXT:    retl
1277 ; X64-LABEL: reg64_lshr_by_negated_unfolded_add_b:
1278 ; X64:       # %bb.0:
1279 ; X64-NEXT:    movq %rdx, %rcx
1280 ; X64-NEXT:    movq %rdi, %rax
1281 ; X64-NEXT:    subl %esi, %ecx
1282 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
1283 ; X64-NEXT:    shrq %cl, %rax
1284 ; X64-NEXT:    retq
1285   %nega = sub i64 0, %a
1286   %negaaddbitwidth = add i64 %nega, 64
1287   %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
1288   %shifted = lshr i64 %val, %negaaddbitwidthaddb
1289   ret i64 %shifted
1292 ;==============================================================================;
1293 ; and patterns with an actual negation+mask
1295 define i32 @reg32_lshr_by_masked_negated_unfolded(i32 %val, i32 %shamt) nounwind {
1296 ; X32-LABEL: reg32_lshr_by_masked_negated_unfolded:
1297 ; X32:       # %bb.0:
1298 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1299 ; X32-NEXT:    xorl %ecx, %ecx
1300 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
1301 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
1302 ; X32-NEXT:    shrl %cl, %eax
1303 ; X32-NEXT:    retl
1305 ; X64-LABEL: reg32_lshr_by_masked_negated_unfolded:
1306 ; X64:       # %bb.0:
1307 ; X64-NEXT:    movl %esi, %ecx
1308 ; X64-NEXT:    movl %edi, %eax
1309 ; X64-NEXT:    negb %cl
1310 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1311 ; X64-NEXT:    shrl %cl, %eax
1312 ; X64-NEXT:    retq
1313   %negshamt = sub i32 0, %shamt
1314   %negaaddbitwidth = and i32 %negshamt, 31
1315   %shifted = lshr i32 %val, %negaaddbitwidth
1316   ret i32 %shifted
1318 define i64 @reg64_lshr_by_masked_negated_unfolded(i64 %val, i64 %shamt) nounwind {
1319 ; X32-LABEL: reg64_lshr_by_masked_negated_unfolded:
1320 ; X32:       # %bb.0:
1321 ; X32-NEXT:    pushl %esi
1322 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1323 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1324 ; X32-NEXT:    xorl %ecx, %ecx
1325 ; X32-NEXT:    movb {{[0-9]+}}(%esp), %dl
1326 ; X32-NEXT:    subb %dl, %cl
1327 ; X32-NEXT:    movl %esi, %edx
1328 ; X32-NEXT:    shrl %cl, %edx
1329 ; X32-NEXT:    shrdl %cl, %esi, %eax
1330 ; X32-NEXT:    testb $32, %cl
1331 ; X32-NEXT:    je .LBB43_2
1332 ; X32-NEXT:  # %bb.1:
1333 ; X32-NEXT:    movl %edx, %eax
1334 ; X32-NEXT:    xorl %edx, %edx
1335 ; X32-NEXT:  .LBB43_2:
1336 ; X32-NEXT:    popl %esi
1337 ; X32-NEXT:    retl
1339 ; X64-LABEL: reg64_lshr_by_masked_negated_unfolded:
1340 ; X64:       # %bb.0:
1341 ; X64-NEXT:    movq %rsi, %rcx
1342 ; X64-NEXT:    movq %rdi, %rax
1343 ; X64-NEXT:    negb %cl
1344 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
1345 ; X64-NEXT:    shrq %cl, %rax
1346 ; X64-NEXT:    retq
1347   %negshamt = sub i64 0, %shamt
1348   %negaaddbitwidth = and i64 %negshamt, 63
1349   %shifted = lshr i64 %val, %negaaddbitwidth
1350   ret i64 %shifted
1353 define i32 @reg32_lshr_by_masked_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
1354 ; X32-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b:
1355 ; X32:       # %bb.0:
1356 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1357 ; X32-NEXT:    xorl %ecx, %ecx
1358 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
1359 ; X32-NEXT:    andl $31, %ecx
1360 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
1361 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
1362 ; X32-NEXT:    shrl %cl, %eax
1363 ; X32-NEXT:    retl
1365 ; X64-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b:
1366 ; X64:       # %bb.0:
1367 ; X64-NEXT:    movl %esi, %ecx
1368 ; X64-NEXT:    movl %edi, %eax
1369 ; X64-NEXT:    negl %ecx
1370 ; X64-NEXT:    andl $31, %ecx
1371 ; X64-NEXT:    subl %edx, %ecx
1372 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1373 ; X64-NEXT:    shrl %cl, %eax
1374 ; X64-NEXT:    retq
1375   %nega = sub i32 0, %a
1376   %negaaddbitwidth = and i32 %nega, 31
1377   %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
1378   %shifted = lshr i32 %val, %negaaddbitwidthsubb
1379   ret i32 %shifted
1381 define i64 @reg64_lshr_by_masked_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
1382 ; X32-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b:
1383 ; X32:       # %bb.0:
1384 ; X32-NEXT:    pushl %esi
1385 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1386 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1387 ; X32-NEXT:    xorl %ecx, %ecx
1388 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
1389 ; X32-NEXT:    andl $63, %ecx
1390 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
1391 ; X32-NEXT:    movl %esi, %edx
1392 ; X32-NEXT:    shrl %cl, %edx
1393 ; X32-NEXT:    shrdl %cl, %esi, %eax
1394 ; X32-NEXT:    testb $32, %cl
1395 ; X32-NEXT:    je .LBB45_2
1396 ; X32-NEXT:  # %bb.1:
1397 ; X32-NEXT:    movl %edx, %eax
1398 ; X32-NEXT:    xorl %edx, %edx
1399 ; X32-NEXT:  .LBB45_2:
1400 ; X32-NEXT:    popl %esi
1401 ; X32-NEXT:    retl
1403 ; X64-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b:
1404 ; X64:       # %bb.0:
1405 ; X64-NEXT:    movq %rsi, %rcx
1406 ; X64-NEXT:    movq %rdi, %rax
1407 ; X64-NEXT:    negl %ecx
1408 ; X64-NEXT:    andl $63, %ecx
1409 ; X64-NEXT:    subl %edx, %ecx
1410 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
1411 ; X64-NEXT:    shrq %cl, %rax
1412 ; X64-NEXT:    retq
1413   %nega = sub i64 0, %a
1414   %negaaddbitwidth = and i64 %nega, 63
1415   %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
1416   %shifted = lshr i64 %val, %negaaddbitwidthsubb
1417   ret i64 %shifted
1420 define i32 @reg32_lshr_by_masked_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
1421 ; X32-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded:
1422 ; X32:       # %bb.0:
1423 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1424 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1425 ; X32-NEXT:    xorl %edx, %edx
1426 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %edx
1427 ; X32-NEXT:    andl $31, %edx
1428 ; X32-NEXT:    subl %edx, %ecx
1429 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
1430 ; X32-NEXT:    shrl %cl, %eax
1431 ; X32-NEXT:    retl
1433 ; X64-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded:
1434 ; X64:       # %bb.0:
1435 ; X64-NEXT:    movl %edx, %ecx
1436 ; X64-NEXT:    movl %edi, %eax
1437 ; X64-NEXT:    negl %esi
1438 ; X64-NEXT:    andl $31, %esi
1439 ; X64-NEXT:    subl %esi, %ecx
1440 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1441 ; X64-NEXT:    shrl %cl, %eax
1442 ; X64-NEXT:    retq
1443   %nega = sub i32 0, %a
1444   %negaaddbitwidth = and i32 %nega, 31
1445   %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
1446   %shifted = lshr i32 %val, %negaaddbitwidthsubb
1447   ret i32 %shifted
1449 define i64 @reg64_lshr_by_masked_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
1450 ; X32-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded:
1451 ; X32:       # %bb.0:
1452 ; X32-NEXT:    pushl %esi
1453 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1454 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1455 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1456 ; X32-NEXT:    xorl %edx, %edx
1457 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %edx
1458 ; X32-NEXT:    andl $63, %edx
1459 ; X32-NEXT:    subl %edx, %ecx
1460 ; X32-NEXT:    movl %esi, %edx
1461 ; X32-NEXT:    shrl %cl, %edx
1462 ; X32-NEXT:    shrdl %cl, %esi, %eax
1463 ; X32-NEXT:    testb $32, %cl
1464 ; X32-NEXT:    je .LBB47_2
1465 ; X32-NEXT:  # %bb.1:
1466 ; X32-NEXT:    movl %edx, %eax
1467 ; X32-NEXT:    xorl %edx, %edx
1468 ; X32-NEXT:  .LBB47_2:
1469 ; X32-NEXT:    popl %esi
1470 ; X32-NEXT:    retl
1472 ; X64-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded:
1473 ; X64:       # %bb.0:
1474 ; X64-NEXT:    movq %rdx, %rcx
1475 ; X64-NEXT:    movq %rdi, %rax
1476 ; X64-NEXT:    negl %esi
1477 ; X64-NEXT:    andl $63, %esi
1478 ; X64-NEXT:    subl %esi, %ecx
1479 ; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
1480 ; X64-NEXT:    shrq %cl, %rax
1481 ; X64-NEXT:    retq
1482   %nega = sub i64 0, %a
1483   %negaaddbitwidth = and i64 %nega, 63
1484   %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
1485   %shifted = lshr i64 %val, %negaaddbitwidthsubb
1486   ret i64 %shifted
1489 define i32 @reg32_lshr_by_masked_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
1490 ; X32-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b:
1491 ; X32:       # %bb.0:
1492 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1493 ; X32-NEXT:    xorl %ecx, %ecx
1494 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
1495 ; X32-NEXT:    andl $31, %ecx
1496 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
1497 ; X32-NEXT:    # kill: def $cl killed $cl killed $ecx
1498 ; X32-NEXT:    shrl %cl, %eax
1499 ; X32-NEXT:    retl
1501 ; X64-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b:
1502 ; X64:       # %bb.0:
1503 ; X64-NEXT:    # kill: def $edx killed $edx def $rdx
1504 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
1505 ; X64-NEXT:    movl %edi, %eax
1506 ; X64-NEXT:    negl %esi
1507 ; X64-NEXT:    andl $31, %esi
1508 ; X64-NEXT:    leal (%rsi,%rdx), %ecx
1509 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1510 ; X64-NEXT:    shrl %cl, %eax
1511 ; X64-NEXT:    retq
1512   %nega = sub i32 0, %a
1513   %negaaddbitwidth = and i32 %nega, 31
1514   %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
1515   %shifted = lshr i32 %val, %negaaddbitwidthaddb
1516   ret i32 %shifted
1518 define i64 @reg64_lshr_by_masked_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
1519 ; X32-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b:
1520 ; X32:       # %bb.0:
1521 ; X32-NEXT:    pushl %esi
1522 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1523 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1524 ; X32-NEXT:    xorl %ecx, %ecx
1525 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx
1526 ; X32-NEXT:    andl $63, %ecx
1527 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx
1528 ; X32-NEXT:    movl %esi, %edx
1529 ; X32-NEXT:    shrl %cl, %edx
1530 ; X32-NEXT:    shrdl %cl, %esi, %eax
1531 ; X32-NEXT:    testb $32, %cl
1532 ; X32-NEXT:    je .LBB49_2
1533 ; X32-NEXT:  # %bb.1:
1534 ; X32-NEXT:    movl %edx, %eax
1535 ; X32-NEXT:    xorl %edx, %edx
1536 ; X32-NEXT:  .LBB49_2:
1537 ; X32-NEXT:    popl %esi
1538 ; X32-NEXT:    retl
1540 ; X64-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b:
1541 ; X64:       # %bb.0:
1542 ; X64-NEXT:    movq %rdi, %rax
1543 ; X64-NEXT:    negl %esi
1544 ; X64-NEXT:    andl $63, %esi
1545 ; X64-NEXT:    leal (%rdx,%rsi), %ecx
1546 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1547 ; X64-NEXT:    shrq %cl, %rax
1548 ; X64-NEXT:    retq
1549   %nega = sub i64 0, %a
1550   %negaaddbitwidth = and i64 %nega, 63
1551   %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
1552   %shifted = lshr i64 %val, %negaaddbitwidthaddb
1553   ret i64 %shifted