Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3677,9 +3677,14 @@ // TODO: Refine on operand return false; } - - // TODO: Handle FMINNUM/FMAXNUM/FMINNAN/FMAXNAN when there is an agreement on - // what they should do. + case ISD::FMINNUM: + case ISD::FMAXNUM: + case ISD::FMINNAN: + case ISD::FMAXNAN: { + // TODO: This could be better if there was an agreement on snan behavior. + return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) && + isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1); + } default: if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN || Index: test/CodeGen/AMDGPU/known-never-snan.ll =================================================================== --- test/CodeGen/AMDGPU/known-never-snan.ll +++ test/CodeGen/AMDGPU/known-never-snan.ll @@ -99,8 +99,7 @@ ; GCN-NEXT: v_rcp_f32_e32 v0, v0 ; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1 ; GCN-NEXT: v_min_f32_e32 v0, v0, v1 -; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0 -; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0 +; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0 ; GCN-NEXT: s_setpc_b64 s[30:31] %a.nnan.add = fdiv nnan float 1.0, %a %b.nnan.add = fadd nnan float %b, 1.0 @@ -110,6 +109,38 @@ ret float %med } +define float @v_test_known_not_minnum_maybe_nan_src0_input_fmed3_r_i_i_f32(float %a, float %b) #0 { +; GCN-LABEL: v_test_known_not_minnum_maybe_nan_src0_input_fmed3_r_i_i_f32: +; GCN: ; %bb.0: +; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1 +; GCN-NEXT: v_min_f32_e32 v0, v0, v1 +; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0 +; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0 +; GCN-NEXT: s_setpc_b64 s[30:31] + %b.nsnan = fadd float %b, 1.0 + %known.not.snan = call float @llvm.minnum.f32(float %a, float %b.nsnan) + %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0) + %med = call float @llvm.minnum.f32(float %max, float 4.0) + ret float %med +} + +define float @v_test_known_not_minnum_maybe_nan_src1_input_fmed3_r_i_i_f32(float %a, float %b) #0 { +; GCN-LABEL: v_test_known_not_minnum_maybe_nan_src1_input_fmed3_r_i_i_f32: +; GCN: ; %bb.0: +; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GCN-NEXT: v_add_f32_e32 v0, 1.0, v0 +; GCN-NEXT: v_min_f32_e32 v0, v0, v1 +; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0 +; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0 +; GCN-NEXT: s_setpc_b64 s[30:31] + %a.nsnan = fadd float %a, 1.0 + %known.not.snan = call float @llvm.minnum.f32(float %a.nsnan, float %b) + %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0) + %med = call float @llvm.minnum.f32(float %max, float 4.0) + ret float %med +} + define float @v_minnum_possible_nan_lhs_input_fmed3_r_i_i_f32(float %a, float %b) #0 { ; GCN-LABEL: v_minnum_possible_nan_lhs_input_fmed3_r_i_i_f32: ; GCN: ; %bb.0: @@ -148,8 +179,8 @@ ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) ; GCN-NEXT: v_rcp_f32_e32 v0, v0 ; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1 -; GCN-NEXT: v_max3_f32 v0, v0, v1, 2.0 -; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0 +; GCN-NEXT: v_max_f32_e32 v0, v0, v1 +; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0 ; GCN-NEXT: s_setpc_b64 s[30:31] %a.nnan.add = fdiv nnan float 1.0, %a %b.nnan.add = fadd nnan float %b, 1.0