[llvm] [ValueTracking] Propagate sign information out of loop (PR #175590)
Kshitij Paranjape via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 29 07:50:25 PST 2026
https://github.com/kshitijvp updated https://github.com/llvm/llvm-project/pull/175590
>From 6cc88734604fb7aeca93cce1d24c2c73fe1dd4f5 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Mon, 12 Jan 2026 22:20:27 +0530
Subject: [PATCH 01/17] [AggressiveInstCombine] Propogate sign information out
of loop
LLVM converts sqrt libcall to intrinsic call if the argument
is within the range(greater than or equal to 0.0). In this case
the compiler is not able to deduce the non-negativity on
its own. Extended ValueTracking to understand such loops.
Fixes llvm/llvm-project#174813
---
llvm/lib/Analysis/ValueTracking.cpp | 20 +++++++-
.../libcalltointrinsic.ll | 48 +++++++++++++++++++
2 files changed, 67 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Transforms/AggressiveInstCombine/libcalltointrinsic.ll
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index dbb44c8828545..65822a62c6f3d 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5953,7 +5953,25 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
// Unreachable blocks may have zero-operand PHI nodes.
if (P->getNumIncomingValues() == 0)
break;
-
+ // Look for the case of a for loop which has a positive
+ // initial value and is incremented by a squared value.
+ // This will propogate sign information out of such loops.
+ if (P->getNumIncomingValues() == 2) {
+ Value *Start = P->getIncomingValue(0);
+ Value *RecurValue = P->getIncomingValue(1);
+ Value *X;
+ if (match(RecurValue,
+ m_Intrinsic<Intrinsic::fmuladd>(m_Value(X), m_Value(X), m_Specific(P)))) {
+ KnownFPClass KnownStart;
+ computeKnownFPClass(Start, DemandedElts,
+ KnownFPClass::OrderedLessThanZeroMask, KnownStart,
+ Q, Depth + 1);
+ if (KnownStart.cannotBeOrderedLessThanZero()) {
+ Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ }
+ break;
+ }
+ }
// Otherwise take the unions of the known bit sets of the operands,
// taking conservative care to avoid excessive recursion.
const unsigned PhiRecursionLimit = MaxAnalysisRecursionDepth - 2;
diff --git a/llvm/test/Transforms/AggressiveInstCombine/libcalltointrinsic.ll b/llvm/test/Transforms/AggressiveInstCombine/libcalltointrinsic.ll
new file mode 100644
index 0000000000000..a734abb6727e3
--- /dev/null
+++ b/llvm/test/Transforms/AggressiveInstCombine/libcalltointrinsic.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define dso_local noundef double @CompareDistmats(ptr noundef %distmat1, ptr noundef %distmat2) local_unnamed_addr {
+; CHECK-LABEL: @CompareDistmats(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[FOR_BODY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[ENTRY]] ], [ false, [[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
+; CHECK: for.cond.cleanup:
+; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[RMSD_0]])
+; CHECK-NEXT: ret double [[SQRT]]
+; CHECK: for.body:
+; CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[DISTMAT1:%.*]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[DISTMAT2:%.*]], align 8
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[TMP0]], [[TMP1]]
+; CHECK-NEXT: [[TMP2]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: br label [[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %2, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %0 = load double, ptr %distmat1, align 8
+ %1 = load double, ptr %distmat2, align 8
+ %sub = fsub double %0, %1
+ %2 = call double @llvm.fmuladd.f64(double %sub, double %sub, double %RMSD.0)
+ br label %for.cond
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn memory(write)
+declare double @sqrt(double noundef) local_unnamed_addr
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare double @llvm.fmuladd.f64(double, double, double)
>From a308a16c5505b0e8f4cafff3da0432a5c8104baf Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 00:33:51 +0530
Subject: [PATCH 02/17] Added simple recurrence pattern matcher for ternary
intrinsics
Added functions to match simple recurrence patterns in case
of ternary intrinsics as it was supported only for binary
intrinsics currently. Used the matchSimpleTernaryRecurrence
to match the specific case of for loop in which initial value
is zero and is being incremented by a squared-value. Shifted
the tests to X86 subdirectory and also added negative test
in the case when it is not being incremented by a
squared-value.
---
llvm/include/llvm/Analysis/ValueTracking.h | 4 +
llvm/lib/Analysis/ValueTracking.cpp | 84 +++++++++++++++----
.../AggressiveInstCombine/X86/pr175590.ll | 45 ++++++++++
.../libcalltointrinsic.ll | 48 -----------
4 files changed, 119 insertions(+), 62 deletions(-)
create mode 100644 llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
delete mode 100644 llvm/test/Transforms/AggressiveInstCombine/libcalltointrinsic.ll
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 2ce49c558b241..62ff63e2bfb5c 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -1006,6 +1006,10 @@ LLVM_ABI bool matchSimpleBinaryIntrinsicRecurrence(const IntrinsicInst *I,
/// T | T | F
/// F | T | T
/// (A)
+LLVM_ABI bool matchSimpleTernaryIntrinsicRecurrence(const IntrinsicInst *I,
+ PHINode *&P, Value *&Init,
+ Value *&OtherOp0,
+ Value *&OtherOp1);
LLVM_ABI std::optional<bool>
isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL,
bool LHSIsTrue = true, unsigned Depth = 0);
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 65822a62c6f3d..557d2f407a7ee 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1771,7 +1771,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
const PHINode *P = cast<PHINode>(I);
BinaryOperator *BO = nullptr;
Value *R = nullptr, *L = nullptr;
- if (matchSimpleRecurrence(P, BO, R, L)) {
+ if (llvm::matchSimpleRecurrence(P, BO, R, L)) {
// Handle the case of a simple two-predecessor recurrence PHI.
// There's a lot more that could theoretically be done here, but
// this is sufficient to catch some interesting cases.
@@ -5955,21 +5955,26 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
break;
// Look for the case of a for loop which has a positive
// initial value and is incremented by a squared value.
- // This will propogate sign information out of such loops.
+ // This will propagate sign information out of such loops.
if (P->getNumIncomingValues() == 2) {
- Value *Start = P->getIncomingValue(0);
Value *RecurValue = P->getIncomingValue(1);
- Value *X;
- if (match(RecurValue,
- m_Intrinsic<Intrinsic::fmuladd>(m_Value(X), m_Value(X), m_Specific(P)))) {
- KnownFPClass KnownStart;
- computeKnownFPClass(Start, DemandedElts,
- KnownFPClass::OrderedLessThanZeroMask, KnownStart,
- Q, Depth + 1);
- if (KnownStart.cannotBeOrderedLessThanZero()) {
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ IntrinsicInst* I = dyn_cast<IntrinsicInst>(RecurValue);
+ Value *R, *L;
+ Value *Init;
+ PHINode *PN;
+ if (matchSimpleTernaryIntrinsicRecurrence(I, PN, Init, L, R)) {
+ switch(I->getIntrinsicID()) {
+ case Intrinsic::fmuladd: {
+ KnownFPClass KnownStart;
+ computeKnownFPClass(Init, DemandedElts,
+ KnownFPClass::OrderedGreaterThanZeroMask, KnownStart,
+ Q, Depth + 1 );
+ if (KnownStart.cannotBeOrderedLessThanZero() && R == L) {
+ Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ }
+ break;
+ }
}
- break;
}
}
// Otherwise take the unions of the known bit sets of the operands,
@@ -9288,6 +9293,40 @@ static bool matchTwoInputRecurrence(const PHINode *PN, InstTy *&Inst,
return false;
}
+template <typename InstTy>
+static bool matchThreeInputRecurrence(const PHINode *PN, InstTy *&Inst,
+ Value *&Init, Value *&OtherOp0,
+ Value *&OtherOp1) {
+ if (PN->getNumIncomingValues() != 2)
+ return false;
+
+ for (unsigned I = 0; I != 3; ++I) {
+ if (auto *Operation = dyn_cast<InstTy>(PN->getIncomingValue(I));
+ Operation) {
+ Value *Op0 = Operation->getOperand(0);
+ Value *Op1 = Operation->getOperand(1);
+ Value *Op2 = Operation->getOperand(2);
+
+ if (Op0 != PN && Op1 != PN && Op2 != PN)
+ continue;
+
+ Inst = Operation;
+ Init = PN->getIncomingValue(!I);
+ if (Op0 == PN) {
+ OtherOp0 = Op1;
+ OtherOp1 = Op2;
+ } else if (Op1 == PN) {
+ OtherOp0 = Op0;
+ OtherOp1 = Op2;
+ } else {
+ OtherOp0 = Op0;
+ OtherOp1 = Op1;
+ }
+ return true;
+ }
+ }
+ return false;
+}
bool llvm::matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO,
Value *&Start, Value *&Step) {
// We try to match a recurrence of the form:
@@ -9324,6 +9363,23 @@ bool llvm::matchSimpleBinaryIntrinsicRecurrence(const IntrinsicInst *I,
return P && matchTwoInputRecurrence(P, II, Init, OtherOp) && II == I;
}
+bool llvm::matchSimpleTernaryIntrinsicRecurrence(const IntrinsicInst *I,
+ PHINode *&P, Value *&Init,
+ Value *&OtherOp0, Value*&OtherOp1) {
+ if (I->arg_size() != 3 || I->getType() != I->getArgOperand(0)->getType() ||
+ I->getType() != I->getArgOperand(1)->getType() ||
+ I->getType() != I->getArgOperand(2)->getType())
+ return false;
+ IntrinsicInst *II = nullptr;
+ P = dyn_cast<PHINode>(I->getArgOperand(0));
+ if (!P) {
+ P = dyn_cast<PHINode>(I->getArgOperand(1));
+ if (!P)
+ P = dyn_cast<PHINode>(I->getArgOperand(2));
+ }
+ return P && matchThreeInputRecurrence(P, II, Init, OtherOp0, OtherOp1) && II == I;
+}
+
/// Return true if "icmp Pred LHS RHS" is always true.
static bool isTruePredicate(CmpInst::Predicate Pred, const Value *LHS,
const Value *RHS) {
@@ -10560,4 +10616,4 @@ bool llvm::collectPossibleValues(const Value *V,
}
}
return true;
-}
+}
\ No newline at end of file
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
new file mode 100644
index 0000000000000..c504762af8cae
--- /dev/null
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
+target triple = "x86_64-unknown-linux-gnu"
+define dso_local noundef double @CompareDistmats(double noundef %distmat1_, double noundef %distmat2_) local_unnamed_addr #0 {
+; CHECK-LABEL: define dso_local noundef double @CompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[TMP0:%.*]] = tail call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double 0.000000e+00)
+; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[TMP0]])
+; CHECK-NEXT: ret double [[SQRT]]
+;
+entry:
+ %sub = fsub double %distmat1_, %distmat2_
+ %fmacall = tail call double @llvm.fmuladd.f64(double %sub, double %sub, double 0.000000e+00)
+ %call = tail call double @sqrt(double noundef %fmacall) #3
+ ret double %call
+}
+
+define dso_local noundef double @nonSquareCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) local_unnamed_addr #0 {
+; CHECK-LABEL: define dso_local noundef double @nonSquareCompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) local_unnamed_addr #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[ADD:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL:%.*]] = tail call double @llvm.fmuladd.f64(double [[SUB]], double [[ADD]], double 0.000000e+00)
+; CHECK-NEXT: [[CALL:%.*]] = tail call double @sqrt(double noundef [[FMACALL]]) #[[ATTR3:[0-9]+]]
+; CHECK-NEXT: ret double [[CALL]]
+;
+entry:
+ %sub = fsub double %distmat1_, %distmat2_
+ %add = fsub double %distmat1_, %distmat2_
+ %fmacall = tail call double @llvm.fmuladd.f64(double %sub, double %add, double 0.000000e+00)
+ %call = tail call double @sqrt(double noundef %fmacall) #3
+ ret double %call
+}
+
+declare double @llvm.fmuladd.f64(double, double, double) #1
+
+declare double @sqrt(double noundef) local_unnamed_addr #2
+
+attributes #0 = { mustprogress nofree norecurse nounwind willreturn memory(errnomem: write) uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="znver3" "target-features"="+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdpru,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" }
+attributes #1 = { mustprogress nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #2 = { mustprogress nocallback nofree nounwind willreturn memory(errnomem: write) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="znver3" "target-features"="+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdpru,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" }
+attributes #3 = { nounwind }
diff --git a/llvm/test/Transforms/AggressiveInstCombine/libcalltointrinsic.ll b/llvm/test/Transforms/AggressiveInstCombine/libcalltointrinsic.ll
deleted file mode 100644
index a734abb6727e3..0000000000000
--- a/llvm/test/Transforms/AggressiveInstCombine/libcalltointrinsic.ll
+++ /dev/null
@@ -1,48 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
-target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
-define dso_local noundef double @CompareDistmats(ptr noundef %distmat1, ptr noundef %distmat2) local_unnamed_addr {
-; CHECK-LABEL: @CompareDistmats(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[FOR_COND:%.*]]
-; CHECK: for.cond:
-; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[FOR_BODY:%.*]] ]
-; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[ENTRY]] ], [ false, [[FOR_BODY]] ]
-; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
-; CHECK: for.cond.cleanup:
-; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[RMSD_0]])
-; CHECK-NEXT: ret double [[SQRT]]
-; CHECK: for.body:
-; CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[DISTMAT1:%.*]], align 8
-; CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[DISTMAT2:%.*]], align 8
-; CHECK-NEXT: [[SUB:%.*]] = fsub double [[TMP0]], [[TMP1]]
-; CHECK-NEXT: [[TMP2]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
-; CHECK-NEXT: br label [[FOR_COND]]
-;
-entry:
- br label %for.cond
-
-for.cond: ; preds = %for.body, %entry
- %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %2, %for.body ]
- %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
- br i1 %cmp, label %for.body, label %for.cond.cleanup
-
-for.cond.cleanup: ; preds = %for.cond
- %call = call double @sqrt(double noundef %RMSD.0)
- ret double %call
-
-for.body: ; preds = %for.cond
- %0 = load double, ptr %distmat1, align 8
- %1 = load double, ptr %distmat2, align 8
- %sub = fsub double %0, %1
- %2 = call double @llvm.fmuladd.f64(double %sub, double %sub, double %RMSD.0)
- br label %for.cond
-}
-
-; Function Attrs: mustprogress nofree nounwind willreturn memory(write)
-declare double @sqrt(double noundef) local_unnamed_addr
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none)
-declare double @llvm.fmuladd.f64(double, double, double)
>From c58a1bf2c3f10400cfee6d53191da3a264ba61e6 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 02:01:15 +0530
Subject: [PATCH 03/17] Check for null value after dyn_cast
---
llvm/lib/Analysis/ValueTracking.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 557d2f407a7ee..d4949f7551468 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5959,6 +5959,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
if (P->getNumIncomingValues() == 2) {
Value *RecurValue = P->getIncomingValue(1);
IntrinsicInst* I = dyn_cast<IntrinsicInst>(RecurValue);
+ if (!I)
+ break;
Value *R, *L;
Value *Init;
PHINode *PN;
>From cd2d10853921a7cd6b6376ff0944ba055d4d983c Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 12:16:09 +0530
Subject: [PATCH 04/17] Made necessary changes
---
llvm/include/llvm/Analysis/ValueTracking.h | 9 ++--
llvm/lib/Analysis/ValueTracking.cpp | 53 +++++++++----------
.../AggressiveInstCombine/X86/pr175590.ll | 8 +--
3 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 62ff63e2bfb5c..b31d46d94bf11 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -996,6 +996,11 @@ LLVM_ABI bool matchSimpleBinaryIntrinsicRecurrence(const IntrinsicInst *I,
PHINode *&P, Value *&Init,
Value *&OtherOp);
+LLVM_ABI bool matchSimpleTernaryIntrinsicRecurrence(const IntrinsicInst *I,
+ PHINode *&P, Value *&Init,
+ Value *&OtherOp0,
+ Value *&OtherOp1);
+
/// Return true if RHS is known to be implied true by LHS. Return false if
/// RHS is known to be implied false by LHS. Otherwise, return std::nullopt if
/// no implication can be made. A & B must be i1 (boolean) values or a vector of
@@ -1006,10 +1011,6 @@ LLVM_ABI bool matchSimpleBinaryIntrinsicRecurrence(const IntrinsicInst *I,
/// T | T | F
/// F | T | T
/// (A)
-LLVM_ABI bool matchSimpleTernaryIntrinsicRecurrence(const IntrinsicInst *I,
- PHINode *&P, Value *&Init,
- Value *&OtherOp0,
- Value *&OtherOp1);
LLVM_ABI std::optional<bool>
isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL,
bool LHSIsTrue = true, unsigned Depth = 0);
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d4949f7551468..c80ba3b360d02 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1771,7 +1771,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
const PHINode *P = cast<PHINode>(I);
BinaryOperator *BO = nullptr;
Value *R = nullptr, *L = nullptr;
- if (llvm::matchSimpleRecurrence(P, BO, R, L)) {
+ if (matchSimpleRecurrence(P, BO, R, L)) {
// Handle the case of a simple two-predecessor recurrence PHI.
// There's a lot more that could theoretically be done here, but
// this is sufficient to catch some interesting cases.
@@ -5953,32 +5953,6 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
// Unreachable blocks may have zero-operand PHI nodes.
if (P->getNumIncomingValues() == 0)
break;
- // Look for the case of a for loop which has a positive
- // initial value and is incremented by a squared value.
- // This will propagate sign information out of such loops.
- if (P->getNumIncomingValues() == 2) {
- Value *RecurValue = P->getIncomingValue(1);
- IntrinsicInst* I = dyn_cast<IntrinsicInst>(RecurValue);
- if (!I)
- break;
- Value *R, *L;
- Value *Init;
- PHINode *PN;
- if (matchSimpleTernaryIntrinsicRecurrence(I, PN, Init, L, R)) {
- switch(I->getIntrinsicID()) {
- case Intrinsic::fmuladd: {
- KnownFPClass KnownStart;
- computeKnownFPClass(Init, DemandedElts,
- KnownFPClass::OrderedGreaterThanZeroMask, KnownStart,
- Q, Depth + 1 );
- if (KnownStart.cannotBeOrderedLessThanZero() && R == L) {
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
- }
- break;
- }
- }
- }
- }
// Otherwise take the unions of the known bit sets of the operands,
// taking conservative care to avoid excessive recursion.
const unsigned PhiRecursionLimit = MaxAnalysisRecursionDepth - 2;
@@ -6018,6 +5992,31 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
}
}
+ // Look for the case of a for loop which has a positive
+ // initial value and is incremented by a squared value.
+ // This will propagate sign information out of such loops.
+ if (P->getNumIncomingValues() == 2) {
+ Value *RecurValue = P->getIncomingValue(1);
+ IntrinsicInst *I = dyn_cast<IntrinsicInst>(RecurValue);
+ if (!I)
+ break;
+ Value *R, *L;
+ Value *Init;
+ PHINode *PN;
+ if (matchSimpleTernaryIntrinsicRecurrence(I, PN, Init, L, R)) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::fmuladd: {
+ KnownFPClass KnownStart;
+ computeKnownFPClass(Init, DemandedElts,
+ KnownFPClass::OrderedGreaterThanZeroMask,
+ KnownStart, Q, Depth + 1);
+ if (KnownStart.cannotBeOrderedLessThanZero() && L == R)
+ Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ break;
+ }
+ }
+ }
+ }
break;
}
case Instruction::BitCast: {
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
index c504762af8cae..e0d8197e2d3ad 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
@@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
-define dso_local noundef double @CompareDistmats(double noundef %distmat1_, double noundef %distmat2_) local_unnamed_addr #0 {
-; CHECK-LABEL: define dso_local noundef double @CompareDistmats(
+define double @CompareDistmats(double noundef %distmat1_, double noundef %distmat2_) local_unnamed_addr #0 {
+; CHECK-LABEL: define double @CompareDistmats(
; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
@@ -17,8 +17,8 @@ entry:
ret double %call
}
-define dso_local noundef double @nonSquareCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) local_unnamed_addr #0 {
-; CHECK-LABEL: define dso_local noundef double @nonSquareCompareDistmats(
+define double @nonSquareCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) local_unnamed_addr #0 {
+; CHECK-LABEL: define double @nonSquareCompareDistmats(
; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) local_unnamed_addr #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
>From e21a9c934a5b4d59caa14abe4bb215d3036b48d7 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 12:28:30 +0530
Subject: [PATCH 05/17] Modified Tests
---
.../AggressiveInstCombine/X86/pr175590.ll | 89 +++++++++++++------
1 file changed, 61 insertions(+), 28 deletions(-)
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
index e0d8197e2d3ad..5eb3e44191389 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
@@ -1,45 +1,78 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
-define double @CompareDistmats(double noundef %distmat1_, double noundef %distmat2_) local_unnamed_addr #0 {
+define double @CompareDistmats(double %distmat1_, double %distmat2_) {
; CHECK-LABEL: define double @CompareDistmats(
-; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
-; CHECK-NEXT: [[TMP0:%.*]] = tail call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double 0.000000e+00)
-; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[TMP0]])
+; CHECK-SAME: double [[DISTMAT1_:%.*]], double [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[TMP0:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[RMSD_0]])
; CHECK-NEXT: ret double [[SQRT]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[TMP0]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: br label %[[FOR_COND]]
;
entry:
- %sub = fsub double %distmat1_, %distmat2_
- %fmacall = tail call double @llvm.fmuladd.f64(double %sub, double %sub, double 0.000000e+00)
- %call = tail call double @sqrt(double noundef %fmacall) #3
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %0, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %0 = call double @llvm.fmuladd.f64(double %sub, double %sub, double %RMSD.0)
+ br label %for.cond
}
-define double @nonSquareCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) local_unnamed_addr #0 {
+declare double @llvm.fmuladd.f64(double, double, double)
+
+declare double @sqrt(double noundef)
+
+define double @nonSquareCompareDistmats(double %distmat1_, double %distmat2_) {
; CHECK-LABEL: define double @nonSquareCompareDistmats(
-; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) local_unnamed_addr #[[ATTR0]] {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
-; CHECK-NEXT: [[ADD:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
-; CHECK-NEXT: [[FMACALL:%.*]] = tail call double @llvm.fmuladd.f64(double [[SUB]], double [[ADD]], double 0.000000e+00)
-; CHECK-NEXT: [[CALL:%.*]] = tail call double @sqrt(double noundef [[FMACALL]]) #[[ATTR3:[0-9]+]]
+; CHECK-SAME: double [[DISTMAT1_:%.*]], double [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[TMP0:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[CALL:%.*]] = call double @sqrt(double noundef [[RMSD_0]])
; CHECK-NEXT: ret double [[CALL]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[ADD:%.*]] = fadd double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[TMP0]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[ADD]], double [[RMSD_0]])
+; CHECK-NEXT: br label %[[FOR_COND]]
;
entry:
- %sub = fsub double %distmat1_, %distmat2_
- %add = fsub double %distmat1_, %distmat2_
- %fmacall = tail call double @llvm.fmuladd.f64(double %sub, double %add, double 0.000000e+00)
- %call = tail call double @sqrt(double noundef %fmacall) #3
- ret double %call
-}
+ br label %for.cond
-declare double @llvm.fmuladd.f64(double, double, double) #1
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %0, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
-declare double @sqrt(double noundef) local_unnamed_addr #2
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
-attributes #0 = { mustprogress nofree norecurse nounwind willreturn memory(errnomem: write) uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="znver3" "target-features"="+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdpru,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" }
-attributes #1 = { mustprogress nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
-attributes #2 = { mustprogress nocallback nofree nounwind willreturn memory(errnomem: write) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="znver3" "target-features"="+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdpru,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" }
-attributes #3 = { nounwind }
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %add = fadd double %distmat1_, %distmat2_
+ %0 = call double @llvm.fmuladd.f64(double %sub, double %add, double %RMSD.0)
+ br label %for.cond
+}
>From bd71fd25f93a1a82da33691d54603c5480aa5380 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 12:32:40 +0530
Subject: [PATCH 06/17] Used named values in test
---
.../test/Transforms/AggressiveInstCombine/X86/pr175590.ll | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
index 5eb3e44191389..a26f81c7ea622 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
@@ -22,7 +22,7 @@ entry:
br label %for.cond
for.cond: ; preds = %for.body, %entry
- %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %0, %for.body ]
+ %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %fmacall, %for.body ]
%cmp = phi i1 [ true, %entry ], [ false, %for.body ]
br i1 %cmp, label %for.body, label %for.cond.cleanup
@@ -32,7 +32,7 @@ for.cond.cleanup: ; preds = %for.cond
for.body: ; preds = %for.cond
%sub = fsub double %distmat1_, %distmat2_
- %0 = call double @llvm.fmuladd.f64(double %sub, double %sub, double %RMSD.0)
+ %fmacall = call double @llvm.fmuladd.f64(double %sub, double %sub, double %RMSD.0)
br label %for.cond
}
@@ -62,7 +62,7 @@ entry:
br label %for.cond
for.cond: ; preds = %for.body, %entry
- %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %0, %for.body ]
+ %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %fmacall, %for.body ]
%cmp = phi i1 [ true, %entry ], [ false, %for.body ]
br i1 %cmp, label %for.body, label %for.cond.cleanup
@@ -73,6 +73,6 @@ for.cond.cleanup: ; preds = %for.cond
for.body: ; preds = %for.cond
%sub = fsub double %distmat1_, %distmat2_
%add = fadd double %distmat1_, %distmat2_
- %0 = call double @llvm.fmuladd.f64(double %sub, double %add, double %RMSD.0)
+ %fmacall = call double @llvm.fmuladd.f64(double %sub, double %add, double %RMSD.0)
br label %for.cond
}
>From 08565c4a7015b2bd7be4a8d872f54565a888fc4c Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 12:42:16 +0530
Subject: [PATCH 07/17] Improved Code Formatting
---
llvm/lib/Analysis/ValueTracking.cpp | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index c80ba3b360d02..99b76395255df 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9300,7 +9300,7 @@ static bool matchThreeInputRecurrence(const PHINode *PN, InstTy *&Inst,
Value *&OtherOp1) {
if (PN->getNumIncomingValues() != 2)
return false;
-
+
for (unsigned I = 0; I != 3; ++I) {
if (auto *Operation = dyn_cast<InstTy>(PN->getIncomingValue(I));
Operation) {
@@ -9365,8 +9365,9 @@ bool llvm::matchSimpleBinaryIntrinsicRecurrence(const IntrinsicInst *I,
}
bool llvm::matchSimpleTernaryIntrinsicRecurrence(const IntrinsicInst *I,
- PHINode *&P, Value *&Init,
- Value *&OtherOp0, Value*&OtherOp1) {
+ PHINode *&P, Value *&Init,
+ Value *&OtherOp0,
+ Value *&OtherOp1) {
if (I->arg_size() != 3 || I->getType() != I->getArgOperand(0)->getType() ||
I->getType() != I->getArgOperand(1)->getType() ||
I->getType() != I->getArgOperand(2)->getType())
@@ -9378,7 +9379,8 @@ bool llvm::matchSimpleTernaryIntrinsicRecurrence(const IntrinsicInst *I,
if (!P)
P = dyn_cast<PHINode>(I->getArgOperand(2));
}
- return P && matchThreeInputRecurrence(P, II, Init, OtherOp0, OtherOp1) && II == I;
+ return P && matchThreeInputRecurrence(P, II, Init, OtherOp0, OtherOp1) &&
+ II == I;
}
/// Return true if "icmp Pred LHS RHS" is always true.
>From 1bc86bb50e9a086e0ab6ea26fc0f9b204bfb6720 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 12:46:27 +0530
Subject: [PATCH 08/17] Nitpick
---
llvm/lib/Analysis/ValueTracking.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 99b76395255df..9b60d8f0a551f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5953,6 +5953,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
// Unreachable blocks may have zero-operand PHI nodes.
if (P->getNumIncomingValues() == 0)
break;
+
// Otherwise take the unions of the known bit sets of the operands,
// taking conservative care to avoid excessive recursion.
const unsigned PhiRecursionLimit = MaxAnalysisRecursionDepth - 2;
>From 2f576161b2b9a9885fba1f06f96267ed3cda9614 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 12:48:23 +0530
Subject: [PATCH 09/17] Small Fix
---
llvm/lib/Analysis/ValueTracking.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9b60d8f0a551f..a40ac719d2242 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -10620,4 +10620,4 @@ bool llvm::collectPossibleValues(const Value *V,
}
}
return true;
-}
\ No newline at end of file
+}
>From e300ebf1c58ca5f07c17a23fc71d16e9d7ce3d90 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 13:23:14 +0530
Subject: [PATCH 10/17] Adding isGuaranteedNotUndef check
---
llvm/lib/Analysis/ValueTracking.cpp | 2 +-
.../test/Transforms/AggressiveInstCombine/X86/pr175590.ll | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index a40ac719d2242..4ace5577013cd 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6011,7 +6011,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
computeKnownFPClass(Init, DemandedElts,
KnownFPClass::OrderedGreaterThanZeroMask,
KnownStart, Q, Depth + 1);
- if (KnownStart.cannotBeOrderedLessThanZero() && L == R)
+ if (KnownStart.cannotBeOrderedLessThanZero() && L == R && isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
break;
}
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
index a26f81c7ea622..0bd25807f3b82 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
@@ -1,9 +1,9 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
-define double @CompareDistmats(double %distmat1_, double %distmat2_) {
+define double @CompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
; CHECK-LABEL: define double @CompareDistmats(
-; CHECK-SAME: double [[DISTMAT1_:%.*]], double [[DISTMAT2_:%.*]]) {
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[FOR_COND:.*]]
; CHECK: [[FOR_COND]]:
@@ -40,9 +40,9 @@ declare double @llvm.fmuladd.f64(double, double, double)
declare double @sqrt(double noundef)
-define double @nonSquareCompareDistmats(double %distmat1_, double %distmat2_) {
+define double @nonSquareCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
; CHECK-LABEL: define double @nonSquareCompareDistmats(
-; CHECK-SAME: double [[DISTMAT1_:%.*]], double [[DISTMAT2_:%.*]]) {
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[FOR_COND:.*]]
; CHECK: [[FOR_COND]]:
>From 98009941a804d9d5e08736116e1274a2883f2050 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Sat, 17 Jan 2026 13:27:54 +0530
Subject: [PATCH 11/17] Improve code formatting
---
llvm/lib/Analysis/ValueTracking.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 4ace5577013cd..d0261450cd11e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6011,7 +6011,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
computeKnownFPClass(Init, DemandedElts,
KnownFPClass::OrderedGreaterThanZeroMask,
KnownStart, Q, Depth + 1);
- if (KnownStart.cannotBeOrderedLessThanZero() && L == R && isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
+ if (KnownStart.cannotBeOrderedLessThanZero() && L == R &&
+ isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
break;
}
>From 384d4e294f08ebe7464c961ed78f3f317498e8d6 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Wed, 21 Jan 2026 00:44:56 +0530
Subject: [PATCH 12/17] Added documentation and more negative tests
---
llvm/include/llvm/Analysis/ValueTracking.h | 11 +++++
.../AggressiveInstCombine/X86/pr175590.ll | 43 +++++++++++++++++--
2 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index b31d46d94bf11..26931c68d4742 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -996,6 +996,17 @@ LLVM_ABI bool matchSimpleBinaryIntrinsicRecurrence(const IntrinsicInst *I,
PHINode *&P, Value *&Init,
Value *&OtherOp);
+/// Attempt to match a simple value-accumulating recurrence of the form:
+/// %llvm.intrinsic.acc = phi Ty [%Init, %Entry], [%llvm.intrinsic, %backedge]
+/// %llvm.intrinsic = call Ty @llvm.intrinsic(%OtherOp0, %OtherOp1, %llvm.intrinsic.acc)
+/// OR
+/// %llvm.intrinsic.acc = phi Ty [%Init, %Entry], [%llvm.intrinsic, %backedge]
+/// %llvm.intrinsic = call Ty @llvm.intrinsic(%llvm.intrinsic.acc, %OtherOp0, %OtherOp1)
+///
+/// The recurrence relation is of kind:
+/// X_0 = %a (initial value),
+/// X_i = call @llvm.ternary.intrinsic(X_i-1, %b, %c)
+/// Where %b, %c are not required to be loop-invariant.
LLVM_ABI bool matchSimpleTernaryIntrinsicRecurrence(const IntrinsicInst *I,
PHINode *&P, Value *&Init,
Value *&OtherOp0,
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
index 0bd25807f3b82..d27dff893918a 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
@@ -7,7 +7,7 @@ define double @CompareDistmats(double noundef %distmat1_, double noundef %distma
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[FOR_COND:.*]]
; CHECK: [[FOR_COND]]:
-; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[TMP0:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
; CHECK: [[FOR_COND_CLEANUP]]:
@@ -15,7 +15,7 @@ define double @CompareDistmats(double noundef %distmat1_, double noundef %distma
; CHECK-NEXT: ret double [[SQRT]]
; CHECK: [[FOR_BODY]]:
; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
-; CHECK-NEXT: [[TMP0]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
; CHECK-NEXT: br label %[[FOR_COND]]
;
entry:
@@ -46,7 +46,7 @@ define double @nonSquareCompareDistmats(double noundef %distmat1_, double nounde
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[FOR_COND:.*]]
; CHECK: [[FOR_COND]]:
-; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[TMP0:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
; CHECK: [[FOR_COND_CLEANUP]]:
@@ -55,7 +55,7 @@ define double @nonSquareCompareDistmats(double noundef %distmat1_, double nounde
; CHECK: [[FOR_BODY]]:
; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
; CHECK-NEXT: [[ADD:%.*]] = fadd double [[DISTMAT1_]], [[DISTMAT2_]]
-; CHECK-NEXT: [[TMP0]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[ADD]], double [[RMSD_0]])
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[ADD]], double [[RMSD_0]])
; CHECK-NEXT: br label %[[FOR_COND]]
;
entry:
@@ -76,3 +76,38 @@ for.body: ; preds = %for.cond
%fmacall = call double @llvm.fmuladd.f64(double %sub, double %add, double %RMSD.0)
br label %for.cond
}
+
+define double @negInitialCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
+; CHECK-LABEL: define double @negInitialCompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ -1.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[CALL:%.*]] = call double @sqrt(double noundef [[RMSD_0]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ -1.000000e+00, %entry ], [ %fmacall, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %fmacall = call double @llvm.fmuladd.f64(double %sub, double %sub, double %RMSD.0)
+ br label %for.cond
+}
>From bb19c35061c0d212a91e95f7259d88bb22d0e2c4 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Wed, 21 Jan 2026 00:49:42 +0530
Subject: [PATCH 13/17] Fix code formatting
---
llvm/include/llvm/Analysis/ValueTracking.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 26931c68d4742..53a74efc00edb 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -998,10 +998,12 @@ LLVM_ABI bool matchSimpleBinaryIntrinsicRecurrence(const IntrinsicInst *I,
/// Attempt to match a simple value-accumulating recurrence of the form:
/// %llvm.intrinsic.acc = phi Ty [%Init, %Entry], [%llvm.intrinsic, %backedge]
-/// %llvm.intrinsic = call Ty @llvm.intrinsic(%OtherOp0, %OtherOp1, %llvm.intrinsic.acc)
+/// %llvm.intrinsic = call Ty @llvm.intrinsic(%OtherOp0, %OtherOp1,
+/// %llvm.intrinsic.acc)
/// OR
/// %llvm.intrinsic.acc = phi Ty [%Init, %Entry], [%llvm.intrinsic, %backedge]
-/// %llvm.intrinsic = call Ty @llvm.intrinsic(%llvm.intrinsic.acc, %OtherOp0, %OtherOp1)
+/// %llvm.intrinsic = call Ty @llvm.intrinsic(%llvm.intrinsic.acc, %OtherOp0,
+/// %OtherOp1)
///
/// The recurrence relation is of kind:
/// X_0 = %a (initial value),
>From 72b3364b2f576e7c248bed60233f6ebe4fd80519 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Wed, 21 Jan 2026 01:29:15 +0530
Subject: [PATCH 14/17] Added handling for fma and more tests
---
llvm/lib/Analysis/ValueTracking.cpp | 1 +
.../AggressiveInstCombine/X86/pr175590.ll | 76 ++++++++++++++++++-
2 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d0261450cd11e..9903e9043e3b5 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6006,6 +6006,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
PHINode *PN;
if (matchSimpleTernaryIntrinsicRecurrence(I, PN, Init, L, R)) {
switch (I->getIntrinsicID()) {
+ case Intrinsic::fma:
case Intrinsic::fmuladd: {
KnownFPClass KnownStart;
computeKnownFPClass(Init, DemandedElts,
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
index d27dff893918a..c0d92ea4047b3 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
@@ -36,9 +36,40 @@ for.body: ; preds = %for.cond
br label %for.cond
}
-declare double @llvm.fmuladd.f64(double, double, double)
+define double @fmaCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
+; CHECK-LABEL: define double @fmaCompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[RMSD_0]])
+; CHECK-NEXT: ret double [[SQRT]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fma.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
+entry:
+ br label %for.cond
-declare double @sqrt(double noundef)
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %fmacall, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %fmacall = call double @llvm.fma.f64(double %sub, double %sub, double %RMSD.0)
+ br label %for.cond
+}
define double @nonSquareCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
; CHECK-LABEL: define double @nonSquareCompareDistmats(
@@ -111,3 +142,44 @@ for.body: ; preds = %for.cond
%fmacall = call double @llvm.fmuladd.f64(double %sub, double %sub, double %RMSD.0)
br label %for.cond
}
+
+define double @notMatchingRecurrenceCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
+; CHECK-LABEL: define double @notMatchingRecurrenceCompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ -1.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[CALL:%.*]] = call double @sqrt(double noundef [[RMSD_0]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[SUB]])
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ -1.000000e+00, %entry ], [ %fmacall, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %fmacall = call double @llvm.fmuladd.f64(double %sub, double %sub, double %sub)
+ br label %for.cond
+}
+
+declare double @llvm.fmuladd.f64(double, double, double)
+
+declare double @llvm.fma.f64(double, double, double)
+
+declare double @sqrt(double noundef)
>From b43ab93b0c5b404340f6a0e6e582af2cfc7f143a Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Thu, 29 Jan 2026 21:05:03 +0530
Subject: [PATCH 15/17] Avoid use of core fmuladd class logic
---
llvm/lib/Analysis/ValueTracking.cpp | 10 ++++++----
.../Transforms/AggressiveInstCombine/X86/pr175590.ll | 4 ++--
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index f1da7682477af..a245cd95ec9fb 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5969,13 +5969,15 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
switch (I->getIntrinsicID()) {
case Intrinsic::fma:
case Intrinsic::fmuladd: {
- KnownFPClass KnownStart;
+ KnownFPClass KnownStart, KnownL;
computeKnownFPClass(Init, DemandedElts,
KnownFPClass::OrderedGreaterThanZeroMask,
KnownStart, Q, Depth + 1);
- if (KnownStart.cannotBeOrderedLessThanZero() && L == R &&
- isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ computeKnownFPClass(L, DemandedElts,
+ KnownFPClass::OrderedGreaterThanZeroMask,
+ KnownL, Q, Depth + 1);
+ if (L == R && isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
+ Known = KnownFPClass::fma_square(KnownL, KnownStart);
break;
}
}
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
index c0d92ea4047b3..b0e3818bc02b8 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
@@ -15,7 +15,7 @@ define double @CompareDistmats(double noundef %distmat1_, double noundef %distma
; CHECK-NEXT: ret double [[SQRT]]
; CHECK: [[FOR_BODY]]:
; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
-; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double noundef [[SUB]], double noundef [[SUB]], double [[RMSD_0]])
; CHECK-NEXT: br label %[[FOR_COND]]
;
entry:
@@ -32,7 +32,7 @@ for.cond.cleanup: ; preds = %for.cond
for.body: ; preds = %for.cond
%sub = fsub double %distmat1_, %distmat2_
- %fmacall = call double @llvm.fmuladd.f64(double %sub, double %sub, double %RMSD.0)
+ %fmacall = call double @llvm.fmuladd.f64(double noundef %sub, double noundef %sub, double %RMSD.0)
br label %for.cond
}
>From 49398f90b72e7b501652ddd9fc741cbd735916b1 Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Thu, 29 Jan 2026 21:14:17 +0530
Subject: [PATCH 16/17] Correct code formatting
---
llvm/lib/Analysis/ValueTracking.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index a245cd95ec9fb..5b15c7a6623ab 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5976,7 +5976,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
computeKnownFPClass(L, DemandedElts,
KnownFPClass::OrderedGreaterThanZeroMask,
KnownL, Q, Depth + 1);
- if (L == R && isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
+ if (L == R &&
+ isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
Known = KnownFPClass::fma_square(KnownL, KnownStart);
break;
}
>From f2abd0211212d1c3e6e49aa8dbca0b661734f28b Mon Sep 17 00:00:00 2001
From: Kshitij Paranjape <kshitijvparanjape at gmail.com>
Date: Thu, 29 Jan 2026 21:20:01 +0530
Subject: [PATCH 17/17] Improve code formatting
---
llvm/lib/Analysis/ValueTracking.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5b15c7a6623ab..739f199de0037 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5974,10 +5974,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
KnownFPClass::OrderedGreaterThanZeroMask,
KnownStart, Q, Depth + 1);
computeKnownFPClass(L, DemandedElts,
- KnownFPClass::OrderedGreaterThanZeroMask,
- KnownL, Q, Depth + 1);
+ KnownFPClass::OrderedGreaterThanZeroMask, KnownL,
+ Q, Depth + 1);
if (L == R &&
- isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
+ isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
Known = KnownFPClass::fma_square(KnownL, KnownStart);
break;
}
More information about the llvm-commits
mailing list