From afcb25aaebdc5e966c5e64f60610162b2718b4ec Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 13 Jan 2025 11:41:50 +0000 Subject: [PATCH 1/3] VT: squah compile-time regression from 66badf2 66badf2 (VT: teach a special-case optz about samesign) introduced a compile-time regression due to the use of CmpPredicate::getMatching, which is unnecessarily inefficient. Introduce CmpPredicate::getSignedPredicate, which alleviates the inefficiency problem and squashes the compile-time regression. --- llvm/include/llvm/IR/CmpPredicate.h | 6 ++++++ llvm/lib/Analysis/ValueTracking.cpp | 9 +++++---- llvm/lib/IR/Instructions.cpp | 4 ++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/IR/CmpPredicate.h b/llvm/include/llvm/IR/CmpPredicate.h index 9aa1449465f5f..829339088e7c3 100644 --- a/llvm/include/llvm/IR/CmpPredicate.h +++ b/llvm/include/llvm/IR/CmpPredicate.h @@ -53,6 +53,12 @@ class CmpPredicate { static std::optional getMatching(CmpPredicate A, CmpPredicate B); + /// Attempts to return a signed CmpInst::Predicate from the CmpPredicate. If + /// the CmpPredicate has samesign, return the signedness-flipped predicate + /// (which would be signed), dropping samesign information. Otherwise, return + /// the predicate, dropping samesign information. + CmpInst::Predicate getSignedPredicate() const; + /// An operator== on the underlying Predicate. bool operator==(CmpInst::Predicate P) const { return Pred == P; } bool operator!=(CmpInst::Predicate P) const { return Pred != P; } diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 0e50fc60ce792..0fabe45628b01 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -9495,8 +9495,9 @@ isImpliedCondICmps(const ICmpInst *LHS, CmpPredicate RPred, const Value *R0, // must be positive if X >= Y and no overflow". // Take SGT as an example: L0:x > L1:y and C >= 0 // ==> R0:(x -nsw y) < R1:(-C) is false - if ((CmpPredicate::getMatching(LPred, ICmpInst::ICMP_SGT) || - CmpPredicate::getMatching(LPred, ICmpInst::ICMP_SGE)) && + CmpInst::Predicate SignedLPred = LPred.getSignedPredicate(); + if ((SignedLPred == ICmpInst::ICMP_SGT || + SignedLPred == ICmpInst::ICMP_SGE) && match(R0, m_NSWSub(m_Specific(L0), m_Specific(L1)))) { if (match(R1, m_NonPositive()) && isImpliedCondMatchingOperands(LPred, RPred) == false) @@ -9505,8 +9506,8 @@ isImpliedCondICmps(const ICmpInst *LHS, CmpPredicate RPred, const Value *R0, // Take SLT as an example: L0:x < L1:y and C <= 0 // ==> R0:(x -nsw y) < R1:(-C) is true - if ((CmpPredicate::getMatching(LPred, ICmpInst::ICMP_SLT) || - CmpPredicate::getMatching(LPred, ICmpInst::ICMP_SLE)) && + if ((SignedLPred == ICmpInst::ICMP_SLT || + SignedLPred == ICmpInst::ICMP_SLE) && match(R0, m_NSWSub(m_Specific(L0), m_Specific(L1)))) { if (match(R1, m_NonNegative()) && isImpliedCondMatchingOperands(LPred, RPred) == true) diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 49c148bb68a4d..b78e045f9c919 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -3939,6 +3939,10 @@ std::optional CmpPredicate::getMatching(CmpPredicate A, return {}; } +CmpInst::Predicate CmpPredicate::getSignedPredicate() const { + return HasSameSign ? ICmpInst::getFlippedSignednessPredicate(Pred) : Pred; +} + CmpPredicate CmpPredicate::get(const CmpInst *Cmp) { if (auto *ICI = dyn_cast(Cmp)) return ICI->getCmpPredicate(); From 1ae91e059c617cfb4139694c35dfdbc617c1b4aa Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 13 Jan 2025 12:15:08 +0000 Subject: [PATCH 2/3] IR: use ICmpInst::getSignedPredicate --- llvm/include/llvm/IR/CmpPredicate.h | 6 +++--- llvm/lib/IR/Instructions.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/IR/CmpPredicate.h b/llvm/include/llvm/IR/CmpPredicate.h index 829339088e7c3..ccc3f3e1ab5d0 100644 --- a/llvm/include/llvm/IR/CmpPredicate.h +++ b/llvm/include/llvm/IR/CmpPredicate.h @@ -54,9 +54,9 @@ class CmpPredicate { CmpPredicate B); /// Attempts to return a signed CmpInst::Predicate from the CmpPredicate. If - /// the CmpPredicate has samesign, return the signedness-flipped predicate - /// (which would be signed), dropping samesign information. Otherwise, return - /// the predicate, dropping samesign information. + /// the CmpPredicate has samesign, return ICmpInst::getSignedPredicate, + /// dropping samesign information. Otherwise, return the predicate, dropping + /// samesign information. CmpInst::Predicate getSignedPredicate() const; /// An operator== on the underlying Predicate. diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index b78e045f9c919..0cb1bbde279b9 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -3940,7 +3940,7 @@ std::optional CmpPredicate::getMatching(CmpPredicate A, } CmpInst::Predicate CmpPredicate::getSignedPredicate() const { - return HasSameSign ? ICmpInst::getFlippedSignednessPredicate(Pred) : Pred; + return HasSameSign ? ICmpInst::getSignedPredicate(Pred) : Pred; } CmpPredicate CmpPredicate::get(const CmpInst *Cmp) { From c9f361fa34eb5affdaf7151ea4e87773287646a0 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 13 Jan 2025 16:15:15 +0000 Subject: [PATCH 3/3] CmpPredicate: rename fn to getPreferredSignedPredicate --- llvm/include/llvm/IR/CmpPredicate.h | 2 +- llvm/lib/Analysis/ValueTracking.cpp | 2 +- llvm/lib/IR/Instructions.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/IR/CmpPredicate.h b/llvm/include/llvm/IR/CmpPredicate.h index ccc3f3e1ab5d0..6921afbc58d25 100644 --- a/llvm/include/llvm/IR/CmpPredicate.h +++ b/llvm/include/llvm/IR/CmpPredicate.h @@ -57,7 +57,7 @@ class CmpPredicate { /// the CmpPredicate has samesign, return ICmpInst::getSignedPredicate, /// dropping samesign information. Otherwise, return the predicate, dropping /// samesign information. - CmpInst::Predicate getSignedPredicate() const; + CmpInst::Predicate getPreferredSignedPredicate() const; /// An operator== on the underlying Predicate. bool operator==(CmpInst::Predicate P) const { return Pred == P; } diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 0fabe45628b01..381e2d8b5b0fe 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -9495,7 +9495,7 @@ isImpliedCondICmps(const ICmpInst *LHS, CmpPredicate RPred, const Value *R0, // must be positive if X >= Y and no overflow". // Take SGT as an example: L0:x > L1:y and C >= 0 // ==> R0:(x -nsw y) < R1:(-C) is false - CmpInst::Predicate SignedLPred = LPred.getSignedPredicate(); + CmpInst::Predicate SignedLPred = LPred.getPreferredSignedPredicate(); if ((SignedLPred == ICmpInst::ICMP_SGT || SignedLPred == ICmpInst::ICMP_SGE) && match(R0, m_NSWSub(m_Specific(L0), m_Specific(L1)))) { diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 0cb1bbde279b9..1bf8f6584e909 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -3939,7 +3939,7 @@ std::optional CmpPredicate::getMatching(CmpPredicate A, return {}; } -CmpInst::Predicate CmpPredicate::getSignedPredicate() const { +CmpInst::Predicate CmpPredicate::getPreferredSignedPredicate() const { return HasSameSign ? ICmpInst::getSignedPredicate(Pred) : Pred; }