diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4070,9 +4070,7 @@ // change the sign of a zero operand. bool HasNoSignedZeros = Q.CxtI && isa(Q.CxtI) && Q.CxtI->hasNoSignedZeros(); - const APFloat *C; - if (HasNoSignedZeros || (match(T, m_APFloat(C)) && C->isNonZero()) || - (match(F, m_APFloat(C)) && C->isNonZero())) { + if (HasNoSignedZeros || match(T, m_NonZeroFP()) || match(F, m_NonZeroFP())) { // (T == F) ? T : F --> F // (F == T) ? T : F --> F if (Pred == FCmpInst::FCMP_OEQ) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3485,9 +3485,9 @@ if (FPMathOp->hasNoInfs()) return true; - // Handle scalar constants. - if (auto *CFP = dyn_cast(V)) - return !CFP->isInfinity(); + // Handle scalar and fixed width vector constants. + if (isa(V)) + return match(V, m_NonInf()); if (Depth == MaxAnalysisRecursionDepth) return false; @@ -3517,25 +3517,6 @@ } } - // try to handle fixed width vector constants - auto *VFVTy = dyn_cast(V->getType()); - if (VFVTy && isa(V)) { - // For vectors, verify that each element is not infinity. - unsigned NumElts = VFVTy->getNumElements(); - for (unsigned i = 0; i != NumElts; ++i) { - Constant *Elt = cast(V)->getAggregateElement(i); - if (!Elt) - return false; - if (isa(Elt)) - continue; - auto *CElt = dyn_cast(Elt); - if (!CElt || CElt->isInfinity()) - return false; - } - // All elements were confirmed non-infinity or undefined. - return true; - } - // was not able to prove that V never contains infinity return false; } @@ -3549,9 +3530,9 @@ if (FPMathOp->hasNoNaNs()) return true; - // Handle scalar constants. - if (auto *CFP = dyn_cast(V)) - return !CFP->isNaN(); + // Handle scalar and fixed width vector constants. + if (isa(V)) + return match(V, m_NonNaN()); if (Depth == MaxAnalysisRecursionDepth) return false; @@ -3622,25 +3603,6 @@ } } - // Try to handle fixed width vector constants - auto *VFVTy = dyn_cast(V->getType()); - if (VFVTy && isa(V)) { - // For vectors, verify that each element is not NaN. - unsigned NumElts = VFVTy->getNumElements(); - for (unsigned i = 0; i != NumElts; ++i) { - Constant *Elt = cast(V)->getAggregateElement(i); - if (!Elt) - return false; - if (isa(Elt)) - continue; - auto *CElt = dyn_cast(Elt); - if (!CElt || CElt->isNaN()) - return false; - } - // All elements were confirmed not-NaN or undefined. - return true; - } - // Was not able to prove that V never contains NaN return false; } @@ -5326,7 +5288,7 @@ RHS = FalseVal; const APFloat *FC1; - if (CmpRHS != TrueVal || !match(CmpRHS, m_APFloat(FC1)) || !FC1->isFinite()) + if (CmpRHS != TrueVal || !match(CmpRHS, m_Finite(FC1))) return {SPF_UNKNOWN, SPNB_NA, false}; const APFloat *FC2; diff --git a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll --- a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll +++ b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll @@ -16,6 +16,21 @@ ret float %r } +; (X < C1) ? C1 : MIN(X, C2) +define <2 x float> @clamp_float_fast_ordered_strict_maxmin_vec(<2 x float> %x) { +; CHECK-LABEL: define {{[^@]+}}@clamp_float_fast_ordered_strict_maxmin_vec( +; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt <2 x float> [[X:%.*]], +; CHECK-NEXT: [[MIN:%.*]] = select <2 x i1> [[CMP2]], <2 x float> [[X]], <2 x float> +; CHECK-NEXT: [[TMP1:%.*]] = call fast <2 x float> @llvm.maxnum.v2f32(<2 x float> [[MIN]], <2 x float> ) +; CHECK-NEXT: ret <2 x float> [[TMP1]] +; + %cmp2 = fcmp fast olt <2 x float> %x, + %min = select <2 x i1> %cmp2, <2 x float> %x, <2 x float> + %cmp1 = fcmp fast olt <2 x float> %x, + %r = select <2 x i1> %cmp1, <2 x float> , <2 x float> %min + ret <2 x float> %r +} + ; (X <= C1) ? C1 : MIN(X, C2) define float @clamp_float_fast_ordered_nonstrict_maxmin(float %x) { ; CHECK-LABEL: define {{[^@]+}}@clamp_float_fast_ordered_nonstrict_maxmin( diff --git a/llvm/test/Transforms/InstSimplify/fcmp-select.ll b/llvm/test/Transforms/InstSimplify/fcmp-select.ll --- a/llvm/test/Transforms/InstSimplify/fcmp-select.ll +++ b/llvm/test/Transforms/InstSimplify/fcmp-select.ll @@ -12,6 +12,17 @@ ret double %cond } +; X == <4.0, 2.0, undef> ? X : <4.0, 2.0, undef> --> <4.0, 2.0, undef> + +define <3 x double> @oeq_vec(<3 x double> %x) { +; CHECK-LABEL: @oeq_vec( +; CHECK-NEXT: ret <3 x double> +; + %cmp = fcmp oeq <3 x double> %x, + %cond = select <3 x i1> %cmp, <3 x double> %x, <3 x double> + ret <3 x double> %cond +} + ; X == 42.0 ? 42.0 : X --> X define float @oeq_swapped(float %x) {