[llvm] [InstCombine] Drop alignment assumptions more aggressively (PR #196060)

Nikolas Klauser via llvm-commits llvm-commits at lists.llvm.org
Wed May 6 05:50:51 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/196060

>From ec4a436b40abe635cdf9849dd911684de8f491ab Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 6 May 2026 14:47:19 +0200
Subject: [PATCH] [InstCombine] Drop alignment assumptions more aggressively

---
 llvm/include/llvm/Analysis/ValueTracking.h    |  76 +-
 llvm/include/llvm/Analysis/WithCache.h        |   9 +-
 llvm/include/llvm/IR/IRBuilder.h              |   2 +-
 .../Transforms/InstCombine/InstCombiner.h     |   7 +-
 llvm/lib/Analysis/ValueTracking.cpp           | 824 +++++++++++-------
 llvm/lib/IR/IRBuilder.cpp                     |   2 +-
 .../InstCombine/InstCombineCalls.cpp          |  10 +-
 .../InstCombineSimplifyDemanded.cpp           |  89 +-
 .../InstCombine/assume-redundant.ll           |   1 -
 llvm/test/Transforms/InstCombine/assume.ll    |  13 +
 10 files changed, 639 insertions(+), 394 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index ff2712efe1ef5..a354dc6a6d715 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) = delete;
 
 /// 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, DemandedElts, Q, Depth + 1);
+    unsigned SignBits =
+        ComputeNumSignBits(Op0, DemandedElts, Q, AllowEphemerals, Depth + 1);
     unsigned TyBits = Op0->getType()->getScalarSizeInBits();
     unsigned OutValidBits = 2 * (TyBits - SignBits + 1);
 
@@ -1047,7 +1071,8 @@ static void computeKnownBitsFromCond(const Value *V, Value *Cond,
 }
 
 void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
-                                       const SimplifyQuery &Q, unsigned Depth) {
+                                       const SimplifyQuery &Q,
+                                       bool AllowEphemerals, unsigned Depth) {
   // Handle injected condition.
   if (Q.CC && Q.CC->AffectedValues.contains(V))
     computeKnownBitsFromCond(V, Q.CC->Cond, Known, Q, Q.CC->Invert, Depth);
@@ -1094,12 +1119,9 @@ void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
         continue;
       if (RetainedKnowledge RK = getKnowledgeFromBundle(
               *I, I->bundle_op_info_begin()[Elem.Index])) {
-        // Allow AllowEphemerals in isValidAssumeForContext, as the CxtI might
-        // be the producer of the pointer in the bundle. At the moment, align
-        // assumptions aren't optimized away.
         if (RK.WasOn == V && RK.AttrKind == Attribute::Alignment &&
             isPowerOf2_64(RK.ArgValue) &&
-            isValidAssumeForContext(I, Q.CxtI, Q.DT, /*AllowEphemerals*/ true))
+            isValidAssumeForContext(I, Q.CxtI, Q.DT, AllowEphemerals))
           Known.Zero.setLowBits(Log2_64(RK.ArgValue));
       }
       continue;
@@ -1165,23 +1187,27 @@ void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
 /// combined for all permitted shift amounts.
 static void computeKnownBitsFromShiftOperator(
     const Operator *I, const APInt &DemandedElts, KnownBits &Known,
-    KnownBits &Known2, const SimplifyQuery &Q, unsigned Depth,
+    KnownBits &Known2, const SimplifyQuery &Q, bool AllowEphemerals,
+    unsigned Depth,
     function_ref<KnownBits(const KnownBits &, const KnownBits &, bool)> KF) {
-  computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
-  computeKnownBits(I->getOperand(1), DemandedElts, Known, Q, Depth + 1);
+  computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, AllowEphemerals,
+                   Depth + 1);
+  computeKnownBits(I->getOperand(1), DemandedElts, Known, Q, AllowEphemerals,
+                   Depth + 1);
   // To limit compile-time impact, only query isKnownNonZero() if we know at
   // least something about the shift amount.
   bool ShAmtNonZero =
-      Known.isNonZero() ||
-      (Known.getMaxValue().ult(Known.getBitWidth()) &&
-       isKnownNonZero(I->getOperand(1), DemandedElts, Q, Depth + 1));
+      Known.isNonZero() || (Known.getMaxValue().ult(Known.getBitWidth()) &&
+                            isKnownNonZero(I->getOperand(1), DemandedElts, Q,
+                                           AllowEphemerals, Depth + 1));
   Known = KF(Known2, Known, ShAmtNonZero);
 }
 
 static KnownBits
 getKnownBitsFromAndXorOr(const Operator *I, const APInt &DemandedElts,
                          const KnownBits &KnownLHS, const KnownBits &KnownRHS,
-                         const SimplifyQuery &Q, unsigned Depth) {
+                         const SimplifyQuery &Q, bool AllowEphemerals,
+                         unsigned Depth) {
   unsigned BitWidth = KnownLHS.getBitWidth();
   KnownBits KnownOut(BitWidth);
   bool IsAnd = false;
@@ -1238,7 +1264,7 @@ getKnownBitsFromAndXorOr(const Operator *I, const APInt &DemandedElts,
        match(I, m_c_BinOp(m_Value(X), m_Sub(m_Deferred(X), m_Value(Y)))) ||
        match(I, m_c_BinOp(m_Value(X), m_Sub(m_Value(Y), m_Deferred(X)))))) {
     KnownBits KnownY(BitWidth);
-    computeKnownBits(Y, DemandedElts, KnownY, Q, Depth + 1);
+    computeKnownBits(Y, DemandedElts, KnownY, Q, AllowEphemerals, Depth + 1);
     if (KnownY.countMinTrailingOnes() > 0) {
       if (IsAnd)
         KnownOut.Zero.setBit(0);
@@ -1259,12 +1285,14 @@ static KnownBits computeKnownBitsForHorizontalOperation(
                                       DemandedElts, DemandedEltsLHS,
                                       DemandedEltsRHS);
 
-  const auto ComputeForSingleOpFunc =
-      [Depth, &Q, KnownBitsFunc](const Value *Op, APInt &DemandedEltsOp) {
-        return KnownBitsFunc(
-            computeKnownBits(Op, DemandedEltsOp, Q, Depth + 1),
-            computeKnownBits(Op, DemandedEltsOp << 1, Q, Depth + 1));
-      };
+  const auto ComputeForSingleOpFunc = [Depth, &Q,
+                                       KnownBitsFunc](const Value *Op,
+                                                      APInt &DemandedEltsOp) {
+    return KnownBitsFunc(computeKnownBits(Op, DemandedEltsOp, Q,
+                                          /*AllowEphemerals=*/true, Depth + 1),
+                         computeKnownBits(Op, DemandedEltsOp << 1, Q,
+                                          /*AllowEphemerals=*/true, Depth + 1));
+  };
 
   if (DemandedEltsRHS.isZero())
     return ComputeForSingleOpFunc(I->getOperand(0), DemandedEltsLHS);
@@ -1276,17 +1304,15 @@ static KnownBits computeKnownBitsForHorizontalOperation(
 }
 
 // Public so this can be used in `SimplifyDemandedUseBits`.
-KnownBits llvm::analyzeKnownBitsFromAndXorOr(const Operator *I,
-                                             const KnownBits &KnownLHS,
-                                             const KnownBits &KnownRHS,
-                                             const SimplifyQuery &SQ,
-                                             unsigned Depth) {
+KnownBits llvm::analyzeKnownBitsFromAndXorOr(
+    const Operator *I, const KnownBits &KnownLHS, const KnownBits &KnownRHS,
+    const SimplifyQuery &SQ, bool AllowEphemerals, unsigned Depth) {
   auto *FVTy = dyn_cast<FixedVectorType>(I->getType());
   APInt DemandedElts =
       FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1);
 
   return getKnownBitsFromAndXorOr(I, DemandedElts, KnownLHS, KnownRHS, SQ,
-                                  Depth);
+                                  AllowEphemerals, Depth);
 }
 
 ConstantRange llvm::getVScaleRange(const Function *F, unsigned BitWidth) {
@@ -1404,6 +1430,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
                                          const APInt &DemandedElts,
                                          KnownBits &Known,
                                          const SimplifyQuery &Q,
+                                         bool AllowEphemerals,
                                          unsigned Depth) {
   unsigned BitWidth = Known.getBitWidth();
 
@@ -1416,40 +1443,53 @@ static void computeKnownBitsFromOperator(const Operator *I,
       computeKnownBitsFromRangeMetadata(*MD, Known);
     break;
   case Instruction::And:
-    computeKnownBits(I->getOperand(1), DemandedElts, Known, Q, Depth + 1);
-    computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
+    computeKnownBits(I->getOperand(1), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, AllowEphemerals,
+                     Depth + 1);
 
-    Known = getKnownBitsFromAndXorOr(I, DemandedElts, Known2, Known, Q, Depth);
+    Known = getKnownBitsFromAndXorOr(I, DemandedElts, Known2, Known, Q,
+                                     AllowEphemerals, Depth);
     break;
   case Instruction::Or:
-    computeKnownBits(I->getOperand(1), DemandedElts, Known, Q, Depth + 1);
-    computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
+    computeKnownBits(I->getOperand(1), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, AllowEphemerals,
+                     Depth + 1);
 
-    Known = getKnownBitsFromAndXorOr(I, DemandedElts, Known2, Known, Q, Depth);
+    Known = getKnownBitsFromAndXorOr(I, DemandedElts, Known2, Known, Q,
+                                     AllowEphemerals, Depth);
     break;
   case Instruction::Xor:
-    computeKnownBits(I->getOperand(1), DemandedElts, Known, Q, Depth + 1);
-    computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
+    computeKnownBits(I->getOperand(1), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, AllowEphemerals,
+                     Depth + 1);
 
-    Known = getKnownBitsFromAndXorOr(I, DemandedElts, Known2, Known, Q, Depth);
+    Known = getKnownBitsFromAndXorOr(I, DemandedElts, Known2, Known, Q,
+                                     AllowEphemerals, Depth);
     break;
   case Instruction::Mul: {
     bool NSW = Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(I));
     bool NUW = Q.IIQ.hasNoUnsignedWrap(cast<OverflowingBinaryOperator>(I));
     computeKnownBitsMul(I->getOperand(0), I->getOperand(1), NSW, NUW,
-                        DemandedElts, Known, Known2, Q, Depth);
+                        DemandedElts, Known, Known2, Q, AllowEphemerals, Depth);
     break;
   }
   case Instruction::UDiv: {
-    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-    computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
+    computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, AllowEphemerals,
+                     Depth + 1);
     Known =
         KnownBits::udiv(Known, Known2, Q.IIQ.isExact(cast<BinaryOperator>(I)));
     break;
   }
   case Instruction::SDiv: {
-    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-    computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
+    computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, AllowEphemerals,
+                     Depth + 1);
     Known =
         KnownBits::sdiv(Known, Known2, Q.IIQ.isExact(cast<BinaryOperator>(I)));
     break;
@@ -1457,7 +1497,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
   case Instruction::Select: {
     auto ComputeForArm = [&](Value *Arm, bool Invert) {
       KnownBits Res(Known.getBitWidth());
-      computeKnownBits(Arm, DemandedElts, Res, Q, Depth + 1);
+      computeKnownBits(Arm, DemandedElts, Res, Q, AllowEphemerals, Depth + 1);
       adjustKnownBitsForSelectArm(Res, I->getOperand(0), Arm, Invert, Q, Depth);
       return Res;
     };
@@ -1493,7 +1533,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
 
     assert(SrcBitWidth && "SrcBitWidth can't be zero");
     Known = Known.anyextOrTrunc(SrcBitWidth);
-    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
     if (auto *Inst = dyn_cast<PossiblyNonNegInst>(I);
         Inst && Inst->hasNonNeg() && !Known.isNegative())
       Known.makeNonNegative();
@@ -1506,7 +1547,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
         // TODO: For now, not handling conversions like:
         // (bitcast i64 %x to <2 x i32>)
         !I->getType()->isVectorTy()) {
-      computeKnownBits(I->getOperand(0), Known, Q, Depth + 1);
+      computeKnownBits(I->getOperand(0), Known, Q, AllowEphemerals, Depth + 1);
       break;
     }
 
@@ -1585,7 +1626,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
       KnownBits KnownSrc(SubBitWidth);
       for (unsigned i = 0; i != SubScale; ++i) {
         computeKnownBits(I->getOperand(0), SubDemandedElts.shl(i), KnownSrc, Q,
-                         Depth + 1);
+                         AllowEphemerals, Depth + 1);
         unsigned ShiftElt = IsLE ? i : SubScale - 1 - i;
         Known.insertBits(KnownSrc, ShiftElt * SubBitWidth);
       }
