1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-unknown   | FileCheck %s --check-prefix=X32
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64
4
5;==============================================================================;
6; the shift amount is negated (shiftbitwidth - shiftamt)
7;==============================================================================;
8
9; shift left
10;------------------------------------------------------------------------------;
11
12define 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
21;
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
33}
34define 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
44;
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
57}
58define 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
69;
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
82}
83define 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
91;
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
103}
104
105define 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
124;
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
136}
137define 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
157;
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
170}
171define 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
195;
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
208}
209define 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
233;
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
245}
246
247; logical shift right
248;------------------------------------------------------------------------------;
249
250define 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
259;
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
271}
272define 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
282;
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
295}
296define 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
307;
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
320}
321define 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
329;
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
341}
342
343define 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
362;
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
374}
375define 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
395;
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
408}
409define 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
433;
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
446}
447define 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
471;
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
483}
484
485; arithmetic shift right
486;------------------------------------------------------------------------------;
487
488define 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
497;
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
509}
510define 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
520;
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
533}
534define 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
545;
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
558}
559define 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
567;
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
579}
580
581define 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
601;
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
613}
614define 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
635;
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
648}
649define 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
674;
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
687}
688define 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
713;
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
725}
726
727;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
728; next let's only test simple reg pattern, and only lshr.
729;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
730
731;==============================================================================;
732; subtraction from negated shift amount
733
734define 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
744;
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
759}
760define 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
781;
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
794}
795
796;==============================================================================;
797; subtraction of negated shift amount
798
799define 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
808;
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
822}
823define 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
843;
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
855}
856
857;==============================================================================;
858; add to negated shift amount
859;
860
861define 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
870;
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
883}
884define 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
904;
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
917}
918
919;==============================================================================;
920; subtraction of negated shift amounts
921
922define 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
931;
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
945}
946define 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
965;
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
979}
980
981;==============================================================================;
982; addition of negated shift amounts
983
984define 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
994;
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
1010}
1011define 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
1032;
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
1046}
1047
1048;==============================================================================;
1049; and patterns with an actual negation+addition
1050
1051define 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
1060;
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
1073}
1074define 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
1093;
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
1106}
1107
1108define 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
1118;
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
1134}
1135define 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
1156;
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
1170}
1171
1172define 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
1181;
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
1196}
1197define 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
1217;
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
1230}
1231
1232define 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
1241;
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
1255}
1256define 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
1276;
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
1290}
1291
1292;==============================================================================;
1293; and patterns with an actual negation+mask
1294
1295define 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
1304;
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
1317}
1318define 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
1338;
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
1351}
1352
1353define 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
1364;
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
1380}
1381define 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
1402;
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
1418}
1419
1420define 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
1432;
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
1448}
1449define 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
1471;
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
1487}
1488
1489define 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
1500;
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
1517}
1518define 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
1539;
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
1554}
1555
1556define i16 @sh_trunc_sh(i64 %x) {
1557; X32-LABEL: sh_trunc_sh:
1558; X32:       # %bb.0:
1559; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1560; X32-NEXT:    shrl $4, %eax
1561; X32-NEXT:    andl $15, %eax
1562; X32-NEXT:    # kill: def $ax killed $ax killed $eax
1563; X32-NEXT:    retl
1564;
1565; X64-LABEL: sh_trunc_sh:
1566; X64:       # %bb.0:
1567; X64-NEXT:    movq %rdi, %rax
1568; X64-NEXT:    shrq $36, %rax
1569; X64-NEXT:    andl $15, %eax
1570; X64-NEXT:    # kill: def $ax killed $ax killed $rax
1571; X64-NEXT:    retq
1572  %s = lshr i64 %x, 24
1573  %t = trunc i64 %s to i16
1574  %r = lshr i16 %t, 12
1575  ret i16 %r
1576}
1577