[DAGCombiner] Attempt to mask vectors before zero extension instead of after.
[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: and    w8, w0, #0xffff
127 ; CHECK: add    x0, x1, w8, uxtw #3
128 ; CHECK: ret
129   %c = zext i16 %a to i64
130   %d = shl i64 %c, 3
131   %e = add i64 %x, %d
132   ret i64 %e
133 }
134
135 ; rdar://9160598
136 define i64 @t15(i64 %a, i64 %x) nounwind ssp {
137 entry:
138 ; CHECK-LABEL: t15:
139 ; CHECK: add x0, x1, w0, uxtw
140 ; CHECK: ret
141   %b = and i64 %a, 4294967295
142   %c = add i64 %x, %b
143   ret i64 %c
144 }
145
146 define i64 @t16(i64 %x) nounwind ssp {
147 entry:
148 ; CHECK-LABEL: t16:
149 ; CHECK: lsl x0, x0, #1
150 ; CHECK: ret
151   %a = shl i64 %x, 1
152   ret i64 %a
153 }
154
155 ; rdar://9166974
156 define i64 @t17(i16 %a, i64 %x) nounwind ssp {
157 entry:
158 ; CHECK-LABEL: t17:
159 ; CHECK: sxth [[REG:x[0-9]+]], w0
160 ; CHECK: neg x0, [[REG]], lsl #32
161 ; CHECK: ret
162   %tmp16 = sext i16 %a to i64
163   %tmp17 = mul i64 %tmp16, -4294967296
164   ret i64 %tmp17
165 }
166
167 define i32 @t18(i32 %a, i32 %b) nounwind readnone ssp {
168 entry:
169 ; CHECK-LABEL: t18:
170 ; CHECK: sdiv w0, w0, w1
171 ; CHECK: ret
172   %sdiv = call i32 @llvm.aarch64.sdiv.i32(i32 %a, i32 %b)
173   ret i32 %sdiv
174 }
175
176 define i64 @t19(i64 %a, i64 %b) nounwind readnone ssp {
177 entry:
178 ; CHECK-LABEL: t19:
179 ; CHECK: sdiv x0, x0, x1
180 ; CHECK: ret
181   %sdiv = call i64 @llvm.aarch64.sdiv.i64(i64 %a, i64 %b)
182   ret i64 %sdiv
183 }
184
185 define i32 @t20(i32 %a, i32 %b) nounwind readnone ssp {
186 entry:
187 ; CHECK-LABEL: t20:
188 ; CHECK: udiv w0, w0, w1
189 ; CHECK: ret
190   %udiv = call i32 @llvm.aarch64.udiv.i32(i32 %a, i32 %b)
191   ret i32 %udiv
192 }
193
194 define i64 @t21(i64 %a, i64 %b) nounwind readnone ssp {
195 entry:
196 ; CHECK-LABEL: t21:
197 ; CHECK: udiv x0, x0, x1
198 ; CHECK: ret
199   %udiv = call i64 @llvm.aarch64.udiv.i64(i64 %a, i64 %b)
200   ret i64 %udiv
201 }
202
203 declare i32 @llvm.aarch64.sdiv.i32(i32, i32) nounwind readnone
204 declare i64 @llvm.aarch64.sdiv.i64(i64, i64) nounwind readnone
205 declare i32 @llvm.aarch64.udiv.i32(i32, i32) nounwind readnone
206 declare i64 @llvm.aarch64.udiv.i64(i64, i64) nounwind readnone
207
208 ; 32-bit not.
209 define i32 @inv_32(i32 %x) nounwind ssp {
210 entry:
211 ; CHECK: inv_32
212 ; CHECK: mvn w0, w0
213 ; CHECK: ret
214   %inv = xor i32 %x, -1
215   ret i32 %inv
216 }
217
218 ; 64-bit not.
219 define i64 @inv_64(i64 %x) nounwind ssp {
220 entry:
221 ; CHECK: inv_64
222 ; CHECK: mvn x0, x0
223 ; CHECK: ret
224   %inv = xor i64 %x, -1
225   ret i64 %inv
226 }
227
228 ; Multiplying by a power of two plus or minus one is better done via shift
229 ; and add/sub rather than the madd/msub instructions. The latter are 4+ cycles,
230 ; and the former are two (total for the two instruction sequence for subtract).
231 define i32 @f0(i32 %a) nounwind readnone ssp {
232 ; CHECK-LABEL: f0:
233 ; CHECK-NEXT: add w0, w0, w0, lsl #3
234 ; CHECK-NEXT: ret
235   %res = mul i32 %a, 9
236   ret i32 %res
237 }
238
239 define i64 @f1(i64 %a) nounwind readnone ssp {
240 ; CHECK-LABEL: f1:
241 ; CHECK-NEXT: lsl x8, x0, #4
242 ; CHECK-NEXT: sub x0, x8, x0
243 ; CHECK-NEXT: ret
244   %res = mul i64 %a, 15
245   ret i64 %res
246 }
247
248 define i32 @f2(i32 %a) nounwind readnone ssp {
249 ; CHECK-LABEL: f2:
250 ; CHECK-NEXT: lsl w8, w0, #3
251 ; CHECK-NEXT: sub w0, w8, w0
252 ; CHECK-NEXT: ret
253   %res = mul nsw i32 %a, 7
254   ret i32 %res
255 }
256
257 define i64 @f3(i64 %a) nounwind readnone ssp {
258 ; CHECK-LABEL: f3:
259 ; CHECK-NEXT: add x0, x0, x0, lsl #4
260 ; CHECK-NEXT: ret
261   %res = mul nsw i64 %a, 17
262   ret i64 %res
263 }
264
265 define i32 @f4(i32 %a) nounwind readnone ssp {
266 ; CHECK-LABEL: f4:
267 ; CHECK-NEXT: add w0, w0, w0, lsl #1
268 ; CHECK-NEXT: ret
269   %res = mul i32 %a, 3
270   ret i32 %res
271 }