[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