llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-llvm-transforms Author: Matt Arsenault (arsenm) <details> <summary>Changes</summary> Consider if the result can be nan, or if the inputs cannot be infinity from the flag when trying to simplify fmul into copysign. --- Full diff: https://github.com/llvm/llvm-project/pull/174024.diff 2 Files Affected: - (modified) llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (+18-6) - (modified) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll (+18-12) ``````````diff diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 0b5854f169440..73cddec73c45b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -2061,11 +2061,16 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V, if (!I->hasOneUse()) return nullptr; + bool NoInfsFlag = false; + if (auto *FPOp = dyn_cast<FPMathOperator>(I)) { if (FPOp->hasNoNaNs()) DemandedMask &= ~fcNan; - if (FPOp->hasNoInfs()) + + if (FPOp->hasNoInfs()) { DemandedMask &= ~fcInf; + NoInfsFlag = true; + } } switch (I->getOpcode()) { case Instruction::FNeg: { @@ -2355,8 +2360,15 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V, KnownRHS.knownNot(fcNan); } - // TODO: Apply knowledge of no-infinity returns to sources. - if (KnownLHS.isKnownNeverInfOrNaN() && + if (NoInfsFlag) { + // Flag implies inputs cannot be infinity. + KnownLHS.knownNot(fcInf); + KnownRHS.knownNot(fcInf); + } + + bool NonNanResult = (DemandedMask & fcNan) == fcNone; + + if ((NonNanResult || KnownLHS.isKnownNeverInfOrNaN()) && KnownRHS.isKnownAlways(fcPosZero | fcNan)) { // => copysign(+0, lhs) // Note: Dropping canonicalize @@ -2366,7 +2378,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V, } if (KnownLHS.isKnownAlways(fcPosZero | fcNan) && - KnownRHS.isKnownNeverInfOrNaN()) { + (NonNanResult || KnownRHS.isKnownNeverInfOrNaN())) { // => copysign(+0, rhs) // Note: Dropping canonicalize Value *Copysign = Builder.CreateCopySign(X, Y); @@ -2374,7 +2386,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V, return Copysign; } - if (KnownLHS.isKnownNeverInfOrNaN() && + if ((NonNanResult || KnownLHS.isKnownNeverInfOrNaN()) && KnownRHS.isKnownAlways(fcNegZero | fcNan)) { // => copysign(0, fneg(lhs)) // Note: Dropping canonicalize @@ -2384,7 +2396,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V, } if (KnownLHS.isKnownAlways(fcNegZero | fcNan) && - KnownRHS.isKnownNeverInfOrNaN()) { + (NonNanResult || KnownRHS.isKnownNeverInfOrNaN())) { // => copysign(+0, fneg(rhs)) // Note: Dropping canonicalize Value *Copysign = Builder.CreateCopySign(X, Builder.CreateFNegFMF(Y, I)); diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll index cb83fdc3e7a6b..b81a8bc162546 100644 --- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll +++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll @@ -609,7 +609,7 @@ define nofpclass(nan) float @ret_no_nan_result__known_negative_non0__fmul__known define nofpclass(inf nan) float @ret_noinf_nonan__known_pzero_or_nan__fmul__not_inf_or_nan(float nofpclass(inf sub norm nzero) %pzero.or.nan, float %unknown) { ; CHECK-LABEL: define nofpclass(nan inf) float @ret_noinf_nonan__known_pzero_or_nan__fmul__not_inf_or_nan( ; CHECK-SAME: float nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], float [[UNKNOWN:%.*]]) { -; CHECK-NEXT: [[MUL:%.*]] = fmul float [[UNKNOWN]], 0.000000e+00 +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[UNKNOWN]]) ; CHECK-NEXT: ret float [[MUL]] ; %mul = fmul float %pzero.or.nan, %unknown @@ -620,7 +620,7 @@ define nofpclass(inf nan) float @ret_noinf_nonan__known_pzero_or_nan__fmul__not_ define nofpclass(inf nan) float @ret_noinf_nonan__not_inf_or_nan__fmul__known_pzero_or_nan(float nofpclass(inf sub norm nzero) %pzero.or.nan, float %unknown) { ; CHECK-LABEL: define nofpclass(nan inf) float @ret_noinf_nonan__not_inf_or_nan__fmul__known_pzero_or_nan( ; CHECK-SAME: float nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], float [[UNKNOWN:%.*]]) { -; CHECK-NEXT: [[MUL:%.*]] = fmul float [[UNKNOWN]], 0.000000e+00 +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[UNKNOWN]]) ; CHECK-NEXT: ret float [[MUL]] ; %mul = fmul float %pzero.or.nan, %unknown @@ -869,7 +869,7 @@ define nofpclass(nan) float @ret_no_nan__fmul_pzero__unknown(float %unknown) { ; CHECK-LABEL: define nofpclass(nan) float @ret_no_nan__fmul_pzero__unknown( ; CHECK-SAME: float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[PZERO:%.*]] = call float @returns_pzero() -; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[UNKNOWN]], 0.000000e+00 +; CHECK-NEXT: [[FMUL:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[UNKNOWN]]) ; CHECK-NEXT: ret float [[FMUL]] ; %pzero = call float @returns_pzero() @@ -881,7 +881,7 @@ define nofpclass(nan) float @ret_no_nan__fmul_unknown__pzero(float %unknown) { ; CHECK-LABEL: define nofpclass(nan) float @ret_no_nan__fmul_unknown__pzero( ; CHECK-SAME: float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[PZERO:%.*]] = call float @returns_pzero() -; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[UNKNOWN]], 0.000000e+00 +; CHECK-NEXT: [[FMUL:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[UNKNOWN]]) ; CHECK-NEXT: ret float [[FMUL]] ; %pzero = call float @returns_pzero() @@ -893,7 +893,8 @@ define nofpclass(nan) float @ret_no_nan__fmul_nzero__unknown(float %unknown) { ; CHECK-LABEL: define nofpclass(nan) float @ret_no_nan__fmul_nzero__unknown( ; CHECK-SAME: float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[NZERO:%.*]] = call float @returns_nzero() -; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[UNKNOWN]], -0.000000e+00 +; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[UNKNOWN]] +; CHECK-NEXT: [[FMUL:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]]) ; CHECK-NEXT: ret float [[FMUL]] ; %nzero = call float @returns_nzero() @@ -905,7 +906,8 @@ define nofpclass(nan) float @ret_no_nan__fmul_unknown__nzero(float %unknown) { ; CHECK-LABEL: define nofpclass(nan) float @ret_no_nan__fmul_unknown__nzero( ; CHECK-SAME: float [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[NZERO:%.*]] = call float @returns_nzero() -; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[UNKNOWN]], -0.000000e+00 +; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[UNKNOWN]] +; CHECK-NEXT: [[FMUL:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]]) ; CHECK-NEXT: ret float [[FMUL]] ; %nzero = call float @returns_nzero() @@ -1031,7 +1033,8 @@ define nofpclass(inf) float @ret_noinf__not_inf_or_nan__fmul__nzero_or_nan(float define nofpclass(nan) float @ret_nonan__nzero_or_nan__fmul__not_inf_or_nan(float nofpclass(inf sub norm pzero) %nzero.or.nan, float nofpclass(nan) %not.nan) { ; CHECK-LABEL: define nofpclass(nan) float @ret_nonan__nzero_or_nan__fmul__not_inf_or_nan( ; CHECK-SAME: float nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) { -; CHECK-NEXT: [[MUL:%.*]] = fmul float [[NOT_NAN]], -0.000000e+00 +; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[NOT_NAN]] +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]]) ; CHECK-NEXT: ret float [[MUL]] ; %mul = fmul float %nzero.or.nan, %not.nan @@ -1042,7 +1045,8 @@ define nofpclass(nan) float @ret_nonan__nzero_or_nan__fmul__not_inf_or_nan(float define nofpclass(nan) float @ret_nonan__not_inf_or_nan__fmul__nzero_or_nan(float nofpclass(nan) %not.nan, float nofpclass(inf sub norm pzero) %nzero.or.nan) { ; CHECK-LABEL: define nofpclass(nan) float @ret_nonan__not_inf_or_nan__fmul__nzero_or_nan( ; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]], float nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) { -; CHECK-NEXT: [[MUL:%.*]] = fmul float [[NOT_NAN]], -0.000000e+00 +; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[NOT_NAN]] +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]]) ; CHECK-NEXT: ret float [[MUL]] ; %mul = fmul float %not.nan, %nzero.or.nan @@ -1053,7 +1057,8 @@ define nofpclass(nan) float @ret_nonan__not_inf_or_nan__fmul__nzero_or_nan(float define nofpclass(snan) float @ret__nzero_or_nan__fmul_ninf__not_inf_or_nan(float nofpclass(inf sub norm pzero) %nzero.or.nan, float nofpclass(nan) %not.nan) { ; CHECK-LABEL: define nofpclass(snan) float @ret__nzero_or_nan__fmul_ninf__not_inf_or_nan( ; CHECK-SAME: float nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) { -; CHECK-NEXT: [[MUL:%.*]] = fmul ninf float [[NZERO_OR_NAN]], [[NOT_NAN]] +; CHECK-NEXT: [[TMP1:%.*]] = fneg ninf float [[NOT_NAN]] +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float [[NZERO_OR_NAN]], float [[TMP1]]) ; CHECK-NEXT: ret float [[MUL]] ; %mul = fmul ninf float %nzero.or.nan, %not.nan @@ -1064,7 +1069,8 @@ define nofpclass(snan) float @ret__nzero_or_nan__fmul_ninf__not_inf_or_nan(float define nofpclass(snan) float @ret_not_inf_or_nan__fmul_ninf__nzero_or_nan(float nofpclass(nan) %not.nan, float nofpclass(inf sub norm pzero) %nzero.or.nan) { ; CHECK-LABEL: define nofpclass(snan) float @ret_not_inf_or_nan__fmul_ninf__nzero_or_nan( ; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]], float nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) { -; CHECK-NEXT: [[MUL:%.*]] = fmul ninf float [[NOT_NAN]], [[NZERO_OR_NAN]] +; CHECK-NEXT: [[TMP1:%.*]] = fneg ninf float [[NOT_NAN]] +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float [[NZERO_OR_NAN]], float [[TMP1]]) ; CHECK-NEXT: ret float [[MUL]] ; %mul = fmul ninf float %not.nan, %nzero.or.nan @@ -1187,7 +1193,7 @@ define nofpclass(inf) float @ret_noinf__not_inf_or_nan__fmul__pzero_or_nan(float define nofpclass(snan) float @ret__pzero_or_nan__fmul_ninf__not_inf_or_nan(float nofpclass(inf sub norm nzero) %pzero.or.nan, float nofpclass(nan) %not.nan) { ; CHECK-LABEL: define nofpclass(snan) float @ret__pzero_or_nan__fmul_ninf__not_inf_or_nan( ; CHECK-SAME: float nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) { -; CHECK-NEXT: [[MUL:%.*]] = fmul ninf float [[PZERO_OR_NAN]], [[NOT_NAN]] +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float [[PZERO_OR_NAN]], float [[NOT_NAN]]) ; CHECK-NEXT: ret float [[MUL]] ; %mul = fmul ninf float %pzero.or.nan, %not.nan @@ -1198,7 +1204,7 @@ define nofpclass(snan) float @ret__pzero_or_nan__fmul_ninf__not_inf_or_nan(float define nofpclass(snan) float @ret_not_inf_or_nan__fmul_ninf__pzero_or_nan(float nofpclass(nan) %not.nan, float nofpclass(inf sub norm nzero) %pzero.or.nan) { ; CHECK-LABEL: define nofpclass(snan) float @ret_not_inf_or_nan__fmul_ninf__pzero_or_nan( ; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]], float nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) { -; CHECK-NEXT: [[MUL:%.*]] = fmul ninf float [[NOT_NAN]], [[PZERO_OR_NAN]] +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float [[PZERO_OR_NAN]], float [[NOT_NAN]]) ; CHECK-NEXT: ret float [[MUL]] ; %mul = fmul ninf float %not.nan, %pzero.or.nan `````````` </details> https://github.com/llvm/llvm-project/pull/174024 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
