1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
3 ; RUN: llc < %s -mtriple=aarch64-windows | FileCheck %s -check-prefix=CHECK-WIN
4 ; RUN: llc < %s -mtriple=aarch64-apple-darwin | FileCheck %s -check-prefix=CHECK-DARWIN
6 ; The Windows runtime doesn't have these.
7 ; CHECK-WIN-NOT: __ashlti3
8 ; CHECK-WIN-NOT: __ashrti3
10 ; Darwin compiler-rt excludes these.
11 ; CHECK-DARWIN-NOT: __ashlti3
12 ; CHECK-DARWIN-NOT: __ashrti3
14 define i64 @f0(i64 %val, i64 %amt) minsize optsize {
17 ; CHECK-NEXT: lsl x0, x0, x1
20 ; CHECK-WIN-LABEL: f0:
21 ; CHECK-WIN: // %bb.0:
22 ; CHECK-WIN-NEXT: lsl x0, x0, x1
25 ; CHECK-DARWIN-LABEL: f0:
26 ; CHECK-DARWIN: ; %bb.0:
27 ; CHECK-DARWIN-NEXT: lsl x0, x0, x1
28 ; CHECK-DARWIN-NEXT: ret
29 %res = shl i64 %val, %amt
33 define i32 @f1(i64 %x, i64 %y) minsize optsize {
36 ; CHECK-NEXT: lsl x0, x0, x1
37 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
40 ; CHECK-WIN-LABEL: f1:
41 ; CHECK-WIN: // %bb.0:
42 ; CHECK-WIN-NEXT: lsl x0, x0, x1
43 ; CHECK-WIN-NEXT: // kill: def $w0 killed $w0 killed $x0
46 ; CHECK-DARWIN-LABEL: f1:
47 ; CHECK-DARWIN: ; %bb.0:
48 ; CHECK-DARWIN-NEXT: lsl x0, x0, x1
49 ; CHECK-DARWIN-NEXT: ; kill: def $w0 killed $w0 killed $x0
50 ; CHECK-DARWIN-NEXT: ret
52 %b = trunc i64 %a to i32
56 define i32 @f2(i64 %x, i64 %y) minsize optsize {
59 ; CHECK-NEXT: asr x0, x0, x1
60 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
63 ; CHECK-WIN-LABEL: f2:
64 ; CHECK-WIN: // %bb.0:
65 ; CHECK-WIN-NEXT: asr x0, x0, x1
66 ; CHECK-WIN-NEXT: // kill: def $w0 killed $w0 killed $x0
69 ; CHECK-DARWIN-LABEL: f2:
70 ; CHECK-DARWIN: ; %bb.0:
71 ; CHECK-DARWIN-NEXT: asr x0, x0, x1
72 ; CHECK-DARWIN-NEXT: ; kill: def $w0 killed $w0 killed $x0
73 ; CHECK-DARWIN-NEXT: ret
75 %b = trunc i64 %a to i32
79 define i32 @f3(i64 %x, i64 %y) minsize optsize {
82 ; CHECK-NEXT: lsr x0, x0, x1
83 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
86 ; CHECK-WIN-LABEL: f3:
87 ; CHECK-WIN: // %bb.0:
88 ; CHECK-WIN-NEXT: lsr x0, x0, x1
89 ; CHECK-WIN-NEXT: // kill: def $w0 killed $w0 killed $x0
92 ; CHECK-DARWIN-LABEL: f3:
93 ; CHECK-DARWIN: ; %bb.0:
94 ; CHECK-DARWIN-NEXT: lsr x0, x0, x1
95 ; CHECK-DARWIN-NEXT: ; kill: def $w0 killed $w0 killed $x0
96 ; CHECK-DARWIN-NEXT: ret
98 %b = trunc i64 %a to i32
102 define dso_local { i64, i64 } @shl128(i64 %x.coerce0, i64 %x.coerce1, i8 signext %y) minsize optsize {
103 ; CHECK-LABEL: shl128:
104 ; CHECK: // %bb.0: // %entry
105 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
106 ; CHECK-NEXT: .cfi_def_cfa_offset 16
107 ; CHECK-NEXT: .cfi_offset w30, -16
108 ; CHECK-NEXT: bl __ashlti3
109 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
112 ; CHECK-WIN-LABEL: shl128:
113 ; CHECK-WIN: // %bb.0: // %entry
114 ; CHECK-WIN-NEXT: lsr x8, x0, #1
115 ; CHECK-WIN-NEXT: mvn w9, w2
116 ; CHECK-WIN-NEXT: mov w10, w2
117 ; CHECK-WIN-NEXT: lsl x11, x0, x10
118 ; CHECK-WIN-NEXT: tst x10, #0x40
119 ; CHECK-WIN-NEXT: lsr x8, x8, x9
120 ; CHECK-WIN-NEXT: lsl x9, x1, x10
121 ; CHECK-WIN-NEXT: csel x0, xzr, x11, ne
122 ; CHECK-WIN-NEXT: orr x8, x9, x8
123 ; CHECK-WIN-NEXT: csel x1, x11, x8, ne
124 ; CHECK-WIN-NEXT: ret
126 ; CHECK-DARWIN-LABEL: shl128:
127 ; CHECK-DARWIN: ; %bb.0: ; %entry
128 ; CHECK-DARWIN-NEXT: lsr x8, x0, #1
129 ; CHECK-DARWIN-NEXT: mvn w9, w2
130 ; CHECK-DARWIN-NEXT: mov w10, w2
131 ; CHECK-DARWIN-NEXT: lsl x11, x0, x10
132 ; CHECK-DARWIN-NEXT: tst x10, #0x40
133 ; CHECK-DARWIN-NEXT: lsr x8, x8, x9
134 ; CHECK-DARWIN-NEXT: lsl x9, x1, x10
135 ; CHECK-DARWIN-NEXT: csel x0, xzr, x11, ne
136 ; CHECK-DARWIN-NEXT: orr x8, x9, x8
137 ; CHECK-DARWIN-NEXT: csel x1, x11, x8, ne
138 ; CHECK-DARWIN-NEXT: ret
141 %x.sroa.2.0.insert.ext = zext i64 %x.coerce1 to i128
142 %x.sroa.2.0.insert.shift = shl nuw i128 %x.sroa.2.0.insert.ext, 64
143 %x.sroa.0.0.insert.ext = zext i64 %x.coerce0 to i128
144 %x.sroa.0.0.insert.insert = or i128 %x.sroa.2.0.insert.shift, %x.sroa.0.0.insert.ext
145 %conv = sext i8 %y to i32
146 %sh_prom = zext i32 %conv to i128
147 %shl = shl i128 %x.sroa.0.0.insert.insert, %sh_prom
148 %retval.sroa.0.0.extract.trunc = trunc i128 %shl to i64
149 %retval.sroa.2.0.extract.shift = lshr i128 %shl, 64
150 %retval.sroa.2.0.extract.trunc = trunc i128 %retval.sroa.2.0.extract.shift to i64
151 %.fca.0.insert = insertvalue { i64, i64 } undef, i64 %retval.sroa.0.0.extract.trunc, 0
152 %.fca.1.insert = insertvalue { i64, i64 } %.fca.0.insert, i64 %retval.sroa.2.0.extract.trunc, 1
153 ret { i64, i64 } %.fca.1.insert
156 define dso_local { i64, i64 } @ashr128(i64 %x.coerce0, i64 %x.coerce1, i8 signext %y) minsize optsize {
157 ; CHECK-LABEL: ashr128:
158 ; CHECK: // %bb.0: // %entry
159 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
160 ; CHECK-NEXT: .cfi_def_cfa_offset 16
161 ; CHECK-NEXT: .cfi_offset w30, -16
162 ; CHECK-NEXT: bl __ashrti3
163 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
166 ; CHECK-WIN-LABEL: ashr128:
167 ; CHECK-WIN: // %bb.0: // %entry
168 ; CHECK-WIN-NEXT: lsl x8, x1, #1
169 ; CHECK-WIN-NEXT: mov w9, w2
170 ; CHECK-WIN-NEXT: mvn w10, w2
171 ; CHECK-WIN-NEXT: lsr x11, x0, x9
172 ; CHECK-WIN-NEXT: asr x12, x1, #63
173 ; CHECK-WIN-NEXT: tst x9, #0x40
174 ; CHECK-WIN-NEXT: lsl x8, x8, x10
175 ; CHECK-WIN-NEXT: asr x10, x1, x9
176 ; CHECK-WIN-NEXT: orr x8, x8, x11
177 ; CHECK-WIN-NEXT: csel x1, x12, x10, ne
178 ; CHECK-WIN-NEXT: csel x0, x10, x8, ne
179 ; CHECK-WIN-NEXT: ret
181 ; CHECK-DARWIN-LABEL: ashr128:
182 ; CHECK-DARWIN: ; %bb.0: ; %entry
183 ; CHECK-DARWIN-NEXT: lsl x8, x1, #1
184 ; CHECK-DARWIN-NEXT: mov w9, w2
185 ; CHECK-DARWIN-NEXT: mvn w10, w2
186 ; CHECK-DARWIN-NEXT: lsr x11, x0, x9
187 ; CHECK-DARWIN-NEXT: asr x12, x1, #63
188 ; CHECK-DARWIN-NEXT: tst x9, #0x40
189 ; CHECK-DARWIN-NEXT: lsl x8, x8, x10
190 ; CHECK-DARWIN-NEXT: asr x10, x1, x9
191 ; CHECK-DARWIN-NEXT: orr x8, x8, x11
192 ; CHECK-DARWIN-NEXT: csel x1, x12, x10, ne
193 ; CHECK-DARWIN-NEXT: csel x0, x10, x8, ne
194 ; CHECK-DARWIN-NEXT: ret
196 %x.sroa.2.0.insert.ext = zext i64 %x.coerce1 to i128
197 %x.sroa.2.0.insert.shift = shl nuw i128 %x.sroa.2.0.insert.ext, 64
198 %x.sroa.0.0.insert.ext = zext i64 %x.coerce0 to i128
199 %x.sroa.0.0.insert.insert = or i128 %x.sroa.2.0.insert.shift, %x.sroa.0.0.insert.ext
200 %conv = sext i8 %y to i32
201 %sh_prom = zext i32 %conv to i128
202 %shr = ashr i128 %x.sroa.0.0.insert.insert, %sh_prom
203 %retval.sroa.0.0.extract.trunc = trunc i128 %shr to i64
204 %retval.sroa.2.0.extract.shift = lshr i128 %shr, 64
205 %retval.sroa.2.0.extract.trunc = trunc i128 %retval.sroa.2.0.extract.shift to i64
206 %.fca.0.insert = insertvalue { i64, i64 } undef, i64 %retval.sroa.0.0.extract.trunc, 0
207 %.fca.1.insert = insertvalue { i64, i64 } %.fca.0.insert, i64 %retval.sroa.2.0.extract.trunc, 1
208 ret { i64, i64 } %.fca.1.insert
211 define dso_local { i64, i64 } @lshr128(i64 %x.coerce0, i64 %x.coerce1, i8 signext %y) minsize optsize {
212 ; CHECK-LABEL: lshr128:
213 ; CHECK: // %bb.0: // %entry
214 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
215 ; CHECK-NEXT: .cfi_def_cfa_offset 16
216 ; CHECK-NEXT: .cfi_offset w30, -16
217 ; CHECK-NEXT: bl __lshrti3
218 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
221 ; CHECK-WIN-LABEL: lshr128:
222 ; CHECK-WIN: // %bb.0: // %entry
223 ; CHECK-WIN-NEXT: lsl x8, x1, #1
224 ; CHECK-WIN-NEXT: mov w9, w2
225 ; CHECK-WIN-NEXT: mvn w10, w2
226 ; CHECK-WIN-NEXT: lsr x11, x0, x9
227 ; CHECK-WIN-NEXT: tst x9, #0x40
228 ; CHECK-WIN-NEXT: lsl x8, x8, x10
229 ; CHECK-WIN-NEXT: lsr x10, x1, x9
230 ; CHECK-WIN-NEXT: orr x8, x8, x11
231 ; CHECK-WIN-NEXT: csel x1, xzr, x10, ne
232 ; CHECK-WIN-NEXT: csel x0, x10, x8, ne
233 ; CHECK-WIN-NEXT: ret
235 ; CHECK-DARWIN-LABEL: lshr128:
236 ; CHECK-DARWIN: ; %bb.0: ; %entry
237 ; CHECK-DARWIN-NEXT: lsl x8, x1, #1
238 ; CHECK-DARWIN-NEXT: mov w9, w2
239 ; CHECK-DARWIN-NEXT: mvn w10, w2
240 ; CHECK-DARWIN-NEXT: lsr x11, x0, x9
241 ; CHECK-DARWIN-NEXT: tst x9, #0x40
242 ; CHECK-DARWIN-NEXT: lsl x8, x8, x10
243 ; CHECK-DARWIN-NEXT: lsr x10, x1, x9
244 ; CHECK-DARWIN-NEXT: orr x8, x8, x11
245 ; CHECK-DARWIN-NEXT: csel x1, xzr, x10, ne
246 ; CHECK-DARWIN-NEXT: csel x0, x10, x8, ne
247 ; CHECK-DARWIN-NEXT: ret
249 %x.sroa.2.0.insert.ext = zext i64 %x.coerce1 to i128
250 %x.sroa.2.0.insert.shift = shl nuw i128 %x.sroa.2.0.insert.ext, 64
251 %x.sroa.0.0.insert.ext = zext i64 %x.coerce0 to i128
252 %x.sroa.0.0.insert.insert = or i128 %x.sroa.2.0.insert.shift, %x.sroa.0.0.insert.ext
253 %conv = sext i8 %y to i32
254 %sh_prom = zext i32 %conv to i128
255 %shr = lshr i128 %x.sroa.0.0.insert.insert, %sh_prom
256 %retval.sroa.0.0.extract.trunc = trunc i128 %shr to i64
257 %retval.sroa.2.0.extract.shift = lshr i128 %shr, 64
258 %retval.sroa.2.0.extract.trunc = trunc i128 %retval.sroa.2.0.extract.shift to i64
259 %.fca.0.insert = insertvalue { i64, i64 } undef, i64 %retval.sroa.0.0.extract.trunc, 0
260 %.fca.1.insert = insertvalue { i64, i64 } %.fca.0.insert, i64 %retval.sroa.2.0.extract.trunc, 1
261 ret { i64, i64 } %.fca.1.insert