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