@@ -1598,7 +1639,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
       APInt SubDemandedElts =
           APIntOps::ScaleBitMask(DemandedElts, NumElts / SubScale);
       computeKnownBits(I->getOperand(0), SubDemandedElts, KnownSrc, Q,
-                       Depth + 1);
+                       AllowEphemerals, Depth + 1);
 
       Known.setAllConflict();
       for (unsigned i = 0; i != NumElts; ++i) {
@@ -1618,7 +1659,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
     unsigned SrcBitWidth = I->getOperand(0)->getType()->getScalarSizeInBits();
 
     Known = Known.trunc(SrcBitWidth);
-    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
     // If the sign bit of the input is known set or clear, then we know the
     // top bits of the result.
     Known = Known.sext(BitWidth);
@@ -1631,8 +1673,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
                          bool ShAmtNonZero) {
       return KnownBits::shl(KnownVal, KnownAmt, NUW, NSW, ShAmtNonZero);
     };
-    computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Q, Depth,
-                                      KF);
+    computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Q,
+                                      AllowEphemerals, Depth, KF);
     // Trailing zeros of a right-shifted constant never decrease.
     const APInt *C;
     if (match(I->getOperand(0), m_APInt(C)))
@@ -1645,8 +1687,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
                       bool ShAmtNonZero) {
       return KnownBits::lshr(KnownVal, KnownAmt, ShAmtNonZero, Exact);
     };
-    computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Q, Depth,
-                                      KF);
+    computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Q,
+                                      AllowEphemerals, Depth, KF);
     // Leading zeros of a left-shifted constant never decrease.
     const APInt *C;
     if (match(I->getOperand(0), m_APInt(C)))
@@ -1659,33 +1701,39 @@ static void computeKnownBitsFromOperator(const Operator *I,
                       bool ShAmtNonZero) {
       return KnownBits::ashr(KnownVal, KnownAmt, ShAmtNonZero, Exact);
     };
-    computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Q, Depth,
-                                      KF);
+    computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Q,
+                                      AllowEphemerals, Depth, KF);
     break;
   }
   case Instruction::Sub: {
     bool NSW = Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(I));
     bool NUW = Q.IIQ.hasNoUnsignedWrap(cast<OverflowingBinaryOperator>(I));
     computeKnownBitsAddSub(false, I->getOperand(0), I->getOperand(1), NSW, NUW,
-                           DemandedElts, Known, Known2, Q, Depth);
+                           DemandedElts, Known, Known2, Q, AllowEphemerals,
+                           Depth);
     break;
   }
   case Instruction::Add: {
     bool NSW = Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(I));
     bool NUW = Q.IIQ.hasNoUnsignedWrap(cast<OverflowingBinaryOperator>(I));
     computeKnownBitsAddSub(true, I->getOperand(0), I->getOperand(1), NSW, NUW,
-                           DemandedElts, Known, Known2, Q, Depth);
+                           DemandedElts, Known, Known2, Q, AllowEphemerals,
+                           Depth);
     break;
   }
   case Instruction::SRem:
-    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-    computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
+    computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, AllowEphemerals,
+                     Depth + 1);
     Known = KnownBits::srem(Known, Known2);
     break;
 
   case Instruction::URem:
-    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-    computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
+    computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, AllowEphemerals,
+                     Depth + 1);
     Known = KnownBits::urem(Known, Known2);
     break;
   case Instruction::Alloca:
@@ -1694,7 +1742,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
   case Instruction::GetElementPtr: {
     // Analyze all of the subscripts of this getelementptr instruction
     // to determine if we can prove known low zero bits.
-    computeKnownBits(I->getOperand(0), Known, Q, Depth + 1);
+    computeKnownBits(I->getOperand(0), Known, Q, AllowEphemerals, Depth + 1);
     // Accumulate the constant indices in a separate variable
     // to minimize the number of calls to computeForAddSub.
     unsigned IndexWidth = Q.DL.getIndexTypeSizeInBits(I->getType());
@@ -1762,7 +1810,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
       }
 
       KnownBits IndexBits =
-          computeKnownBits(Index, Q, Depth + 1).sextOrTrunc(IndexWidth);
+          computeKnownBits(Index, Q, /*AllowEphemerals=*/true, Depth + 1)
+              .sextOrTrunc(IndexWidth);
       KnownBits ScalingFactor(IndexWidth);
       // Multiply by current sizeof type.
       // &A[i] == A + i * sizeof(*A[i]).
@@ -1817,7 +1866,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
         // add sufficient tests to cover.
         SimplifyQuery RecQ = Q.getWithoutCondContext();
         RecQ.CxtI = P;
