[llvm] [InstCombine] Drop alignment assumptions more aggressively (PR #196060)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 6 05:50:31 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Nikolas Klauser (philnik777)
<details>
<summary>Changes</summary>
Most of the patch passes `AllowEphemerals` through `computeKnownBits` to `isValidAssumeForContext`. The actually interesting part of the change is that `computeKnownBits` is now given a context instruction when trying to drop alignment assumes.
---
Patch is 130.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/196060.diff
10 Files Affected:
- (modified) llvm/include/llvm/Analysis/ValueTracking.h (+55-21)
- (modified) llvm/include/llvm/Analysis/WithCache.h (+7-2)
- (modified) llvm/include/llvm/IR/IRBuilder.h (+1-1)
- (modified) llvm/include/llvm/Transforms/InstCombine/InstCombiner.h (+5-2)
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+500-324)
- (modified) llvm/lib/IR/IRBuilder.cpp (+1-1)
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp (+5-4)
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (+51-38)
- (modified) llvm/test/Transforms/InstCombine/assume-redundant.ll (-1)
- (modified) llvm/test/Transforms/InstCombine/assume.ll (+13)
``````````diff
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index ff2712efe1ef5..1e283da30e6b1 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -58,12 +58,17 @@ constexpr unsigned MaxLookupSearchDepth = 10;
/// where V is a vector, the known zero and known one values are the
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
-LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known,
- const DataLayout &DL,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr,
- const DominatorTree *DT = nullptr,
- bool UseInstrInfo = true, unsigned Depth = 0);
+LLVM_ABI void
+computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr,
+ const DominatorTree *DT = nullptr, bool UseInstrInfo = true,
+ bool AllowEphemerals = true, unsigned Depth = 0);
+
+template <class T>
+void computeKnownBits(const Value *, KnownBits &, const DataLayout &,
+ AssumptionCache *, const Instruction *,
+ const DominatorTree *, bool, T, unsigned = 0);
/// Returns the known bits rather than passing by reference.
LLVM_ABI KnownBits computeKnownBits(const Value *V, const DataLayout &DL,
@@ -83,13 +88,25 @@ LLVM_ABI KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
unsigned Depth = 0);
LLVM_ABI KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
- const SimplifyQuery &Q, unsigned Depth = 0);
+ const SimplifyQuery &Q,
+ bool AllowEphemerals, unsigned Depth = 0);
+
+template <class T>
+void computeKnownBits(const Value *, const APInt &, const SimplifyQuery &, T,
+ unsigned = 0) = delete;
+// The original declaration is in "llvm/Analysis/WithCache.h"
LLVM_ABI KnownBits computeKnownBits(const Value *V, const SimplifyQuery &Q,
- unsigned Depth = 0);
+ bool AllowEphemerals,
+ unsigned Depth);
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known,
- const SimplifyQuery &Q, unsigned Depth = 0);
+ const SimplifyQuery &Q, bool AllowEphemerals,
+ unsigned Depth = 0);
+
+template <class T>
+void computeKnownBits(const Value *, KnownBits &, const SimplifyQuery &, T,
+ unsigned = 0) = delete;
/// Compute known bits from the range metadata.
/// \p KnownZero the set of bits that are known to be zero
@@ -100,14 +117,23 @@ LLVM_ABI void computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
/// Merge bits known from context-dependent facts into Known.
LLVM_ABI void computeKnownBitsFromContext(const Value *V, KnownBits &Known,
const SimplifyQuery &Q,
+ bool AllowEphemerals = true,
unsigned Depth = 0);
+template <class T>
+void computeKnownBitsFromContext(const Value *, KnownBits &,
+ const SimplifyQuery &, T,
+ unsigned = 0) = delete;
+
/// Using KnownBits LHS/RHS produce the known bits for logic op (and/xor/or).
-LLVM_ABI KnownBits analyzeKnownBitsFromAndXorOr(const Operator *I,
- const KnownBits &KnownLHS,
- const KnownBits &KnownRHS,
- const SimplifyQuery &SQ,
- unsigned Depth = 0);
+LLVM_ABI KnownBits analyzeKnownBitsFromAndXorOr(
+ const Operator *I, const KnownBits &KnownLHS, const KnownBits &KnownRHS,
+ const SimplifyQuery &SQ, bool AllowEphemerals, unsigned Depth = 0);
+
+template <class T>
+KnownBits analyzeKnownBitsFromAndXorOr(const Operator *, const KnownBits &,
+ const KnownBits &, const SimplifyQuery &,
+ T, unsigned = 0) = delete;
/// Adjust \p Known for the given select \p Arm to include information from the
/// select \p Cond.
@@ -156,7 +182,11 @@ LLVM_ABI bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI);
/// pointer couldn't possibly be null at the specified instruction.
/// Supports values with integer or pointer type and vectors of integers.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q,
- unsigned Depth = 0);
+ bool AllowEphemerals = true, unsigned Depth = 0);
+
+template <class T>
+void isKnownNonZero(const Value *, const SimplifyQuery &, T,
+ unsigned = 0) = delete;
/// Return true if the two given values are negation.
/// Currently can recoginze Value pair:
@@ -210,12 +240,16 @@ LLVM_ABI bool MaskedValueIsZero(const Value *V, const APInt &Mask,
/// equal to each other, so we return 3. For vectors, return the number of
/// sign bits for the vector element with the mininum number of known sign
/// bits.
-LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL,
- AssumptionCache *AC = nullptr,
- const Instruction *CxtI = nullptr,
- const DominatorTree *DT = nullptr,
- bool UseInstrInfo = true,
- unsigned Depth = 0);
+LLVM_ABI unsigned ComputeNumSignBits(
+ const Value *Op, const DataLayout &DL, AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr,
+ bool UseInstrInfo = true, bool AllowEphemerals = true, unsigned Depth = 0);
+
+template <class T>
+unsigned ComputeNumSignBits(const Value *, const DataLayout &,
+ AssumptionCache *, const Instruction *,
+ const DominatorTree *, bool, T,
+ unsigned = 0) = delete;
/// Get the upper bound on bit size for this Value \p Op as a signed integer.
/// i.e. x == sext(trunc(x to MaxSignificantBits) to bitwidth(x)).
diff --git a/llvm/include/llvm/Analysis/WithCache.h b/llvm/include/llvm/Analysis/WithCache.h
index 3bf35a889bbf2..8389a0959a76e 100644
--- a/llvm/include/llvm/Analysis/WithCache.h
+++ b/llvm/include/llvm/Analysis/WithCache.h
@@ -23,7 +23,12 @@
namespace llvm {
struct SimplifyQuery;
LLVM_ABI KnownBits computeKnownBits(const Value *V, const SimplifyQuery &Q,
- unsigned Depth);
+ bool AllowEphemerals = true,
+ unsigned Depth = 0);
+
+template <class T, std::enable_if_t<std::is_convertible_v<T, bool>, int> = 0>
+KnownBits computeKnownBits(const Value *, const SimplifyQuery &, T,
+ unsigned = 0) = delete;
template <typename Arg> class WithCache {
static_assert(std::is_pointer_v<Arg>, "WithCache requires a pointer type!");
@@ -45,7 +50,7 @@ template <typename Arg> class WithCache {
mutable KnownBits Known;
void calculateKnownBits(const SimplifyQuery &Q) const {
- Known = computeKnownBits(Pointer.getPointer(), Q, 0);
+ Known = computeKnownBits(Pointer.getPointer(), Q);
Pointer.setInt(true);
}
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index e28a9027740a3..ca085bb4aaa11 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -2807,7 +2807,7 @@ class IRBuilderBase {
/// specified alignment.
LLVM_ABI CallInst *CreateAlignmentAssumption(const DataLayout &DL,
Value *PtrValue,
- unsigned Alignment,
+ uint64_t Alignment,
Value *OffsetValue = nullptr);
/// Create an assume intrinsic call that represents an alignment
diff --git a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
index 5670d9b6f9f89..73f5c25456a52 100644
--- a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
+++ b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
@@ -445,12 +445,15 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
void computeKnownBits(const Value *V, KnownBits &Known,
const Instruction *CxtI, unsigned Depth = 0) const {
- llvm::computeKnownBits(V, Known, SQ.getWithInstruction(CxtI), Depth);
+ llvm::computeKnownBits(V, Known, SQ.getWithInstruction(CxtI),
+ /*AllowEphemerals=*/true, Depth);
}
KnownBits computeKnownBits(const Value *V, const Instruction *CxtI,
+ bool AllowEphemerals = true,
unsigned Depth = 0) const {
- return llvm::computeKnownBits(V, SQ.getWithInstruction(CxtI), Depth);
+ return llvm::computeKnownBits(V, SQ.getWithInstruction(CxtI),
+ AllowEphemerals, Depth);
}
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero = false,
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 40f1025fed4fb..a382307b2af67 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -136,26 +136,28 @@ static bool getShuffleDemandedElts(const ShuffleVectorInst *Shuf,
static void computeKnownBits(const Value *V, const APInt &DemandedElts,
KnownBits &Known, const SimplifyQuery &Q,
- unsigned Depth);
+ bool AllowEphemerals, unsigned Depth);
void llvm::computeKnownBits(const Value *V, KnownBits &Known,
- const SimplifyQuery &Q, unsigned Depth) {
+ const SimplifyQuery &Q, bool AllowEphemerals,
+ unsigned Depth) {
// Since the number of lanes in a scalable vector is unknown at compile time,
// we track one bit which is implicitly broadcast to all lanes. This means
// that all lanes in a scalable vector are considered demanded.
auto *FVTy = dyn_cast<FixedVectorType>(V->getType());
APInt DemandedElts =
FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1);
- ::computeKnownBits(V, DemandedElts, Known, Q, Depth);
+ ::computeKnownBits(V, DemandedElts, Known, Q, AllowEphemerals, Depth);
}
void llvm::computeKnownBits(const Value *V, KnownBits &Known,
const DataLayout &DL, AssumptionCache *AC,
const Instruction *CxtI, const DominatorTree *DT,
- bool UseInstrInfo, unsigned Depth) {
+ bool UseInstrInfo, bool AllowEphemerals,
+ unsigned Depth) {
computeKnownBits(V, Known,
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo),
- Depth);
+ AllowEphemerals, Depth);
}
KnownBits llvm::computeKnownBits(const Value *V, const DataLayout &DL,
@@ -163,7 +165,8 @@ KnownBits llvm::computeKnownBits(const Value *V, const DataLayout &DL,
const DominatorTree *DT, bool UseInstrInfo,
unsigned Depth) {
return computeKnownBits(
- V, SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo), Depth);
+ V, SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo),
+ /*AllowEphemerals=*/true, Depth);
}
KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
@@ -173,7 +176,8 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
unsigned Depth) {
return computeKnownBits(
V, DemandedElts,
- SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo), Depth);
+ SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo),
+ /*AllowEphemerals=*/true, Depth);
}
static bool haveNoCommonBitsSetSpecialCases(const Value *LHS, const Value *RHS,
@@ -276,11 +280,17 @@ bool llvm::isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL,
}
static bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
- const SimplifyQuery &Q, unsigned Depth);
+ const SimplifyQuery &Q, bool AllowEphemerals,
+ unsigned Depth);
+
+template <class T>
+void isKnownNonZero(const Value *, const APInt &, const SimplifyQuery &, T,
+ unsigned = 0) = delete;
bool llvm::isKnownNonNegative(const Value *V, const SimplifyQuery &SQ,
unsigned Depth) {
- return computeKnownBits(V, SQ, Depth).isNonNegative();
+ return computeKnownBits(V, SQ, /*AllowEphemerals=*/true, Depth)
+ .isNonNegative();
}
bool llvm::isKnownPositive(const Value *V, const SimplifyQuery &SQ,
@@ -290,19 +300,20 @@ bool llvm::isKnownPositive(const Value *V, const SimplifyQuery &SQ,
// If `isKnownNonNegative` ever becomes more sophisticated, make sure to keep
// this updated.
- KnownBits Known = computeKnownBits(V, SQ, Depth);
+ KnownBits Known = computeKnownBits(V, SQ, /*AllowEphemerals=*/true, Depth);
return Known.isNonNegative() &&
- (Known.isNonZero() || isKnownNonZero(V, SQ, Depth));
+ (Known.isNonZero() ||
+ isKnownNonZero(V, SQ, /*AllowEphemerals=*/true, Depth));
}
bool llvm::isKnownNegative(const Value *V, const SimplifyQuery &SQ,
unsigned Depth) {
- return computeKnownBits(V, SQ, Depth).isNegative();
+ return computeKnownBits(V, SQ, /*AllowEphemerals=*/true, Depth).isNegative();
}
static bool isKnownNonEqual(const Value *V1, const Value *V2,
const APInt &DemandedElts, const SimplifyQuery &Q,
- unsigned Depth);
+ bool AllowEphemerals, unsigned Depth);
bool llvm::isKnownNonEqual(const Value *V1, const Value *V2,
const SimplifyQuery &Q, unsigned Depth) {
@@ -312,33 +323,40 @@ bool llvm::isKnownNonEqual(const Value *V1, const Value *V2,
auto *FVTy = dyn_cast<FixedVectorType>(V1->getType());
APInt DemandedElts =
FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1);
- return ::isKnownNonEqual(V1, V2, DemandedElts, Q, Depth);
+ return ::isKnownNonEqual(V1, V2, DemandedElts, Q, /*AllowEphemerals=*/true,
+ Depth);
}
bool llvm::MaskedValueIsZero(const Value *V, const APInt &Mask,
const SimplifyQuery &SQ, unsigned Depth) {
KnownBits Known(Mask.getBitWidth());
- computeKnownBits(V, Known, SQ, Depth);
+ computeKnownBits(V, Known, SQ, /*AllowEphemerals=*/true, Depth);
return Mask.isSubsetOf(Known.Zero);
}
static unsigned ComputeNumSignBits(const Value *V, const APInt &DemandedElts,
- const SimplifyQuery &Q, unsigned Depth);
+ const SimplifyQuery &Q, bool AllowEphemerals,
+ unsigned Depth);
static unsigned ComputeNumSignBits(const Value *V, const SimplifyQuery &Q,
- unsigned Depth = 0) {
+ bool AllowEphemerals, unsigned Depth = 0) {
auto *FVTy = dyn_cast<FixedVectorType>(V->getType());
APInt DemandedElts =
FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1);
- return ComputeNumSignBits(V, DemandedElts, Q, Depth);
+ return ComputeNumSignBits(V, DemandedElts, Q, AllowEphemerals, Depth);
}
+template <class T>
+void ComputeNumSignBits(const Value *, const SimplifyQuery &, T &&,
+ unsigned = 0) = delete;
+
unsigned llvm::ComputeNumSignBits(const Value *V, const DataLayout &DL,
AssumptionCache *AC, const Instruction *CxtI,
const DominatorTree *DT, bool UseInstrInfo,
- unsigned Depth) {
+ bool AllowEphemerals, unsigned Depth) {
return ::ComputeNumSignBits(
- V, SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo), Depth);
+ V, SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo),
+ AllowEphemerals, Depth);
}
unsigned llvm::ComputeMaxSignificantBits(const Value *V, const DataLayout &DL,
@@ -435,7 +453,8 @@ static void computeKnownBitsFromLerpPattern(const Value *Op0, const Value *Op1,
const auto ComputeKnownBitsOrOne = [&](const Value *V) {
// For some of the values we use the convention of leaving
// it nullptr to signify an implicit constant 1.
- return V ? computeKnownBits(V, DemandedElts, Q, Depth + 1)
+ return V ? computeKnownBits(V, DemandedElts, Q, /*AllowEphemerals=*/true,
+ Depth + 1)
: KnownBits::makeConstant(APInt(BitWidth, 1));
};
@@ -448,11 +467,13 @@ static void computeKnownBitsFromLerpPattern(const Value *Op0, const Value *Op1,
if (!KnownD.isNonNegative())
return;
- const KnownBits KnownB = computeKnownBits(B, DemandedElts, Q, Depth + 1);
+ const KnownBits KnownB =
+ computeKnownBits(B, DemandedElts, Q, /*AllowEphemerals=*/true, Depth + 1);
if (!KnownB.isNonNegative())
return;
- const KnownBits KnownC = computeKnownBits(C, DemandedElts, Q, Depth + 1);
+ const KnownBits KnownC =
+ computeKnownBits(C, DemandedElts, Q, /*AllowEphemerals=*/true, Depth + 1);
if (!KnownC.isNonNegative())
return;
@@ -487,15 +508,16 @@ static void computeKnownBitsAddSub(bool Add, const Value *Op0, const Value *Op1,
bool NSW, bool NUW,
const APInt &DemandedElts,
KnownBits &KnownOut, KnownBits &Known2,
- const SimplifyQuery &Q, unsigned Depth) {
- computeKnownBits(Op1, DemandedElts, KnownOut, Q, Depth + 1);
+ const SimplifyQuery &Q, bool AllowEphemerals,
+ unsigned Depth) {
+ computeKnownBits(Op1, DemandedElts, KnownOut, Q, AllowEphemerals, Depth + 1);
// If one operand is unknown and we have no nowrap information,
// the result will be unknown independently of the second operand.
if (KnownOut.isUnknown() && !NSW && !NUW)
return;
- computeKnownBits(Op0, DemandedElts, Known2, Q, Depth + 1);
+ computeKnownBits(Op0, DemandedElts, Known2, Q, AllowEphemerals, Depth + 1);
KnownOut = KnownBits::computeForAddSub(Add, NSW, NUW, Known2, KnownOut);
if (!Add && NSW && !KnownOut.isNonNegative() &&
@@ -512,9 +534,10 @@ static void computeKnownBitsAddSub(bool Add, const Value *Op0, const Value *Op1,
static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW,
bool NUW, const APInt &DemandedElts,
KnownBits &Known, KnownBits &Known2,
- const SimplifyQuery &Q, unsigned Depth) {
- computeKnownBits(Op1, DemandedElts, Known, Q, Depth + 1);
- computeKnownBits(Op0, DemandedElts, Known2, Q, Depth + 1);
+ const SimplifyQuery &Q, bool AllowEphemerals,
+ unsigned Depth) {
+ computeKnownBits(Op1, DemandedElts, Known, Q, AllowEphemerals, Depth + 1);
+ computeKnownBits(Op0, DemandedElts, Known2, Q, AllowEphemerals, Depth + 1);
bool isKnownNegative = false;
bool isKnownNonNegative = false;
@@ -555,7 +578,8 @@ static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW,
Known = KnownBits::mul(Known, Known2, SelfMultiply);
if (SelfMultiply) {
- unsigned SignBits = ComputeNumSignBits(Op0, Dema...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/196060
More information about the llvm-commits
mailing list