[FastISel][AArch64] Optimize compare-and-branch for i1 to use 'tbz'.
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-arith.ll
1 ; RUN: llc < %s -march=arm64 -asm-verbose=false | FileCheck %s
2
3 define i32 @t1(i32 %a, i32 %b) nounwind readnone ssp {
4 entry:
5 ; CHECK-LABEL: t1:
6 ; CHECK: add w0, w1, w0
7 ; CHECK: ret
8   %add = add i32 %b, %a
9   ret i32 %add
10 }
11
12 define i32 @t2(i32 %a, i32 %b) nounwind readnone ssp {
13 entry:
14 ; CHECK-LABEL: t2:
15 ; CHECK: udiv w0, w0, w1
16 ; CHECK: ret
17   %udiv = udiv i32 %a, %b
18   ret i32 %udiv
19 }
20
21 define i64 @t3(i64 %a, i64 %b) nounwind readnone ssp {
22 entry:
23 ; CHECK-LABEL: t3:
24 ; CHECK: udiv x0, x0, x1
25 ; CHECK: ret
26   %udiv = udiv i64 %a, %b
27   ret i64 %udiv
28 }
29
30 define i32 @t4(i32 %a, i32 %b) nounwind readnone ssp {
31 entry:
32 ; CHECK-LABEL: t4:
33 ; CHECK: sdiv w0, w0, w1
34 ; CHECK: ret
35   %sdiv = sdiv i32 %a, %b
36   ret i32 %sdiv
37 }
38
39 define i64 @t5(i64 %a, i64 %b) nounwind readnone ssp {
40 entry:
41 ; CHECK-LABEL: t5:
42 ; CHECK: sdiv x0, x0, x1
43 ; CHECK: ret
44   %sdiv = sdiv i64 %a, %b
45   ret i64 %sdiv
46 }
47
48 define i32 @t6(i32 %a, i32 %b) nounwind readnone ssp {
49 entry:
50 ; CHECK-LABEL: t6:
51 ; CHECK: lsl w0, w0, w1
52 ; CHECK: ret
53   %shl = shl i32 %a, %b
54   ret i32 %shl
55 }
56
57 define i64 @t7(i64 %a, i64 %b) nounwind readnone ssp {
58 entry:
59 ; CHECK-LABEL: t7:
60 ; CHECK: lsl x0, x0, x1
61 ; CHECK: ret
62   %shl = shl i64 %a, %b
63   ret i64 %shl
64 }
65
66 define i32 @t8(i32 %a, i32 %b) nounwind readnone ssp {
67 entry:
68 ; CHECK-LABEL: t8:
69 ; CHECK: lsr w0, w0, w1
70 ; CHECK: ret
71   %lshr = lshr i32 %a, %b
72   ret i32 %lshr
73 }
74
75 define i64 @t9(i64 %a, i64 %b) nounwind readnone ssp {
76 entry:
77 ; CHECK-LABEL: t9:
78 ; CHECK: lsr x0, x0, x1
79 ; CHECK: ret
80   %lshr = lshr i64 %a, %b
81   ret i64 %lshr
82 }
83
84 define i32 @t10(i32 %a, i32 %b) nounwind readnone ssp {
85 entry:
86 ; CHECK-LABEL: t10:
87 ; CHECK: asr w0, w0, w1
88 ; CHECK: ret
89   %ashr = ashr i32 %a, %b
90   ret i32 %ashr
91 }
92
93 define i64 @t11(i64 %a, i64 %b) nounwind readnone ssp {
94 entry:
95 ; CHECK-LABEL: t11:
96 ; CHECK: asr x0, x0, x1
97 ; CHECK: ret
98   %ashr = ashr i64 %a, %b
99   ret i64 %ashr
100 }
101
102 define i32 @t12(i16 %a, i32 %x) nounwind ssp {
103 entry:
104 ; CHECK-LABEL: t12:
105 ; CHECK: add    w0, w1, w0, sxth
106 ; CHECK: ret
107   %c = sext i16 %a to i32
108   %e = add i32 %x, %c
109   ret i32 %e
110 }
111
112 define i32 @t13(i16 %a, i32 %x) nounwind ssp {
113 entry:
114 ; CHECK-LABEL: t13:
115 ; CHECK: add    w0, w1, w0, sxth #2
116 ; CHECK: ret
117   %c = sext i16 %a to i32
118   %d = shl i32 %c, 2
119   %e = add i32 %x, %d
120   ret i32 %e
121 }
122
123 define i64 @t14(i16 %a, i64 %x) nounwind ssp {
124 entry:
125 ; CHECK-LABEL: t14:
126 ; CHECK: add    x0, x1, w0, uxth #3
127 ; CHECK: ret
128   %c = zext i16 %a to i64
129   %d = shl i64 %c, 3
130   %e = add i64 %x, %d
131   ret i64 %e
132 }
133
134 ; rdar://9160598
135 define i64 @t15(i64 %a, i64 %x) nounwind ssp {
136 entry:
137 ; CHECK-LABEL: t15:
138 ; CHECK: add x0, x1, w0, uxtw
139 ; CHECK: ret
140   %b = and i64 %a, 4294967295
141   %c = add i64 %x, %b
142   ret i64 %c
143 }
144
145 define i64 @t16(i64 %x) nounwind ssp {
146 entry:
147 ; CHECK-LABEL: t16:
148 ; CHECK: lsl x0, x0, #1
149 ; CHECK: ret
150   %a = shl i64 %x, 1
151   ret i64 %a
152 }
153
154 ; rdar://9166974
155 define i64 @t17(i16 %a, i64 %x) nounwind ssp {
156 entry:
157 ; CHECK-LABEL: t17:
158 ; CHECK: sxth [[REG:x[0-9]+]], w0
159 ; CHECK: neg x0, [[REG]], lsl #32
160 ; CHECK: ret
161   %tmp16 = sext i16 %a to i64
162   %tmp17 = mul i64 %tmp16, -4294967296
163   ret i64 %tmp17
164 }
165
166 define i32 @t18(i32 %a, i32 %b) nounwind readnone ssp {
167 entry:
168 ; CHECK-LABEL: t18:
169 ; CHECK: sdiv w0, w0, w1
170 ; CHECK: ret
171   %sdiv = call i32 @llvm.aarch64.sdiv.i32(i32 %a, i32 %b)
172   ret i32 %sdiv
173 }
174
175 define i64 @t19(i64 %a, i64 %b) nounwind readnone ssp {
176 entry:
177 ; CHECK-LABEL: t19:
178 ; CHECK: sdiv x0, x0, x1
179 ; CHECK: ret
180   %sdiv = call i64 @llvm.aarch64.sdiv.i64(i64 %a, i64 %b)
181   ret i64 %sdiv
182 }
183
184 define i32 @t20(i32 %a, i32 %b) nounwind readnone ssp {
185 entry:
186 ; CHECK-LABEL: t20:
187 ; CHECK: udiv w0, w0, w1
188 ; CHECK: ret
189   %udiv = call i32 @llvm.aarch64.udiv.i32(i32 %a, i32 %b)
190   ret i32 %udiv
191 }
192
193 define i64 @t21(i64 %a, i64 %b) nounwind readnone ssp {
194 entry:
195 ; CHECK-LABEL: t21:
196 ; CHECK: udiv x0, x0, x1
197 ; CHECK: ret
198   %udiv = call i64 @llvm.aarch64.udiv.i64(i64 %a, i64 %b)
199   ret i64 %udiv
200 }
201
202 declare i32 @llvm.aarch64.sdiv.i32(i32, i32) nounwind readnone
203 declare i64 @llvm.aarch64.sdiv.i64(i64, i64) nounwind readnone
204 declare i32 @llvm.aarch64.udiv.i32(i32, i32) nounwind readnone
205 declare i64 @llvm.aarch64.udiv.i64(i64, i64) nounwind readnone
206
207 ; 32-bit not.
208 define i32 @inv_32(i32 %x) nounwind ssp {
209 entry:
210 ; CHECK: inv_32
211 ; CHECK: mvn w0, w0
212 ; CHECK: ret
213   %inv = xor i32 %x, -1
214   ret i32 %inv
215 }
216
217 ; 64-bit not.
218 define i64 @inv_64(i64 %x) nounwind ssp {
219 entry:
220 ; CHECK: inv_64
221 ; CHECK: mvn x0, x0
222 ; CHECK: ret
223   %inv = xor i64 %x, -1
224   ret i64 %inv
225 }
226
227 ; Multiplying by a power of two plus or minus one is better done via shift
228 ; and add/sub rather than the madd/msub instructions. The latter are 4+ cycles,
229 ; and the former are two (total for the two instruction sequence for subtract).
230 define i32 @f0(i32 %a) nounwind readnone ssp {
231 ; CHECK-LABEL: f0:
232 ; CHECK-NEXT: add w0, w0, w0, lsl #3
233 ; CHECK-NEXT: ret
234   %res = mul i32 %a, 9
235   ret i32 %res
236 }
237
238 define i64 @f1(i64 %a) nounwind readnone ssp {
239 ; CHECK-LABEL: f1:
240 ; CHECK-NEXT: lsl x8, x0, #4
241 ; CHECK-NEXT: sub x0, x8, x0
242 ; CHECK-NEXT: ret
243   %res = mul i64 %a, 15
244   ret i64 %res
245 }
246
247 define i32 @f2(i32 %a) nounwind readnone ssp {
248 ; CHECK-LABEL: f2:
249 ; CHECK-NEXT: lsl w8, w0, #3
250 ; CHECK-NEXT: sub w0, w8, w0
251 ; CHECK-NEXT: ret
252   %res = mul nsw i32 %a, 7
253   ret i32 %res
254 }
255
256 define i64 @f3(i64 %a) nounwind readnone ssp {
257 ; CHECK-LABEL: f3:
258 ; CHECK-NEXT: add x0, x0, x0, lsl #4
259 ; CHECK-NEXT: ret
260   %res = mul nsw i64 %a, 17
261   ret i64 %res
262 }
263
264 define i32 @f4(i32 %a) nounwind readnone ssp {
265 ; CHECK-LABEL: f4:
266 ; CHECK-NEXT: add w0, w0, w0, lsl #1
267 ; CHECK-NEXT: ret
268   %res = mul i32 %a, 3
269   ret i32 %res
270 }