1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -target-feature +avx512fp16 -o - | FileCheck %s --check-prefixes=AVX
3 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s --check-prefixes=X86
5 // AVX-LABEL: @add_half_rr(
7 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
8 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
9 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
10 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
11 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
12 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
13 // AVX-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
14 // AVX-NEXT: [[ADD:%.*]] = fadd half [[TMP0]], [[TMP1]]
15 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
16 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
17 // AVX-NEXT: store half [[ADD]], ptr [[RETVAL_REALP]], align 2
18 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
19 // AVX-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
20 // AVX-NEXT: ret <2 x half> [[TMP2]]
22 // X86-LABEL: @add_half_rr(
24 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
25 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
26 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
27 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
28 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
29 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
30 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
31 // X86-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
32 // X86-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float
33 // X86-NEXT: [[ADD:%.*]] = fadd float [[EXT]], [[EXT1]]
34 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD]] to half
35 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
36 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
37 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
38 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
39 // X86-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
40 // X86-NEXT: ret <2 x half> [[TMP2]]
42 _Float16 _Complex
add_half_rr(_Float16 a
, _Float16 b
) {
46 // AVX-LABEL: @add_half_cr(
48 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
49 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
50 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
51 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
52 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
53 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
54 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
55 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
56 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
57 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
58 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[A_REAL]], [[TMP0]]
59 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
60 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
61 // AVX-NEXT: store half [[ADD_R]], ptr [[RETVAL_REALP]], align 2
62 // AVX-NEXT: store half [[A_IMAG]], ptr [[RETVAL_IMAGP]], align 2
63 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
64 // AVX-NEXT: ret <2 x half> [[TMP1]]
66 // X86-LABEL: @add_half_cr(
68 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
69 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
70 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
71 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
72 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
73 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
74 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
75 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
76 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
77 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
78 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
79 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
80 // X86-NEXT: [[EXT2:%.*]] = fpext half [[TMP0]] to float
81 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[EXT2]]
82 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R]] to half
83 // X86-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[EXT1]] to half
84 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
85 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
86 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
87 // X86-NEXT: store half [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 2
88 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
89 // X86-NEXT: ret <2 x half> [[TMP1]]
91 _Float16 _Complex
add_half_cr(_Float16 _Complex a
, _Float16 b
) {
95 // AVX-LABEL: @add_half_rc(
97 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
98 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
99 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
100 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
101 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
102 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
103 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
104 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
105 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
106 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
107 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[TMP0]], [[B_REAL]]
108 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
109 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
110 // AVX-NEXT: store half [[ADD_R]], ptr [[RETVAL_REALP]], align 2
111 // AVX-NEXT: store half [[B_IMAG]], ptr [[RETVAL_IMAGP]], align 2
112 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
113 // AVX-NEXT: ret <2 x half> [[TMP1]]
115 // X86-LABEL: @add_half_rc(
117 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
118 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
119 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
120 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
121 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
122 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
123 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
124 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
125 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
126 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
127 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
128 // X86-NEXT: [[EXT1:%.*]] = fpext half [[B_REAL]] to float
129 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_IMAG]] to float
130 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[EXT1]]
131 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R]] to half
132 // X86-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[EXT2]] to half
133 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
134 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
135 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
136 // X86-NEXT: store half [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 2
137 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
138 // X86-NEXT: ret <2 x half> [[TMP1]]
140 _Float16 _Complex
add_half_rc(_Float16 a
, _Float16 _Complex b
) {
144 // AVX-LABEL: @add_half_cc(
146 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
147 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
148 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
149 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
150 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
151 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
152 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
153 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
154 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
155 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
156 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
157 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
158 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
159 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[A_REAL]], [[B_REAL]]
160 // AVX-NEXT: [[ADD_I:%.*]] = fadd half [[A_IMAG]], [[B_IMAG]]
161 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
162 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
163 // AVX-NEXT: store half [[ADD_R]], ptr [[RETVAL_REALP]], align 2
164 // AVX-NEXT: store half [[ADD_I]], ptr [[RETVAL_IMAGP]], align 2
165 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
166 // AVX-NEXT: ret <2 x half> [[TMP0]]
168 // X86-LABEL: @add_half_cc(
170 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
171 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
172 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
173 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
174 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
175 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
176 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
177 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
178 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
179 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
180 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
181 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
182 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
183 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
184 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
185 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float
186 // X86-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float
187 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[EXT2]]
188 // X86-NEXT: [[ADD_I:%.*]] = fadd float [[EXT1]], [[EXT3]]
189 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R]] to half
190 // X86-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[ADD_I]] to half
191 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
192 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
193 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
194 // X86-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2
195 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
196 // X86-NEXT: ret <2 x half> [[TMP0]]
198 _Float16 _Complex
add_half_cc(_Float16 _Complex a
, _Float16 _Complex b
) {
202 // AVX-LABEL: @add2_haff_rrr(
204 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
205 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
206 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
207 // AVX-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
208 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
209 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
210 // AVX-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
211 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
212 // AVX-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
213 // AVX-NEXT: [[ADD:%.*]] = fadd half [[TMP0]], [[TMP1]]
214 // AVX-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2
215 // AVX-NEXT: [[ADD1:%.*]] = fadd half [[ADD]], [[TMP2]]
216 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
217 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
218 // AVX-NEXT: store half [[ADD1]], ptr [[RETVAL_REALP]], align 2
219 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
220 // AVX-NEXT: [[TMP3:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
221 // AVX-NEXT: ret <2 x half> [[TMP3]]
223 // X86-LABEL: @add2_haff_rrr(
225 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
226 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
227 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
228 // X86-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
229 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
230 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
231 // X86-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
232 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
233 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
234 // X86-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
235 // X86-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float
236 // X86-NEXT: [[ADD:%.*]] = fadd float [[EXT]], [[EXT1]]
237 // X86-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2
238 // X86-NEXT: [[EXT2:%.*]] = fpext half [[TMP2]] to float
239 // X86-NEXT: [[ADD3:%.*]] = fadd float [[ADD]], [[EXT2]]
240 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD3]] to half
241 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
242 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
243 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
244 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
245 // X86-NEXT: [[TMP3:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
246 // X86-NEXT: ret <2 x half> [[TMP3]]
248 _Float16 _Complex
add2_haff_rrr(_Float16 a
, _Float16 b
, _Float16 c
) {
252 // AVX-LABEL: @add2_haff_rcr(
254 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
255 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
256 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
257 // AVX-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
258 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
259 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
260 // AVX-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
261 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
262 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
263 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
264 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
265 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
266 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[TMP0]], [[B_REAL]]
267 // AVX-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2
268 // AVX-NEXT: [[ADD_R1:%.*]] = fadd half [[ADD_R]], [[TMP1]]
269 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
270 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
271 // AVX-NEXT: store half [[ADD_R1]], ptr [[RETVAL_REALP]], align 2
272 // AVX-NEXT: store half [[B_IMAG]], ptr [[RETVAL_IMAGP]], align 2
273 // AVX-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
274 // AVX-NEXT: ret <2 x half> [[TMP2]]
276 // X86-LABEL: @add2_haff_rcr(
278 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
279 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
280 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
281 // X86-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
282 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
283 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
284 // X86-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
285 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
286 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
287 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
288 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
289 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
290 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
291 // X86-NEXT: [[EXT1:%.*]] = fpext half [[B_REAL]] to float
292 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_IMAG]] to float
293 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[EXT1]]
294 // X86-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2
295 // X86-NEXT: [[EXT3:%.*]] = fpext half [[TMP1]] to float
296 // X86-NEXT: [[ADD_R4:%.*]] = fadd float [[ADD_R]], [[EXT3]]
297 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R4]] to half
298 // X86-NEXT: [[UNPROMOTION5:%.*]] = fptrunc float [[EXT2]] to half
299 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
300 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
301 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
302 // X86-NEXT: store half [[UNPROMOTION5]], ptr [[RETVAL_IMAGP]], align 2
303 // X86-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
304 // X86-NEXT: ret <2 x half> [[TMP2]]
306 _Float16 _Complex
add2_haff_rcr(_Float16 a
, _Float16 _Complex b
, _Float16 c
) {
310 // AVX-LABEL: @add2_haff_rcc(
312 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
313 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
314 // AVX-NEXT: [[C:%.*]] = alloca { half, half }, align 2
315 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
316 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
317 // AVX-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
318 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
319 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
320 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
321 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
322 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
323 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
324 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[TMP0]], [[B_REAL]]
325 // AVX-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
326 // AVX-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
327 // AVX-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
328 // AVX-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
329 // AVX-NEXT: [[ADD_R1:%.*]] = fadd half [[ADD_R]], [[C_REAL]]
330 // AVX-NEXT: [[ADD_I:%.*]] = fadd half [[B_IMAG]], [[C_IMAG]]
331 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
332 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
333 // AVX-NEXT: store half [[ADD_R1]], ptr [[RETVAL_REALP]], align 2
334 // AVX-NEXT: store half [[ADD_I]], ptr [[RETVAL_IMAGP]], align 2
335 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
336 // AVX-NEXT: ret <2 x half> [[TMP1]]
338 // X86-LABEL: @add2_haff_rcc(
340 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
341 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
342 // X86-NEXT: [[C:%.*]] = alloca { half, half }, align 2
343 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
344 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
345 // X86-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
346 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
347 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
348 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
349 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
350 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
351 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
352 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
353 // X86-NEXT: [[EXT1:%.*]] = fpext half [[B_REAL]] to float
354 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_IMAG]] to float
355 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[EXT1]]
356 // X86-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
357 // X86-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
358 // X86-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
359 // X86-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
360 // X86-NEXT: [[EXT3:%.*]] = fpext half [[C_REAL]] to float
361 // X86-NEXT: [[EXT4:%.*]] = fpext half [[C_IMAG]] to float
362 // X86-NEXT: [[ADD_R5:%.*]] = fadd float [[ADD_R]], [[EXT3]]
363 // X86-NEXT: [[ADD_I:%.*]] = fadd float [[EXT2]], [[EXT4]]
364 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R5]] to half
365 // X86-NEXT: [[UNPROMOTION6:%.*]] = fptrunc float [[ADD_I]] to half
366 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
367 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
368 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
369 // X86-NEXT: store half [[UNPROMOTION6]], ptr [[RETVAL_IMAGP]], align 2
370 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
371 // X86-NEXT: ret <2 x half> [[TMP1]]
373 _Float16 _Complex
add2_haff_rcc(_Float16 a
, _Float16 _Complex b
, _Float16 _Complex c
) {
377 // AVX-LABEL: @add2_haff_crr(
379 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
380 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
381 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
382 // AVX-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
383 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
384 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
385 // AVX-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
386 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
387 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
388 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
389 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
390 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
391 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[A_REAL]], [[TMP0]]
392 // AVX-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2
393 // AVX-NEXT: [[ADD_R1:%.*]] = fadd half [[ADD_R]], [[TMP1]]
394 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
395 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
396 // AVX-NEXT: store half [[ADD_R1]], ptr [[RETVAL_REALP]], align 2
397 // AVX-NEXT: store half [[A_IMAG]], ptr [[RETVAL_IMAGP]], align 2
398 // AVX-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
399 // AVX-NEXT: ret <2 x half> [[TMP2]]
401 // X86-LABEL: @add2_haff_crr(
403 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
404 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
405 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
406 // X86-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
407 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
408 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
409 // X86-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
410 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
411 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
412 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
413 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
414 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
415 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
416 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
417 // X86-NEXT: [[EXT2:%.*]] = fpext half [[TMP0]] to float
418 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[EXT2]]
419 // X86-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2
420 // X86-NEXT: [[EXT3:%.*]] = fpext half [[TMP1]] to float
421 // X86-NEXT: [[ADD_R4:%.*]] = fadd float [[ADD_R]], [[EXT3]]
422 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R4]] to half
423 // X86-NEXT: [[UNPROMOTION5:%.*]] = fptrunc float [[EXT1]] to half
424 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
425 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
426 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
427 // X86-NEXT: store half [[UNPROMOTION5]], ptr [[RETVAL_IMAGP]], align 2
428 // X86-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
429 // X86-NEXT: ret <2 x half> [[TMP2]]
431 _Float16 _Complex
add2_haff_crr(_Float16 _Complex a
, _Float16 b
, _Float16 c
) {
435 // AVX-LABEL: @add2_haff_ccr(
437 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
438 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
439 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
440 // AVX-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
441 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
442 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
443 // AVX-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
444 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
445 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
446 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
447 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
448 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
449 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
450 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
451 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
452 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[A_REAL]], [[B_REAL]]
453 // AVX-NEXT: [[ADD_I:%.*]] = fadd half [[A_IMAG]], [[B_IMAG]]
454 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[C_ADDR]], align 2
455 // AVX-NEXT: [[ADD_R1:%.*]] = fadd half [[ADD_R]], [[TMP0]]
456 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
457 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
458 // AVX-NEXT: store half [[ADD_R1]], ptr [[RETVAL_REALP]], align 2
459 // AVX-NEXT: store half [[ADD_I]], ptr [[RETVAL_IMAGP]], align 2
460 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
461 // AVX-NEXT: ret <2 x half> [[TMP1]]
463 // X86-LABEL: @add2_haff_ccr(
465 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
466 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
467 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
468 // X86-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
469 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
470 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
471 // X86-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
472 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
473 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
474 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
475 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
476 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
477 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
478 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
479 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
480 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
481 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
482 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float
483 // X86-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float
484 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[EXT2]]
485 // X86-NEXT: [[ADD_I:%.*]] = fadd float [[EXT1]], [[EXT3]]
486 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[C_ADDR]], align 2
487 // X86-NEXT: [[EXT4:%.*]] = fpext half [[TMP0]] to float
488 // X86-NEXT: [[ADD_R5:%.*]] = fadd float [[ADD_R]], [[EXT4]]
489 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R5]] to half
490 // X86-NEXT: [[UNPROMOTION6:%.*]] = fptrunc float [[ADD_I]] to half
491 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
492 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
493 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
494 // X86-NEXT: store half [[UNPROMOTION6]], ptr [[RETVAL_IMAGP]], align 2
495 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
496 // X86-NEXT: ret <2 x half> [[TMP1]]
498 _Float16 _Complex
add2_haff_ccr(_Float16 _Complex a
, _Float16 _Complex b
, _Float16 c
) {
502 // AVX-LABEL: @add2_haff_crc(
504 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
505 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
506 // AVX-NEXT: [[C:%.*]] = alloca { half, half }, align 2
507 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
508 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
509 // AVX-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
510 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
511 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
512 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
513 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
514 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
515 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
516 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[A_REAL]], [[TMP0]]
517 // AVX-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
518 // AVX-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
519 // AVX-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
520 // AVX-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
521 // AVX-NEXT: [[ADD_R1:%.*]] = fadd half [[ADD_R]], [[C_REAL]]
522 // AVX-NEXT: [[ADD_I:%.*]] = fadd half [[A_IMAG]], [[C_IMAG]]
523 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
524 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
525 // AVX-NEXT: store half [[ADD_R1]], ptr [[RETVAL_REALP]], align 2
526 // AVX-NEXT: store half [[ADD_I]], ptr [[RETVAL_IMAGP]], align 2
527 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
528 // AVX-NEXT: ret <2 x half> [[TMP1]]
530 // X86-LABEL: @add2_haff_crc(
532 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
533 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
534 // X86-NEXT: [[C:%.*]] = alloca { half, half }, align 2
535 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
536 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
537 // X86-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
538 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
539 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
540 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
541 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
542 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
543 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
544 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
545 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
546 // X86-NEXT: [[EXT2:%.*]] = fpext half [[TMP0]] to float
547 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[EXT2]]
548 // X86-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
549 // X86-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
550 // X86-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
551 // X86-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
552 // X86-NEXT: [[EXT3:%.*]] = fpext half [[C_REAL]] to float
553 // X86-NEXT: [[EXT4:%.*]] = fpext half [[C_IMAG]] to float
554 // X86-NEXT: [[ADD_R5:%.*]] = fadd float [[ADD_R]], [[EXT3]]
555 // X86-NEXT: [[ADD_I:%.*]] = fadd float [[EXT1]], [[EXT4]]
556 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R5]] to half
557 // X86-NEXT: [[UNPROMOTION6:%.*]] = fptrunc float [[ADD_I]] to half
558 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
559 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
560 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
561 // X86-NEXT: store half [[UNPROMOTION6]], ptr [[RETVAL_IMAGP]], align 2
562 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
563 // X86-NEXT: ret <2 x half> [[TMP1]]
565 _Float16 _Complex
add2_haff_crc(_Float16 _Complex a
, _Float16 b
, _Float16 _Complex c
) {
569 // AVX-LABEL: @add2_haff_ccc(
571 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
572 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
573 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
574 // AVX-NEXT: [[C:%.*]] = alloca { half, half }, align 2
575 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
576 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
577 // AVX-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
578 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
579 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
580 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
581 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
582 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
583 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
584 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
585 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
586 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[A_REAL]], [[B_REAL]]
587 // AVX-NEXT: [[ADD_I:%.*]] = fadd half [[A_IMAG]], [[B_IMAG]]
588 // AVX-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
589 // AVX-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
590 // AVX-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
591 // AVX-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
592 // AVX-NEXT: [[ADD_R1:%.*]] = fadd half [[ADD_R]], [[C_REAL]]
593 // AVX-NEXT: [[ADD_I2:%.*]] = fadd half [[ADD_I]], [[C_IMAG]]
594 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
595 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
596 // AVX-NEXT: store half [[ADD_R1]], ptr [[RETVAL_REALP]], align 2
597 // AVX-NEXT: store half [[ADD_I2]], ptr [[RETVAL_IMAGP]], align 2
598 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
599 // AVX-NEXT: ret <2 x half> [[TMP0]]
601 // X86-LABEL: @add2_haff_ccc(
603 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
604 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
605 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
606 // X86-NEXT: [[C:%.*]] = alloca { half, half }, align 2
607 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
608 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
609 // X86-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
610 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
611 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
612 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
613 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
614 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
615 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
616 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
617 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
618 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
619 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
620 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float
621 // X86-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float
622 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[EXT2]]
623 // X86-NEXT: [[ADD_I:%.*]] = fadd float [[EXT1]], [[EXT3]]
624 // X86-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
625 // X86-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
626 // X86-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
627 // X86-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
628 // X86-NEXT: [[EXT4:%.*]] = fpext half [[C_REAL]] to float
629 // X86-NEXT: [[EXT5:%.*]] = fpext half [[C_IMAG]] to float
630 // X86-NEXT: [[ADD_R6:%.*]] = fadd float [[ADD_R]], [[EXT4]]
631 // X86-NEXT: [[ADD_I7:%.*]] = fadd float [[ADD_I]], [[EXT5]]
632 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R6]] to half
633 // X86-NEXT: [[UNPROMOTION8:%.*]] = fptrunc float [[ADD_I7]] to half
634 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
635 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
636 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
637 // X86-NEXT: store half [[UNPROMOTION8]], ptr [[RETVAL_IMAGP]], align 2
638 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
639 // X86-NEXT: ret <2 x half> [[TMP0]]
641 _Float16 _Complex
add2_haff_ccc(_Float16 _Complex a
, _Float16 _Complex b
, _Float16 _Complex c
) {
645 // AVX-LABEL: @sub_half_rr(
647 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
648 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
649 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
650 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
651 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
652 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
653 // AVX-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
654 // AVX-NEXT: [[SUB:%.*]] = fsub half [[TMP0]], [[TMP1]]
655 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
656 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
657 // AVX-NEXT: store half [[SUB]], ptr [[RETVAL_REALP]], align 2
658 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
659 // AVX-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
660 // AVX-NEXT: ret <2 x half> [[TMP2]]
662 // X86-LABEL: @sub_half_rr(
664 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
665 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
666 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
667 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
668 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
669 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
670 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
671 // X86-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
672 // X86-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float
673 // X86-NEXT: [[SUB:%.*]] = fsub float [[EXT]], [[EXT1]]
674 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[SUB]] to half
675 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
676 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
677 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
678 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
679 // X86-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
680 // X86-NEXT: ret <2 x half> [[TMP2]]
682 _Float16 _Complex
sub_half_rr(_Float16 a
, _Float16 b
) {
686 // AVX-LABEL: @sub_half_cr(
688 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
689 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
690 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
691 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
692 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
693 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
694 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
695 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
696 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
697 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
698 // AVX-NEXT: [[SUB_R:%.*]] = fsub half [[A_REAL]], [[TMP0]]
699 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
700 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
701 // AVX-NEXT: store half [[SUB_R]], ptr [[RETVAL_REALP]], align 2
702 // AVX-NEXT: store half [[A_IMAG]], ptr [[RETVAL_IMAGP]], align 2
703 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
704 // AVX-NEXT: ret <2 x half> [[TMP1]]
706 // X86-LABEL: @sub_half_cr(
708 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
709 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
710 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
711 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
712 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
713 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
714 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
715 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
716 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
717 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
718 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
719 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
720 // X86-NEXT: [[EXT2:%.*]] = fpext half [[TMP0]] to float
721 // X86-NEXT: [[SUB_R:%.*]] = fsub float [[EXT]], [[EXT2]]
722 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[SUB_R]] to half
723 // X86-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[EXT1]] to half
724 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
725 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
726 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
727 // X86-NEXT: store half [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 2
728 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
729 // X86-NEXT: ret <2 x half> [[TMP1]]
731 _Float16 _Complex
sub_half_cr(_Float16 _Complex a
, _Float16 b
) {
735 // AVX-LABEL: @sub_half_rc(
737 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
738 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
739 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
740 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
741 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
742 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
743 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
744 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
745 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
746 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
747 // AVX-NEXT: [[SUB_R:%.*]] = fsub half [[TMP0]], [[B_REAL]]
748 // AVX-NEXT: [[SUB_I:%.*]] = fneg half [[B_IMAG]]
749 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
750 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
751 // AVX-NEXT: store half [[SUB_R]], ptr [[RETVAL_REALP]], align 2
752 // AVX-NEXT: store half [[SUB_I]], ptr [[RETVAL_IMAGP]], align 2
753 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
754 // AVX-NEXT: ret <2 x half> [[TMP1]]
756 // X86-LABEL: @sub_half_rc(
758 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
759 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
760 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
761 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
762 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
763 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
764 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
765 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
766 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
767 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
768 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
769 // X86-NEXT: [[EXT1:%.*]] = fpext half [[B_REAL]] to float
770 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_IMAG]] to float
771 // X86-NEXT: [[SUB_R:%.*]] = fsub float [[EXT]], [[EXT1]]
772 // X86-NEXT: [[SUB_I:%.*]] = fneg float [[EXT2]]
773 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[SUB_R]] to half
774 // X86-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[SUB_I]] to half
775 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
776 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
777 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
778 // X86-NEXT: store half [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 2
779 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
780 // X86-NEXT: ret <2 x half> [[TMP1]]
782 _Float16 _Complex
sub_half_rc(_Float16 a
, _Float16 _Complex b
) {
786 // AVX-LABEL: @sub_half_cc(
788 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
789 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
790 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
791 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
792 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
793 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
794 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
795 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
796 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
797 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
798 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
799 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
800 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
801 // AVX-NEXT: [[SUB_R:%.*]] = fsub half [[A_REAL]], [[B_REAL]]
802 // AVX-NEXT: [[SUB_I:%.*]] = fsub half [[A_IMAG]], [[B_IMAG]]
803 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
804 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
805 // AVX-NEXT: store half [[SUB_R]], ptr [[RETVAL_REALP]], align 2
806 // AVX-NEXT: store half [[SUB_I]], ptr [[RETVAL_IMAGP]], align 2
807 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
808 // AVX-NEXT: ret <2 x half> [[TMP0]]
810 // X86-LABEL: @sub_half_cc(
812 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
813 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
814 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
815 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
816 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
817 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
818 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
819 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
820 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
821 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
822 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
823 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
824 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
825 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
826 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
827 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float
828 // X86-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float
829 // X86-NEXT: [[SUB_R:%.*]] = fsub float [[EXT]], [[EXT2]]
830 // X86-NEXT: [[SUB_I:%.*]] = fsub float [[EXT1]], [[EXT3]]
831 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[SUB_R]] to half
832 // X86-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[SUB_I]] to half
833 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
834 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
835 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
836 // X86-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2
837 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
838 // X86-NEXT: ret <2 x half> [[TMP0]]
840 _Float16 _Complex
sub_half_cc(_Float16 _Complex a
, _Float16 _Complex b
) {
844 // AVX-LABEL: @mul_half_rr(
846 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
847 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
848 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
849 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
850 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
851 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
852 // AVX-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
853 // AVX-NEXT: [[MUL:%.*]] = fmul half [[TMP0]], [[TMP1]]
854 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
855 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
856 // AVX-NEXT: store half [[MUL]], ptr [[RETVAL_REALP]], align 2
857 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
858 // AVX-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
859 // AVX-NEXT: ret <2 x half> [[TMP2]]
861 // X86-LABEL: @mul_half_rr(
863 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
864 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
865 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
866 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
867 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
868 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
869 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
870 // X86-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
871 // X86-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float
872 // X86-NEXT: [[MUL:%.*]] = fmul float [[EXT]], [[EXT1]]
873 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL]] to half
874 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
875 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
876 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
877 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
878 // X86-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
879 // X86-NEXT: ret <2 x half> [[TMP2]]
881 _Float16 _Complex
mul_half_rr(_Float16 a
, _Float16 b
) {
885 // AVX-LABEL: @mul_half_cr(
887 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
888 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
889 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
890 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
891 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
892 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
893 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
894 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
895 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
896 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
897 // AVX-NEXT: [[MUL_RL:%.*]] = fmul half [[A_REAL]], [[TMP0]]
898 // AVX-NEXT: [[MUL_IL:%.*]] = fmul half [[A_IMAG]], [[TMP0]]
899 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
900 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
901 // AVX-NEXT: store half [[MUL_RL]], ptr [[RETVAL_REALP]], align 2
902 // AVX-NEXT: store half [[MUL_IL]], ptr [[RETVAL_IMAGP]], align 2
903 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
904 // AVX-NEXT: ret <2 x half> [[TMP1]]
906 // X86-LABEL: @mul_half_cr(
908 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
909 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
910 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
911 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
912 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
913 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
914 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
915 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
916 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
917 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
918 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
919 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
920 // X86-NEXT: [[EXT2:%.*]] = fpext half [[TMP0]] to float
921 // X86-NEXT: [[MUL_RL:%.*]] = fmul float [[EXT]], [[EXT2]]
922 // X86-NEXT: [[MUL_IL:%.*]] = fmul float [[EXT1]], [[EXT2]]
923 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_RL]] to half
924 // X86-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[MUL_IL]] to half
925 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
926 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
927 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
928 // X86-NEXT: store half [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 2
929 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
930 // X86-NEXT: ret <2 x half> [[TMP1]]
932 _Float16 _Complex
mul_half_cr(_Float16 _Complex a
, _Float16 b
) {
936 // AVX-LABEL: @mul_half_rc(
938 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
939 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
940 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
941 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
942 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
943 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
944 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
945 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
946 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
947 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
948 // AVX-NEXT: [[MUL_RL:%.*]] = fmul half [[TMP0]], [[B_REAL]]
949 // AVX-NEXT: [[MUL_IR:%.*]] = fmul half [[TMP0]], [[B_IMAG]]
950 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
951 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
952 // AVX-NEXT: store half [[MUL_RL]], ptr [[RETVAL_REALP]], align 2
953 // AVX-NEXT: store half [[MUL_IR]], ptr [[RETVAL_IMAGP]], align 2
954 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
955 // AVX-NEXT: ret <2 x half> [[TMP1]]
957 // X86-LABEL: @mul_half_rc(
959 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
960 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
961 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
962 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
963 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
964 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
965 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
966 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
967 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
968 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
969 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
970 // X86-NEXT: [[EXT1:%.*]] = fpext half [[B_REAL]] to float
971 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_IMAG]] to float
972 // X86-NEXT: [[MUL_RL:%.*]] = fmul float [[EXT]], [[EXT1]]
973 // X86-NEXT: [[MUL_IR:%.*]] = fmul float [[EXT]], [[EXT2]]
974 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_RL]] to half
975 // X86-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[MUL_IR]] to half
976 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
977 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
978 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
979 // X86-NEXT: store half [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 2
980 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
981 // X86-NEXT: ret <2 x half> [[TMP1]]
983 _Float16 _Complex
mul_half_rc(_Float16 a
, _Float16 _Complex b
) {
987 // AVX-LABEL: @mul_half_cc(
989 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
990 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
991 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
992 // AVX-NEXT: [[COERCE:%.*]] = alloca { half, half }, align 2
993 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
994 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
995 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
996 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
997 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
998 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
999 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
1000 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
1001 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
1002 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
1003 // AVX-NEXT: [[MUL_AC:%.*]] = fmul half [[A_REAL]], [[B_REAL]]
1004 // AVX-NEXT: [[MUL_BD:%.*]] = fmul half [[A_IMAG]], [[B_IMAG]]
1005 // AVX-NEXT: [[MUL_AD:%.*]] = fmul half [[A_REAL]], [[B_IMAG]]
1006 // AVX-NEXT: [[MUL_BC:%.*]] = fmul half [[A_IMAG]], [[B_REAL]]
1007 // AVX-NEXT: [[MUL_R:%.*]] = fsub half [[MUL_AC]], [[MUL_BD]]
1008 // AVX-NEXT: [[MUL_I:%.*]] = fadd half [[MUL_AD]], [[MUL_BC]]
1009 // AVX-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno half [[MUL_R]], [[MUL_R]]
1010 // AVX-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]]
1011 // AVX: complex_mul_imag_nan:
1012 // AVX-NEXT: [[ISNAN_CMP1:%.*]] = fcmp uno half [[MUL_I]], [[MUL_I]]
1013 // AVX-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
1014 // AVX: complex_mul_libcall:
1015 // AVX-NEXT: [[CALL:%.*]] = call <2 x half> @__mulhc3(half noundef [[A_REAL]], half noundef [[A_IMAG]], half noundef [[B_REAL]], half noundef [[B_IMAG]]) #[[ATTR1:[0-9]+]]
1016 // AVX-NEXT: store <2 x half> [[CALL]], ptr [[COERCE]], align 2
1017 // AVX-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[COERCE]], i32 0, i32 0
1018 // AVX-NEXT: [[COERCE_REAL:%.*]] = load half, ptr [[COERCE_REALP]], align 2
1019 // AVX-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[COERCE]], i32 0, i32 1
1020 // AVX-NEXT: [[COERCE_IMAG:%.*]] = load half, ptr [[COERCE_IMAGP]], align 2
1021 // AVX-NEXT: br label [[COMPLEX_MUL_CONT]]
1022 // AVX: complex_mul_cont:
1023 // AVX-NEXT: [[REAL_MUL_PHI:%.*]] = phi half [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ]
1024 // AVX-NEXT: [[IMAG_MUL_PHI:%.*]] = phi half [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ]
1025 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1026 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1027 // AVX-NEXT: store half [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 2
1028 // AVX-NEXT: store half [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 2
1029 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1030 // AVX-NEXT: ret <2 x half> [[TMP0]]
1032 // X86-LABEL: @mul_half_cc(
1034 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1035 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1036 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
1037 // X86-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
1038 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1039 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
1040 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1041 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1042 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1043 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1044 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1045 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
1046 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
1047 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
1048 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
1049 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
1050 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float
1051 // X86-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float
1052 // X86-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]]
1053 // X86-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]]
1054 // X86-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]]
1055 // X86-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]]
1056 // X86-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]]
1057 // X86-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]]
1058 // X86-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno float [[MUL_R]], [[MUL_R]]
1059 // X86-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]]
1060 // X86: complex_mul_imag_nan:
1061 // X86-NEXT: [[ISNAN_CMP4:%.*]] = fcmp uno float [[MUL_I]], [[MUL_I]]
1062 // X86-NEXT: br i1 [[ISNAN_CMP4]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
1063 // X86: complex_mul_libcall:
1064 // X86-NEXT: [[CALL:%.*]] = call <2 x float> @__mulsc3(float noundef [[EXT]], float noundef [[EXT1]], float noundef [[EXT2]], float noundef [[EXT3]]) #[[ATTR2:[0-9]+]]
1065 // X86-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4
1066 // X86-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0
1067 // X86-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4
1068 // X86-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1
1069 // X86-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4
1070 // X86-NEXT: br label [[COMPLEX_MUL_CONT]]
1071 // X86: complex_mul_cont:
1072 // X86-NEXT: [[REAL_MUL_PHI:%.*]] = phi float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ]
1073 // X86-NEXT: [[IMAG_MUL_PHI:%.*]] = phi float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ]
1074 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[REAL_MUL_PHI]] to half
1075 // X86-NEXT: [[UNPROMOTION5:%.*]] = fptrunc float [[IMAG_MUL_PHI]] to half
1076 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1077 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1078 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1079 // X86-NEXT: store half [[UNPROMOTION5]], ptr [[RETVAL_IMAGP]], align 2
1080 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1081 // X86-NEXT: ret <2 x half> [[TMP0]]
1083 _Float16 _Complex
mul_half_cc(_Float16 _Complex a
, _Float16 _Complex b
) {
1086 // AVX-LABEL: @div_half_rr(
1088 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1089 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1090 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
1091 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1092 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
1093 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1094 // AVX-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
1095 // AVX-NEXT: [[DIV:%.*]] = fdiv half [[TMP0]], [[TMP1]]
1096 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1097 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1098 // AVX-NEXT: store half [[DIV]], ptr [[RETVAL_REALP]], align 2
1099 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1100 // AVX-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1101 // AVX-NEXT: ret <2 x half> [[TMP2]]
1103 // X86-LABEL: @div_half_rr(
1105 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1106 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1107 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
1108 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1109 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
1110 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1111 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
1112 // X86-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2
1113 // X86-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float
1114 // X86-NEXT: [[DIV:%.*]] = fdiv float [[EXT]], [[EXT1]]
1115 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[DIV]] to half
1116 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1117 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1118 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1119 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1120 // X86-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1121 // X86-NEXT: ret <2 x half> [[TMP2]]
1123 _Float16 _Complex
div_half_rr(_Float16 a
, _Float16 b
) {
1127 // AVX-LABEL: @div_half_cr(
1129 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1130 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1131 // AVX-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
1132 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1133 // AVX-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
1134 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1135 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1136 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1137 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1138 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
1139 // AVX-NEXT: [[TMP1:%.*]] = fdiv half [[A_REAL]], [[TMP0]]
1140 // AVX-NEXT: [[TMP2:%.*]] = fdiv half [[A_IMAG]], [[TMP0]]
1141 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1142 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1143 // AVX-NEXT: store half [[TMP1]], ptr [[RETVAL_REALP]], align 2
1144 // AVX-NEXT: store half [[TMP2]], ptr [[RETVAL_IMAGP]], align 2
1145 // AVX-NEXT: [[TMP3:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1146 // AVX-NEXT: ret <2 x half> [[TMP3]]
1148 // X86-LABEL: @div_half_cr(
1150 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1151 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1152 // X86-NEXT: [[B_ADDR:%.*]] = alloca half, align 2
1153 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1154 // X86-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2
1155 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1156 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1157 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1158 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1159 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1160 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
1161 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[B_ADDR]], align 2
1162 // X86-NEXT: [[EXT2:%.*]] = fpext half [[TMP0]] to float
1163 // X86-NEXT: [[TMP1:%.*]] = fdiv float [[EXT]], [[EXT2]]
1164 // X86-NEXT: [[TMP2:%.*]] = fdiv float [[EXT1]], [[EXT2]]
1165 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP1]] to half
1166 // X86-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[TMP2]] to half
1167 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1168 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1169 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1170 // X86-NEXT: store half [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 2
1171 // X86-NEXT: [[TMP3:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1172 // X86-NEXT: ret <2 x half> [[TMP3]]
1174 _Float16 _Complex
div_half_cr(_Float16 _Complex a
, _Float16 b
) {
1177 // AVX-LABEL: @div_half_rc(
1179 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1180 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
1181 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1182 // AVX-NEXT: [[COERCE:%.*]] = alloca { half, half }, align 2
1183 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
1184 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1185 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1186 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
1187 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
1188 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
1189 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
1190 // AVX-NEXT: [[CALL:%.*]] = call <2 x half> @__divhc3(half noundef [[TMP0]], half noundef 0xH0000, half noundef [[B_REAL]], half noundef [[B_IMAG]]) #[[ATTR1]]
1191 // AVX-NEXT: store <2 x half> [[CALL]], ptr [[COERCE]], align 2
1192 // AVX-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[COERCE]], i32 0, i32 0
1193 // AVX-NEXT: [[COERCE_REAL:%.*]] = load half, ptr [[COERCE_REALP]], align 2
1194 // AVX-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[COERCE]], i32 0, i32 1
1195 // AVX-NEXT: [[COERCE_IMAG:%.*]] = load half, ptr [[COERCE_IMAGP]], align 2
1196 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1197 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1198 // AVX-NEXT: store half [[COERCE_REAL]], ptr [[RETVAL_REALP]], align 2
1199 // AVX-NEXT: store half [[COERCE_IMAG]], ptr [[RETVAL_IMAGP]], align 2
1200 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1201 // AVX-NEXT: ret <2 x half> [[TMP1]]
1203 // X86-LABEL: @div_half_rc(
1205 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1206 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
1207 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1208 // X86-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
1209 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
1210 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1211 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1212 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
1213 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
1214 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
1215 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
1216 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
1217 // X86-NEXT: [[EXT1:%.*]] = fpext half [[B_REAL]] to float
1218 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_IMAG]] to float
1219 // X86-NEXT: [[CALL:%.*]] = call <2 x float> @__divsc3(float noundef [[EXT]], float noundef 0.000000e+00, float noundef [[EXT1]], float noundef [[EXT2]]) #[[ATTR2]]
1220 // X86-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4
1221 // X86-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0
1222 // X86-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4
1223 // X86-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1
1224 // X86-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4
1225 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[COERCE_REAL]] to half
1226 // X86-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[COERCE_IMAG]] to half
1227 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1228 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1229 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1230 // X86-NEXT: store half [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 2
1231 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1232 // X86-NEXT: ret <2 x half> [[TMP1]]
1234 _Float16 _Complex
div_half_rc(_Float16 a
, _Float16 _Complex b
) {
1238 // AVX-LABEL: @div_half_cc(
1240 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1241 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1242 // AVX-NEXT: [[B:%.*]] = alloca { half, half }, align 2
1243 // AVX-NEXT: [[COERCE:%.*]] = alloca { half, half }, align 2
1244 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1245 // AVX-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
1246 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1247 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1248 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1249 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1250 // AVX-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
1251 // AVX-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
1252 // AVX-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
1253 // AVX-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
1254 // AVX-NEXT: [[CALL:%.*]] = call <2 x half> @__divhc3(half noundef [[A_REAL]], half noundef [[A_IMAG]], half noundef [[B_REAL]], half noundef [[B_IMAG]]) #[[ATTR1]]
1255 // AVX-NEXT: store <2 x half> [[CALL]], ptr [[COERCE]], align 2
1256 // AVX-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[COERCE]], i32 0, i32 0
1257 // AVX-NEXT: [[COERCE_REAL:%.*]] = load half, ptr [[COERCE_REALP]], align 2
1258 // AVX-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[COERCE]], i32 0, i32 1
1259 // AVX-NEXT: [[COERCE_IMAG:%.*]] = load half, ptr [[COERCE_IMAGP]], align 2
1260 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1261 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1262 // AVX-NEXT: store half [[COERCE_REAL]], ptr [[RETVAL_REALP]], align 2
1263 // AVX-NEXT: store half [[COERCE_IMAG]], ptr [[RETVAL_IMAGP]], align 2
1264 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1265 // AVX-NEXT: ret <2 x half> [[TMP0]]
1267 // X86-LABEL: @div_half_cc(
1269 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1270 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1271 // X86-NEXT: [[B:%.*]] = alloca { half, half }, align 2
1272 // X86-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
1273 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1274 // X86-NEXT: store <2 x half> [[B_COERCE:%.*]], ptr [[B]], align 2
1275 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1276 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1277 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1278 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1279 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1280 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
1281 // X86-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0
1282 // X86-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2
1283 // X86-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1
1284 // X86-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2
1285 // X86-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float
1286 // X86-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float
1287 // X86-NEXT: [[CALL:%.*]] = call <2 x float> @__divsc3(float noundef [[EXT]], float noundef [[EXT1]], float noundef [[EXT2]], float noundef [[EXT3]]) #[[ATTR2]]
1288 // X86-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4
1289 // X86-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0
1290 // X86-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4
1291 // X86-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1
1292 // X86-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4
1293 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[COERCE_REAL]] to half
1294 // X86-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[COERCE_IMAG]] to half
1295 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1296 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1297 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1298 // X86-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2
1299 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1300 // X86-NEXT: ret <2 x half> [[TMP0]]
1302 _Float16 _Complex
div_half_cc(_Float16 _Complex a
, _Float16 _Complex b
) {
1306 // AVX-LABEL: @addcompound_half_rr(
1308 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1309 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1310 // AVX-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
1311 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1312 // AVX-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
1313 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1314 // AVX-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2
1315 // AVX-NEXT: [[ADD:%.*]] = fadd half [[TMP1]], [[TMP0]]
1316 // AVX-NEXT: store half [[ADD]], ptr [[C_ADDR]], align 2
1317 // AVX-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2
1318 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1319 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1320 // AVX-NEXT: store half [[TMP2]], ptr [[RETVAL_REALP]], align 2
1321 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1322 // AVX-NEXT: [[TMP3:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1323 // AVX-NEXT: ret <2 x half> [[TMP3]]
1325 // X86-LABEL: @addcompound_half_rr(
1327 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1328 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1329 // X86-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
1330 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1331 // X86-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
1332 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1333 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
1334 // X86-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2
1335 // X86-NEXT: [[CONV:%.*]] = fpext half [[TMP1]] to float
1336 // X86-NEXT: [[ADD:%.*]] = fadd float [[CONV]], [[EXT]]
1337 // X86-NEXT: [[CONV1:%.*]] = fptrunc float [[ADD]] to half
1338 // X86-NEXT: store half [[CONV1]], ptr [[C_ADDR]], align 2
1339 // X86-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2
1340 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1341 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1342 // X86-NEXT: store half [[TMP2]], ptr [[RETVAL_REALP]], align 2
1343 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1344 // X86-NEXT: [[TMP3:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1345 // X86-NEXT: ret <2 x half> [[TMP3]]
1347 _Float16 _Complex
addcompound_half_rr(_Float16 a
, _Float16 c
) {
1352 // AVX-LABEL: @addcompound_half_cr(
1354 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1355 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1356 // AVX-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
1357 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1358 // AVX-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
1359 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1360 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1361 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1362 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1363 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[C_ADDR]], align 2
1364 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[TMP0]], [[A_REAL]]
1365 // AVX-NEXT: store half [[ADD_R]], ptr [[C_ADDR]], align 2
1366 // AVX-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2
1367 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1368 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1369 // AVX-NEXT: store half [[TMP1]], ptr [[RETVAL_REALP]], align 2
1370 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1371 // AVX-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1372 // AVX-NEXT: ret <2 x half> [[TMP2]]
1374 // X86-LABEL: @addcompound_half_cr(
1376 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1377 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1378 // X86-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
1379 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1380 // X86-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2
1381 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1382 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1383 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1384 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1385 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1386 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
1387 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[C_ADDR]], align 2
1388 // X86-NEXT: [[CONV:%.*]] = fpext half [[TMP0]] to float
1389 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[CONV]], [[EXT]]
1390 // X86-NEXT: [[CONV2:%.*]] = fptrunc float [[ADD_R]] to half
1391 // X86-NEXT: store half [[CONV2]], ptr [[C_ADDR]], align 2
1392 // X86-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2
1393 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1394 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1395 // X86-NEXT: store half [[TMP1]], ptr [[RETVAL_REALP]], align 2
1396 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1397 // X86-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1398 // X86-NEXT: ret <2 x half> [[TMP2]]
1400 _Float16 _Complex
addcompound_half_cr(_Float16 _Complex a
, _Float16 c
) {
1405 // AVX-LABEL: @addcompound_half_rc(
1407 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1408 // AVX-NEXT: [[C:%.*]] = alloca { half, half }, align 2
1409 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1410 // AVX-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
1411 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1412 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1413 // AVX-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1414 // AVX-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
1415 // AVX-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1416 // AVX-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
1417 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[C_REAL]], [[TMP0]]
1418 // AVX-NEXT: [[C_REALP1:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1419 // AVX-NEXT: [[C_IMAGP2:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1420 // AVX-NEXT: store half [[ADD_R]], ptr [[C_REALP1]], align 2
1421 // AVX-NEXT: store half [[C_IMAG]], ptr [[C_IMAGP2]], align 2
1422 // AVX-NEXT: [[C_REALP3:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1423 // AVX-NEXT: [[C_REAL4:%.*]] = load half, ptr [[C_REALP3]], align 2
1424 // AVX-NEXT: [[C_IMAGP5:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1425 // AVX-NEXT: [[C_IMAG6:%.*]] = load half, ptr [[C_IMAGP5]], align 2
1426 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1427 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1428 // AVX-NEXT: store half [[C_REAL4]], ptr [[RETVAL_REALP]], align 2
1429 // AVX-NEXT: store half [[C_IMAG6]], ptr [[RETVAL_IMAGP]], align 2
1430 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1431 // AVX-NEXT: ret <2 x half> [[TMP1]]
1433 // X86-LABEL: @addcompound_half_rc(
1435 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1436 // X86-NEXT: [[C:%.*]] = alloca { half, half }, align 2
1437 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1438 // X86-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
1439 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1440 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1441 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
1442 // X86-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1443 // X86-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
1444 // X86-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1445 // X86-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
1446 // X86-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to float
1447 // X86-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to float
1448 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[CONV]], [[EXT]]
1449 // X86-NEXT: [[CONV2:%.*]] = fptrunc float [[ADD_R]] to half
1450 // X86-NEXT: [[CONV3:%.*]] = fptrunc float [[CONV1]] to half
1451 // X86-NEXT: [[C_REALP4:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1452 // X86-NEXT: [[C_IMAGP5:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1453 // X86-NEXT: store half [[CONV2]], ptr [[C_REALP4]], align 2
1454 // X86-NEXT: store half [[CONV3]], ptr [[C_IMAGP5]], align 2
1455 // X86-NEXT: [[C_REALP6:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1456 // X86-NEXT: [[C_REAL7:%.*]] = load half, ptr [[C_REALP6]], align 2
1457 // X86-NEXT: [[C_IMAGP8:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1458 // X86-NEXT: [[C_IMAG9:%.*]] = load half, ptr [[C_IMAGP8]], align 2
1459 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1460 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1461 // X86-NEXT: store half [[C_REAL7]], ptr [[RETVAL_REALP]], align 2
1462 // X86-NEXT: store half [[C_IMAG9]], ptr [[RETVAL_IMAGP]], align 2
1463 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1464 // X86-NEXT: ret <2 x half> [[TMP1]]
1466 _Float16 _Complex
addcompound_half_rc(_Float16 a
, _Float16 _Complex c
) {
1471 // AVX-LABEL: @addcompound_half_cc(
1473 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1474 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1475 // AVX-NEXT: [[C:%.*]] = alloca { half, half }, align 2
1476 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1477 // AVX-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
1478 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1479 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1480 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1481 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1482 // AVX-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1483 // AVX-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
1484 // AVX-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1485 // AVX-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
1486 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[C_REAL]], [[A_REAL]]
1487 // AVX-NEXT: [[ADD_I:%.*]] = fadd half [[C_IMAG]], [[A_IMAG]]
1488 // AVX-NEXT: [[C_REALP1:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1489 // AVX-NEXT: [[C_IMAGP2:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1490 // AVX-NEXT: store half [[ADD_R]], ptr [[C_REALP1]], align 2
1491 // AVX-NEXT: store half [[ADD_I]], ptr [[C_IMAGP2]], align 2
1492 // AVX-NEXT: [[C_REALP3:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1493 // AVX-NEXT: [[C_REAL4:%.*]] = load half, ptr [[C_REALP3]], align 2
1494 // AVX-NEXT: [[C_IMAGP5:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1495 // AVX-NEXT: [[C_IMAG6:%.*]] = load half, ptr [[C_IMAGP5]], align 2
1496 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1497 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1498 // AVX-NEXT: store half [[C_REAL4]], ptr [[RETVAL_REALP]], align 2
1499 // AVX-NEXT: store half [[C_IMAG6]], ptr [[RETVAL_IMAGP]], align 2
1500 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1501 // AVX-NEXT: ret <2 x half> [[TMP0]]
1503 // X86-LABEL: @addcompound_half_cc(
1505 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1506 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1507 // X86-NEXT: [[C:%.*]] = alloca { half, half }, align 2
1508 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1509 // X86-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
1510 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1511 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1512 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1513 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1514 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1515 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
1516 // X86-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1517 // X86-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
1518 // X86-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1519 // X86-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
1520 // X86-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to float
1521 // X86-NEXT: [[CONV2:%.*]] = fpext half [[C_IMAG]] to float
1522 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[CONV]], [[EXT]]
1523 // X86-NEXT: [[ADD_I:%.*]] = fadd float [[CONV2]], [[EXT1]]
1524 // X86-NEXT: [[CONV3:%.*]] = fptrunc float [[ADD_R]] to half
1525 // X86-NEXT: [[CONV4:%.*]] = fptrunc float [[ADD_I]] to half
1526 // X86-NEXT: [[C_REALP5:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1527 // X86-NEXT: [[C_IMAGP6:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1528 // X86-NEXT: store half [[CONV3]], ptr [[C_REALP5]], align 2
1529 // X86-NEXT: store half [[CONV4]], ptr [[C_IMAGP6]], align 2
1530 // X86-NEXT: [[C_REALP7:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1531 // X86-NEXT: [[C_REAL8:%.*]] = load half, ptr [[C_REALP7]], align 2
1532 // X86-NEXT: [[C_IMAGP9:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1533 // X86-NEXT: [[C_IMAG10:%.*]] = load half, ptr [[C_IMAGP9]], align 2
1534 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1535 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1536 // X86-NEXT: store half [[C_REAL8]], ptr [[RETVAL_REALP]], align 2
1537 // X86-NEXT: store half [[C_IMAG10]], ptr [[RETVAL_IMAGP]], align 2
1538 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1539 // X86-NEXT: ret <2 x half> [[TMP0]]
1541 _Float16 _Complex
addcompound_half_cc(_Float16 _Complex a
, _Float16 _Complex c
) {
1546 // AVX-LABEL: @MinusOp_r(
1548 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1549 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1550 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1551 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1552 // AVX-NEXT: [[FNEG:%.*]] = fneg half [[TMP0]]
1553 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1554 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1555 // AVX-NEXT: store half [[FNEG]], ptr [[RETVAL_REALP]], align 2
1556 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1557 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1558 // AVX-NEXT: ret <2 x half> [[TMP1]]
1560 // X86-LABEL: @MinusOp_r(
1562 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1563 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1564 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1565 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1566 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
1567 // X86-NEXT: [[FNEG:%.*]] = fneg float [[EXT]]
1568 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[FNEG]] to half
1569 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1570 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1571 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1572 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1573 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1574 // X86-NEXT: ret <2 x half> [[TMP1]]
1576 _Float16 _Complex
MinusOp_r(_Float16 a
) {
1580 // AVX-LABEL: @MinusOp_c(
1582 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1583 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1584 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1585 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1586 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1587 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1588 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1589 // AVX-NEXT: [[NEG_R:%.*]] = fneg half [[A_REAL]]
1590 // AVX-NEXT: [[NEG_I:%.*]] = fneg half [[A_IMAG]]
1591 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1592 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1593 // AVX-NEXT: store half [[NEG_R]], ptr [[RETVAL_REALP]], align 2
1594 // AVX-NEXT: store half [[NEG_I]], ptr [[RETVAL_IMAGP]], align 2
1595 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1596 // AVX-NEXT: ret <2 x half> [[TMP0]]
1598 // X86-LABEL: @MinusOp_c(
1600 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1601 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1602 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1603 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1604 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1605 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1606 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1607 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1608 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
1609 // X86-NEXT: [[NEG_R:%.*]] = fneg float [[EXT]]
1610 // X86-NEXT: [[NEG_I:%.*]] = fneg float [[EXT1]]
1611 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[NEG_R]] to half
1612 // X86-NEXT: [[UNPROMOTION2:%.*]] = fptrunc float [[NEG_I]] to half
1613 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1614 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1615 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1616 // X86-NEXT: store half [[UNPROMOTION2]], ptr [[RETVAL_IMAGP]], align 2
1617 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1618 // X86-NEXT: ret <2 x half> [[TMP0]]
1620 _Float16 _Complex
MinusOp_c(_Float16 _Complex a
) {
1624 // AVX-LABEL: @PlusOp_r(
1626 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1627 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1628 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1629 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1630 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1631 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1632 // AVX-NEXT: store half [[TMP0]], ptr [[RETVAL_REALP]], align 2
1633 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1634 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1635 // AVX-NEXT: ret <2 x half> [[TMP1]]
1637 // X86-LABEL: @PlusOp_r(
1639 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1640 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1641 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1642 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1643 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
1644 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half
1645 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1646 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1647 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1648 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1649 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1650 // X86-NEXT: ret <2 x half> [[TMP1]]
1652 _Float16 _Complex
PlusOp_r(_Float16 a
) {
1656 // AVX-LABEL: @PlusOp_c(
1658 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1659 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1660 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1661 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1662 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1663 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1664 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1665 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1666 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1667 // AVX-NEXT: store half [[A_REAL]], ptr [[RETVAL_REALP]], align 2
1668 // AVX-NEXT: store half [[A_IMAG]], ptr [[RETVAL_IMAGP]], align 2
1669 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1670 // AVX-NEXT: ret <2 x half> [[TMP0]]
1672 // X86-LABEL: @PlusOp_c(
1674 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1675 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1676 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1677 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1678 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1679 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1680 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1681 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1682 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
1683 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half
1684 // X86-NEXT: [[UNPROMOTION2:%.*]] = fptrunc float [[EXT1]] to half
1685 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1686 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1687 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1688 // X86-NEXT: store half [[UNPROMOTION2]], ptr [[RETVAL_IMAGP]], align 2
1689 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1690 // X86-NEXT: ret <2 x half> [[TMP0]]
1692 _Float16 _Complex
PlusOp_c(_Float16 _Complex a
) {
1696 // AVX-LABEL: @RealOp_r(
1698 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1699 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1700 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1701 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1702 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1703 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1704 // AVX-NEXT: store half [[TMP0]], ptr [[RETVAL_REALP]], align 2
1705 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1706 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1707 // AVX-NEXT: ret <2 x half> [[TMP1]]
1709 // X86-LABEL: @RealOp_r(
1711 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1712 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1713 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1714 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1715 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
1716 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half
1717 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1718 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1719 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1720 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1721 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1722 // X86-NEXT: ret <2 x half> [[TMP1]]
1724 _Float16 _Complex
RealOp_r(_Float16 a
) {
1728 // AVX-LABEL: @RealOp_c(
1730 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1731 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1732 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1733 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1734 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_REALP]], align 2
1735 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1736 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1737 // AVX-NEXT: store half [[TMP0]], ptr [[RETVAL_REALP]], align 2
1738 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1739 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1740 // AVX-NEXT: ret <2 x half> [[TMP1]]
1742 // X86-LABEL: @RealOp_c(
1744 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1745 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1746 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1747 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1748 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1749 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1750 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half
1751 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1752 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1753 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1754 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1755 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1756 // X86-NEXT: ret <2 x half> [[TMP0]]
1758 _Float16 _Complex
RealOp_c(_Float16 _Complex a
) {
1762 // AVX-LABEL: @ImagOp_r(
1764 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1765 // AVX-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1766 // AVX-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1767 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1768 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1769 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1770 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_REALP]], align 2
1771 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1772 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1773 // AVX-NEXT: ret <2 x half> [[TMP1]]
1775 // X86-LABEL: @ImagOp_r(
1777 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1778 // X86-NEXT: [[A_ADDR:%.*]] = alloca half, align 2
1779 // X86-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2
1780 // X86-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2
1781 // X86-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float
1782 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1783 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1784 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_REALP]], align 2
1785 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1786 // X86-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1787 // X86-NEXT: ret <2 x half> [[TMP1]]
1789 _Float16 _Complex
ImagOp_r(_Float16 a
) {
1793 // AVX-LABEL: @ImagOp_c(
1795 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1796 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1797 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1798 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1799 // AVX-NEXT: [[TMP0:%.*]] = load half, ptr [[A_IMAGP]], align 2
1800 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1801 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1802 // AVX-NEXT: store half [[TMP0]], ptr [[RETVAL_REALP]], align 2
1803 // AVX-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1804 // AVX-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1805 // AVX-NEXT: ret <2 x half> [[TMP1]]
1807 // X86-LABEL: @ImagOp_c(
1809 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1810 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1811 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1812 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1813 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1814 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_IMAG]] to float
1815 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half
1816 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1817 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1818 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1819 // X86-NEXT: store half 0xH0000, ptr [[RETVAL_IMAGP]], align 2
1820 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1821 // X86-NEXT: ret <2 x half> [[TMP0]]
1823 _Float16 _Complex
ImagOp_c(_Float16 _Complex a
) {
1827 // AVX-LABEL: @MinusOp_c_c(
1829 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1830 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1831 // AVX-NEXT: [[C:%.*]] = alloca { half, half }, align 2
1832 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1833 // AVX-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
1834 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1835 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1836 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1837 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1838 // AVX-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1839 // AVX-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
1840 // AVX-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1841 // AVX-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
1842 // AVX-NEXT: [[NEG_R:%.*]] = fneg half [[C_REAL]]
1843 // AVX-NEXT: [[NEG_I:%.*]] = fneg half [[C_IMAG]]
1844 // AVX-NEXT: [[ADD_R:%.*]] = fadd half [[A_REAL]], [[NEG_R]]
1845 // AVX-NEXT: [[ADD_I:%.*]] = fadd half [[A_IMAG]], [[NEG_I]]
1846 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1847 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1848 // AVX-NEXT: store half [[ADD_R]], ptr [[RETVAL_REALP]], align 2
1849 // AVX-NEXT: store half [[ADD_I]], ptr [[RETVAL_IMAGP]], align 2
1850 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1851 // AVX-NEXT: ret <2 x half> [[TMP0]]
1853 // X86-LABEL: @MinusOp_c_c(
1855 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1856 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1857 // X86-NEXT: [[C:%.*]] = alloca { half, half }, align 2
1858 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1859 // X86-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
1860 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1861 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1862 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1863 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1864 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1865 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
1866 // X86-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1867 // X86-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
1868 // X86-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1869 // X86-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
1870 // X86-NEXT: [[EXT2:%.*]] = fpext half [[C_REAL]] to float
1871 // X86-NEXT: [[EXT3:%.*]] = fpext half [[C_IMAG]] to float
1872 // X86-NEXT: [[NEG_R:%.*]] = fneg float [[EXT2]]
1873 // X86-NEXT: [[NEG_I:%.*]] = fneg float [[EXT3]]
1874 // X86-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[NEG_R]]
1875 // X86-NEXT: [[ADD_I:%.*]] = fadd float [[EXT1]], [[NEG_I]]
1876 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R]] to half
1877 // X86-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[ADD_I]] to half
1878 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1879 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1880 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1881 // X86-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2
1882 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1883 // X86-NEXT: ret <2 x half> [[TMP0]]
1885 _Float16 _Complex
MinusOp_c_c(_Float16 _Complex a
, _Float16 _Complex c
) {
1889 // AVX-LABEL: @PlusOp_c_c(
1891 // AVX-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1892 // AVX-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1893 // AVX-NEXT: [[C:%.*]] = alloca { half, half }, align 2
1894 // AVX-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1895 // AVX-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
1896 // AVX-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1897 // AVX-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1898 // AVX-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1899 // AVX-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1900 // AVX-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1901 // AVX-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
1902 // AVX-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1903 // AVX-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
1904 // AVX-NEXT: [[SUB_R:%.*]] = fsub half [[A_REAL]], [[C_REAL]]
1905 // AVX-NEXT: [[SUB_I:%.*]] = fsub half [[A_IMAG]], [[C_IMAG]]
1906 // AVX-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1907 // AVX-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1908 // AVX-NEXT: store half [[SUB_R]], ptr [[RETVAL_REALP]], align 2
1909 // AVX-NEXT: store half [[SUB_I]], ptr [[RETVAL_IMAGP]], align 2
1910 // AVX-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1911 // AVX-NEXT: ret <2 x half> [[TMP0]]
1913 // X86-LABEL: @PlusOp_c_c(
1915 // X86-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
1916 // X86-NEXT: [[A:%.*]] = alloca { half, half }, align 2
1917 // X86-NEXT: [[C:%.*]] = alloca { half, half }, align 2
1918 // X86-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2
1919 // X86-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2
1920 // X86-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0
1921 // X86-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2
1922 // X86-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1
1923 // X86-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2
1924 // X86-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float
1925 // X86-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float
1926 // X86-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0
1927 // X86-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
1928 // X86-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1
1929 // X86-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
1930 // X86-NEXT: [[EXT2:%.*]] = fpext half [[C_REAL]] to float
1931 // X86-NEXT: [[EXT3:%.*]] = fpext half [[C_IMAG]] to float
1932 // X86-NEXT: [[SUB_R:%.*]] = fsub float [[EXT]], [[EXT2]]
1933 // X86-NEXT: [[SUB_I:%.*]] = fsub float [[EXT1]], [[EXT3]]
1934 // X86-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[SUB_R]] to half
1935 // X86-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[SUB_I]] to half
1936 // X86-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0
1937 // X86-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1
1938 // X86-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
1939 // X86-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2
1940 // X86-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
1941 // X86-NEXT: ret <2 x half> [[TMP0]]
1943 _Float16 _Complex
PlusOp_c_c(_Float16 _Complex a
, _Float16 _Complex c
) {