Revert "[AArch64] Add DAG combine for extract extend pattern"
[oota-llvm.git] / test / CodeGen / AArch64 / f16-convert.ll
1 ; RUN: llc < %s -mtriple=arm64-apple-ios -asm-verbose=false | FileCheck %s
2
3 define float @load0(i16* nocapture readonly %a) nounwind {
4 ; CHECK-LABEL: load0:
5 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0]
6 ; CHECK-NEXT: fcvt s0, [[HREG]]
7 ; CHECK-NEXT: ret
8
9   %tmp = load i16, i16* %a, align 2
10   %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
11   ret float %tmp1
12 }
13
14 define double @load1(i16* nocapture readonly %a) nounwind {
15 ; CHECK-LABEL: load1:
16 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0]
17 ; CHECK-NEXT: fcvt d0, [[HREG]]
18 ; CHECK-NEXT: ret
19
20   %tmp = load i16, i16* %a, align 2
21   %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp)
22   ret double %conv
23 }
24
25 define float @load2(i16* nocapture readonly %a, i32 %i) nounwind {
26 ; CHECK-LABEL: load2:
27 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, w1, sxtw #1]
28 ; CHECK-NEXT: fcvt s0, [[HREG]]
29 ; CHECK-NEXT: ret
30
31   %idxprom = sext i32 %i to i64
32   %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom
33   %tmp = load i16, i16* %arrayidx, align 2
34   %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
35   ret float %tmp1
36 }
37
38 define double @load3(i16* nocapture readonly %a, i32 %i) nounwind {
39 ; CHECK-LABEL: load3:
40 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, w1, sxtw #1]
41 ; CHECK-NEXT: fcvt d0, [[HREG]]
42 ; CHECK-NEXT: ret
43
44   %idxprom = sext i32 %i to i64
45   %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom
46   %tmp = load i16, i16* %arrayidx, align 2
47   %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp)
48   ret double %conv
49 }
50
51 define float @load4(i16* nocapture readonly %a, i64 %i) nounwind {
52 ; CHECK-LABEL: load4:
53 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, x1, lsl #1]
54 ; CHECK-NEXT: fcvt s0, [[HREG]]
55 ; CHECK-NEXT: ret
56
57   %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i
58   %tmp = load i16, i16* %arrayidx, align 2
59   %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
60   ret float %tmp1
61 }
62
63 define double @load5(i16* nocapture readonly %a, i64 %i) nounwind {
64 ; CHECK-LABEL: load5:
65 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, x1, lsl #1]
66 ; CHECK-NEXT: fcvt d0, [[HREG]]
67 ; CHECK-NEXT: ret
68
69   %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i
70   %tmp = load i16, i16* %arrayidx, align 2
71   %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp)
72   ret double %conv
73 }
74
75 define float @load6(i16* nocapture readonly %a) nounwind {
76 ; CHECK-LABEL: load6:
77 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, #20]
78 ; CHECK-NEXT: fcvt s0, [[HREG]]
79 ; CHECK-NEXT: ret
80
81   %arrayidx = getelementptr inbounds i16, i16* %a, i64 10
82   %tmp = load i16, i16* %arrayidx, align 2
83   %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
84   ret float %tmp1
85 }
86
87 define double @load7(i16* nocapture readonly %a) nounwind {
88 ; CHECK-LABEL: load7:
89 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, #20]
90 ; CHECK-NEXT: fcvt d0, [[HREG]]
91 ; CHECK-NEXT: ret
92
93   %arrayidx = getelementptr inbounds i16, i16* %a, i64 10
94   %tmp = load i16, i16* %arrayidx, align 2
95   %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp)
96   ret double %conv
97 }
98
99 define float @load8(i16* nocapture readonly %a) nounwind {
100 ; CHECK-LABEL: load8:
101 ; CHECK-NEXT: ldur [[HREG:h[0-9]+]], [x0, #-20]
102 ; CHECK-NEXT: fcvt s0, [[HREG]]
103 ; CHECK-NEXT: ret
104
105   %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10
106   %tmp = load i16, i16* %arrayidx, align 2
107   %tmp1 = tail call float @llvm.convert.from.fp16.f32(i16 %tmp)
108   ret float %tmp1
109 }
110
111 define double @load9(i16* nocapture readonly %a) nounwind {
112 ; CHECK-LABEL: load9:
113 ; CHECK-NEXT: ldur [[HREG:h[0-9]+]], [x0, #-20]
114 ; CHECK-NEXT: fcvt d0, [[HREG]]
115 ; CHECK-NEXT: ret
116
117   %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10
118   %tmp = load i16, i16* %arrayidx, align 2
119   %conv = tail call double @llvm.convert.from.fp16.f64(i16 %tmp)
120   ret double %conv
121 }
122
123 define void @store0(i16* nocapture %a, float %val) nounwind {
124 ; CHECK-LABEL: store0:
125 ; CHECK-NEXT: fcvt h0, s0
126 ; CHECK-NEXT: str  h0, [x0]
127 ; CHECK-NEXT: ret
128
129   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
130   store i16 %tmp, i16* %a, align 2
131   ret void
132 }
133
134 define void @store1(i16* nocapture %a, double %val) nounwind {
135 ; CHECK-LABEL: store1:
136 ; CHECK-NEXT: fcvt s0, d0
137 ; CHECK-NEXT: fcvt h0, s0
138 ; CHECK-NEXT: str  h0, [x0]
139 ; CHECK-NEXT: ret
140
141   %conv = fptrunc double %val to float
142   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
143   store i16 %tmp, i16* %a, align 2
144   ret void
145 }
146
147 define void @store2(i16* nocapture %a, i32 %i, float %val) nounwind {
148 ; CHECK-LABEL: store2:
149 ; CHECK-NEXT: fcvt h0, s0
150 ; CHECK-NEXT: str h0, [x0, w1, sxtw #1]
151 ; CHECK-NEXT: ret
152
153   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
154   %idxprom = sext i32 %i to i64
155   %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom
156   store i16 %tmp, i16* %arrayidx, align 2
157   ret void
158 }
159
160 define void @store3(i16* nocapture %a, i32 %i, double %val) nounwind {
161 ; CHECK-LABEL: store3:
162 ; CHECK-NEXT: fcvt s0, d0
163 ; CHECK-NEXT: fcvt h0, s0
164 ; CHECK-NEXT: str h0, [x0, w1, sxtw #1]
165 ; CHECK-NEXT: ret
166
167   %conv = fptrunc double %val to float
168   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
169   %idxprom = sext i32 %i to i64
170   %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom
171   store i16 %tmp, i16* %arrayidx, align 2
172   ret void
173 }
174
175 define void @store4(i16* nocapture %a, i64 %i, float %val) nounwind {
176 ; CHECK-LABEL: store4:
177 ; CHECK-NEXT: fcvt h0, s0
178 ; CHECK-NEXT: str h0, [x0, x1, lsl #1]
179 ; CHECK-NEXT: ret
180
181   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
182   %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i
183   store i16 %tmp, i16* %arrayidx, align 2
184   ret void
185 }
186
187 define void @store5(i16* nocapture %a, i64 %i, double %val) nounwind {
188 ; CHECK-LABEL: store5:
189 ; CHECK-NEXT: fcvt s0, d0
190 ; CHECK-NEXT: fcvt h0, s0
191 ; CHECK-NEXT: str h0, [x0, x1, lsl #1]
192 ; CHECK-NEXT: ret
193
194   %conv = fptrunc double %val to float
195   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
196   %arrayidx = getelementptr inbounds i16, i16* %a, i64 %i
197   store i16 %tmp, i16* %arrayidx, align 2
198   ret void
199 }
200
201 define void @store6(i16* nocapture %a, float %val) nounwind {
202 ; CHECK-LABEL: store6:
203 ; CHECK-NEXT: fcvt h0, s0
204 ; CHECK-NEXT: str h0, [x0, #20]
205 ; CHECK-NEXT: ret
206
207   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
208   %arrayidx = getelementptr inbounds i16, i16* %a, i64 10
209   store i16 %tmp, i16* %arrayidx, align 2
210   ret void
211 }
212
213 define void @store7(i16* nocapture %a, double %val) nounwind {
214 ; CHECK-LABEL: store7:
215 ; CHECK-NEXT: fcvt s0, d0
216 ; CHECK-NEXT: fcvt h0, s0
217 ; CHECK-NEXT: str h0, [x0, #20]
218 ; CHECK-NEXT: ret
219
220   %conv = fptrunc double %val to float
221   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
222   %arrayidx = getelementptr inbounds i16, i16* %a, i64 10
223   store i16 %tmp, i16* %arrayidx, align 2
224   ret void
225 }
226
227 define void @store8(i16* nocapture %a, float %val) nounwind {
228 ; CHECK-LABEL: store8:
229 ; CHECK-NEXT: fcvt h0, s0
230 ; CHECK-NEXT: stur h0, [x0, #-20]
231 ; CHECK-NEXT: ret
232
233   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %val)
234   %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10
235   store i16 %tmp, i16* %arrayidx, align 2
236   ret void
237 }
238
239 define void @store9(i16* nocapture %a, double %val) nounwind {
240 ; CHECK-LABEL: store9:
241 ; CHECK-NEXT: fcvt s0, d0
242 ; CHECK-NEXT: fcvt h0, s0
243 ; CHECK-NEXT: stur h0, [x0, #-20]
244 ; CHECK-NEXT: ret
245
246   %conv = fptrunc double %val to float
247   %tmp = tail call i16 @llvm.convert.to.fp16.f32(float %conv)
248   %arrayidx = getelementptr inbounds i16, i16* %a, i64 -10
249   store i16 %tmp, i16* %arrayidx, align 2
250   ret void
251 }
252
253 declare i16 @llvm.convert.to.fp16.f32(float) nounwind readnone
254 declare float @llvm.convert.from.fp16.f32(i16) nounwind readnone
255 declare i16 @llvm.convert.to.fp16.f64(double) nounwind readnone
256 declare double @llvm.convert.from.fp16.f64(i16) nounwind readnone