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