1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s
4 ; SHLD/SHRD manual shifts
6 define i64 @test1(i64 %hi, i64 %lo, i64 %bits) nounwind {
9 ; CHECK-NEXT: movq %rdx, %rcx
10 ; CHECK-NEXT: movq %rdi, %rax
11 ; CHECK-NEXT: andl $63, %ecx
12 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
13 ; CHECK-NEXT: shldq %cl, %rsi, %rax
15 %and = and i64 %bits, 63
16 %and64 = sub i64 64, %and
17 %sh_lo = lshr i64 %lo, %and64
18 %sh_hi = shl i64 %hi, %and
19 %sh = or i64 %sh_lo, %sh_hi
23 define i64 @test2(i64 %hi, i64 %lo, i64 %bits) nounwind {
26 ; CHECK-NEXT: movq %rdx, %rcx
27 ; CHECK-NEXT: movq %rsi, %rax
28 ; CHECK-NEXT: andl $63, %ecx
29 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
30 ; CHECK-NEXT: shrdq %cl, %rdi, %rax
32 %and = and i64 %bits, 63
33 %and64 = sub i64 64, %and
34 %sh_lo = shl i64 %hi, %and64
35 %sh_hi = lshr i64 %lo, %and
36 %sh = or i64 %sh_lo, %sh_hi
40 define i64 @test3(i64 %hi, i64 %lo, i64 %bits) nounwind {
43 ; CHECK-NEXT: movq %rdx, %rcx
44 ; CHECK-NEXT: movq %rdi, %rax
45 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
46 ; CHECK-NEXT: shldq %cl, %rsi, %rax
48 %bits64 = sub i64 64, %bits
49 %sh_lo = lshr i64 %lo, %bits64
50 %sh_hi = shl i64 %hi, %bits
51 %sh = or i64 %sh_lo, %sh_hi
55 define i64 @test4(i64 %hi, i64 %lo, i64 %bits) nounwind {
58 ; CHECK-NEXT: movq %rdx, %rcx
59 ; CHECK-NEXT: movq %rsi, %rax
60 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
61 ; CHECK-NEXT: shrdq %cl, %rdi, %rax
63 %bits64 = sub i64 64, %bits
64 %sh_lo = shl i64 %hi, %bits64
65 %sh_hi = lshr i64 %lo, %bits
66 %sh = or i64 %sh_lo, %sh_hi
70 define i64 @test5(i64 %hi, i64 %lo, i64 %bits) nounwind {
73 ; CHECK-NEXT: movq %rdx, %rcx
74 ; CHECK-NEXT: movq %rdi, %rax
75 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
76 ; CHECK-NEXT: shldq %cl, %rsi, %rax
78 %bits64 = xor i64 %bits, 63
79 %lo2 = lshr i64 %lo, 1
80 %sh_lo = lshr i64 %lo2, %bits64
81 %sh_hi = shl i64 %hi, %bits
82 %sh = or i64 %sh_lo, %sh_hi
86 define i64 @test6(i64 %hi, i64 %lo, i64 %bits) nounwind {
89 ; CHECK-NEXT: movq %rdx, %rcx
90 ; CHECK-NEXT: movq %rdi, %rax
91 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
92 ; CHECK-NEXT: shrdq %cl, %rsi, %rax
94 %bits64 = xor i64 %bits, 63
96 %sh_lo = shl i64 %lo2, %bits64
97 %sh_hi = lshr i64 %hi, %bits
98 %sh = or i64 %sh_lo, %sh_hi
102 define i64 @test7(i64 %hi, i64 %lo, i64 %bits) nounwind {
103 ; CHECK-LABEL: test7:
105 ; CHECK-NEXT: movq %rdx, %rcx
106 ; CHECK-NEXT: movq %rdi, %rax
107 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
108 ; CHECK-NEXT: shrdq %cl, %rsi, %rax
110 %bits64 = xor i64 %bits, 63
111 %lo2 = add i64 %lo, %lo
112 %sh_lo = shl i64 %lo2, %bits64
113 %sh_hi = lshr i64 %hi, %bits
114 %sh = or i64 %sh_lo, %sh_hi
118 define i64 @test8(i64 %hi, i64 %lo, i64 %bits) nounwind {
119 ; CHECK-LABEL: test8:
121 ; CHECK-NEXT: movq %rdx, %rcx
122 ; CHECK-NEXT: movq %rdi, %rax
123 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
124 ; CHECK-NEXT: shldq %cl, %rsi, %rax
126 %tbits = trunc i64 %bits to i8
127 %tand = and i8 %tbits, 63
128 %tand64 = sub i8 64, %tand
129 %and = zext i8 %tand to i64
130 %and64 = zext i8 %tand64 to i64
131 %sh_lo = lshr i64 %lo, %and64
132 %sh_hi = shl i64 %hi, %and
133 %sh = or i64 %sh_lo, %sh_hi