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(