; 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 {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 ; 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 {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 ; 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 {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 ; 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 {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 ; 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 {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 ; 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: vmovsh {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 ; CHECK-NEXT: vandps %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: vmovsh {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 ; CHECK-NEXT: vxorps %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 {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2 ; 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: vmovsh {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 ; CHECK-NEXT: vorps %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 }