; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+avx512fp16 < %s | FileCheck %s
; Test cases derived from float/double tests in fp-logic.ll
; 1 FP operand, 1 int operand, int result
define i16 @f1(half %x, i16 %y) {
; CHECK-LABEL: f1:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovw %xmm0, %eax
; CHECK-NEXT: andl %edi, %eax
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 %bc1, %y
ret i16 %and
}
; Swap operands of the logic op.
define i16 @f2(half %x, i16 %y) {
; CHECK-LABEL: f2:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovw %xmm0, %eax
; CHECK-NEXT: andl %edi, %eax
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 %y, %bc1
ret i16 %and
}
; 1 FP operand, 1 constant operand, int result
define i16 @f3(half %x) {
; CHECK-LABEL: f3:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovw %xmm0, %eax
; CHECK-NEXT: andl $1, %eax
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 %bc1, 1
ret i16 %and
}
; Swap operands of the logic op.
define i16 @f4(half %x) {
; CHECK-LABEL: f4:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovw %xmm0, %eax
; CHECK-NEXT: andl $2, %eax
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 2, %bc1
ret i16 %and
}
; 1 FP operand, 1 integer operand, FP result
define half @f5(half %x, i16 %y) {
; CHECK-LABEL: f5:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovw %edi, %xmm1
; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 %bc1, %y
%bc2 = bitcast i16 %and to half
ret half %bc2
}
; Swap operands of the logic op.
define half @f6(half %x, i16 %y) {
; CHECK-LABEL: f6:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovw %edi, %xmm1
; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 %y, %bc1
%bc2 = bitcast i16 %and to half
ret half %bc2
}
; 1 FP operand, 1 constant operand, FP result
define half @f7(half %x) {
; CHECK-LABEL: f7:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovsh {{.*#+}} xmm1 = [1.7881E-7,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 %bc1, 3
%bc2 = bitcast i16 %and to half
ret half %bc2
}
; Swap operands of the logic op.
define half @f8(half %x) {
; CHECK-LABEL: f8:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovsh {{.*#+}} xmm1 = [2.3842E-7,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 4, %bc1
%bc2 = bitcast i16 %and to half
ret half %bc2
}
; 2 FP operands, int result
define i16 @f9(half %x, half %y) {
; CHECK-LABEL: f9:
; CHECK: # %bb.0:
; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: vmovw %xmm0, %eax
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%bc2 = bitcast half %y to i16
%and = and i16 %bc1, %bc2
ret i16 %and
}
; 2 FP operands, FP result
define half @f10(half %x, half %y) {
; CHECK-LABEL: f10:
; CHECK: # %bb.0:
; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%bc2 = bitcast half %y to i16
%and = and i16 %bc1, %bc2
%bc3 = bitcast i16 %and to half
ret half %bc3
}
define half @or(half %x, half %y) {
; CHECK-LABEL: or:
; CHECK: # %bb.0:
; CHECK-NEXT: vorps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%bc2 = bitcast half %y to i16
%and = or i16 %bc1, %bc2
%bc3 = bitcast i16 %and to half
ret half %bc3
}
define half @xor(half %x, half %y) {
; CHECK-LABEL: xor:
; CHECK: # %bb.0:
; CHECK-NEXT: vxorps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%bc2 = bitcast half %y to i16
%and = xor i16 %bc1, %bc2
%bc3 = bitcast i16 %and to half
ret half %bc3
}
define half @f7_or(half %x) {
; CHECK-LABEL: f7_or:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovsh {{.*#+}} xmm1 = [1.7881E-7,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-NEXT: vorps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = or i16 %bc1, 3
%bc2 = bitcast i16 %and to half
ret half %bc2
}
define half @f7_xor(half %x) {
; CHECK-LABEL: f7_xor:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovsh {{.*#+}} xmm1 = [1.7881E-7,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-NEXT: vxorps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = xor i16 %bc1, 3
%bc2 = bitcast i16 %and to half
ret half %bc2
}
; Grabbing the sign bit is a special case that could be handled
; by movmskps/movmskpd, but if we're not shifting it over, then
; a simple FP logic op is cheaper.
define half @movmsk(half %x) {
; CHECK-LABEL: movmsk:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovsh {{.*#+}} 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]
; CHECK-NEXT: vandps %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 %bc1, 32768
%bc2 = bitcast i16 %and to half
ret half %bc2
}
define half @bitcast_fabs(half %x) {
; CHECK-LABEL: bitcast_fabs:
; CHECK: # %bb.0:
; CHECK-NEXT: vpbroadcastw {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN]
; CHECK-NEXT: vpand %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%and = and i16 %bc1, 32767
%bc2 = bitcast i16 %and to half
ret half %bc2
}
define half @bitcast_fneg(half %x) {
; CHECK-LABEL: bitcast_fneg:
; CHECK: # %bb.0:
; 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]
; CHECK-NEXT: vpxor %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %x to i16
%xor = xor i16 %bc1, 32768
%bc2 = bitcast i16 %xor to half
ret half %bc2
}
define <8 x half> @bitcast_fabs_vec(<8 x half> %x) {
; CHECK-LABEL: bitcast_fabs_vec:
; CHECK: # %bb.0:
; CHECK-NEXT: vpbroadcastw {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN]
; CHECK-NEXT: vpand %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast <8 x half> %x to <8 x i16>
%and = and <8 x i16> %bc1, <i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767>
%bc2 = bitcast <8 x i16> %and to <8 x half>
ret <8 x half> %bc2
}
define <8 x half> @bitcast_fneg_vec(<8 x half> %x) {
; CHECK-LABEL: bitcast_fneg_vec:
; CHECK: # %bb.0:
; 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]
; CHECK-NEXT: vpxor %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast <8 x half> %x to <8 x i16>
%xor = xor <8 x i16> %bc1, <i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768>
%bc2 = bitcast <8 x i16> %xor to <8 x half>
ret <8 x half> %bc2
}
define half @fadd_bitcast_fneg(half %x, half %y) {
; CHECK-LABEL: fadd_bitcast_fneg:
; CHECK: # %bb.0:
; CHECK-NEXT: vsubsh %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %y to i16
%xor = xor i16 %bc1, 32768
%bc2 = bitcast i16 %xor to half
%fadd = fadd half %x, %bc2
ret half %fadd
}
define half @fsub_bitcast_fneg(half %x, half %y) {
; CHECK-LABEL: fsub_bitcast_fneg:
; CHECK: # %bb.0:
; CHECK-NEXT: vmovsh {{.*#+}} xmm2 = [NaN,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-NEXT: vxorps %xmm2, %xmm1, %xmm1
; CHECK-NEXT: vsubsh %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast half %y to i16
%xor = xor i16 %bc1, 32767
%bc2 = bitcast i16 %xor to half
%fsub = fsub half %x, %bc2
ret half %fsub
}
define half @nabs(half %a) {
; CHECK-LABEL: nabs:
; CHECK: # %bb.0:
; 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]
; CHECK-NEXT: vpor %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%conv = bitcast half %a to i16
%and = or i16 %conv, -32768
%conv1 = bitcast i16 %and to half
ret half %conv1
}
define <8 x half> @nabsv8f16(<8 x half> %a) {
; CHECK-LABEL: nabsv8f16:
; CHECK: # %bb.0:
; 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]
; CHECK-NEXT: vpor %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%conv = bitcast <8 x half> %a to <8 x i16>
%and = or <8 x i16> %conv, <i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768>
%conv1 = bitcast <8 x i16> %and to <8 x half>
ret <8 x half> %conv1
}
define <8 x half> @fadd_bitcast_fneg_vec(<8 x half> %x, <8 x half> %y) {
; CHECK-LABEL: fadd_bitcast_fneg_vec:
; CHECK: # %bb.0:
; CHECK-NEXT: vsubph %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast <8 x half> %y to <8 x i16>
%xor = xor <8 x i16> %bc1, <i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768>
%bc2 = bitcast <8 x i16> %xor to <8 x half>
%fadd = fadd <8 x half> %x, %bc2
ret <8 x half> %fadd
}
define <8 x half> @fadd_bitcast_fneg_vec_undef_elts(<8 x half> %x, <8 x half> %y) {
; CHECK-LABEL: fadd_bitcast_fneg_vec_undef_elts:
; CHECK: # %bb.0:
; CHECK-NEXT: vsubph %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast <8 x half> %y to <8 x i16>
%xor = xor <8 x i16> %bc1, <i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 undef, i16 32768>
%bc2 = bitcast <8 x i16> %xor to <8 x half>
%fadd = fadd <8 x half> %x, %bc2
ret <8 x half> %fadd
}
define <8 x half> @fsub_bitcast_fneg_vec(<8 x half> %x, <8 x half> %y) {
; CHECK-LABEL: fsub_bitcast_fneg_vec:
; CHECK: # %bb.0:
; CHECK-NEXT: vaddph %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast <8 x half> %y to <8 x i16>
%xor = xor <8 x i16> %bc1, <i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768>
%bc2 = bitcast <8 x i16> %xor to <8 x half>
%fsub = fsub <8 x half> %x, %bc2
ret <8 x half> %fsub
}
define <8 x half> @fsub_bitcast_fneg_vec_undef_elts(<8 x half> %x, <8 x half> %y) {
; CHECK-LABEL: fsub_bitcast_fneg_vec_undef_elts:
; CHECK: # %bb.0:
; CHECK-NEXT: vaddph %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast <8 x half> %y to <8 x i16>
%xor = xor <8 x i16> %bc1, <i16 undef, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 undef>
%bc2 = bitcast <8 x i16> %xor to <8 x half>
%fsub = fsub <8 x half> %x, %bc2
ret <8 x half> %fsub
}
define <8 x half> @fadd_bitcast_fneg_vec_width(<8 x half> %x, <8 x half> %y) {
; CHECK-LABEL: fadd_bitcast_fneg_vec_width:
; CHECK: # %bb.0:
; CHECK-NEXT: vxorpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm1, %xmm1
; CHECK-NEXT: vaddph %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast <8 x half> %y to <2 x i64>
%xor = xor <2 x i64> %bc1, <i64 -9223231297218904064, i64 -9223231297218904064>
%bc2 = bitcast <2 x i64> %xor to <8 x half>
%fadd = fadd <8 x half> %x, %bc2
ret <8 x half> %fadd
}
define <8 x half> @fsub_bitcast_fneg_vec_width(<8 x half> %x, <8 x half> %y) {
; CHECK-LABEL: fsub_bitcast_fneg_vec_width:
; CHECK: # %bb.0:
; CHECK-NEXT: vxorpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm1, %xmm1
; CHECK-NEXT: vsubph %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
%bc1 = bitcast <8 x half> %y to <2 x i64>
%xor = xor <2 x i64> %bc1, <i64 -9223231297218904064, i64 -9223231297218904064>
%bc2 = bitcast <2 x i64> %xor to <8 x half>
%fsub = fsub <8 x half> %x, %bc2
ret <8 x half> %fsub
}