aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2022-05-13 09:15:22 -0400
committerSanjay Patel <spatel@rotateright.com>2022-05-13 09:59:41 -0400
commitee6754c277a67cbc51eb6b3eb704a0ff751f9ddd (patch)
treec2e0b8fc353543913fbef773dd7e474232e47109 /llvm/lib/Analysis/ValueTracking.cpp
parent0fefb56da7fd04c36675eebc2f9d1d851dca725b (diff)
downloadllvm-ee6754c277a67cbc51eb6b3eb704a0ff751f9ddd.zip
llvm-ee6754c277a67cbc51eb6b3eb704a0ff751f9ddd.tar.gz
llvm-ee6754c277a67cbc51eb6b3eb704a0ff751f9ddd.tar.bz2
[ValueTracking] recognize sub X, (X % Y) as not overflowing
I fixed some poison-safety violations on related patterns in InstCombine and noticed that we missed adding nsw/nuw on them, so this adds clauses to the underlying analysis for that. We need the undef input restriction to make this safe according to Alive2: https://alive2.llvm.org/ce/z/48g9K8 Differential Revision: https://reviews.llvm.org/D125500
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 0144ce4..ed196b1 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4841,6 +4841,15 @@ OverflowResult llvm::computeOverflowForUnsignedSub(const Value *LHS,
AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT) {
+ // X - (X % ?)
+ // The remainder of a value can't have greater magnitude than itself,
+ // so the subtraction can't overflow.
+ // TODO: There are other patterns like this.
+ // See simplifyICmpWithBinOpOnLHS() for candidates.
+ if (match(RHS, m_URem(m_Specific(LHS), m_Value())) &&
+ isGuaranteedNotToBeUndefOrPoison(LHS, AC, CxtI, DT))
+ return OverflowResult::NeverOverflows;
+
// Checking for conditions implied by dominating conditions may be expensive.
// Limit it to usub_with_overflow calls for now.
if (match(CxtI,
@@ -4864,6 +4873,13 @@ OverflowResult llvm::computeOverflowForSignedSub(const Value *LHS,
AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT) {
+ // X - (X % ?)
+ // The remainder of a value can't have greater magnitude than itself,
+ // so the subtraction can't overflow.
+ if (match(RHS, m_SRem(m_Specific(LHS), m_Value())) &&
+ isGuaranteedNotToBeUndefOrPoison(LHS, AC, CxtI, DT))
+ return OverflowResult::NeverOverflows;
+
// If LHS and RHS each have at least two sign bits, the subtraction
// cannot overflow.
if (ComputeNumSignBits(LHS, DL, 0, AC, CxtI, DT) > 1 &&