-        computeKnownBits(R, DemandedElts, Known2, RecQ, Depth + 1);
+        computeKnownBits(R, DemandedElts, Known2, RecQ, AllowEphemerals,
+                         Depth + 1);
         switch (Opcode) {
         case Instruction::Shl:
           // A shl recurrence will only increase the tailing zeros
@@ -1860,12 +1910,14 @@ static void computeKnownBitsFromOperator(const Operator *I,
         // Ok, we have a PHI of the form L op= R. Check for low
         // zero bits.
         RecQ.CxtI = RInst;
-        computeKnownBits(R, DemandedElts, Known2, RecQ, Depth + 1);
+        computeKnownBits(R, DemandedElts, Known2, RecQ, AllowEphemerals,
+                         Depth + 1);
 
         // We need to take the minimum number of known bits
         KnownBits Known3(BitWidth);
         RecQ.CxtI = LInst;
-        computeKnownBits(L, DemandedElts, Known3, RecQ, Depth + 1);
+        computeKnownBits(L, DemandedElts, Known3, RecQ, AllowEphemerals,
+                         Depth + 1);
 
         Known.Zero.setLowBits(std::min(Known2.countMinTrailingZeros(),
                                        Known3.countMinTrailingZeros()));
@@ -1954,7 +2006,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
         // want to waste time spinning around in loops.
         // TODO: See if we can base recursion limiter on number of incoming phi
         // edges so we don't overly clamp analysis.
-        computeKnownBits(IncValue, DemandedElts, Known2, RecQ,
+        computeKnownBits(IncValue, DemandedElts, Known2, RecQ, AllowEphemerals,
                          MaxAnalysisRecursionDepth - 1);
 
         // See if we can further use a conditional branch into the phi
@@ -2015,7 +2067,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
 
     if (const Value *RV = CB->getReturnedArgOperand()) {
       if (RV->getType() == I->getType()) {
-        computeKnownBits(RV, Known2, Q, Depth + 1);
+        computeKnownBits(RV, Known2, Q, AllowEphemerals, Depth + 1);
         Known = Known.unionWith(Known2);
         // If the function doesn't return properly for all input values
         // (e.g. unreachable exits) then there might be conflicts between the
@@ -2030,21 +2082,25 @@ static void computeKnownBitsFromOperator(const Operator *I,
       default:
         break;
       case Intrinsic::abs: {
-        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         bool IntMinIsPoison = match(II->getArgOperand(1), m_One());
         Known = Known.unionWith(Known2.abs(IntMinIsPoison));
         break;
       }
       case Intrinsic::bitreverse:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = Known.unionWith(Known2.reverseBits());
         break;
       case Intrinsic::bswap:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = Known.unionWith(Known2.byteSwap());
         break;
       case Intrinsic::ctlz: {
-        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         // If we have a known 1, its position is our upper bound.
         unsigned PossibleLZ = Known2.countMaxLeadingZeros();
         // If this call is poison for 0 input, the result will be less than 2^n.
@@ -2055,7 +2111,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
         break;
       }
       case Intrinsic::cttz: {
-        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         // If we have a known 1, its position is our upper bound.
         unsigned PossibleTZ = Known2.countMaxTrailingZeros();
         // If this call is poison for 0 input, the result will be less than 2^n.
@@ -2066,7 +2123,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
         break;
       }
       case Intrinsic::ctpop: {
-        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         // We can bound the space the count needs.  Also, bits known to be zero
         // can't contribute to the population.
         unsigned BitsPossiblySet = Known2.countMaxPopulation();
@@ -2083,42 +2141,54 @@ static void computeKnownBitsFromOperator(const Operator *I,
           break;
 
         KnownBits Known3(BitWidth);
-        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known3, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known3, Q,
+                         AllowEphemerals, Depth + 1);
         Known = II->getIntrinsicID() == Intrinsic::fshl
                     ? KnownBits::fshl(Known2, Known3, *SA)
                     : KnownBits::fshr(Known2, Known3, *SA);
         break;
       }
       case Intrinsic::clmul:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::clmul(Known, Known2);
         break;
       case Intrinsic::uadd_sat:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::uadd_sat(Known, Known2);
         break;
       case Intrinsic::usub_sat:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::usub_sat(Known, Known2);
         break;
       case Intrinsic::sadd_sat:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::sadd_sat(Known, Known2);
         break;
       case Intrinsic::ssub_sat:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::ssub_sat(Known, Known2);
         break;
         // Vec reverse preserves bits from input vec.
       case Intrinsic::vector_reverse:
         computeKnownBits(I->getOperand(0), DemandedElts.reverseBits(), Known, Q,
-                         Depth + 1);
+                         AllowEphemerals, Depth + 1);
         break;
         // for min/max/and/or reduce, any bit common to each element in the
         // input vec is set in the output.
@@ -2128,10 +2198,12 @@ static void computeKnownBitsFromOperator(const Operator *I,
       case Intrinsic::vector_reduce_umin:
       case Intrinsic::vector_reduce_smax:
       case Intrinsic::vector_reduce_smin:
-        computeKnownBits(I->getOperand(0), Known, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), Known, Q, AllowEphemerals,
+                         Depth + 1);
         break;
       case Intrinsic::vector_reduce_xor: {
-        computeKnownBits(I->getOperand(0), Known, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), Known, Q, AllowEphemerals,
+                         Depth + 1);
         // The zeros common to all vecs are zero in the output.
         // If the number of elements is odd, then the common ones remain. If the
         // number of elements is even, then the common ones becomes zeros.
@@ -2149,38 +2221,49 @@ static void computeKnownBitsFromOperator(const Operator *I,
         auto *VecTy = dyn_cast<FixedVectorType>(I->getOperand(0)->getType());
         if (!VecTy)
           break;
-        computeKnownBits(I->getOperand(0), Known, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), Known, Q, AllowEphemerals,
+                         Depth + 1);
         Known = Known.reduceAdd(VecTy->getNumElements());
         break;
       }
       case Intrinsic::umin:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::umin(Known, Known2);
         break;
       case Intrinsic::umax:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::umax(Known, Known2);
         break;
       case Intrinsic::smin:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::smin(Known, Known2);
         unionWithMinMaxIntrinsicClamp(II, Known);
         break;
       case Intrinsic::smax:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::smax(Known, Known2);
         unionWithMinMaxIntrinsicClamp(II, Known);
         break;
       case Intrinsic::ptrmask: {
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
 
         const Value *Mask = I->getOperand(1);
         Known2 = KnownBits(Mask->getType()->getScalarSizeInBits());
-        computeKnownBits(Mask, DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(Mask, DemandedElts, Known2, Q, AllowEphemerals,
+                         Depth + 1);
         // TODO: 1-extend would be more precise.
         Known &= Known2.anyextOrTrunc(BitWidth);
         break;
@@ -2188,15 +2271,19 @@ static void computeKnownBitsFromOperator(const Operator *I,
       case Intrinsic::x86_sse2_pmulh_w:
       case Intrinsic::x86_avx2_pmulh_w:
       case Intrinsic::x86_avx512_pmulh_w_512:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::mulhs(Known, Known2);
         break;
       case Intrinsic::x86_sse2_pmulhu_w:
       case Intrinsic::x86_avx2_pmulhu_w:
       case Intrinsic::x86_avx512_pmulhu_w_512:
-        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth + 1);
-        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(0), DemandedElts, Known, Q,
+                         AllowEphemerals, Depth + 1);
+        computeKnownBits(I->getOperand(1), DemandedElts, Known2, Q,
+                         AllowEphemerals, Depth + 1);
         Known = KnownBits::mulhu(Known, Known2);
         break;
       case Intrinsic::x86_sse42_crc32_64_64:
@@ -2264,7 +2351,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
         // most 31 + src1.
         Known.Zero.setBitsFrom(
             II->getIntrinsicID() == Intrinsic::amdgcn_mbcnt_lo ? 6 : 5);
-        computeKnownBits(I->getOperand(1), Known2, Q, Depth + 1);
+        computeKnownBits(I->getOperand(1), Known2, Q, AllowEphemerals,
+                         Depth + 1);
         Known = KnownBits::add(Known, Known2);
         break;
       }
@@ -2281,7 +2369,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
   }
   case Instruction::ShuffleVector: {
     if (auto *Splat = getSplatValue(I)) {
-      computeKnownBits(Splat, Known, Q, Depth + 1);
+      computeKnownBits(Splat, Known, Q, AllowEphemerals, Depth + 1);
       break;
     }
 
@@ -2301,14 +2389,14 @@ static void computeKnownBitsFromOperator(const Operator *I,
     Known.setAllConflict();
     if (!!DemandedLHS) {
       const Value *LHS = Shuf->getOperand(0);
-      computeKnownBits(LHS, DemandedLHS, Known, Q, Depth + 1);
+      computeKnownBits(LHS, DemandedLHS, Known, Q, AllowEphemerals, Depth + 1);
       // If we don't know any bits, early out.
       if (Known.isUnknown())
         break;
     }
     if (!!DemandedRHS) {
       const Value *RHS = Shuf->getOperand(1);
-      computeKnownBits(RHS, DemandedRHS, Known2, Q, Depth + 1);
+      computeKnownBits(RHS, DemandedRHS, Known2, Q, AllowEphemerals, Depth + 1);
       Known = Known.intersectWith(Known2);
     }
     break;
@@ -2332,14 +2420,15 @@ static void computeKnownBitsFromOperator(const Operator *I,
 
     Known.setAllConflict();
     if (NeedsElt) {
-      computeKnownBits(Elt, Known, Q, Depth + 1);
+      computeKnownBits(Elt, Known, Q, AllowEphemerals, Depth + 1);
       // If we don't know any bits, early out.
       if (Known.isUnknown())
         break;
     }
 
     if (!DemandedVecElts.isZero()) {
-      computeKnownBits(Vec, DemandedVecElts, Known2, Q, Depth + 1);
+      computeKnownBits(Vec, DemandedVecElts, Known2, Q, AllowEphemerals,
+                       Depth + 1);
       Known = Known.intersectWith(Known2);
     }
     break;
@@ -2359,7 +2448,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
     APInt DemandedVecElts = APInt::getAllOnes(NumElts);
     if (CIdx && CIdx->getValue().ult(NumElts))
       DemandedVecElts = APInt::getOneBitSet(NumElts, CIdx->getZExtValue());
-    computeKnownBits(Vec, DemandedVecElts, Known, Q, Depth + 1);
+    computeKnownBits(Vec, DemandedVecElts, Known, Q, AllowEphemerals,
+                     Depth + 1);
     break;
   }
   case Instruction::ExtractValue:
@@ -2371,20 +2461,23 @@ static void computeKnownBitsFromOperator(const Operator *I,
         default: break;
         case Intrinsic::uadd_with_overflow:
         case Intrinsic::sadd_with_overflow:
-          computeKnownBitsAddSub(
-              true, II->getArgOperand(0), II->getArgOperand(1), /*NSW=*/false,
-              /* NUW=*/false, DemandedElts, Known, Known2, Q, Depth);
+          computeKnownBitsAddSub(true, II->getArgOperand(0),
+                                 II->getArgOperand(1), /*NSW=*/false,
+                                 /* NUW=*/false, DemandedElts, Known, Known2, Q,
+                                 AllowEphemerals, Depth);
           break;
         case Intrinsic::usub_with_overflow:
         case Intrinsic::ssub_with_overflow:
-          computeKnownBitsAddSub(
-              false, II->getArgOperand(0), II->getArgOperand(1), /*NSW=*/false,
-              /* NUW=*/false, DemandedElts, Known, Known2, Q, Depth);
+          computeKnownBitsAddSub(false, II->getArgOperand(0),
+                                 II->getArgOperand(1), /*NSW=*/false,
+                                 /* NUW=*/false, DemandedElts, Known, Known2, Q,
+                                 AllowEphemerals, Depth);
           break;
         case Intrinsic::umul_with_overflow:
         case Intrinsic::smul_with_overflow:
           computeKnownBitsMul(II->getArgOperand(0), II->getArgOperand(1), false,
-                              false, DemandedElts, Known, Known2, Q, Depth);
+                              false, DemandedElts, Known, Known2, Q,
+                              AllowEphemerals, Depth);
           break;
         }
       }
@@ -2393,7 +2486,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
   case Instruction::Freeze:
     if (isGuaranteedNotToBePoison(I->getOperand(0), Q.AC, Q.CxtI, Q.DT,
                                   Depth + 1))
-      computeKnownBits(I->getOperand(0), Known, Q, Depth + 1);
+      computeKnownBits(I->getOperand(0), Known, Q, AllowEphemerals, Depth + 1);
     break;
   }
 }
@@ -2401,18 +2494,19 @@ static void computeKnownBitsFromOperator(const Operator *I,
 /// Determine which bits of V are known to be either zero or one and return
 /// them.
 KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
-                                 const SimplifyQuery &Q, unsigned Depth) {
+                                 const SimplifyQuery &Q, bool AllowEphemerals,
+                                 unsigned Depth) {
   KnownBits Known(getBitWidth(V->getType(), Q.DL));
-  ::computeKnownBits(V, DemandedElts, Known, Q, Depth);
+  ::computeKnownBits(V, DemandedElts, Known, Q, AllowEphemerals, Depth);
   return Known;
 }
 
 /// Determine which bits of V are known to be either zero or one and return
 /// them.
 KnownBits llvm::computeKnownBits(const Value *V, const SimplifyQuery &Q,
-                                 unsigned Depth) {
+                                 bool AllowEphemerals, unsigned Depth) {
   KnownBits Known(getBitWidth(V->getType(), Q.DL));
-  computeKnownBits(V, Known, Q, Depth);
+  computeKnownBits(V, Known, Q, AllowEphemerals, Depth);
   return Known;
 }
 
@@ -2433,7 +2527,7 @@ KnownBits llvm::computeKnownBits(const Value *V, const SimplifyQuery &Q,
 /// for all of the demanded elements in the vector specified by DemandedElts.
 void computeKnownBits(const Value *V, const APInt &DemandedElts,
                       KnownBits &Known, const SimplifyQuery &Q,
-                      unsigned Depth) {
+                      bool AllowEphemerals, unsigned Depth) {
   if (!DemandedElts) {
     // No demanded elts, better to assume we don't know anything.
     Known.resetAll();
@@ -2547,12 +2641,13 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
   // the bits of its aliasee.
   if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
     if (!GA->isInterposable())
-      computeKnownBits(GA->getAliasee(), Known, Q, Depth + 1);
+      computeKnownBits(GA->getAliasee(), Known, Q, AllowEphemerals, Depth + 1);
     return;
   }
 
   if (const Operator *I = dyn_cast<Operator>(V))
-    computeKnownBitsFromOperator(I, DemandedElts, Known, Q, Depth);
+    computeKnownBitsFromOperator(I, DemandedElts, Known, Q, AllowEphemerals,
+                                 Depth);
   else if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
     if (std::optional<ConstantRange> CR = GV->getAbsoluteSymbolRange())
       Known = CR->toKnownBits();
@@ -2568,7 +2663,7 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
   // Therefore, we run them after computeKnownBitsFromOperator.
 
   // Check whether we can determine known bits from context such as assumes.
-  computeKnownBitsFromContext(V, Known, Q, Depth);
+  computeKnownBitsFromContext(V, Known, Q, AllowEphemerals, Depth);
 }
 
 /// Try to detect a recurrence that the value of the induction variable is
@@ -2737,7 +2832,7 @@ bool llvm::isKnownToBeAPowerOfTwo(const Value *V, bool OrZero,
   case Instruction::Mul:
     return isKnownToBeAPowerOfTwo(I->getOperand(1), OrZero, Q, Depth) &&
            isKnownToBeAPowerOfTwo(I->getOperand(0), OrZero, Q, Depth) &&
-           (OrZero || isKnownNonZero(I, Q, Depth));
+           (OrZero || isKnownNonZero(I, Q, /*AllowEphemerals=*/true, Depth));
   case Instruction::And:
     // A power of two and'd with anything is a power of two or zero.
     if (OrZero &&
@@ -2747,7 +2842,8 @@ bool llvm::isKnownToBeAPowerOfTwo(const Value *V, bool OrZero,
     // X & (-X) is always a power of two or zero.
     if (match(I->getOperand(0), m_Neg(m_Specific(I->getOperand(1)))) ||
         match(I->getOperand(1), m_Neg(m_Specific(I->getOperand(0)))))
-      return OrZero || isKnownNonZero(I->getOperand(0), Q, Depth);
+      return OrZero || isKnownNonZero(I->getOperand(0), Q,
+                                      /*AllowEphemerals=*/true, Depth);
     return false;
   case Instruction::Add: {
     // Adding a power-of-two or zero to the same power-of-two or zero yields
@@ -2766,10 +2862,12 @@ bool llvm::isKnownToBeAPowerOfTwo(const Value *V, bool OrZero,
 
       unsigned BitWidth = V->getType()->getScalarSizeInBits();
       KnownBits LHSBits(BitWidth);
-      computeKnownBits(I->getOperand(0), LHSBits, Q, Depth);
+      computeKnownBits(I->getOperand(0), LHSBits, Q, /*AllowEphemerals=*/true,
+                       Depth);
 
       KnownBits RHSBits(BitWidth);
-      computeKnownBits(I->getOperand(1), RHSBits, Q, Depth);
+      computeKnownBits(I->getOperand(1), RHSBits, Q, /*AllowEphemerals=*/true,
+                       Depth);
       // If i8 V is a power of two or zero:
       //  ZeroBits: 1 1 1 0 1 1 1 1
       // ~ZeroBits: 0 0 0 1 0 0 0 0
@@ -2870,7 +2968,8 @@ static bool isGEPKnownNonNull(const GEPOperator *GEP, const SimplifyQuery &Q,
 
   // If the base pointer is non-null, we cannot walk to a null address with an
   // inbounds GEP in address space zero.
-  if (isKnownNonZero(GEP->getPointerOperand(), Q, Depth))
+  if (isKnownNonZero(GEP->getPointerOperand(), Q, /*AllowEphemerals=*/true,
+                     Depth))
     return true;
 
   // Walk the GEP operands and see if any operand introduces a non-zero offset.
@@ -2909,7 +3008,7 @@ static bool isGEPKnownNonNull(const GEPOperator *GEP, const SimplifyQuery &Q,
     if (Depth++ >= MaxAnalysisRecursionDepth)
       continue;
 
-    if (isKnownNonZero(GTI.getOperand(), Q, Depth))
+    if (isKnownNonZero(GTI.getOperand(), Q, /*AllowEphemerals=*/true, Depth))
       return true;
   }
 
@@ -3067,23 +3166,25 @@ static bool matchOpWithOpEqZero(Value *Op0, Value *Op1) {
 
 static bool isNonZeroAdd(const APInt &DemandedElts, const SimplifyQuery &Q,
                          unsigned BitWidth, Value *X, Value *Y, bool NSW,
-                         bool NUW, unsigned Depth) {
+                         bool NUW, bool AllowEphemerals, unsigned Depth) {
   // (X + (X != 0)) is non zero
   if (matchOpWithOpEqZero(X, Y))
     return true;
 
   if (NUW)
-    return isKnownNonZero(Y, DemandedElts, Q, Depth) ||
-           isKnownNonZero(X, DemandedElts, Q, Depth);
+    return isKnownNonZero(Y, DemandedElts, Q, AllowEphemerals, Depth) ||
+           isKnownNonZero(X, DemandedElts, Q, AllowEphemerals, Depth);
 
-  KnownBits XKnown = computeKnownBits(X, DemandedElts, Q, Depth);
-  KnownBits YKnown = computeKnownBits(Y, DemandedElts, Q, Depth);
+  KnownBits XKnown =
+      computeKnownBits(X, DemandedElts, Q, /*AllowEphemerals=*/true, Depth);
+  KnownBits YKnown =
+      computeKnownBits(Y, DemandedElts, Q, /*AllowEphemerals=*/true, Depth);
 
   // If X and Y are both non-negative (as signed values) then their sum is not
   // zero unless both X and Y are zero.
   if (XKnown.isNonNegative() && YKnown.isNonNegative())
-    if (isKnownNonZero(Y, DemandedElts, Q, Depth) ||
-        isKnownNonZero(X, DemandedElts, Q, Depth))
+    if (isKnownNonZero(Y, DemandedElts, Q, AllowEphemerals, Depth) ||
+        isKnownNonZero(X, DemandedElts, Q, AllowEphemerals, Depth))
       return true;
 
   // If X and Y are both negative (as signed values) then their sum is not
@@ -3113,7 +3214,7 @@ static bool isNonZeroAdd(const APInt &DemandedElts, const SimplifyQuery &Q,
 
 static bool isNonZeroSub(const APInt &DemandedElts, const SimplifyQuery &Q,
                          unsigned BitWidth, Value *X, Value *Y,
-                         unsigned Depth) {
+                         bool AllowEphemerals, unsigned Depth) {
   // (X - (X != 0)) is non zero
   // ((X != 0) - X) is non zero
   if (matchOpWithOpEqZero(X, Y))
@@ -3121,30 +3222,34 @@ static bool isNonZeroSub(const APInt &DemandedElts, const SimplifyQuery &Q,
 
   // TODO: Move this case into isKnownNonEqual().
   if (auto *C = dyn_cast<Constant>(X))
-    if (C->isNullValue() && isKnownNonZero(Y, DemandedElts, Q, Depth))
+    if (C->isNullValue() &&
+        isKnownNonZero(Y, DemandedElts, Q, AllowEphemerals, Depth))
       return true;
 
-  return ::isKnownNonEqual(X, Y, DemandedElts, Q, Depth);
+  return ::isKnownNonEqual(X, Y, DemandedElts, Q, AllowEphemerals, Depth);
 }
 
 static bool isNonZeroMul(const APInt &DemandedElts, const SimplifyQuery &Q,
                          unsigned BitWidth, Value *X, Value *Y, bool NSW,
-                         bool NUW, unsigned Depth) {
+                         bool NUW, bool AllowEphemerals, unsigned Depth) {
   // If X and Y are non-zero then so is X * Y as long as the multiplication
   // does not overflow.
   if (NSW || NUW)
-    return isKnownNonZero(X, DemandedElts, Q, Depth) &&
-           isKnownNonZero(Y, DemandedElts, Q, Depth);
+    return isKnownNonZero(X, DemandedElts, Q, AllowEphemerals, Depth) &&
+           isKnownNonZero(Y, DemandedElts, Q, AllowEphemerals, Depth);
 
   // If either X or Y is odd, then if the other is non-zero the result can't
   // be zero.
-  KnownBits XKnown = computeKnownBits(X, DemandedElts, Q, Depth);
+  KnownBits XKnown =
+      computeKnownBits(X, DemandedElts, Q, /*AllowEphemerals=*/true, Depth);
   if (XKnown.One[0])
-    return isKnownNonZero(Y, DemandedElts, Q, Depth);
+    return isKnownNonZero(Y, DemandedElts, Q, AllowEphemerals, Depth);
 
-  KnownBits YKnown = computeKnownBits(Y, DemandedElts, Q, Depth);
+  KnownBits YKnown =
+      computeKnownBits(Y, DemandedElts, Q, /*AllowEphemerals=*/true, Depth);
   if (YKnown.One[0])
-    return XKnown.isNonZero() || isKnownNonZero(X, DemandedElts, Q, Depth);
+    return XKnown.isNonZero() ||
+           isKnownNonZero(X, DemandedElts, Q, AllowEphemerals, Depth);
 
   // If there exists any subset of X (sX) and subset of Y (sY) s.t sX * sY is
   // non-zero, then X * Y is non-zero. We can find sX and sY by just taking
@@ -3157,7 +3262,7 @@ static bool isNonZeroMul(const APInt &DemandedElts, const SimplifyQuery &Q,
 
 static bool isNonZeroShift(const Operator *I, const APInt &DemandedElts,
                            const SimplifyQuery &Q, const KnownBits &KnownVal,
-                           unsigned Depth) {
+                           bool AllowEphemerals, unsigned Depth) {
   auto ShiftOp = [&](const APInt &Lhs, const APInt &Rhs) {
     switch (I->getOpcode()) {
     case Instruction::Shl:
@@ -3186,8 +3291,8 @@ static bool isNonZeroShift(const Operator *I, const APInt &DemandedElts,
   if (KnownVal.isUnknown())
     return false;
 
-  KnownBits KnownCnt =
-      computeKnownBits(I->getOperand(1), DemandedElts, Q, Depth);
+  KnownBits KnownCnt = computeKnownBits(I->getOperand(1), DemandedElts, Q,
+                                        AllowEphemerals, Depth);
   APInt MaxShift = KnownCnt.getMaxValue();
   unsigned NumBits = KnownVal.getBitWidth();
   if (MaxShift.uge(NumBits))
@@ -3200,7 +3305,7 @@ static bool isNonZeroShift(const Operator *I, const APInt &DemandedElts,
   // non-zero then at least one non-zero bit must remain.
   if (InvShiftOp(KnownVal.Zero, NumBits - MaxShift)
           .eq(InvShiftOp(APInt::getAllOnes(NumBits), NumBits - MaxShift)) &&
-      isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth))
+      isKnownNonZero(I->getOperand(0), DemandedElts, Q, AllowEphemerals, Depth))
     return true;
 
   return false;
@@ -3208,7 +3313,8 @@ static bool isNonZeroShift(const Operator *I, const APInt &DemandedElts,
 
 static bool isKnownNonZeroFromOperator(const Operator *I,
                                        const APInt &DemandedElts,
-                                       const SimplifyQuery &Q, unsigned Depth) {
+                                       const SimplifyQuery &Q,
+                                       bool AllowEphemerals, unsigned Depth) {
   unsigned BitWidth = getBitWidth(I->getType()->getScalarType(), Q.DL);
   switch (I->getOpcode()) {
   case Instruction::Alloca:
@@ -3249,7 +3355,7 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
     Type *FromTy = I->getOperand(0)->getType();
     if ((FromTy->isIntOrIntVectorTy() || FromTy->isPtrOrPtrVectorTy()) &&
         (BitWidth % getBitWidth(FromTy->getScalarType(), Q.DL)) == 0)
-      return isKnownNonZero(I->getOperand(0), Q, Depth);
+      return isKnownNonZero(I->getOperand(0), Q, AllowEphemerals, Depth);
   } break;
   case Instruction::IntToPtr:
     // Note that we have to take special care to avoid looking through
@@ -3258,24 +3364,28 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
     if (!isa<ScalableVectorType>(I->getType()) &&
         Q.DL.getTypeSizeInBits(I->getOperand(0)->getType()).getFixedValue() <=
             Q.DL.getTypeSizeInBits(I->getType()).getFixedValue())
-      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
+      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, AllowEphemerals,
+                            Depth);
     break;
   case Instruction::PtrToAddr:
     // isKnownNonZero() for pointers refers to the address bits being non-zero,
     // so we can directly forward.
-    return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
+    return isKnownNonZero(I->getOperand(0), DemandedElts, Q, AllowEphemerals,
+                          Depth);
   case Instruction::PtrToInt:
     // For inttoptr, make sure the result size is >= the address size. If the
     // address is non-zero, any larger value is also non-zero.
     if (Q.DL.getAddressSizeInBits(I->getOperand(0)->getType()) <=
         I->getType()->getScalarSizeInBits())
-      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
+      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, AllowEphemerals,
+                            Depth);
     break;
   case Instruction::Trunc:
     // nuw/nsw trunc preserves zero/non-zero status of input.
     if (auto *TI = dyn_cast<TruncInst>(I))
       if (TI->hasNoSignedWrap() || TI->hasNoUnsignedWrap())
-        return isKnownNonZero(TI->getOperand(0), DemandedElts, Q, Depth);
+        return isKnownNonZero(TI->getOperand(0), DemandedElts, Q,
+                              AllowEphemerals, Depth);
     break;
 
   // Iff x - y != 0, then x ^ y != 0
@@ -3283,70 +3393,77 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
   case Instruction::Xor:
   case Instruction::Sub:
     return isNonZeroSub(DemandedElts, Q, BitWidth, I->getOperand(0),
-                        I->getOperand(1), Depth);
+                        I->getOperand(1), AllowEphemerals, Depth);
   case Instruction::Or:
     // (X | (X != 0)) is non zero
     if (matchOpWithOpEqZero(I->getOperand(0), I->getOperand(1)))
       return true;
     // X | Y != 0 if X != Y.
     if (isKnownNonEqual(I->getOperand(0), I->getOperand(1), DemandedElts, Q,
-                        Depth))
+                        AllowEphemerals, Depth))
       return true;
     // X | Y != 0 if X != 0 or Y != 0.
-    return isKnownNonZero(I->getOperand(1), DemandedElts, Q, Depth) ||
-           isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
+    return isKnownNonZero(I->getOperand(1), DemandedElts, Q, AllowEphemerals,
+                          Depth) ||
+           isKnownNonZero(I->getOperand(0), DemandedElts, Q, AllowEphemerals,
+                          Depth);
   case Instruction::SExt:
   case Instruction::ZExt:
     // ext X != 0 if X != 0.
-    return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
+    return isKnownNonZero(I->getOperand(0), DemandedElts, Q, AllowEphemerals,
+                          Depth);
 
   case Instruction::Shl: {
     // shl nsw/nuw can't remove any non-zero bits.
     const OverflowingBinaryOperator *BO = cast<OverflowingBinaryOperator>(I);
     if (Q.IIQ.hasNoUnsignedWrap(BO) || Q.IIQ.hasNoSignedWrap(BO))
-      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
+      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, AllowEphemerals,
+                            Depth);
 
     // shl X, Y != 0 if X is odd.  Note that the value of the shift is undefined
     // if the lowest bit is shifted off the end.
     KnownBits Known(BitWidth);
-    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, Depth);
+    computeKnownBits(I->getOperand(0), DemandedElts, Known, Q, AllowEphemerals,
+                     Depth);
     if (Known.One[0])
       return true;
 
-    return isNonZeroShift(I, DemandedElts, Q, Known, Depth);
+    return isNonZeroShift(I, DemandedElts, Q, Known, AllowEphemerals, Depth);
   }
   case Instruction::LShr:
   case Instruction::AShr: {
     // shr exact can only shift out zero bits.
     const PossiblyExactOperator *BO = cast<PossiblyExactOperator>(I);
     if (BO->isExact())
-      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
+      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, AllowEphemerals,
+                            Depth);
 
     // shr X, Y != 0 if X is negative.  Note that the value of the shift is not
     // defined if the sign bit is shifted off the end.
-    KnownBits Known =
-        computeKnownBits(I->getOperand(0), DemandedElts, Q, Depth);
+    KnownBits Known = computeKnownBits(I->getOperand(0), DemandedElts, Q,
+                                       AllowEphemerals, Depth);
     if (Known.isNegative())
       return true;
 
-    return isNonZeroShift(I, DemandedElts, Q, Known, Depth);
+    return isNonZeroShift(I, DemandedElts, Q, Known, AllowEphemerals, Depth);
   }
   case Instruction::UDiv:
   case Instruction::SDiv: {
     // X / Y
     // div exact can only produce a zero if the dividend is zero.
     if (cast<PossiblyExactOperator>(I)->isExact())
-      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, Depth);
+      return isKnownNonZero(I->getOperand(0), DemandedElts, Q, AllowEphemerals,
+                            Depth);
 
-    KnownBits XKnown =
-        computeKnownBits(I->getOperand(0), DemandedElts, Q, Depth);
+    KnownBits XKnown = computeKnownBits(I->getOperand(0), DemandedElts, Q,
+                                        AllowEphemerals, Depth);
     // If X is fully unknown we won't be able to figure anything out so don't
     // both computing knownbits for Y.
     if (XKnown.isUnknown())
       return false;
 
-    KnownBits YKnown =
-        computeKnownBits(I->getOperand(1), DemandedElts, Q, Depth);
+    KnownBits YKnown = computeKnownBits(I->getOperand(1), DemandedElts, Q,
+                                        AllowEphemerals, Depth);
     if (I->getOpcode() == Instruction::SDiv) {
       // For signed division need to compare abs value of the operands.
       XKnown = XKnown.abs(/*IntMinIsPoison*/ false);
@@ -3366,13 +3483,13 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
     auto *BO = cast<OverflowingBinaryOperator>(I);
     return isNonZeroAdd(DemandedElts, Q, BitWidth, I->getOperand(0),
                         I->getOperand(1), Q.IIQ.hasNoSignedWrap(BO),
-                        Q.IIQ.hasNoUnsignedWrap(BO), Depth);
+                        Q.IIQ.hasNoUnsignedWrap(BO), AllowEphemerals, Depth);
   }
   case Instruction::Mul: {
     const OverflowingBinaryOperator *BO = cast<OverflowingBinaryOperator>(I);
     return isNonZeroMul(DemandedElts, Q, BitWidth, I->getOperand(0),
                         I->getOperand(1), Q.IIQ.hasNoSignedWrap(BO),
-                        Q.IIQ.hasNoUnsignedWrap(BO), Depth);
+                        Q.IIQ.hasNoUnsignedWrap(BO), AllowEphemerals, Depth);
   }
   case Instruction::Select: {
     // (C ? X : Y) != 0 if X != 0 and Y != 0.
@@ -3385,7 +3502,7 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
       Value *Op;
       Op = IsTrueArm ? I->getOperand(1) : I->getOperand(2);
       // Op is trivially non-zero.
-      if (isKnownNonZero(Op, DemandedElts, Q, Depth))
+      if (isKnownNonZero(Op, DemandedElts, Q, AllowEphemerals, Depth))
         return true;
 
       // The condition of the select dominates the true/false arm. Check if the
@@ -3435,7 +3552,8 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
         }
       }
       // Finally recurse on the edge and check it directly.
-      return isKnownNonZero(U.get(), DemandedElts, RecQ, NewDepth);
+      return isKnownNonZero(U.get(), DemandedElts, RecQ, AllowEphemerals,
+                            NewDepth);
     });
   }
   case Instruction::InsertElement: {
@@ -3457,9 +3575,9 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
 
     // Result is zero if Elt is non-zero and rest of the demanded elts in Vec
     // are non-zero.
-    return (SkipElt || isKnownNonZero(Elt, Q, Depth)) &&
+    return (SkipElt || isKnownNonZero(Elt, Q, AllowEphemerals, Depth)) &&
            (DemandedVecElts.isZero() ||
-            isKnownNonZero(Vec, DemandedVecElts, Q, Depth));
+            isKnownNonZero(Vec, DemandedVecElts, Q, AllowEphemerals, Depth));
   }
   case Instruction::ExtractElement:
     if (const auto *EEI = dyn_cast<ExtractElementInst>(I)) {
@@ -3471,7 +3589,7 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
         APInt DemandedVecElts = APInt::getAllOnes(NumElts);
         if (CIdx && CIdx->getValue().ult(NumElts))
           DemandedVecElts = APInt::getOneBitSet(NumElts, CIdx->getZExtValue());
-        return isKnownNonZero(Vec, DemandedVecElts, Q, Depth);
+        return isKnownNonZero(Vec, DemandedVecElts, Q, AllowEphemerals, Depth);
       }
     }
     break;
@@ -3486,12 +3604,14 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
       break;
     // If demanded elements for both vecs are non-zero, the shuffle is non-zero.
     return (DemandedRHS.isZero() ||
-            isKnownNonZero(Shuf->getOperand(1), DemandedRHS, Q, Depth)) &&
+            isKnownNonZero(Shuf->getOperand(1), DemandedRHS, Q, AllowEphemerals,
+                           Depth)) &&
            (DemandedLHS.isZero() ||
-            isKnownNonZero(Shuf->getOperand(0), DemandedLHS, Q, Depth));
+            isKnownNonZero(Shuf->getOperand(0), DemandedLHS, Q, AllowEphemerals,
+                           Depth));
   }
   case Instruction::Freeze:
