|  | ; 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 | 
|  | } |