Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2030,6 +2030,19 @@ } } + // Canonicalize select of FP values where NaN and -0.0 are not valid as + // minnum/maxnum intrinsics. + if (isa(SI) && SI.hasNoNaNs() && SI.hasNoSignedZeros()) { + Value *X, *Y; + if (match(&SI, m_OrdFMax(m_Value(X), m_Value(Y)))) + return replaceInstUsesWith( + SI, Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, X, Y, &SI)); + + if (match(&SI, m_OrdFMin(m_Value(X), m_Value(Y)))) + return replaceInstUsesWith( + SI, Builder.CreateBinaryIntrinsic(Intrinsic::minnum, X, Y, &SI)); + } + // See if we can fold the select into a phi node if the condition is a select. if (auto *PN = dyn_cast(SI.getCondition())) // The true/false values have to be live in the PHI predecessor's blocks. Index: llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll +++ llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll @@ -313,9 +313,8 @@ define float @maxnum_ogt_fmf_on_select(float %a, float %b) { ; CHECK-LABEL: @maxnum_ogt_fmf_on_select( -; CHECK-NEXT: [[COND:%.*]] = fcmp ogt float [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[F:%.*]] = select nnan nsz i1 [[COND]], float [[A]], float [[B]] -; CHECK-NEXT: ret float [[F]] +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[A:%.*]], float [[B:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] ; %cond = fcmp ogt float %a, %b %f = select nnan nsz i1 %cond, float %a, float %b @@ -324,9 +323,8 @@ define <2 x float> @maxnum_oge_fmf_on_select(<2 x float> %a, <2 x float> %b) { ; CHECK-LABEL: @maxnum_oge_fmf_on_select( -; CHECK-NEXT: [[COND:%.*]] = fcmp oge <2 x float> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[F:%.*]] = select nnan ninf nsz <2 x i1> [[COND]], <2 x float> [[A]], <2 x float> [[B]] -; CHECK-NEXT: ret <2 x float> [[F]] +; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]]) +; CHECK-NEXT: ret <2 x float> [[TMP1]] ; %cond = fcmp oge <2 x float> %a, %b %f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b @@ -379,9 +377,8 @@ define float @minnum_olt_fmf_on_select(float %a, float %b) { ; CHECK-LABEL: @minnum_olt_fmf_on_select( -; CHECK-NEXT: [[COND:%.*]] = fcmp olt float [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[F:%.*]] = select nnan nsz i1 [[COND]], float [[A]], float [[B]] -; CHECK-NEXT: ret float [[F]] +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] ; %cond = fcmp olt float %a, %b %f = select nnan nsz i1 %cond, float %a, float %b @@ -390,9 +387,8 @@ define <2 x float> @minnum_ole_fmf_on_select(<2 x float> %a, <2 x float> %b) { ; CHECK-LABEL: @minnum_ole_fmf_on_select( -; CHECK-NEXT: [[COND:%.*]] = fcmp ole <2 x float> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[F:%.*]] = select nnan ninf nsz <2 x i1> [[COND]], <2 x float> [[A]], <2 x float> [[B]] -; CHECK-NEXT: ret <2 x float> [[F]] +; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]]) +; CHECK-NEXT: ret <2 x float> [[TMP1]] ; %cond = fcmp ole <2 x float> %a, %b %f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b