-    return isKnownNonZero(I->getOperand(0), Q, Depth) &&
+    return isKnownNonZero(I->getOperand(0), Q, AllowEphemerals, Depth) &&
            isGuaranteedNotToBePoison(I->getOperand(0), Q.AC, Q.CxtI, Q.DT,
                                      Depth);
   case Instruction::Load: {
@@ -3521,14 +3641,15 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
         return isNonZeroAdd(DemandedElts, Q, BitWidth, WO->getArgOperand(0),
                             WO->getArgOperand(1),
                             /*NSW=*/false,
-                            /*NUW=*/false, Depth);
+                            /*NUW=*/false, AllowEphemerals, Depth);
       case Instruction::Sub:
         return isNonZeroSub(DemandedElts, Q, BitWidth, WO->getArgOperand(0),
-                            WO->getArgOperand(1), Depth);
+                            WO->getArgOperand(1), AllowEphemerals, Depth);
       case Instruction::Mul:
         return isNonZeroMul(DemandedElts, Q, BitWidth, WO->getArgOperand(0),
                             WO->getArgOperand(1),
-                            /*NSW=*/false, /*NUW=*/false, Depth);
+                            /*NSW=*/false, /*NUW=*/false, AllowEphemerals,
+                            Depth);
         break;
       }
     }
