[llvm] bd4fe78 - InstCombine: Fix wrong insert point for various fmul->copysign simplifies (#180840)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 11 00:14:59 PST 2026
Author: Matt Arsenault
Date: 2026-02-11T09:14:55+01:00
New Revision: bd4fe78c84103564732e67ed32eeebb17843ea0e
URL: https://github.com/llvm/llvm-project/commit/bd4fe78c84103564732e67ed32eeebb17843ea0e
DIFF: https://github.com/llvm/llvm-project/commit/bd4fe78c84103564732e67ed32eeebb17843ea0e.diff
LOG: InstCombine: Fix wrong insert point for various fmul->copysign simplifies (#180840)
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index bc5bdcca08ab2..ec59aa7314963 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2554,6 +2554,9 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
// 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 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
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 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
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 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
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 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
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 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
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 90ca307b20ffa..57ca1a9db2ddf 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 @@ define nofpclass(nsub) float @ret__known_pzero_or_nan__fmul__not_inf_or_nan(floa
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 @@ define nofpclass(nsub) float @ret__not_inf_or_nan__fmul__known_pzero_or_nan(floa
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 @@ define nofpclass(nsub) float @ret__known_inf_or_nan__fmul__known_negative_non0(f
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 @@ define nofpclass(nsub) float @ret__known_negative_non0__fmul__known_inf_or_nan(f
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 @@ define nofpclass(nan) float @ret_no_nan__fmul_nzero__unknown(float %unknown) {
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 @@ define nofpclass(snan) float @known__nzero_or_nan__fmul__not_inf_or_nan(float no
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(
More information about the llvm-commits
mailing list