InstCombine: Fix wrong insert point for various fmul->copysign simplifies (#180840)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index bc5bdcc..ec59aa7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2554,6 +2554,9 @@ // X * -0.0 --> copysign(0.0, -X) if ((NonNanResult || KnownLHS.isKnownNeverInfOrNaN()) && KnownRHS.isKnownAlways(fcPosZero | fcNan)) { + IRBuilderBase::InsertPointGuard Guard(Builder); + Builder.SetInsertPoint(I); + // => copysign(+0, lhs) // Note: Dropping canonicalize Value *Copysign = Builder.CreateCopySign(Y, X, FMF); @@ -2563,6 +2566,9 @@ if (KnownLHS.isKnownAlways(fcPosZero | fcNan) && (NonNanResult || KnownRHS.isKnownNeverInfOrNaN())) { + IRBuilderBase::InsertPointGuard Guard(Builder); + Builder.SetInsertPoint(I); + // => copysign(+0, rhs) // Note: Dropping canonicalize Value *Copysign = Builder.CreateCopySign(X, Y, FMF); @@ -2572,6 +2578,9 @@ if ((NonNanResult || KnownLHS.isKnownNeverInfOrNaN()) && KnownRHS.isKnownAlways(fcNegZero | fcNan)) { + IRBuilderBase::InsertPointGuard Guard(Builder); + Builder.SetInsertPoint(I); + // => copysign(0, fneg(lhs)) // Note: Dropping canonicalize Value *Copysign = @@ -2582,6 +2591,9 @@ if (KnownLHS.isKnownAlways(fcNegZero | fcNan) && (NonNanResult || KnownRHS.isKnownNeverInfOrNaN())) { + IRBuilderBase::InsertPointGuard Guard(Builder); + Builder.SetInsertPoint(I); + // => copysign(+0, fneg(rhs)) // Note: Dropping canonicalize Value *Copysign = @@ -2596,6 +2608,9 @@ if (KnownLHS.isKnownAlways(fcInf | fcNan) && (KnownRHS.isKnownNeverNaN() && KnownRHS.cannotBeOrderedGreaterEqZero(Mode))) { + IRBuilderBase::InsertPointGuard Guard(Builder); + Builder.SetInsertPoint(I); + // Note: Dropping canonicalize Value *Neg = Builder.CreateFNegFMF(X, FMF); Neg->takeName(I); @@ -2605,6 +2620,9 @@ if (KnownRHS.isKnownAlways(fcInf | fcNan) && (KnownLHS.isKnownNeverNaN() && KnownLHS.cannotBeOrderedGreaterEqZero(Mode))) { + IRBuilderBase::InsertPointGuard Guard(Builder); + Builder.SetInsertPoint(I); + // Note: Dropping canonicalize Value *Neg = Builder.CreateFNegFMF(Y, FMF); Neg->takeName(I);
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll index 90ca307..57ca1a9 100644 --- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll +++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
@@ -532,6 +532,18 @@ ret float %mul } +define nofpclass(nsub) float @ret__known_pzero_or_nan__fmul__not_inf_or_nan__insert_point(float nofpclass(inf sub norm nzero) %pzero.or.nan, float nofpclass(inf nan) %not.inf.or.nan) { +; CHECK-LABEL: define nofpclass(nsub) float @ret__known_pzero_or_nan__fmul__not_inf_or_nan__insert_point( +; CHECK-SAME: float nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], float nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]]) { +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float [[PZERO_OR_NAN]], float [[NOT_INF_OR_NAN]]) +; CHECK-NEXT: [[BARRIER:%.*]] = call float @llvm.arithmetic.fence.f32(float [[MUL]]) +; CHECK-NEXT: ret float [[BARRIER]] +; + %mul = fmul float %pzero.or.nan, %not.inf.or.nan + %barrier = call float @llvm.arithmetic.fence.f32(float %mul) + ret float %barrier +} + ; missing nnan lhs define nofpclass(nsub) float @ret__not_inf__fmul__known_pzero_or_nan(float nofpclass(inf) %not.inf, float nofpclass(inf sub norm nzero) %pzero.or.nan) { ; CHECK-LABEL: define nofpclass(nsub) float @ret__not_inf__fmul__known_pzero_or_nan( @@ -554,6 +566,18 @@ ret float %mul } +define nofpclass(nsub) float @ret__not_inf_or_nan__fmul__known_pzero_or_nan__insert_point(float nofpclass(inf nan) %not.inf.or.nan, float nofpclass(inf sub norm nzero) %pzero.or.nan) { +; CHECK-LABEL: define nofpclass(nsub) float @ret__not_inf_or_nan__fmul__known_pzero_or_nan__insert_point( +; CHECK-SAME: float nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]], float nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) { +; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float [[PZERO_OR_NAN]], float [[NOT_INF_OR_NAN]]) +; CHECK-NEXT: [[BARRIER:%.*]] = call float @llvm.arithmetic.fence.f32(float [[MUL]]) +; CHECK-NEXT: ret float [[BARRIER]] +; + %mul = fmul float %not.inf.or.nan, %pzero.or.nan + %barrier = call float @llvm.arithmetic.fence.f32(float %mul) + ret float %barrier +} + ; Missing no-nan on RHS to turn into fneg define nofpclass(nsub) float @ret__known_inf_or_nan__fmul__known_negative_non0_or_nan(float nofpclass(zero sub norm) %inf.or.nan, float nofpclass(zero pinf pnorm psub) %negative.non0.or.nan) { ; CHECK-LABEL: define nofpclass(nsub) float @ret__known_inf_or_nan__fmul__known_negative_non0_or_nan( @@ -587,6 +611,18 @@ ret float %mul } +define nofpclass(nsub) float @ret__known_inf_or_nan__fmul__known_negative_non0__insert_point(float nofpclass(zero sub norm) %inf.or.nan, float nofpclass(nan zero pinf pnorm psub) %negative.non0) { +; CHECK-LABEL: define nofpclass(nsub) float @ret__known_inf_or_nan__fmul__known_negative_non0__insert_point( +; CHECK-SAME: float nofpclass(zero sub norm) [[INF_OR_NAN:%.*]], float nofpclass(nan pinf zero psub pnorm) [[NEGATIVE_NON0:%.*]]) { +; CHECK-NEXT: [[MUL:%.*]] = fneg float [[INF_OR_NAN]] +; CHECK-NEXT: [[BARRIER:%.*]] = call float @llvm.arithmetic.fence.f32(float [[MUL]]) +; CHECK-NEXT: ret float [[BARRIER]] +; + %mul = fmul float %inf.or.nan, %negative.non0 + %barrier = call float @llvm.arithmetic.fence.f32(float %mul) + ret float %barrier +} + ; -> fneg define nofpclass(nsub) float @ret__known_negative_non0__fmul__known_inf_or_nan(float nofpclass(nan zero pinf pnorm psub) %negative.non0, float nofpclass(zero sub norm) %inf.or.nan) { ; CHECK-LABEL: define nofpclass(nsub) float @ret__known_negative_non0__fmul__known_inf_or_nan( @@ -598,6 +634,18 @@ ret float %mul } +define nofpclass(nsub) float @ret__known_negative_non0__fmul__known_inf_or_nan__insert_pt(float nofpclass(nan zero pinf pnorm psub) %negative.non0, float nofpclass(zero sub norm) %inf.or.nan) { +; CHECK-LABEL: define nofpclass(nsub) float @ret__known_negative_non0__fmul__known_inf_or_nan__insert_pt( +; CHECK-SAME: float nofpclass(nan pinf zero psub pnorm) [[NEGATIVE_NON0:%.*]], float nofpclass(zero sub norm) [[INF_OR_NAN:%.*]]) { +; CHECK-NEXT: [[MUL:%.*]] = fneg float [[INF_OR_NAN]] +; CHECK-NEXT: [[BARRIER:%.*]] = call float @llvm.arithmetic.fence.f32(float [[MUL]]) +; CHECK-NEXT: ret float [[BARRIER]] +; + %mul = fmul float %negative.non0, %inf.or.nan + %barrier = call float @llvm.arithmetic.fence.f32(float %mul) + ret float %barrier +} + ; Cannot fold to fneg due to possible nsub input define nofpclass(nsub) float @ret__known_inf_or_nan__fmul__known_negative_non0__daz(float nofpclass(zero sub norm) %inf.or.nan, float nofpclass(nan zero pinf pnorm psub) %negative.non0) #1 { ; CHECK-LABEL: define nofpclass(nsub) float @ret__known_inf_or_nan__fmul__known_negative_non0__daz( @@ -982,6 +1030,21 @@ ret float %fmul } +define nofpclass(nan) float @ret_no_nan__fmul_nzero__unknown_insert_point(float %unknown) { +; CHECK-LABEL: define nofpclass(nan) float @ret_no_nan__fmul_nzero__unknown_insert_point( +; CHECK-SAME: float [[UNKNOWN:%.*]]) { +; CHECK-NEXT: [[NZERO:%.*]] = call float @returns_nzero() +; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[UNKNOWN]] +; CHECK-NEXT: [[FMUL:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]]) +; CHECK-NEXT: [[BARRIER:%.*]] = call float @llvm.arithmetic.fence.f32(float [[FMUL]]) +; CHECK-NEXT: ret float [[BARRIER]] +; + %nzero = call float @returns_nzero() + %fmul = fmul float %nzero, %unknown + %barrier =call float @llvm.arithmetic.fence.f32(float %fmul) + ret float %barrier +} + 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:%.*]]) { @@ -1031,6 +1094,19 @@ ret float %mul } +define nofpclass(snan) float @known__nzero_or_nan__fmul__not_inf_or_nan__insert_point(float nofpclass(inf sub norm pzero) %nzero.or.nan, float nofpclass(inf nan) %not.inf.or.nan) { +; CHECK-LABEL: define nofpclass(snan) float @known__nzero_or_nan__fmul__not_inf_or_nan__insert_point( +; CHECK-SAME: float nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], float nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[NOT_INF_OR_NAN]] +; CHECK-NEXT: [[MUL:%.*]] = call contract float @llvm.copysign.f32(float [[NZERO_OR_NAN]], float [[TMP1]]) +; CHECK-NEXT: [[BARRIER:%.*]] = call float @llvm.arithmetic.fence.f32(float [[MUL]]) +; CHECK-NEXT: ret float [[BARRIER]] +; + %mul = fmul contract float %nzero.or.nan, %not.inf.or.nan + %barrier = call float @llvm.arithmetic.fence.f32(float %mul) + ret float %barrier +} + ; -> copysign + fneg define nofpclass(snan) float @known__not_inf_or_nan__fmul__nzero_or_nan(float nofpclass(inf nan) %not.inf.or.nan, float nofpclass(inf sub norm pzero) %nzero.or.nan) { ; CHECK-LABEL: define nofpclass(snan) float @known__not_inf_or_nan__fmul__nzero_or_nan(