@@ -3541,7 +3662,7 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
       if (Call->isReturnNonNull())
         return true;
       if (const auto *RP = getArgumentAliasingToReturnedPointer(Call, true))
-        return isKnownNonZero(RP, Q, Depth);
+        return isKnownNonZero(RP, Q, AllowEphemerals, Depth);
     } else {
       if (MDNode *Ranges = Q.IIQ.getMetadata(Call, LLVMContext::MD_range))
         return rangeMetadataExcludesValue(Ranges, APInt::getZero(BitWidth));
@@ -3551,7 +3672,8 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
           return true;
       }
       if (const Value *RV = Call->getReturnedArgOperand())
-        if (RV->getType() == I->getType() && isKnownNonZero(RV, Q, Depth))
+        if (RV->getType() == I->getType() &&
+            isKnownNonZero(RV, Q, AllowEphemerals, Depth))
           return true;
     }
 
@@ -3563,7 +3685,8 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
       case Intrinsic::bitreverse:
       case Intrinsic::bswap:
       case Intrinsic::ctpop:
-        return isKnownNonZero(II->getArgOperand(0), DemandedElts, Q, Depth);
+        return isKnownNonZero(II->getArgOperand(0), DemandedElts, Q,
+                              AllowEphemerals, Depth);
         // NB: We don't do usub_sat here as in any case we can prove its
         // non-zero, we will fold it to `sub nuw` in InstCombine.
       case Intrinsic::ssub_sat:
@@ -3573,22 +3696,23 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
         if (BitWidth == 1)
           return false;
         return isNonZeroSub(DemandedElts, Q, BitWidth, II->getArgOperand(0),
-                            II->getArgOperand(1), Depth);
+                            II->getArgOperand(1), AllowEphemerals, Depth);
       case Intrinsic::sadd_sat:
         return isNonZeroAdd(DemandedElts, Q, BitWidth, II->getArgOperand(0),
                             II->getArgOperand(1),
-                            /*NSW=*/true, /* NUW=*/false, Depth);
+                            /*NSW=*/true, /* NUW=*/false, AllowEphemerals,
+                            Depth);
         // Vec reverse preserves zero/non-zero status from input vec.
       case Intrinsic::vector_reverse:
         return isKnownNonZero(II->getArgOperand(0), DemandedElts.reverseBits(),
-                              Q, Depth);
+                              Q, AllowEphemerals, Depth);
         // umin/smin/smax/smin/or of all non-zero elements is always non-zero.
       case Intrinsic::vector_reduce_or:
       case Intrinsic::vector_reduce_umax:
       case Intrinsic::vector_reduce_umin:
       case Intrinsic::vector_reduce_smax:
       case Intrinsic::vector_reduce_smin:
-        return isKnownNonZero(II->getArgOperand(0), Q, Depth);
+        return isKnownNonZero(II->getArgOperand(0), Q, AllowEphemerals, Depth);
       case Intrinsic::umax:
       case Intrinsic::uadd_sat:
         // umax(X, (X != 0)) is non zero
@@ -3596,27 +3720,30 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
         if (matchOpWithOpEqZero(II->getArgOperand(0), II->getArgOperand(1)))
           return true;
 
-        return isKnownNonZero(II->getArgOperand(1), DemandedElts, Q, Depth) ||
-               isKnownNonZero(II->getArgOperand(0), DemandedElts, Q, Depth);
+        return isKnownNonZero(II->getArgOperand(1), DemandedElts, Q,
+                              AllowEphemerals, Depth) ||
+               isKnownNonZero(II->getArgOperand(0), DemandedElts, Q,
+                              AllowEphemerals, Depth);
       case Intrinsic::smax: {
         // If either arg is strictly positive the result is non-zero. Otherwise
         // the result is non-zero if both ops are non-zero.
         auto IsNonZero = [&](Value *Op, std::optional<bool> &OpNonZero,
                              const KnownBits &OpKnown) {
           if (!OpNonZero.has_value())
-            OpNonZero = OpKnown.isNonZero() ||
-                        isKnownNonZero(Op, DemandedElts, Q, Depth);
+            OpNonZero =
+                OpKnown.isNonZero() ||
+                isKnownNonZero(Op, DemandedElts, Q, AllowEphemerals, Depth);
           return *OpNonZero;
         };
         // Avoid re-computing isKnownNonZero.
         std::optional<bool> Op0NonZero, Op1NonZero;
-        KnownBits Op1Known =
-            computeKnownBits(II->getArgOperand(1), DemandedElts, Q, Depth);
+        KnownBits Op1Known = computeKnownBits(
+            II->getArgOperand(1), DemandedElts, Q, AllowEphemerals, Depth);
         if (Op1Known.isNonNegative() &&
             IsNonZero(II->getArgOperand(1), Op1NonZero, Op1Known))
           return true;
-        KnownBits Op0Known =
-            computeKnownBits(II->getArgOperand(0), DemandedElts, Q, Depth);
+        KnownBits Op0Known = computeKnownBits(
+            II->getArgOperand(0), DemandedElts, Q, AllowEphemerals, Depth);
         if (Op0Known.isNonNegative() &&
             IsNonZero(II->getArgOperand(0), Op0NonZero, Op0Known))
           return true;
@@ -3626,12 +3753,12 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
       case Intrinsic::smin: {
         // If either arg is negative the result is non-zero. Otherwise
         // the result is non-zero if both ops are non-zero.
-        KnownBits Op1Known =
-            computeKnownBits(II->getArgOperand(1), DemandedElts, Q, Depth);
+        KnownBits Op1Known = computeKnownBits(
+            II->getArgOperand(1), DemandedElts, Q, AllowEphemerals, Depth);
         if (Op1Known.isNegative())
           return true;
-        KnownBits Op0Known =
-            computeKnownBits(II->getArgOperand(0), DemandedElts, Q, Depth);
+        KnownBits Op0Known = computeKnownBits(
+            II->getArgOperand(0), DemandedElts, Q, AllowEphemerals, Depth);
         if (Op0Known.isNegative())
           return true;
 
@@ -3640,24 +3767,29 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
       }
         [[fallthrough]];
       case Intrinsic::umin:
-        return isKnownNonZero(II->getArgOperand(0), DemandedElts, Q, Depth) &&
-               isKnownNonZero(II->getArgOperand(1), DemandedElts, Q, Depth);
+        return isKnownNonZero(II->getArgOperand(0), DemandedElts, Q,
+                              AllowEphemerals, Depth) &&
+               isKnownNonZero(II->getArgOperand(1), DemandedElts, Q,
+                              AllowEphemerals, Depth);
       case Intrinsic::cttz:
-        return computeKnownBits(II->getArgOperand(0), DemandedElts, Q, Depth)
+        return computeKnownBits(II->getArgOperand(0), DemandedElts, Q,
+                                AllowEphemerals, Depth)
             .Zero[0];
       case Intrinsic::ctlz:
-        return computeKnownBits(II->getArgOperand(0), DemandedElts, Q, Depth)
+        return computeKnownBits(II->getArgOperand(0), DemandedElts, Q,
+                                AllowEphemerals, Depth)
             .isNonNegative();
       case Intrinsic::fshr:
       case Intrinsic::fshl:
         // If Op0 == Op1, this is a rotate. rotate(x, y) != 0 iff x != 0.
         if (II->getArgOperand(0) == II->getArgOperand(1))
-          return isKnownNonZero(II->getArgOperand(0), DemandedElts, Q, Depth);
+          return isKnownNonZero(II->getArgOperand(0), DemandedElts, Q,
+                                AllowEphemerals, Depth);
         break;
       case Intrinsic::vscale:
         return true;
       case Intrinsic::experimental_get_vector_length:
-        return isKnownNonZero(I->getOperand(0), Q, Depth);
+        return isKnownNonZero(I->getOperand(0), Q, AllowEphemerals, Depth);
       default:
         break;
       }
@@ -3669,7 +3801,7 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
   }
 
   KnownBits Known(BitWidth);
-  computeKnownBits(I, DemandedElts, Known, Q, Depth);
+  computeKnownBits(I, DemandedElts, Known, Q, AllowEphemerals, Depth);
   return Known.One != 0;
 }
 
@@ -3680,7 +3812,8 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
 /// pointer couldn't possibly be null at the specified instruction.
 /// Supports values with integer or pointer type and vectors of integers.
 bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
-                    const SimplifyQuery &Q, unsigned Depth) {
+                    const SimplifyQuery &Q, bool AllowEphemerals,
+                    unsigned Depth) {
   Type *Ty = V->getType();
 
 #ifndef NDEBUG
@@ -3720,7 +3853,8 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
 
     // Constant ptrauth can be null, iff the base pointer can be.
     if (auto *CPA = dyn_cast<ConstantPtrAuth>(V))
-      return isKnownNonZero(CPA->getPointer(), DemandedElts, Q, Depth);
+      return isKnownNonZero(CPA->getPointer(), DemandedElts, Q, AllowEphemerals,
+                            Depth);
 
     // A global variable in address space 0 is non null unless extern weak
     // or an absolute symbol reference. Other address spaces may have null as a
@@ -3764,7 +3898,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
   }
 
   if (const auto *I = dyn_cast<Operator>(V))
-    if (isKnownNonZeroFromOperator(I, DemandedElts, Q, Depth))
+    if (isKnownNonZeroFromOperator(I, DemandedElts, Q, AllowEphemerals, Depth))
       return true;
 
   if (!isa<Constant>(V) &&
@@ -3772,17 +3906,17 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
     return true;
 
   if (const Value *Stripped = stripNullTest(V))
-    return isKnownNonZero(Stripped, DemandedElts, Q, Depth);
+    return isKnownNonZero(Stripped, DemandedElts, Q, AllowEphemerals, Depth);
 
   return false;
 }
 
 bool llvm::isKnownNonZero(const Value *V, const SimplifyQuery &Q,
-                          unsigned Depth) {
+                          bool AllowEphemerals, unsigned Depth) {
   auto *FVTy = dyn_cast<FixedVectorType>(V->getType());
   APInt DemandedElts =
       FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1);
-  return ::isKnownNonZero(V, DemandedElts, Q, Depth);
+  return ::isKnownNonZero(V, DemandedElts, Q, AllowEphemerals, Depth);
 }
 
 /// If the pair of operators are the same invertible function, return the
