1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+avx512fp16 < %s | FileCheck %s
4 ; Test cases derived from float/double tests in fp-logic.ll
6 ; 1 FP operand, 1 int operand, int result
8 define i16 @f1(half %x, i16 %y) {
11 ; CHECK-NEXT: vmovw %xmm0, %eax
12 ; CHECK-NEXT: andl %edi, %eax
13 ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
15 %bc1 = bitcast half %x to i16
16 %and = and i16 %bc1, %y
20 ; Swap operands of the logic op.
22 define i16 @f2(half %x, i16 %y) {
25 ; CHECK-NEXT: vmovw %xmm0, %eax
26 ; CHECK-NEXT: andl %edi, %eax
27 ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
29 %bc1 = bitcast half %x to i16
30 %and = and i16 %y, %bc1
34 ; 1 FP operand, 1 constant operand, int result
36 define i16 @f3(half %x) {
39 ; CHECK-NEXT: vmovw %xmm0, %eax
40 ; CHECK-NEXT: andl $1, %eax
41 ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
43 %bc1 = bitcast half %x to i16
44 %and = and i16 %bc1, 1
48 ; Swap operands of the logic op.
50 define i16 @f4(half %x) {
53 ; CHECK-NEXT: vmovw %xmm0, %eax
54 ; CHECK-NEXT: andl $2, %eax
55 ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
57 %bc1 = bitcast half %x to i16
58 %and = and i16 2, %bc1
62 ; 1 FP operand, 1 integer operand, FP result
64 define half @f5(half %x, i16 %y) {
67 ; CHECK-NEXT: vmovw %edi, %xmm1
68 ; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
70 %bc1 = bitcast half %x to i16
71 %and = and i16 %bc1, %y
72 %bc2 = bitcast i16 %and to half
76 ; Swap operands of the logic op.
78 define half @f6(half %x, i16 %y) {
81 ; CHECK-NEXT: vmovw %edi, %xmm1
82 ; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
84 %bc1 = bitcast half %x to i16
85 %and = and i16 %y, %bc1
86 %bc2 = bitcast i16 %and to half
90 ; 1 FP operand, 1 constant operand, FP result
92 define half @f7(half %x) {
95 ; CHECK-NEXT: vmovsh {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
96 ; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
98 %bc1 = bitcast half %x to i16
99 %and = and i16 %bc1, 3
100 %bc2 = bitcast i16 %and to half
104 ; Swap operands of the logic op.
106 define half @f8(half %x) {
109 ; CHECK-NEXT: vmovsh {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
110 ; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
112 %bc1 = bitcast half %x to i16
113 %and = and i16 4, %bc1
114 %bc2 = bitcast i16 %and to half
118 ; 2 FP operands, int result
120 define i16 @f9(half %x, half %y) {
123 ; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
124 ; CHECK-NEXT: vmovw %xmm0, %eax
125 ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
127 %bc1 = bitcast half %x to i16
128 %bc2 = bitcast half %y to i16
129 %and = and i16 %bc1, %bc2
133 ; 2 FP operands, FP result
135 define half @f10(half %x, half %y) {
138 ; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
140 %bc1 = bitcast half %x to i16
141 %bc2 = bitcast half %y to i16
142 %and = and i16 %bc1, %bc2
143 %bc3 = bitcast i16 %and to half
147 define half @or(half %x, half %y) {
150 ; CHECK-NEXT: vorps %xmm1, %xmm0, %xmm0
152 %bc1 = bitcast half %x to i16
153 %bc2 = bitcast half %y to i16
154 %and = or i16 %bc1, %bc2
155 %bc3 = bitcast i16 %and to half
159 define half @xor(half %x, half %y) {
162 ; CHECK-NEXT: vxorps %xmm1, %xmm0, %xmm0
164 %bc1 = bitcast half %x to i16
165 %bc2 = bitcast half %y to i16
166 %and = xor i16 %bc1, %bc2
167 %bc3 = bitcast i16 %and to half
171 define half @f7_or(half %x) {
172 ; CHECK-LABEL: f7_or:
174 ; CHECK-NEXT: vmovsh {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
175 ; CHECK-NEXT: vorps %xmm1, %xmm0, %xmm0
177 %bc1 = bitcast half %x to i16
178 %and = or i16 %bc1, 3
179 %bc2 = bitcast i16 %and to half
183 define half @f7_xor(half %x) {
184 ; CHECK-LABEL: f7_xor:
186 ; CHECK-NEXT: vmovsh {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
187 ; CHECK-NEXT: vxorps %xmm1, %xmm0, %xmm0
189 %bc1 = bitcast half %x to i16
190 %and = xor i16 %bc1, 3
191 %bc2 = bitcast i16 %and to half
195 ; Grabbing the sign bit is a special case that could be handled
196 ; by movmskps/movmskpd, but if we're not shifting it over, then
197 ; a simple FP logic op is cheaper.
199 define half @movmsk(half %x) {
200 ; CHECK-LABEL: movmsk:
202 ; CHECK-NEXT: vmovsh {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
203 ; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
205 %bc1 = bitcast half %x to i16
206 %and = and i16 %bc1, 32768
207 %bc2 = bitcast i16 %and to half
211 define half @bitcast_fabs(half %x) {
212 ; CHECK-LABEL: bitcast_fabs:
214 ; CHECK-NEXT: vpbroadcastw {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN]
215 ; CHECK-NEXT: vpand %xmm1, %xmm0, %xmm0
217 %bc1 = bitcast half %x to i16
218 %and = and i16 %bc1, 32767
219 %bc2 = bitcast i16 %and to half
223 define half @bitcast_fneg(half %x) {
224 ; CHECK-LABEL: bitcast_fneg:
226 ; CHECK-NEXT: vpbroadcastw {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
227 ; CHECK-NEXT: vpxor %xmm1, %xmm0, %xmm0
229 %bc1 = bitcast half %x to i16
230 %xor = xor i16 %bc1, 32768
231 %bc2 = bitcast i16 %xor to half
235 define <8 x half> @bitcast_fabs_vec(<8 x half> %x) {
236 ; CHECK-LABEL: bitcast_fabs_vec:
238 ; CHECK-NEXT: vpbroadcastw {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN]
239 ; CHECK-NEXT: vpand %xmm1, %xmm0, %xmm0
241 %bc1 = bitcast <8 x half> %x to <8 x i16>
242 %and = and <8 x i16> %bc1, <i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767>
243 %bc2 = bitcast <8 x i16> %and to <8 x half>
247 define <8 x half> @bitcast_fneg_vec(<8 x half> %x) {
248 ; CHECK-LABEL: bitcast_fneg_vec:
250 ; CHECK-NEXT: vpbroadcastw {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
251 ; CHECK-NEXT: vpxor %xmm1, %xmm0, %xmm0
253 %bc1 = bitcast <8 x half> %x to <8 x i16>
254 %xor = xor <8 x i16> %bc1, <i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768>
255 %bc2 = bitcast <8 x i16> %xor to <8 x half>
259 define half @fadd_bitcast_fneg(half %x, half %y) {
260 ; CHECK-LABEL: fadd_bitcast_fneg:
262 ; CHECK-NEXT: vsubsh %xmm1, %xmm0, %xmm0
264 %bc1 = bitcast half %y to i16
265 %xor = xor i16 %bc1, 32768
266 %bc2 = bitcast i16 %xor to half
267 %fadd = fadd half %x, %bc2
271 define half @fsub_bitcast_fneg(half %x, half %y) {
272 ; CHECK-LABEL: fsub_bitcast_fneg:
274 ; CHECK-NEXT: vmovsh {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
275 ; CHECK-NEXT: vxorps %xmm2, %xmm1, %xmm1
276 ; CHECK-NEXT: vsubsh %xmm1, %xmm0, %xmm0
278 %bc1 = bitcast half %y to i16
279 %xor = xor i16 %bc1, 32767
280 %bc2 = bitcast i16 %xor to half
281 %fsub = fsub half %x, %bc2
285 define half @nabs(half %a) {
288 ; CHECK-NEXT: vpbroadcastw {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
289 ; CHECK-NEXT: vpor %xmm1, %xmm0, %xmm0
291 %conv = bitcast half %a to i16
292 %and = or i16 %conv, -32768
293 %conv1 = bitcast i16 %and to half
297 define <8 x half> @nabsv8f16(<8 x half> %a) {
298 ; CHECK-LABEL: nabsv8f16:
300 ; CHECK-NEXT: vpbroadcastw {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
301 ; CHECK-NEXT: vpor %xmm1, %xmm0, %xmm0
303 %conv = bitcast <8 x half> %a to <8 x i16>
304 %and = or <8 x i16> %conv, <i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768>
305 %conv1 = bitcast <8 x i16> %and to <8 x half>
306 ret <8 x half> %conv1
309 define <8 x half> @fadd_bitcast_fneg_vec(<8 x half> %x, <8 x half> %y) {
310 ; CHECK-LABEL: fadd_bitcast_fneg_vec:
312 ; CHECK-NEXT: vsubph %xmm1, %xmm0, %xmm0
314 %bc1 = bitcast <8 x half> %y to <8 x i16>
315 %xor = xor <8 x i16> %bc1, <i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768>
316 %bc2 = bitcast <8 x i16> %xor to <8 x half>
317 %fadd = fadd <8 x half> %x, %bc2
321 define <8 x half> @fadd_bitcast_fneg_vec_undef_elts(<8 x half> %x, <8 x half> %y) {
322 ; CHECK-LABEL: fadd_bitcast_fneg_vec_undef_elts:
324 ; CHECK-NEXT: vsubph %xmm1, %xmm0, %xmm0
326 %bc1 = bitcast <8 x half> %y to <8 x i16>
327 %xor = xor <8 x i16> %bc1, <i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 undef, i16 32768>
328 %bc2 = bitcast <8 x i16> %xor to <8 x half>
329 %fadd = fadd <8 x half> %x, %bc2
333 define <8 x half> @fsub_bitcast_fneg_vec(<8 x half> %x, <8 x half> %y) {
334 ; CHECK-LABEL: fsub_bitcast_fneg_vec:
336 ; CHECK-NEXT: vaddph %xmm1, %xmm0, %xmm0
338 %bc1 = bitcast <8 x half> %y to <8 x i16>
339 %xor = xor <8 x i16> %bc1, <i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768>
340 %bc2 = bitcast <8 x i16> %xor to <8 x half>
341 %fsub = fsub <8 x half> %x, %bc2
345 define <8 x half> @fsub_bitcast_fneg_vec_undef_elts(<8 x half> %x, <8 x half> %y) {
346 ; CHECK-LABEL: fsub_bitcast_fneg_vec_undef_elts:
348 ; CHECK-NEXT: vaddph %xmm1, %xmm0, %xmm0
350 %bc1 = bitcast <8 x half> %y to <8 x i16>
351 %xor = xor <8 x i16> %bc1, <i16 undef, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 undef>
352 %bc2 = bitcast <8 x i16> %xor to <8 x half>
353 %fsub = fsub <8 x half> %x, %bc2
357 define <8 x half> @fadd_bitcast_fneg_vec_width(<8 x half> %x, <8 x half> %y) {
358 ; CHECK-LABEL: fadd_bitcast_fneg_vec_width:
360 ; CHECK-NEXT: vxorpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm1, %xmm1
361 ; CHECK-NEXT: vaddph %xmm1, %xmm0, %xmm0
363 %bc1 = bitcast <8 x half> %y to <2 x i64>
364 %xor = xor <2 x i64> %bc1, <i64 -9223231297218904064, i64 -9223231297218904064>
365 %bc2 = bitcast <2 x i64> %xor to <8 x half>
366 %fadd = fadd <8 x half> %x, %bc2
370 define <8 x half> @fsub_bitcast_fneg_vec_width(<8 x half> %x, <8 x half> %y) {
371 ; CHECK-LABEL: fsub_bitcast_fneg_vec_width:
373 ; CHECK-NEXT: vxorpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm1, %xmm1
374 ; CHECK-NEXT: vsubph %xmm1, %xmm0, %xmm0
376 %bc1 = bitcast <8 x half> %y to <2 x i64>
377 %xor = xor <2 x i64> %bc1, <i64 -9223231297218904064, i64 -9223231297218904064>
378 %bc2 = bitcast <2 x i64> %xor to <8 x half>
379 %fsub = fsub <8 x half> %x, %bc2