• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=X86
3; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s  --check-prefix=X64
4
5; Shift i64 integers on 32-bit target
6
7define i64 @test1(i64 %X, i8 %C) nounwind {
8; X86-LABEL: test1:
9; X86:       # %bb.0:
10; X86-NEXT:    pushl %esi
11; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
12; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
13; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
14; X86-NEXT:    movl %esi, %eax
15; X86-NEXT:    shll %cl, %eax
16; X86-NEXT:    shldl %cl, %esi, %edx
17; X86-NEXT:    testb $32, %cl
18; X86-NEXT:    je .LBB0_2
19; X86-NEXT:  # %bb.1:
20; X86-NEXT:    movl %eax, %edx
21; X86-NEXT:    xorl %eax, %eax
22; X86-NEXT:  .LBB0_2:
23; X86-NEXT:    popl %esi
24; X86-NEXT:    retl
25;
26; X64-LABEL: test1:
27; X64:       # %bb.0:
28; X64-NEXT:    movl %esi, %ecx
29; X64-NEXT:    shlq %cl, %rdi
30; X64-NEXT:    movq %rdi, %rax
31; X64-NEXT:    retq
32        %shift.upgrd.1 = zext i8 %C to i64              ; <i64> [#uses=1]
33        %Y = shl i64 %X, %shift.upgrd.1         ; <i64> [#uses=1]
34        ret i64 %Y
35}
36
37define i64 @test2(i64 %X, i8 %C) nounwind {
38; X86-LABEL: test2:
39; X86:       # %bb.0:
40; X86-NEXT:    pushl %esi
41; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
42; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
43; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
44; X86-NEXT:    movl %esi, %edx
45; X86-NEXT:    sarl %cl, %edx
46; X86-NEXT:    shrdl %cl, %esi, %eax
47; X86-NEXT:    testb $32, %cl
48; X86-NEXT:    je .LBB1_2
49; X86-NEXT:  # %bb.1:
50; X86-NEXT:    sarl $31, %esi
51; X86-NEXT:    movl %edx, %eax
52; X86-NEXT:    movl %esi, %edx
53; X86-NEXT:  .LBB1_2:
54; X86-NEXT:    popl %esi
55; X86-NEXT:    retl
56;
57; X64-LABEL: test2:
58; X64:       # %bb.0:
59; X64-NEXT:    movl %esi, %ecx
60; X64-NEXT:    sarq %cl, %rdi
61; X64-NEXT:    movq %rdi, %rax
62; X64-NEXT:    retq
63        %shift.upgrd.2 = zext i8 %C to i64              ; <i64> [#uses=1]
64        %Y = ashr i64 %X, %shift.upgrd.2                ; <i64> [#uses=1]
65        ret i64 %Y
66}
67
68define i64 @test3(i64 %X, i8 %C) nounwind {
69; X86-LABEL: test3:
70; X86:       # %bb.0:
71; X86-NEXT:    pushl %esi
72; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
73; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
74; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
75; X86-NEXT:    movl %esi, %edx
76; X86-NEXT:    shrl %cl, %edx
77; X86-NEXT:    shrdl %cl, %esi, %eax
78; X86-NEXT:    testb $32, %cl
79; X86-NEXT:    je .LBB2_2
80; X86-NEXT:  # %bb.1:
81; X86-NEXT:    movl %edx, %eax
82; X86-NEXT:    xorl %edx, %edx
83; X86-NEXT:  .LBB2_2:
84; X86-NEXT:    popl %esi
85; X86-NEXT:    retl
86;
87; X64-LABEL: test3:
88; X64:       # %bb.0:
89; X64-NEXT:    movl %esi, %ecx
90; X64-NEXT:    shrq %cl, %rdi
91; X64-NEXT:    movq %rdi, %rax
92; X64-NEXT:    retq
93        %shift.upgrd.3 = zext i8 %C to i64              ; <i64> [#uses=1]
94        %Y = lshr i64 %X, %shift.upgrd.3                ; <i64> [#uses=1]
95        ret i64 %Y
96}
97
98; Combine 2xi32/2xi16 shifts into SHLD
99
100define i32 @test4(i32 %A, i32 %B, i8 %C) nounwind {
101; X86-LABEL: test4:
102; X86:       # %bb.0:
103; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
104; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
105; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
106; X86-NEXT:    shldl %cl, %edx, %eax
107; X86-NEXT:    retl
108;
109; X64-LABEL: test4:
110; X64:       # %bb.0:
111; X64-NEXT:    movl %edx, %ecx
112; X64-NEXT:    shldl %cl, %esi, %edi
113; X64-NEXT:    movl %edi, %eax
114; X64-NEXT:    retq
115        %shift.upgrd.4 = zext i8 %C to i32              ; <i32> [#uses=1]
116        %X = shl i32 %A, %shift.upgrd.4         ; <i32> [#uses=1]
117        %Cv = sub i8 32, %C             ; <i8> [#uses=1]
118        %shift.upgrd.5 = zext i8 %Cv to i32             ; <i32> [#uses=1]
119        %Y = lshr i32 %B, %shift.upgrd.5                ; <i32> [#uses=1]
120        %Z = or i32 %Y, %X              ; <i32> [#uses=1]
121        ret i32 %Z
122}
123
124define i16 @test5(i16 %A, i16 %B, i8 %C) nounwind {
125; X86-LABEL: test5:
126; X86:       # %bb.0:
127; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
128; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
129; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
130; X86-NEXT:    shldw %cl, %dx, %ax
131; X86-NEXT:    retl
132;
133; X64-LABEL: test5:
134; X64:       # %bb.0:
135; X64-NEXT:    movl %edx, %ecx
136; X64-NEXT:    shldw %cl, %si, %di
137; X64-NEXT:    movl %edi, %eax
138; X64-NEXT:    retq
139        %shift.upgrd.6 = zext i8 %C to i16              ; <i16> [#uses=1]
140        %X = shl i16 %A, %shift.upgrd.6         ; <i16> [#uses=1]
141        %Cv = sub i8 16, %C             ; <i8> [#uses=1]
142        %shift.upgrd.7 = zext i8 %Cv to i16             ; <i16> [#uses=1]
143        %Y = lshr i16 %B, %shift.upgrd.7                ; <i16> [#uses=1]
144        %Z = or i16 %Y, %X              ; <i16> [#uses=1]
145        ret i16 %Z
146}
147
148; Combine 2xi32/2xi16 shifts into SHRD
149
150define i32 @test6(i32 %A, i32 %B, i8 %C) nounwind {
151; X86-LABEL: test6:
152; X86:       # %bb.0:
153; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
154; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
155; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
156; X86-NEXT:    shrdl %cl, %edx, %eax
157; X86-NEXT:    retl
158;
159; X64-LABEL: test6:
160; X64:       # %bb.0:
161; X64-NEXT:    movl %edx, %ecx
162; X64-NEXT:    shrdl %cl, %esi, %edi
163; X64-NEXT:    movl %edi, %eax
164; X64-NEXT:    retq
165        %shift.upgrd.4 = zext i8 %C to i32              ; <i32> [#uses=1]
166        %X = lshr i32 %A, %shift.upgrd.4         ; <i32> [#uses=1]
167        %Cv = sub i8 32, %C             ; <i8> [#uses=1]
168        %shift.upgrd.5 = zext i8 %Cv to i32             ; <i32> [#uses=1]
169        %Y = shl i32 %B, %shift.upgrd.5                ; <i32> [#uses=1]
170        %Z = or i32 %Y, %X              ; <i32> [#uses=1]
171        ret i32 %Z
172}
173
174define i16 @test7(i16 %A, i16 %B, i8 %C) nounwind {
175; X86-LABEL: test7:
176; X86:       # %bb.0:
177; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
178; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
179; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
180; X86-NEXT:    shrdw %cl, %dx, %ax
181; X86-NEXT:    retl
182;
183; X64-LABEL: test7:
184; X64:       # %bb.0:
185; X64-NEXT:    movl %edx, %ecx
186; X64-NEXT:    shrdw %cl, %si, %di
187; X64-NEXT:    movl %edi, %eax
188; X64-NEXT:    retq
189        %shift.upgrd.6 = zext i8 %C to i16              ; <i16> [#uses=1]
190        %X = lshr i16 %A, %shift.upgrd.6         ; <i16> [#uses=1]
191        %Cv = sub i8 16, %C             ; <i8> [#uses=1]
192        %shift.upgrd.7 = zext i8 %Cv to i16             ; <i16> [#uses=1]
193        %Y = shl i16 %B, %shift.upgrd.7                ; <i16> [#uses=1]
194        %Z = or i16 %Y, %X              ; <i16> [#uses=1]
195        ret i16 %Z
196}
197
198; Shift i64 integers on 32-bit target by shift value less then 32 (PR14593)
199
200define i64 @test8(i64 %val, i32 %bits) nounwind {
201; X86-LABEL: test8:
202; X86:       # %bb.0:
203; X86-NEXT:    pushl %esi
204; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
205; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
206; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
207; X86-NEXT:    movl %esi, %eax
208; X86-NEXT:    shll %cl, %eax
209; X86-NEXT:    shldl %cl, %esi, %edx
210; X86-NEXT:    popl %esi
211; X86-NEXT:    retl
212;
213; X64-LABEL: test8:
214; X64:       # %bb.0:
215; X64-NEXT:    andb $31, %sil
216; X64-NEXT:    movl %esi, %ecx
217; X64-NEXT:    shlq %cl, %rdi
218; X64-NEXT:    movq %rdi, %rax
219; X64-NEXT:    retq
220  %and = and i32 %bits, 31
221  %sh_prom = zext i32 %and to i64
222  %shl = shl i64 %val, %sh_prom
223  ret i64 %shl
224}
225
226define i64 @test9(i64 %val, i32 %bits) nounwind {
227; X86-LABEL: test9:
228; X86:       # %bb.0:
229; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
230; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
231; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
232; X86-NEXT:    shrdl %cl, %edx, %eax
233; X86-NEXT:    sarl %cl, %edx
234; X86-NEXT:    retl
235;
236; X64-LABEL: test9:
237; X64:       # %bb.0:
238; X64-NEXT:    andb $31, %sil
239; X64-NEXT:    movl %esi, %ecx
240; X64-NEXT:    sarq %cl, %rdi
241; X64-NEXT:    movq %rdi, %rax
242; X64-NEXT:    retq
243  %and = and i32 %bits, 31
244  %sh_prom = zext i32 %and to i64
245  %ashr = ashr i64 %val, %sh_prom
246  ret i64 %ashr
247}
248
249define i64 @test10(i64 %val, i32 %bits) nounwind {
250; X86-LABEL: test10:
251; X86:       # %bb.0:
252; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
253; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
254; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
255; X86-NEXT:    shrdl %cl, %edx, %eax
256; X86-NEXT:    shrl %cl, %edx
257; X86-NEXT:    retl
258;
259; X64-LABEL: test10:
260; X64:       # %bb.0:
261; X64-NEXT:    andb $31, %sil
262; X64-NEXT:    movl %esi, %ecx
263; X64-NEXT:    shrq %cl, %rdi
264; X64-NEXT:    movq %rdi, %rax
265; X64-NEXT:    retq
266  %and = and i32 %bits, 31
267  %sh_prom = zext i32 %and to i64
268  %lshr = lshr i64 %val, %sh_prom
269  ret i64 %lshr
270}
271
272; SHLD/SHRD manual shifts
273
274define i32 @test11(i32 %hi, i32 %lo, i32 %bits) nounwind {
275; X86-LABEL: test11:
276; X86:       # %bb.0:
277; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
278; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
279; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
280; X86-NEXT:    andl $31, %ecx
281; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
282; X86-NEXT:    shldl %cl, %edx, %eax
283; X86-NEXT:    retl
284;
285; X64-LABEL: test11:
286; X64:       # %bb.0:
287; X64-NEXT:    andl $31, %edx
288; X64-NEXT:    movl %edx, %ecx
289; X64-NEXT:    shldl %cl, %esi, %edi
290; X64-NEXT:    movl %edi, %eax
291; X64-NEXT:    retq
292  %and = and i32 %bits, 31
293  %and32 = sub i32 32, %and
294  %sh_lo = lshr i32 %lo, %and32
295  %sh_hi = shl i32 %hi, %and
296  %sh = or i32 %sh_lo, %sh_hi
297  ret i32 %sh
298}
299
300define i32 @test12(i32 %hi, i32 %lo, i32 %bits) nounwind {
301; X86-LABEL: test12:
302; X86:       # %bb.0:
303; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
304; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
305; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
306; X86-NEXT:    andl $31, %ecx
307; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
308; X86-NEXT:    shrdl %cl, %edx, %eax
309; X86-NEXT:    retl
310;
311; X64-LABEL: test12:
312; X64:       # %bb.0:
313; X64-NEXT:    andl $31, %edx
314; X64-NEXT:    movl %edx, %ecx
315; X64-NEXT:    shrdl %cl, %edi, %esi
316; X64-NEXT:    movl %esi, %eax
317; X64-NEXT:    retq
318  %and = and i32 %bits, 31
319  %and32 = sub i32 32, %and
320  %sh_lo = shl i32 %hi, %and32
321  %sh_hi = lshr i32 %lo, %and
322  %sh = or i32 %sh_lo, %sh_hi
323  ret i32 %sh
324}
325
326define i32 @test13(i32 %hi, i32 %lo, i32 %bits) nounwind {
327; X86-LABEL: test13:
328; X86:       # %bb.0:
329; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
330; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
331; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
332; X86-NEXT:    shldl %cl, %edx, %eax
333; X86-NEXT:    retl
334;
335; X64-LABEL: test13:
336; X64:       # %bb.0:
337; X64-NEXT:    movl %edx, %ecx
338; X64-NEXT:    shldl %cl, %esi, %edi
339; X64-NEXT:    movl %edi, %eax
340; X64-NEXT:    retq
341  %bits32 = sub i32 32, %bits
342  %sh_lo = lshr i32 %lo, %bits32
343  %sh_hi = shl i32 %hi, %bits
344  %sh = or i32 %sh_lo, %sh_hi
345  ret i32 %sh
346}
347
348define i32 @test14(i32 %hi, i32 %lo, i32 %bits) nounwind {
349; X86-LABEL: test14:
350; X86:       # %bb.0:
351; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
352; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
353; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
354; X86-NEXT:    shrdl %cl, %edx, %eax
355; X86-NEXT:    retl
356;
357; X64-LABEL: test14:
358; X64:       # %bb.0:
359; X64-NEXT:    movl %edx, %ecx
360; X64-NEXT:    shrdl %cl, %edi, %esi
361; X64-NEXT:    movl %esi, %eax
362; X64-NEXT:    retq
363  %bits32 = sub i32 32, %bits
364  %sh_lo = shl i32 %hi, %bits32
365  %sh_hi = lshr i32 %lo, %bits
366  %sh = or i32 %sh_lo, %sh_hi
367  ret i32 %sh
368}
369
370define i32 @test15(i32 %hi, i32 %lo, i32 %bits) nounwind {
371; X86-LABEL: test15:
372; X86:       # %bb.0:
373; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
374; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
375; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
376; X86-NEXT:    shldl %cl, %edx, %eax
377; X86-NEXT:    retl
378;
379; X64-LABEL: test15:
380; X64:       # %bb.0:
381; X64-NEXT:    movl %edx, %ecx
382; X64-NEXT:    shldl %cl, %esi, %edi
383; X64-NEXT:    movl %edi, %eax
384; X64-NEXT:    retq
385  %bits32 = xor i32 %bits, 31
386  %lo2 = lshr i32 %lo, 1
387  %sh_lo = lshr i32 %lo2, %bits32
388  %sh_hi = shl i32 %hi, %bits
389  %sh = or i32 %sh_lo, %sh_hi
390  ret i32 %sh
391}
392
393define i32 @test16(i32 %hi, i32 %lo, i32 %bits) nounwind {
394; X86-LABEL: test16:
395; X86:       # %bb.0:
396; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
397; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
398; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
399; X86-NEXT:    shrdl %cl, %edx, %eax
400; X86-NEXT:    retl
401;
402; X64-LABEL: test16:
403; X64:       # %bb.0:
404; X64-NEXT:    movl %edx, %ecx
405; X64-NEXT:    shrdl %cl, %esi, %edi
406; X64-NEXT:    movl %edi, %eax
407; X64-NEXT:    retq
408  %bits32 = xor i32 %bits, 31
409  %lo2 = shl i32 %lo, 1
410  %sh_lo = shl i32 %lo2, %bits32
411  %sh_hi = lshr i32 %hi, %bits
412  %sh = or i32 %sh_lo, %sh_hi
413  ret i32 %sh
414}
415
416define i32 @test17(i32 %hi, i32 %lo, i32 %bits) nounwind {
417; X86-LABEL: test17:
418; X86:       # %bb.0:
419; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
420; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
421; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
422; X86-NEXT:    shrdl %cl, %edx, %eax
423; X86-NEXT:    retl
424;
425; X64-LABEL: test17:
426; X64:       # %bb.0:
427; X64-NEXT:    movl %edx, %ecx
428; X64-NEXT:    shrdl %cl, %esi, %edi
429; X64-NEXT:    movl %edi, %eax
430; X64-NEXT:    retq
431  %bits32 = xor i32 %bits, 31
432  %lo2 = add i32 %lo, %lo
433  %sh_lo = shl i32 %lo2, %bits32
434  %sh_hi = lshr i32 %hi, %bits
435  %sh = or i32 %sh_lo, %sh_hi
436  ret i32 %sh
437}
438