@@ -3910,7 +4044,8 @@ getInvertibleOperands(const Operator *Op1,
 /// implies V2 != V1.
 static bool isModifyingBinopOfNonZero(const Value *V1, const Value *V2,
                                       const APInt &DemandedElts,
-                                      const SimplifyQuery &Q, unsigned Depth) {
+                                      const SimplifyQuery &Q,
+                                      bool AllowEphemerals, unsigned Depth) {
   const BinaryOperator *BO = dyn_cast<BinaryOperator>(V1);
   if (!BO)
     return false;
@@ -3930,7 +4065,7 @@ static bool isModifyingBinopOfNonZero(const Value *V1, const Value *V2,
       Op = BO->getOperand(0);
     else
       return false;
-    return isKnownNonZero(Op, DemandedElts, Q, Depth + 1);
+    return isKnownNonZero(Op, DemandedElts, Q, AllowEphemerals, Depth + 1);
   }
   return false;
 }
@@ -3939,13 +4074,13 @@ static bool isModifyingBinopOfNonZero(const Value *V1, const Value *V2,
 /// the multiplication is nuw or nsw.
 static bool isNonEqualMul(const Value *V1, const Value *V2,
                           const APInt &DemandedElts, const SimplifyQuery &Q,
-                          unsigned Depth) {
+                          bool AllowEphemerals, unsigned Depth) {
   if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(V2)) {
     const APInt *C;
     return match(OBO, m_Mul(m_Specific(V1), m_APInt(C))) &&
            (OBO->hasNoUnsignedWrap() || OBO->hasNoSignedWrap()) &&
            !C->isZero() && !C->isOne() &&
-           isKnownNonZero(V1, DemandedElts, Q, Depth + 1);
+           isKnownNonZero(V1, DemandedElts, Q, AllowEphemerals, Depth + 1);
   }
   return false;
 }
@@ -3954,19 +4089,20 @@ static bool isNonEqualMul(const Value *V1, const Value *V2,
 /// the shift is nuw or nsw.
 static bool isNonEqualShl(const Value *V1, const Value *V2,
                           const APInt &DemandedElts, const SimplifyQuery &Q,
-                          unsigned Depth) {
+                          bool AllowEphemerals, unsigned Depth) {
   if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(V2)) {
     const APInt *C;
     return match(OBO, m_Shl(m_Specific(V1), m_APInt(C))) &&
            (OBO->hasNoUnsignedWrap() || OBO->hasNoSignedWrap()) &&
-           !C->isZero() && isKnownNonZero(V1, DemandedElts, Q, Depth + 1);
+           !C->isZero() &&
+           isKnownNonZero(V1, DemandedElts, Q, AllowEphemerals, Depth + 1);
   }
   return false;
 }
 
 static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
                            const APInt &DemandedElts, const SimplifyQuery &Q,
-                           unsigned Depth) {
+                           bool AllowEphemerals, unsigned Depth) {
   // Check two PHIs are in same block.
   if (PN1->getParent() != PN2->getParent())
     return false;
@@ -3988,7 +4124,8 @@ static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
 
     SimplifyQuery RecQ = Q.getWithoutCondContext();
     RecQ.CxtI = IncomBB->getTerminator();
-    if (!isKnownNonEqual(IV1, IV2, DemandedElts, RecQ, Depth + 1))
+    if (!isKnownNonEqual(IV1, IV2, DemandedElts, RecQ, AllowEphemerals,
+                         Depth + 1))
       return false;
     UsedFullRecursion = true;
   }
@@ -3997,7 +4134,7 @@ static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
 
 static bool isNonEqualSelect(const Value *V1, const Value *V2,
                              const APInt &DemandedElts, const SimplifyQuery &Q,
-                             unsigned Depth) {
+                             bool AllowEphemerals, unsigned Depth) {
   const SelectInst *SI1 = dyn_cast<SelectInst>(V1);
   if (!SI1)
     return false;
@@ -4007,12 +4144,14 @@ static bool isNonEqualSelect(const Value *V1, const Value *V2,
     const Value *Cond2 = SI2->getCondition();
     if (Cond1 == Cond2)
       return isKnownNonEqual(SI1->getTrueValue(), SI2->getTrueValue(),
-                             DemandedElts, Q, Depth + 1) &&
+                             DemandedElts, Q, AllowEphemerals, Depth + 1) &&
              isKnownNonEqual(SI1->getFalseValue(), SI2->getFalseValue(),
-                             DemandedElts, Q, Depth + 1);
+                             DemandedElts, Q, AllowEphemerals, Depth + 1);
   }
-  return isKnownNonEqual(SI1->getTrueValue(), V2, DemandedElts, Q, Depth + 1) &&
-         isKnownNonEqual(SI1->getFalseValue(), V2, DemandedElts, Q, Depth + 1);
+  return isKnownNonEqual(SI1->getTrueValue(), V2, DemandedElts, Q,
+                         AllowEphemerals, Depth + 1) &&
+         isKnownNonEqual(SI1->getFalseValue(), V2, DemandedElts, Q,
+                         AllowEphemerals, Depth + 1);
 }
 
 // Check to see if A is both a GEP and is the incoming value for a PHI in the
@@ -4127,7 +4266,7 @@ static bool isKnownNonEqualFromContext(const Value *V1, const Value *V2,
 /// Return true if it is known that V1 != V2.
 static bool isKnownNonEqual(const Value *V1, const Value *V2,
                             const APInt &DemandedElts, const SimplifyQuery &Q,
-                            unsigned Depth) {
+                            bool AllowEphemerals, unsigned Depth) {
   if (V1 == V2)
     return false;
   if (V1->getType() != V2->getType())
@@ -4145,43 +4284,47 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2,
   if (O1 && O2 && O1->getOpcode() == O2->getOpcode()) {
     if (auto Values = getInvertibleOperands(O1, O2))
       return isKnownNonEqual(Values->first, Values->second, DemandedElts, Q,
-                             Depth + 1);
+                             AllowEphemerals, Depth + 1);
 
     if (const PHINode *PN1 = dyn_cast<PHINode>(V1)) {
       const PHINode *PN2 = cast<PHINode>(V2);
       // FIXME: This is missing a generalization to handle the case where one is
       // a PHI and another one isn't.
-      if (isNonEqualPHIs(PN1, PN2, DemandedElts, Q, Depth))
+      if (isNonEqualPHIs(PN1, PN2, DemandedElts, Q, AllowEphemerals, Depth))
         return true;
     };
   }
 
-  if (isModifyingBinopOfNonZero(V1, V2, DemandedElts, Q, Depth) ||
-      isModifyingBinopOfNonZero(V2, V1, DemandedElts, Q, Depth))
+  if (isModifyingBinopOfNonZero(V1, V2, DemandedElts, Q, AllowEphemerals,
+                                Depth) ||
+      isModifyingBinopOfNonZero(V2, V1, DemandedElts, Q, AllowEphemerals,
+                                Depth))
     return true;
 
-  if (isNonEqualMul(V1, V2, DemandedElts, Q, Depth) ||
-      isNonEqualMul(V2, V1, DemandedElts, Q, Depth))
+  if (isNonEqualMul(V1, V2, DemandedElts, Q, AllowEphemerals, Depth) ||
+      isNonEqualMul(V2, V1, DemandedElts, Q, AllowEphemerals, Depth))
     return true;
 
-  if (isNonEqualShl(V1, V2, DemandedElts, Q, Depth) ||
-      isNonEqualShl(V2, V1, DemandedElts, Q, Depth))
+  if (isNonEqualShl(V1, V2, DemandedElts, Q, AllowEphemerals, Depth) ||
+      isNonEqualShl(V2, V1, DemandedElts, Q, AllowEphemerals, Depth))
     return true;
 
   if (V1->getType()->isIntOrIntVectorTy()) {
     // Are any known bits in V1 contradictory to known bits in V2? If V1
     // has a known zero where V2 has a known one, they must not be equal.
-    KnownBits Known1 = computeKnownBits(V1, DemandedElts, Q, Depth);
+    KnownBits Known1 =
+        computeKnownBits(V1, DemandedElts, Q, AllowEphemerals, Depth);
     if (!Known1.isUnknown()) {
-      KnownBits Known2 = computeKnownBits(V2, DemandedElts, Q, Depth);
+      KnownBits Known2 =
+          computeKnownBits(V2, DemandedElts, Q, AllowEphemerals, Depth);
       if (Known1.Zero.intersects(Known2.One) ||
           Known2.Zero.intersects(Known1.One))
         return true;
     }
   }
 
-  if (isNonEqualSelect(V1, V2, DemandedElts, Q, Depth) ||
-      isNonEqualSelect(V2, V1, DemandedElts, Q, Depth))
+  if (isNonEqualSelect(V1, V2, DemandedElts, Q, AllowEphemerals, Depth) ||
+      isNonEqualSelect(V2, V1, DemandedElts, Q, AllowEphemerals, Depth))
     return true;
 
   if (isNonEqualPointersWithRecursiveGEP(V1, V2, Q) ||
@@ -4193,7 +4336,7 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2,
   // Check PtrToInt type matches the pointer size.
   if (match(V1, m_PtrToIntSameSize(Q.DL, m_Value(A))) &&
       match(V2, m_PtrToIntSameSize(Q.DL, m_Value(B))))
-    return isKnownNonEqual(A, B, DemandedElts, Q, Depth + 1);
+    return isKnownNonEqual(A, B, DemandedElts, Q, AllowEphemerals, Depth + 1);
 
   if (isKnownNonEqualFromContext(V1, V2, Q, Depth))
     return true;
@@ -4230,14 +4373,24 @@ static unsigned computeNumSignBitsVectorConstant(const Value *V,
 
 static unsigned ComputeNumSignBitsImpl(const Value *V,
                                        const APInt &DemandedElts,
-                                       const SimplifyQuery &Q, unsigned Depth);
+                                       const SimplifyQuery &Q,
+                                       bool AllowEphemerals, unsigned Depth);
+
+template <class T>
+void ComputeNumSignBitsImpl(const Value *, const APInt &, const SimplifyQuery &,
+                            T &&, unsigned = 0) = delete;
 
 static unsigned ComputeNumSignBits(const Value *V, const APInt &DemandedElts,
-                                   const SimplifyQuery &Q, unsigned Depth) {
-  unsigned Result = ComputeNumSignBitsImpl(V, DemandedElts, Q, Depth);
+                                   const SimplifyQuery &Q, bool AllowEphemerals,
+                                   unsigned Depth) {
+  unsigned Result =
+      ComputeNumSignBitsImpl(V, DemandedElts, Q, AllowEphemerals, Depth);
   assert(Result > 0 && "At least one sign bit needs to be present!");
   return Result;
 }
+template <class T>
+void ComputeNumSignBits(const Value *, const APInt &, const SimplifyQuery &,
+                        T &&, unsigned = 0) = delete;
 
 /// Return the number of times the sign bit of the register is replicated into
 /// the other bits. We know that at least 1 bit is always equal to the sign bit
@@ -4248,7 +4401,8 @@ static unsigned ComputeNumSignBits(const Value *V, const APInt &DemandedElts,
 /// elements in the vector specified by DemandedElts.
 static unsigned ComputeNumSignBitsImpl(const Value *V,
                                        const APInt &DemandedElts,
-                                       const SimplifyQuery &Q, unsigned Depth) {
+                                       const SimplifyQuery &Q,
+                                       bool AllowEphemerals, unsigned Depth) {
   Type *Ty = V->getType();
 #ifndef NDEBUG
   assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
@@ -4303,7 +4457,7 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
       if (isa<FixedVectorType>(Ty)) {
         // Fast case - sign splat can be simply split across the small elements.
         // This works for both vector and scalar sources
-        Tmp = ComputeNumSignBits(Src, Q, Depth + 1);
+        Tmp = ComputeNumSignBits(Src, Q, AllowEphemerals, Depth + 1);
         if (Tmp == SrcBits)
           return TyBits;
       }
@@ -4311,7 +4465,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
     }
     case Instruction::SExt:
       Tmp = TyBits - U->getOperand(0)->getType()->getScalarSizeInBits();
-      return ComputeNumSignBits(U->getOperand(0), DemandedElts, Q, Depth + 1) +
+      return ComputeNumSignBits(U->getOperand(0), DemandedElts, Q,
+                                AllowEphemerals, Depth + 1) +
              Tmp;
 
     case Instruction::SDiv: {
@@ -4324,8 +4479,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
           break;
 
         // Calculate the incoming numerator bits.
-        unsigned NumBits =
-            ComputeNumSignBits(U->getOperand(0), DemandedElts, Q, Depth + 1);
+        unsigned NumBits = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q,
+                                              AllowEphemerals, Depth + 1);
 
         // Add floor(log(C)) bits to the numerator bits.
         return std::min(TyBits, NumBits + Denominator->logBase2());
@@ -4334,7 +4489,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
     }
 
     case Instruction::SRem: {
-      Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q, Depth + 1);
+      Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q,
+                               AllowEphemerals, Depth + 1);
 
       const APInt *Denominator;
       // srem X, C -> we know that the result is within [-C+1,C) when C is a
@@ -4365,7 +4521,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
     }
 
     case Instruction::AShr: {
-      Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q, Depth + 1);
+      Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q,
+                               AllowEphemerals, Depth + 1);
       // ashr X, C   -> adds C sign bits.  Vectors too.
       const APInt *ShAmt;
       if (match(U->getOperand(1), m_APInt(ShAmt))) {
@@ -4388,11 +4545,12 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
         // all extended bits are shifted out.
         if (match(U->getOperand(0), m_ZExt(m_Value(X))) &&
             ShAmt->uge(TyBits - X->getType()->getScalarSizeInBits())) {
-          Tmp = ComputeNumSignBits(X, DemandedElts, Q, Depth + 1);
+          Tmp = ComputeNumSignBits(X, DemandedElts, Q, AllowEphemerals,
+                                   Depth + 1);
           Tmp += TyBits - X->getType()->getScalarSizeInBits();
         } else
-          Tmp =
-              ComputeNumSignBits(U->getOperand(0), DemandedElts, Q, Depth + 1);
+          Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q,
+                                   AllowEphemerals, Depth + 1);
         if (ShAmt->uge(Tmp))
           break; // Shifted all sign bits out.
         Tmp2 = ShAmt->getZExtValue();
