diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -53157,9 +53157,21 @@ static SDValue combineFMinNumFMaxNum(SDNode *N, SelectionDAG &DAG, const X86Subtarget &Subtarget) { + SDValue Op0 = N->getOperand(0); + SDValue Op1 = N->getOperand(1); + SDLoc DL(N); + EVT VT = N->getValueType(0); - if (Subtarget.useSoftFloat() || isSoftFP16(VT, Subtarget)) + if (Subtarget.useSoftFloat() || isSoftFP16(VT, Subtarget)) { + if (DAG.getTarget().Options.NoNaNsFPMath || N->getFlags().hasNoNaNs()) { + auto MinMaxOp = N->getOpcode() == ISD::FMAXNUM ? ISD::SMAX : ISD::SMIN; + EVT NVT = VT.changeTypeToInteger(); + return DAG.getBitcast(VT, DAG.getNode(MinMaxOp, DL, NVT, + DAG.getBitcast(NVT, Op0), + DAG.getBitcast(NVT, Op1))); + } return SDValue(); + } const TargetLowering &TLI = DAG.getTargetLoweringInfo(); @@ -53169,9 +53181,6 @@ (VT.isVector() && TLI.isTypeLegal(VT)))) return SDValue(); - SDValue Op0 = N->getOperand(0); - SDValue Op1 = N->getOperand(1); - SDLoc DL(N); auto MinMaxOp = N->getOpcode() == ISD::FMAXNUM ? X86ISD::FMAX : X86ISD::FMIN; // If we don't have to respect NaN inputs, this is a direct translation to x86 diff --git a/llvm/test/CodeGen/X86/half.ll b/llvm/test/CodeGen/X86/half.ll --- a/llvm/test/CodeGen/X86/half.ll +++ b/llvm/test/CodeGen/X86/half.ll @@ -1355,4 +1355,37 @@ ret <8 x half> %2 } +declare half @llvm.minnum.f16(half, half) + +define half @pr61271(half %0, half %1) #0 { +; CHECK-LIBCALL-LABEL: pr61271: +; CHECK-LIBCALL: # %bb.0: +; CHECK-LIBCALL-NEXT: pextrw $0, %xmm1, %eax +; CHECK-LIBCALL-NEXT: pextrw $0, %xmm0, %ecx +; CHECK-LIBCALL-NEXT: cmpw %ax, %cx +; CHECK-LIBCALL-NEXT: cmovll %ecx, %eax +; CHECK-LIBCALL-NEXT: pinsrw $0, %eax, %xmm0 +; CHECK-LIBCALL-NEXT: retq +; +; BWON-F16C-LABEL: pr61271: +; BWON-F16C: # %bb.0: +; BWON-F16C-NEXT: vpextrw $0, %xmm1, %eax +; BWON-F16C-NEXT: vpextrw $0, %xmm0, %ecx +; BWON-F16C-NEXT: cmpw %ax, %cx +; BWON-F16C-NEXT: cmovll %ecx, %eax +; BWON-F16C-NEXT: vpinsrw $0, %eax, %xmm0, %xmm0 +; BWON-F16C-NEXT: retq +; +; CHECK-I686-LABEL: pr61271: +; CHECK-I686: # %bb.0: +; CHECK-I686-NEXT: movl {{[0-9]+}}(%esp), %eax +; CHECK-I686-NEXT: movl {{[0-9]+}}(%esp), %ecx +; CHECK-I686-NEXT: cmpw %ax, %cx +; CHECK-I686-NEXT: cmovll %ecx, %eax +; CHECK-I686-NEXT: pinsrw $0, %eax, %xmm0 +; CHECK-I686-NEXT: retl + %3 = call fast half @llvm.minnum.f16(half %0, half %1) + ret half %3 +} + attributes #0 = { nounwind }