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: # kill: def $cl killed $cl killed $rcx
12 ; CHECK-NEXT: shldq %cl, %rsi, %rax
14 %and = and i64 %bits, 63
15 %and64 = sub i64 64, %and
16 %sh_lo = lshr i64 %lo, %and64
17 %sh_hi = shl i64 %hi, %and
18 %sh = or i64 %sh_lo, %sh_hi
22 define i64 @test2(i64 %hi, i64 %lo, i64 %bits) nounwind {
25 ; CHECK-NEXT: movq %rdx, %rcx
26 ; CHECK-NEXT: movq %rsi, %rax
27 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
28 ; CHECK-NEXT: shrdq %cl, %rdi, %rax
30 %and = and i64 %bits, 63
31 %and64 = sub i64 64, %and
32 %sh_lo = shl i64 %hi, %and64
33 %sh_hi = lshr i64 %lo, %and
34 %sh = or i64 %sh_lo, %sh_hi
38 define i64 @test3(i64 %hi, i64 %lo, i64 %bits) nounwind {
41 ; CHECK-NEXT: movq %rdx, %rcx
42 ; CHECK-NEXT: movq %rdi, %rax
43 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
44 ; CHECK-NEXT: shldq %cl, %rsi, %rax
46 %bits64 = sub i64 64, %bits
47 %sh_lo = lshr i64 %lo, %bits64
48 %sh_hi = shl i64 %hi, %bits
49 %sh = or i64 %sh_lo, %sh_hi
53 define i64 @test4(i64 %hi, i64 %lo, i64 %bits) nounwind {
56 ; CHECK-NEXT: movq %rdx, %rcx
57 ; CHECK-NEXT: movq %rsi, %rax
58 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
59 ; CHECK-NEXT: shrdq %cl, %rdi, %rax
61 %bits64 = sub i64 64, %bits
62 %sh_lo = shl i64 %hi, %bits64
63 %sh_hi = lshr i64 %lo, %bits
64 %sh = or i64 %sh_lo, %sh_hi
68 define i64 @test5(i64 %hi, i64 %lo, i64 %bits) nounwind {
71 ; CHECK-NEXT: movq %rdx, %rcx
72 ; CHECK-NEXT: movq %rdi, %rax
73 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
74 ; CHECK-NEXT: shldq %cl, %rsi, %rax
76 %bits64 = xor i64 %bits, 63
77 %lo2 = lshr i64 %lo, 1
78 %sh_lo = lshr i64 %lo2, %bits64
79 %sh_hi = shl i64 %hi, %bits
80 %sh = or i64 %sh_lo, %sh_hi
84 define i64 @test6(i64 %hi, i64 %lo, i64 %bits) nounwind {
87 ; CHECK-NEXT: movq %rdx, %rcx
88 ; CHECK-NEXT: movq %rdi, %rax
89 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
90 ; CHECK-NEXT: shrdq %cl, %rsi, %rax
92 %bits64 = xor i64 %bits, 63
94 %sh_lo = shl i64 %lo2, %bits64
95 %sh_hi = lshr i64 %hi, %bits
96 %sh = or i64 %sh_lo, %sh_hi
100 define i64 @test7(i64 %hi, i64 %lo, i64 %bits) nounwind {
101 ; CHECK-LABEL: test7:
103 ; CHECK-NEXT: movq %rdx, %rcx
104 ; CHECK-NEXT: movq %rdi, %rax
105 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
106 ; CHECK-NEXT: shrdq %cl, %rsi, %rax
108 %bits64 = xor i64 %bits, 63
109 %lo2 = add i64 %lo, %lo
110 %sh_lo = shl i64 %lo2, %bits64
111 %sh_hi = lshr i64 %hi, %bits
112 %sh = or i64 %sh_lo, %sh_hi
116 define i64 @test8(i64 %hi, i64 %lo, i64 %bits) nounwind {
117 ; CHECK-LABEL: test8:
119 ; CHECK-NEXT: movq %rdx, %rcx
120 ; CHECK-NEXT: movq %rdi, %rax
121 ; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
122 ; CHECK-NEXT: shldq %cl, %rsi, %rax
124 %tbits = trunc i64 %bits to i8
125 %tand = and i8 %tbits, 63
126 %tand64 = sub i8 64, %tand
127 %and = zext i8 %tand to i64
128 %and64 = zext i8 %tand64 to i64
129 %sh_lo = lshr i64 %lo, %and64
130 %sh_hi = shl i64 %hi, %and
131 %sh = or i64 %sh_lo, %sh_hi