@@ -4404,9 +4562,11 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
     case Instruction::Or:
     case Instruction::Xor: // NOT is handled here.
       // Logical binary ops preserve the number of sign bits at the worst.
-      Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q, Depth + 1);
+      Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q,
+                               AllowEphemerals, Depth + 1);
       if (Tmp != 1) {
-        Tmp2 = ComputeNumSignBits(U->getOperand(1), DemandedElts, Q, Depth + 1);
+        Tmp2 = ComputeNumSignBits(U->getOperand(1), DemandedElts, Q,
+                                  AllowEphemerals, Depth + 1);
         FirstAnswer = std::min(Tmp, Tmp2);
         // We computed what we know about the sign bits as our first
         // answer. Now proceed to the generic code that uses
@@ -4422,24 +4582,28 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
       if (isSignedMinMaxClamp(U, X, CLow, CHigh))
         return std::min(CLow->getNumSignBits(), CHigh->getNumSignBits());
 
-      Tmp = ComputeNumSignBits(U->getOperand(1), DemandedElts, Q, Depth + 1);
+      Tmp = ComputeNumSignBits(U->getOperand(1), DemandedElts, Q,
+                               AllowEphemerals, Depth + 1);
       if (Tmp == 1)
         break;
-      Tmp2 = ComputeNumSignBits(U->getOperand(2), DemandedElts, Q, Depth + 1);
+      Tmp2 = ComputeNumSignBits(U->getOperand(2), DemandedElts, Q,
+                                AllowEphemerals, Depth + 1);
       return std::min(Tmp, Tmp2);
     }
 
     case Instruction::Add:
       // Add can have at most one carry bit.  Thus we know that the output
       // is, at worst, one more bit than the inputs.
-      Tmp = ComputeNumSignBits(U->getOperand(0), Q, Depth + 1);
-      if (Tmp == 1) break;
+      Tmp = ComputeNumSignBits(U->getOperand(0), Q, AllowEphemerals, Depth + 1);
+      if (Tmp == 1)
+        break;
 
       // Special case decrementing a value (ADD X, -1):
       if (const auto *CRHS = dyn_cast<Constant>(U->getOperand(1)))
         if (CRHS->isAllOnesValue()) {
           KnownBits Known(TyBits);
-          computeKnownBits(U->getOperand(0), DemandedElts, Known, Q, Depth + 1);
+          computeKnownBits(U->getOperand(0), DemandedElts, Known, Q,
+                           AllowEphemerals, Depth + 1);
 
           // If the input is known to be 0 or 1, the output is 0/-1, which is
           // all sign bits set.
@@ -4452,13 +4616,15 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
             return Tmp;
         }
 
-      Tmp2 = ComputeNumSignBits(U->getOperand(1), DemandedElts, Q, Depth + 1);
+      Tmp2 = ComputeNumSignBits(U->getOperand(1), DemandedElts, Q,
+                                AllowEphemerals, Depth + 1);
       if (Tmp2 == 1)
         break;
       return std::min(Tmp, Tmp2) - 1;
 
     case Instruction::Sub:
-      Tmp2 = ComputeNumSignBits(U->getOperand(1), DemandedElts, Q, Depth + 1);
+      Tmp2 = ComputeNumSignBits(U->getOperand(1), DemandedElts, Q,
+                                AllowEphemerals, Depth + 1);
       if (Tmp2 == 1)
         break;
 
@@ -4466,7 +4632,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
       if (const auto *CLHS = dyn_cast<Constant>(U->getOperand(0)))
         if (CLHS->isNullValue()) {
           KnownBits Known(TyBits);
-          computeKnownBits(U->getOperand(1), DemandedElts, Known, Q, Depth + 1);
+          computeKnownBits(U->getOperand(1), DemandedElts, Known, Q,
+                           AllowEphemerals, Depth + 1);
           // If the input is known to be 0 or 1, the output is 0/-1, which is
           // all sign bits set.
           if ((Known.Zero | 1).isAllOnes())
@@ -4483,7 +4650,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
 
       // Sub can have at most one carry bit.  Thus we know that the output
       // is, at worst, one more bit than the inputs.
-      Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q, Depth + 1);
+      Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q,
+                               AllowEphemerals, Depth + 1);
       if (Tmp == 1)
         break;
       return std::min(Tmp, Tmp2) - 1;
@@ -4491,12 +4659,12 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
     case Instruction::Mul: {
       // The output of the Mul can be at most twice the valid bits in the
       // inputs.
-      unsigned SignBitsOp0 =
-          ComputeNumSignBits(U->getOperand(0), DemandedElts, Q, Depth + 1);
+      unsigned SignBitsOp0 = ComputeNumSignBits(U->getOperand(0), DemandedElts,
+                                                Q, AllowEphemerals, Depth + 1);
       if (SignBitsOp0 == 1)
         break;
-      unsigned SignBitsOp1 =
-          ComputeNumSignBits(U->getOperand(1), DemandedElts, Q, Depth + 1);
+      unsigned SignBitsOp1 = ComputeNumSignBits(U->getOperand(1), DemandedElts,
+                                                Q, AllowEphemerals, Depth + 1);
       if (SignBitsOp1 == 1)
         break;
       unsigned OutValidBits =
@@ -4519,8 +4687,9 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
       for (unsigned i = 0, e = NumIncomingValues; i != e; ++i) {
         if (Tmp == 1) return Tmp;
         RecQ.CxtI = PN->getIncomingBlock(i)->getTerminator();
-        Tmp = std::min(Tmp, ComputeNumSignBits(PN->getIncomingValue(i),
-                                               DemandedElts, RecQ, Depth + 1));
+        Tmp = std::min(Tmp,
+                       ComputeNumSignBits(PN->getIncomingValue(i), DemandedElts,
+                                          RecQ, AllowEphemerals, Depth + 1));
       }
       return Tmp;
     }
@@ -4529,8 +4698,9 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
       // If the input contained enough sign bits that some remain after the
       // truncation, then we can make use of that. Otherwise we don't know
       // anything.
-      Tmp = ComputeNumSignBits(U->getOperand(0), Q, Depth + 1);
-      unsigned OperandTyBits = U->getOperand(0)->getType()->getScalarSizeInBits();
+      Tmp = ComputeNumSignBits(U->getOperand(0), Q, AllowEphemerals, Depth + 1);
+      unsigned OperandTyBits =
+          U->getOperand(0)->getType()->getScalarSizeInBits();
       if (Tmp > (OperandTyBits - TyBits))
         return Tmp - (OperandTyBits - TyBits);
 
@@ -4542,7 +4712,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
       // skip tracking the specific element. But at least we might find
       // information valid for all elements of the vector (for example if vector
       // is sign extended, shifted, etc).
-      return ComputeNumSignBits(U->getOperand(0), Q, Depth + 1);
+      return ComputeNumSignBits(U->getOperand(0), Q, AllowEphemerals,
+                                Depth + 1);
 
     case Instruction::ShuffleVector: {
       // Collect the minimum number of sign bits that are shared by every vector
@@ -4560,7 +4731,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
       Tmp = std::numeric_limits<unsigned>::max();
       if (!!DemandedLHS) {
         const Value *LHS = Shuf->getOperand(0);
-        Tmp = ComputeNumSignBits(LHS, DemandedLHS, Q, Depth + 1);
+        Tmp =
+            ComputeNumSignBits(LHS, DemandedLHS, Q, AllowEphemerals, Depth + 1);
       }
       // If we don't know anything, early out and try computeKnownBits
       // fall-back.
@@ -4568,7 +4740,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
         break;
       if (!!DemandedRHS) {
         const Value *RHS = Shuf->getOperand(1);
-        Tmp2 = ComputeNumSignBits(RHS, DemandedRHS, Q, Depth + 1);
+        Tmp2 =
+            ComputeNumSignBits(RHS, DemandedRHS, Q, AllowEphemerals, Depth + 1);
         Tmp = std::min(Tmp, Tmp2);
       }
       // If we don't know anything, early out and try computeKnownBits
@@ -4584,8 +4757,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
         default:
           break;
         case Intrinsic::abs:
-          Tmp =
-              ComputeNumSignBits(U->getOperand(0), DemandedElts, Q, Depth + 1);
+          Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Q,
+                                   AllowEphemerals, Depth + 1);
           if (Tmp == 1)
             break;
 
@@ -4613,7 +4786,7 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
     return VecSignBits;
 
   KnownBits Known(TyBits);
-  computeKnownBits(V, DemandedElts, Known, Q, Depth);
+  computeKnownBits(V, DemandedElts, Known, Q, AllowEphemerals, Depth);
 
   // If we know that the sign bit is either zero or one, determine the number of
   // identical bits in the top of the input value.
@@ -4936,8 +5109,8 @@ static void computeKnownFPClassForFPTrunc(const Operator *Op,
                                           KnownFPClass &Known,
                                           const SimplifyQuery &Q,
                                           unsigned Depth) {
-  if ((InterestedClasses &
-       (KnownFPClass::OrderedLessThanZeroMask | fcNan)) == fcNone)
+  if ((InterestedClasses & (KnownFPClass::OrderedLessThanZeroMask | fcNan)) ==
+      fcNone)
     return;
 
   KnownFPClass KnownSrc;
@@ -5460,7 +5633,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
       unsigned BitWidth = ExpTy->getScalarType()->getIntegerBitWidth();
       KnownBits ExponentKnownBits(BitWidth);
       computeKnownBits(Exp, isa<VectorType>(ExpTy) ? DemandedElts : APInt(1, 1),
-                       ExponentKnownBits, Q, Depth + 1);
+                       ExponentKnownBits, Q, false, Depth + 1);
 
       FPClassTest InterestedSrcs = fcNone;
       if (InterestedClasses & fcNan)
@@ -5490,7 +5663,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
       KnownBits ExpBits;
       if ((KnownSrc.KnownFPClasses & ExpInfoMask) != fcNone) {
         const Value *ExpArg = II->getArgOperand(1);
-        ExpBits = computeKnownBits(ExpArg, DemandedElts, Q, Depth + 1);
+        ExpBits = computeKnownBits(ExpArg, DemandedElts, Q,
+                                   /*AllowEphemerals=*/true, Depth + 1);
       }
 
       const fltSemantics &Flt =
@@ -5850,8 +6024,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
     if (!(InterestedClasses & (fcPosZero | fcNormal | fcInf)))
       break;
 
-    KnownBits IntKnown =
-        computeKnownBits(Op->getOperand(0), DemandedElts, Q, Depth + 1);
+    KnownBits IntKnown = computeKnownBits(Op->getOperand(0), DemandedElts, Q,
+                                          /*AllowEphemerals=*/true, Depth + 1);
 
     // If the integer is non-zero, the result cannot be +0.0
     if (IntKnown.isNonZero())
@@ -6116,7 +6290,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
 
     const Type *EltTy = Ty->getScalarType();
     KnownBits Bits(EltTy->getPrimitiveSizeInBits());
-    computeKnownBits(Src, DemandedElts, Bits, Q, Depth + 1);
+    computeKnownBits(Src, DemandedElts, Bits, Q, false, Depth + 1);
 
     Known = KnownFPClass::bitcast(EltTy->getFltSemantics(), Bits);
     break;
