diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3197,6 +3197,15 @@ Results.push_back(Expanded); break; } + case ISD::FMINIMUM: + case ISD::FMAXIMUM: + Tmp1 = Node->getOperand(0); + Tmp2 = Node->getOperand(1); + Tmp3 = DAG.getSelectCC( + dl, Tmp1, Tmp2, Tmp1, Tmp2, + Node->getOpcode() == ISD::FMINIMUM ? ISD::SETULT : ISD::SETUGT); + Results.push_back(DAG.getSelectCC(dl, Tmp2, Tmp2, Tmp2, Tmp3, ISD::SETUO)); + break; case ISD::FSIN: case ISD::FCOS: { EVT VT = Node->getValueType(0); diff --git a/llvm/test/CodeGen/NVPTX/fminimum-fmaximum.ll b/llvm/test/CodeGen/NVPTX/fminimum-fmaximum.ll --- a/llvm/test/CodeGen/NVPTX/fminimum-fmaximum.ll +++ b/llvm/test/CodeGen/NVPTX/fminimum-fmaximum.ll @@ -5,6 +5,10 @@ ; ---- minimum ---- +declare half @llvm.minimum.f16(half %a, half %b) +declare float @llvm.minimum.f32(float %a, float %b) +declare double @llvm.minimum.f64(double %a, double %b) + ; CHECK-LABEL: minimum_half define half @minimum_half(half %a) #0 { ; CHECK-NONAN: setp @@ -15,6 +19,17 @@ ret half %x } +; CHECK-LABEL: minimum_intr_half +define half @minimum_intr_half(half %a, half %b) #0 { + ; CHECK-NONAN-DAG: setp.ltu.f32 + ; CHECK-NONAN-DAG: setp.nan.f32 + ; CHECK-NONAN-DAG: selp.b16 + ; CHECK-NONAN-DAG: selp.b16 + ; CHECK-NAN: min.NaN.f16 + %x = call half @llvm.minimum.f16(half %a, half %b) + ret half %x +} + ; CHECK-LABEL: minimum_float define float @minimum_float(float %a) #0 { ; CHECK-NONAN: setp @@ -25,6 +40,17 @@ ret float %x } +; CHECK-LABEL: minimum_intr_float +define float @minimum_intr_float(float %a, float %b) #0 { + ; CHECK-NONAN-DAG: setp.ltu.f32 + ; CHECK-NONAN-DAG: setp.nan.f32 + ; CHECK-NONAN-DAG: selp.f32 + ; CHECK-NONAN-DAG: selp.f32 + ; CHECK-NAN: min.NaN.f32 + %x = call float @llvm.minimum.f32(float %a, float %b) + ret float %x +} + ; CHECK-LABEL: minimum_double define double @minimum_double(double %a) #0 { ; CHECK: setp @@ -34,6 +60,16 @@ ret double %x } +; CHECK-LABEL: minimum_intr_double +define double @minimum_intr_double(double %a, double %b) #0 { + ; CHECK-DAG: setp.ltu.f64 + ; CHECK-DAG: setp.nan.f64 + ; CHECK-DAG: selp.f64 + ; CHECK-DAG: selp.f64 + %x = call double @llvm.minimum.f64(double %a, double %b) + ret double %x +} + ; CHECK-LABEL: minimum_v2half define <2 x half> @minimum_v2half(<2 x half> %a) #0 { ; CHECK-NONAN-DAG: setp @@ -48,6 +84,10 @@ ; ---- maximum ---- +declare half @llvm.maximum.f16(half %a, half %b) +declare float @llvm.maximum.f32(float %a, float %b) +declare double @llvm.maximum.f64(double %a, double %b) + ; CHECK-LABEL: maximum_half define half @maximum_half(half %a) #0 { ; CHECK-NONAN: setp @@ -58,6 +98,17 @@ ret half %x } +; CHECK-LABEL: maximum_intr_half +define half @maximum_intr_half(half %a, half %b) #0 { + ; CHECK-NONAN-DAG: setp.gtu.f32 + ; CHECK-NONAN-DAG: setp.nan.f32 + ; CHECK-NONAN-DAG: selp.b16 + ; CHECK-NONAN-DAG: selp.b16 + ; CHECK-NAN: max.NaN.f16 + %x = call half @llvm.maximum.f16(half %a, half %b) + ret half %x +} + ; CHECK-LABEL: maximum_float define float @maximum_float(float %a) #0 { ; CHECK-NONAN: setp @@ -68,6 +119,17 @@ ret float %x } +; CHECK-LABEL: maximum_intr_float +define float @maximum_intr_float(float %a, float %b) #0 { + ; CHECK-NONAN-DAG: setp.gtu.f32 + ; CHECK-NONAN-DAG: setp.nan.f32 + ; CHECK-NONAN-DAG: selp.f32 + ; CHECK-NONAN-DAG: selp.f32 + ; CHECK-NAN: max.NaN.f32 + %x = call float @llvm.maximum.f32(float %a, float %b) + ret float %x +} + ; CHECK-LABEL: maximum_double define double @maximum_double(double %a) #0 { ; CHECK: setp @@ -77,6 +139,16 @@ ret double %x } +; CHECK-LABEL: maximum_intr_double +define double @maximum_intr_double(double %a, double %b) #0 { + ; CHECK-DAG: setp.gtu.f64 + ; CHECK-DAG: setp.nan.f64 + ; CHECK-DAG: selp.f64 + ; CHECK-DAG: selp.f64 + %x = call double @llvm.maximum.f64(double %a, double %b) + ret double %x +} + ; CHECK-LABEL: maximum_v2half define <2 x half> @maximum_v2half(<2 x half> %a) #0 { ; CHECK-NONAN-DAG: setp