@@ -7405,8 +7579,8 @@ OverflowResult llvm::computeOverflowForSignedMul(const Value *LHS,
 
   // Note that underestimating the number of sign bits gives a more
   // conservative answer.
-  unsigned SignBits =
-      ::ComputeNumSignBits(LHS, SQ) + ::ComputeNumSignBits(RHS, SQ);
+  unsigned SignBits = ::ComputeNumSignBits(LHS, SQ, /*AllowEphemerals=*/true) +
+                      ::ComputeNumSignBits(RHS, SQ, /*AllowEphemerals=*/true);
 
   // First handle the easy case: if we have enough sign bits there's
   // definitely no overflow.
@@ -7464,7 +7638,8 @@ computeOverflowForSignedAdd(const WithCache<const Value *> &LHS,
   //
   // Since the carry into the most significant position is always equal to
   // the carry out of the addition, there is no signed overflow.
-  if (::ComputeNumSignBits(LHS, SQ) > 1 && ::ComputeNumSignBits(RHS, SQ) > 1)
+  if (::ComputeNumSignBits(LHS, SQ, /*AllowEphemerals=*/true) > 1 &&
+      ::ComputeNumSignBits(RHS, SQ, /*AllowEphemerals=*/true) > 1)
     return OverflowResult::NeverOverflows;
 
   ConstantRange LHSRange =
@@ -7551,7 +7726,8 @@ OverflowResult llvm::computeOverflowForSignedSub(const Value *LHS,
 
   // If LHS and RHS each have at least two sign bits, the subtraction
   // cannot overflow.
-  if (::ComputeNumSignBits(LHS, SQ) > 1 && ::ComputeNumSignBits(RHS, SQ) > 1)
+  if (::ComputeNumSignBits(LHS, SQ, /*AllowEphemerals=*/true) > 1 &&
+      ::ComputeNumSignBits(RHS, SQ, /*AllowEphemerals=*/true) > 1)
     return OverflowResult::NeverOverflows;
 
   ConstantRange LHSRange =
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index 09945044c79a1..706a977a5b6d5 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -1363,7 +1363,7 @@ CallInst *IRBuilderBase::CreateAlignmentAssumptionHelper(const DataLayout &DL,
 
 CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
                                                    Value *PtrValue,
-                                                   unsigned Alignment,
+                                                   uint64_t Alignment,
                                                    Value *OffsetValue) {
   assert(isa<PointerType>(PtrValue->getType()) &&
          "trying to create an alignment assumption on a non-pointer?");
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index da258b3b34e27..8682cc52c5bdc 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3677,10 +3677,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
         // Compute known bits for the pointer, passing nullptr as context to
         // avoid computeKnownBits using the assumption we are about to remove
         // for reasoning.
-        KnownBits Known = computeKnownBits(RK.WasOn, /*CtxI=*/nullptr);
-        unsigned TZ = std::min(Known.countMinTrailingZeros(),
-                               Value::MaxAlignmentExponent);
-        if ((1ULL << TZ) < RK.ArgValue)
+        KnownBits Known =
+            computeKnownBits(RK.WasOn, II, /*AllowEphemerals=*/false);
+        if ((1 << Known.countMinTrailingZeros()) < RK.ArgValue)
           continue;
         return CallBase::removeOperandBundle(II, OBU.getTagID());
       }
@@ -3739,6 +3738,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
         uint64_t Offset = 0;
         match(A, m_Add(m_Value(A), m_ConstantInt(Offset)));
         if (match(A, m_PtrToIntOrAddr(m_Value(A)))) {
+          Builder.CreateAlignmentAssumption(getDataLayout(), A,
+                                            MinAlign(Offset, AlignMask + 1));
+          return eraseInstFromFunction(*II);
           /// Note: this doesn't preserve the offset information but merges
           /// offset and alignment.
           /// TODO: we can generate a GEP instead of merging the alignment with
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 83ea2d2932ac9..778adca4fbc51 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -171,7 +171,7 @@ bool InstCombinerImpl::SimplifyDemandedBits(Instruction *I, unsigned OpNo,
   Use &U = I->getOperandUse(OpNo);
   Value *V = U.get();
   if (isa<Constant>(V)) {
-    llvm::computeKnownBits(V, Known, Q, Depth);
+    llvm::computeKnownBits(V, Known, Q, /*AllowEphemerals=*/true, Depth);
     return false;
   }
 
@@ -184,7 +184,7 @@ bool InstCombinerImpl::SimplifyDemandedBits(Instruction *I, unsigned OpNo,
 
   Instruction *VInst = dyn_cast<Instruction>(V);
   if (!VInst) {
-    llvm::computeKnownBits(V, Known, Q, Depth);
+    llvm::computeKnownBits(V, Known, Q, /*AllowEphemerals=*/true, Depth);
     return false;
   }
 
@@ -281,7 +281,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
 
   switch (I->getOpcode()) {
   default:
-    llvm::computeKnownBits(I, Known, Q, Depth);
+    llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     break;
   case Instruction::And: {
     // If either the LHS or the RHS are Zero, the result is zero.
@@ -291,7 +291,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
       return I;
 
     Known = analyzeKnownBitsFromAndXorOr(cast<Operator>(I), LHSKnown, RHSKnown,
-                                         Q, Depth);
+                                         Q, /*AllowEphemerals=*/true, Depth);
 
     // If the client is only demanding bits that we know, return the known
     // constant.
@@ -322,7 +322,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
     }
 
     Known = analyzeKnownBitsFromAndXorOr(cast<Operator>(I), LHSKnown, RHSKnown,
-                                         Q, Depth);
+                                         Q, /*AllowEphemerals=*/true, Depth);
 
     // If the client is only demanding bits that we know, return the known
     // constant.
@@ -367,7 +367,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
     }
 
     Known = analyzeKnownBitsFromAndXorOr(cast<Operator>(I), LHSKnown, RHSKnown,
-                                         Q, Depth);
+                                         Q, /*AllowEphemerals=*/true, Depth);
 
     // If the client is only demanding bits that we know, return the known
     // constant.
@@ -716,7 +716,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
       return InsertNewInstWith(And1, I->getIterator());
     }
 
-    llvm::computeKnownBits(I, Known, Q, Depth);
+    llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     break;
   }
   case Instruction::Shl: {
@@ -737,7 +737,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
             auto [IID, FShiftArgs] = *Opt;
             if ((IID == Intrinsic::fshl || IID == Intrinsic::fshr) &&
                 FShiftArgs[0] == FShiftArgs[1]) {
-              llvm::computeKnownBits(I, Known, Q, Depth);
+              llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true,
+                                     Depth);
               break;
             }
           }
@@ -802,7 +803,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
           return I;
         }
       }
-      llvm::computeKnownBits(I, Known, Q, Depth);
+      llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     }
     break;
   }
@@ -819,7 +820,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
             auto [IID, FShiftArgs] = *Opt;
             if ((IID == Intrinsic::fshl || IID == Intrinsic::fshr) &&
                 FShiftArgs[0] == FShiftArgs[1]) {
-              llvm::computeKnownBits(I, Known, Q, Depth);
+              llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true,
+                                     Depth);
               break;
             }
           }
@@ -880,7 +882,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
             simplifyShiftSelectingPackedElement(I, DemandedMask, *this, Depth))
       return V;
 
-    llvm::computeKnownBits(I, Known, Q, Depth);
+    llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     break;
   }
   case Instruction::AShr: {
@@ -934,7 +936,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
           Known, KnownBits::makeConstant(APInt(BitWidth, ShiftAmt)),
           ShiftAmt != 0, I->isExact());
     } else {
-      llvm::computeKnownBits(I, Known, Q, Depth);
+      llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     }
     break;
   }
@@ -956,7 +958,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
       Known = KnownBits::udiv(LHSKnown, KnownBits::makeConstant(*SA),
                               cast<BinaryOperator>(I)->isExact());
     } else {
-      llvm::computeKnownBits(I, Known, Q, Depth);
+      llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     }
     break;
   }
@@ -974,7 +976,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
       break;
     }
 
-    llvm::computeKnownBits(I, Known, Q, Depth);
+    llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     break;
   }
   case Instruction::Call: {
@@ -1186,7 +1188,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
     }
 
     if (!KnownBitsComputed)
-      llvm::computeKnownBits(I, Known, Q, Depth);
+      llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     break;
   }
   }
@@ -1205,7 +1207,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
     return Constant::getIntegerValue(VTy, Known.One);
 
   if (VerifyKnownBits) {
-    KnownBits ReferenceKnown = llvm::computeKnownBits(I, Q, Depth);
+    KnownBits ReferenceKnown =
+        llvm::computeKnownBits(I, Q, /*AllowEphemerals=*/true, Depth);
     if (Known != ReferenceKnown) {
       errs() << "Mismatched known bits for " << *I << " in "
              << I->getFunction()->getName() << "\n";
@@ -1236,11 +1239,13 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
   // this instruction has a simpler value in that context.
   switch (I->getOpcode()) {
   case Instruction::And: {
-    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q, Depth + 1);
-    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
     Known = analyzeKnownBitsFromAndXorOr(cast<Operator>(I), LHSKnown, RHSKnown,
-                                         Q, Depth);
-    computeKnownBitsFromContext(I, Known, Q, Depth);
+                                         Q, /*AllowEphemerals=*/true, Depth);
+    computeKnownBitsFromContext(I, Known, Q, /*AllowEphemerals=*/true, Depth);
 
     // If the client is only demanding bits that we know, return the known
     // constant.
@@ -1257,11 +1262,13 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
     break;
   }
   case Instruction::Or: {
-    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q, Depth + 1);
-    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
     Known = analyzeKnownBitsFromAndXorOr(cast<Operator>(I), LHSKnown, RHSKnown,
-                                         Q, Depth);
-    computeKnownBitsFromContext(I, Known, Q, Depth);
+                                         Q, /*AllowEphemerals=*/true, Depth);
+    computeKnownBitsFromContext(I, Known, Q, /*AllowEphemerals=*/true, Depth);
 
     // If the client is only demanding bits that we know, return the known
     // constant.
@@ -1280,11 +1287,13 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
     break;
   }
   case Instruction::Xor: {
-    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q, Depth + 1);
-    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
     Known = analyzeKnownBitsFromAndXorOr(cast<Operator>(I), LHSKnown, RHSKnown,
-                                         Q, Depth);
-    computeKnownBitsFromContext(I, Known, Q, Depth);
+                                         Q, /*AllowEphemerals=*/true, Depth);
+    computeKnownBitsFromContext(I, Known, Q, /*AllowEphemerals=*/true, Depth);
 
     // If the client is only demanding bits that we know, return the known
     // constant.
@@ -1307,18 +1316,20 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
 
     // If an operand adds zeros to every bit below the highest demanded bit,
     // that operand doesn't change the result. Return the other side.
-    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
     if (DemandedFromOps.isSubsetOf(RHSKnown.Zero))
       return I->getOperand(0);
 
-    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
     if (DemandedFromOps.isSubsetOf(LHSKnown.Zero))
       return I->getOperand(1);
 
     bool NSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
     bool NUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
     Known = KnownBits::add(LHSKnown, RHSKnown, NSW, NUW);
-    computeKnownBitsFromContext(I, Known, Q, Depth);
+    computeKnownBitsFromContext(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     break;
   }
   case Instruction::Sub: {
@@ -1327,20 +1338,22 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
 
     // If an operand subtracts zeros from every bit below the highest demanded
     // bit, that operand doesn't change the result. Return the other side.
-    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(1), RHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
     if (DemandedFromOps.isSubsetOf(RHSKnown.Zero))
       return I->getOperand(0);
 
     bool NSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
     bool NUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
-    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q, Depth + 1);
+    llvm::computeKnownBits(I->getOperand(0), LHSKnown, Q,
+                           /*AllowEphemerals=*/true, Depth + 1);
     Known = KnownBits::sub(LHSKnown, RHSKnown, NSW, NUW);
-    computeKnownBitsFromContext(I, Known, Q, Depth);
+    computeKnownBitsFromContext(I, Known, Q, /*AllowEphemerals=*/true, Depth);
     break;
   }
   case Instruction::AShr: {
     // Compute the Known bits to simplify things downstream.
-    llvm::computeKnownBits(I, Known, Q, Depth);
+    llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
 
     // If this user is only demanding bits that we know, return the known
     // constant.
@@ -1367,7 +1380,7 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedBits(
   }
   default:
     // Compute the Known bits to simplify things downstream.
-    llvm::computeKnownBits(I, Known, Q, Depth);
+    llvm::computeKnownBits(I, Known, Q, /*AllowEphemerals=*/true, Depth);
 
     // If this user is only demanding bits that we know, return the known
     // constant.
@@ -3210,8 +3223,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
       const fltSemantics &FltSem = EltTy->getFltSemantics();
       DenormalMode Mode = F.getDenormalMode(FltSem);
 
-      KnownBits KnownExpBits =
-          ::computeKnownBits(CI->getArgOperand(1), SQ, Depth + 1);
+      KnownBits KnownExpBits = ::computeKnownBits(
+          CI->getArgOperand(1), SQ, /*AllowEphemerals=*/true, Depth + 1);
 
       Known = KnownFPClass::ldexp(KnownSrc, KnownExpBits, FltSem, Mode);
       Known.knownNot(~DemandedMask);
diff --git a/llvm/test/Transforms/InstCombine/assume-redundant.ll b/llvm/test/Transforms/InstCombine/assume-redundant.ll
index 32d803e35a1c3..7e78b43e4e056 100644
--- a/llvm/test/Transforms/InstCombine/assume-redundant.ll
+++ b/llvm/test/Transforms/InstCombine/assume-redundant.ll
@@ -81,4 +81,3 @@ declare void @llvm.assume(i1) #1
 
 attributes #0 = { nounwind uwtable }
 attributes #1 = { nounwind }
-
diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index 6b43430229388..40fe2f5f46f1e 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -7,6 +7,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
 declare void @llvm.assume(i1) #1
+declare ptr @get_ptr()
 
 ; Check that the assume has not been removed:
 
@@ -80,6 +81,18 @@ entry:
   ret void
 }
 
+define void @redundant_align() {
+; CHECK-LABEL: @redundant_align(
+; CHECK-NEXT:    [[PTR:%.*]] = call ptr @get_ptr()
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 8) ]
+; CHECK-NEXT:    ret void
+;
+  %ptr = call ptr @get_ptr()
+  call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8) ]
+  call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8) ]
+  ret void
+}
+
 ; Same check as in @foo1, but make sure it works if the assume is first too.
 
 define i32 @foo2(ptr %a) #0 {



More information about the llvm-commits mailing list