[llvm] [InstCombine] Create a class to lazily track computed known bits (PR #66611)
Dhruv Chawla via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 17 05:14:05 PDT 2023
https://github.com/dc03 updated https://github.com/llvm/llvm-project/pull/66611
>From 9e6f0e2d919c432971b0b5e0db68ac6a7fa3f85c Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Sat, 2 Sep 2023 16:16:18 +0530
Subject: [PATCH 01/16] [InstCombine] Use CachedBitsValue for computing
KnownBits in visitAddSub
This patch changes a few functions to accept a CachedBitsValue(s) so that
known bits information computed in some callees can be propagated to
others from the top level visitAddSub caller.
This gives a speedup of 0.12%:
https://llvm-compile-time-tracker.com/compare.php?from=b6fb6e9ea4e04ed379cf4901f8691cebac412142&to=03910f6a07b9a38bff620c12c0fdf9d7835c48ac&stat=instructions:u
---
llvm/include/llvm/Analysis/ValueTracking.h | 20 ++++-
.../Transforms/InstCombine/InstCombiner.h | 7 +-
llvm/lib/Analysis/ValueTracking.cpp | 82 +++++++++----------
.../InstCombine/InstCombineAddSub.cpp | 9 +-
.../InstCombine/InstCombineInternal.h | 6 +-
5 files changed, 68 insertions(+), 56 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 25272e0581c9385..dc0736f66daf671 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Analysis/SimplifyQuery.h"
+#include "llvm/Analysis/CachedBitsValue.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/FMF.h"
@@ -90,6 +91,18 @@ KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
const DominatorTree *DT = nullptr,
bool UseInstrInfo = true);
+void computeKnownBits(const Value *V, const APInt &DemandedElts,
+ KnownBits &Known, unsigned Depth, const SimplifyQuery &Q);
+
+void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
+ const SimplifyQuery &Q);
+
+KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
+ unsigned Depth, const SimplifyQuery &Q);
+
+KnownBits computeKnownBits(const Value *V, unsigned Depth,
+ const SimplifyQuery &Q);
+
/// Compute known bits from the range metadata.
/// \p KnownZero the set of bits that are known to be zero
/// \p KnownOne the set of bits that are known to be one
@@ -107,7 +120,8 @@ KnownBits analyzeKnownBitsFromAndXorOr(
bool UseInstrInfo = true);
/// Return true if LHS and RHS have no common bits set.
-bool haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
+bool haveNoCommonBitsSet(const CachedBitsConstValue &LHSCache,
+ const CachedBitsConstValue &RHSCache,
const SimplifyQuery &SQ);
/// Return true if the given value is known to have exactly one bit set when
@@ -847,9 +861,9 @@ OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS,
const SimplifyQuery &SQ);
OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS,
const SimplifyQuery &SQ);
-OverflowResult computeOverflowForUnsignedAdd(const Value *LHS, const Value *RHS,
+OverflowResult computeOverflowForUnsignedAdd(const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
const SimplifyQuery &SQ);
-OverflowResult computeOverflowForSignedAdd(const Value *LHS, const Value *RHS,
+OverflowResult computeOverflowForSignedAdd(const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
const SimplifyQuery &SQ);
/// This version also leverages the sign bit of Add if known.
OverflowResult computeOverflowForSignedAdd(const AddOperator *Add,
diff --git a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
index dcfcc8f41dd58d0..c93754c531c6e43 100644
--- a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
+++ b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
@@ -510,14 +510,15 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
SQ.getWithInstruction(CxtI));
}
- OverflowResult computeOverflowForUnsignedAdd(const Value *LHS,
- const Value *RHS,
+ OverflowResult computeOverflowForUnsignedAdd(const CachedBitsConstValue &LHS,
+ const CachedBitsConstValue &RHS,
const Instruction *CxtI) const {
return llvm::computeOverflowForUnsignedAdd(LHS, RHS,
SQ.getWithInstruction(CxtI));
}
- OverflowResult computeOverflowForSignedAdd(const Value *LHS, const Value *RHS,
+ OverflowResult computeOverflowForSignedAdd(const CachedBitsConstValue &LHS,
+ const CachedBitsConstValue &RHS,
const Instruction *CxtI) const {
return llvm::computeOverflowForSignedAdd(LHS, RHS,
SQ.getWithInstruction(CxtI));
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 82310444326d6bb..3f6811c460986bc 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -25,6 +25,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/CachedBitsValue.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/GuardUtils.h"
#include "llvm/Analysis/InstructionSimplify.h"
@@ -144,12 +145,8 @@ static bool getShuffleDemandedElts(const ShuffleVectorInst *Shuf,
DemandedElts, DemandedLHS, DemandedRHS);
}
-static void computeKnownBits(const Value *V, const APInt &DemandedElts,
- KnownBits &Known, unsigned Depth,
- const SimplifyQuery &Q);
-
-static void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
- const SimplifyQuery &Q) {
+void llvm::computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
+ const SimplifyQuery &Q) {
// 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.
@@ -178,12 +175,6 @@ void llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
-static KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
- unsigned Depth, const SimplifyQuery &Q);
-
-static KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const SimplifyQuery &Q);
-
KnownBits llvm::computeKnownBits(const Value *V, const DataLayout &DL,
unsigned Depth, AssumptionCache *AC,
const Instruction *CxtI,
@@ -201,8 +192,12 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
-bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
+bool llvm::haveNoCommonBitsSet(const CachedBitsConstValue &LHSCache,
+ const CachedBitsConstValue &RHSCache,
const SimplifyQuery &SQ) {
+ const Value *LHS = LHSCache.getValue();
+ const Value *RHS = RHSCache.getValue();
+
assert(LHS->getType() == RHS->getType() &&
"LHS and RHS should have the same type");
assert(LHS->getType()->isIntOrIntVectorTy() &&
@@ -250,12 +245,10 @@ bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
match(LHS, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
return true;
}
- IntegerType *IT = cast<IntegerType>(LHS->getType()->getScalarType());
- KnownBits LHSKnown(IT->getBitWidth());
- KnownBits RHSKnown(IT->getBitWidth());
- ::computeKnownBits(LHS, LHSKnown, 0, SQ);
- ::computeKnownBits(RHS, RHSKnown, 0, SQ);
- return KnownBits::haveNoCommonBitsSet(LHSKnown, RHSKnown);
+
+ return KnownBits::haveNoCommonBitsSet(
+ LHSCache.getKnownBits(0, SQ),
+ RHSCache.getKnownBits(0, SQ));
}
bool llvm::isOnlyUsedInZeroEqualityComparison(const Instruction *I) {
@@ -1784,8 +1777,8 @@ static void computeKnownBitsFromOperator(const Operator *I,
/// Determine which bits of V are known to be either zero or one and return
/// them.
-KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
- unsigned Depth, const SimplifyQuery &Q) {
+KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
+ unsigned Depth, const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
computeKnownBits(V, DemandedElts, Known, Depth, Q);
return Known;
@@ -1793,8 +1786,8 @@ KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
/// Determine which bits of V are known to be either zero or one and return
/// them.
-KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const SimplifyQuery &Q) {
+KnownBits llvm::computeKnownBits(const Value *V, unsigned Depth,
+ const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
computeKnownBits(V, Known, Depth, Q);
return Known;
@@ -1815,9 +1808,9 @@ KnownBits computeKnownBits(const Value *V, unsigned Depth,
/// where V is a vector, 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 demanded elements in the vector specified by DemandedElts.
-void computeKnownBits(const Value *V, const APInt &DemandedElts,
- KnownBits &Known, unsigned Depth,
- const SimplifyQuery &Q) {
+void llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
+ KnownBits &Known, unsigned Depth,
+ const SimplifyQuery &Q) {
if (!DemandedElts) {
// No demanded elts, better to assume we don't know anything.
Known.resetAll();
@@ -6255,11 +6248,11 @@ static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
}
/// Combine constant ranges from computeConstantRange() and computeKnownBits().
-static ConstantRange
-computeConstantRangeIncludingKnownBits(const Value *V, bool ForSigned,
- const SimplifyQuery &SQ) {
- KnownBits Known = ::computeKnownBits(V, /*Depth=*/0, SQ);
- ConstantRange CR1 = ConstantRange::fromKnownBits(Known, ForSigned);
+static ConstantRange computeConstantRangeIncludingKnownBits(
+ const CachedBitsConstValue &V, bool ForSigned, const SimplifyQuery &SQ) {
+ ConstantRange CR1 = ConstantRange::fromKnownBits(
+ V.getKnownBits(0, SQ),
+ ForSigned);
ConstantRange CR2 = computeConstantRange(V, ForSigned, SQ.IIQ.UseInstrInfo);
ConstantRange::PreferredRangeType RangeType =
ForSigned ? ConstantRange::Signed : ConstantRange::Unsigned;
@@ -6315,20 +6308,19 @@ OverflowResult llvm::computeOverflowForSignedMul(const Value *LHS,
return OverflowResult::MayOverflow;
}
-OverflowResult llvm::computeOverflowForUnsignedAdd(const Value *LHS,
- const Value *RHS,
- const SimplifyQuery &SQ) {
- ConstantRange LHSRange =
- computeConstantRangeIncludingKnownBits(LHS, /*ForSigned=*/false, SQ);
- ConstantRange RHSRange =
- computeConstantRangeIncludingKnownBits(RHS, /*ForSigned=*/false, SQ);
+OverflowResult llvm::computeOverflowForUnsignedAdd(
+ const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
+ const SimplifyQuery &SQ) {
+ ConstantRange LHSRange = computeConstantRangeIncludingKnownBits(
+ LHS, /*ForSigned=*/false, SQ);
+ ConstantRange RHSRange = computeConstantRangeIncludingKnownBits(
+ RHS, /*ForSigned=*/false, SQ);
return mapOverflowResult(LHSRange.unsignedAddMayOverflow(RHSRange));
}
-static OverflowResult computeOverflowForSignedAdd(const Value *LHS,
- const Value *RHS,
- const AddOperator *Add,
- const SimplifyQuery &SQ) {
+static OverflowResult computeOverflowForSignedAdd(
+ const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
+ const AddOperator *Add, const SimplifyQuery &SQ) {
if (Add && Add->hasNoSignedWrap()) {
return OverflowResult::NeverOverflows;
}
@@ -6944,9 +6936,9 @@ OverflowResult llvm::computeOverflowForSignedAdd(const AddOperator *Add,
Add, SQ);
}
-OverflowResult llvm::computeOverflowForSignedAdd(const Value *LHS,
- const Value *RHS,
- const SimplifyQuery &SQ) {
+OverflowResult llvm::computeOverflowForSignedAdd(
+ const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
+ const SimplifyQuery &SQ) {
return ::computeOverflowForSignedAdd(LHS, RHS, nullptr, SQ);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 44f6e37cb3b4417..19bcba06d20721f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1566,7 +1566,9 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
return replaceInstUsesWith(I, Constant::getNullValue(I.getType()));
// A+B --> A|B iff A and B have no bits set in common.
- if (haveNoCommonBitsSet(LHS, RHS, SQ.getWithInstruction(&I)))
+ CachedBitsConstValue LHSCache(LHS), RHSCache(RHS);
+ if (haveNoCommonBitsSet(LHSCache, RHSCache, SQ.getWithInstruction(&I),
+ /* ComputeKnownBitsBeforeHand */ true))
return BinaryOperator::CreateOr(LHS, RHS);
if (Instruction *Ext = narrowMathIfNoOverflow(I))
@@ -1661,11 +1663,12 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
// willNotOverflowUnsignedAdd to reduce the number of invocations of
// computeKnownBits.
bool Changed = false;
- if (!I.hasNoSignedWrap() && willNotOverflowSignedAdd(LHS, RHS, I)) {
+ if (!I.hasNoSignedWrap() && willNotOverflowSignedAdd(LHSCache, RHSCache, I)) {
Changed = true;
I.setHasNoSignedWrap(true);
}
- if (!I.hasNoUnsignedWrap() && willNotOverflowUnsignedAdd(LHS, RHS, I)) {
+ if (!I.hasNoUnsignedWrap() &&
+ willNotOverflowUnsignedAdd(LHSCache, RHSCache, I)) {
Changed = true;
I.setHasNoUnsignedWrap(true);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 83c127a0ef012ad..0467a5583dbac09 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -295,13 +295,15 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
Instruction *transformSExtICmp(ICmpInst *Cmp, SExtInst &Sext);
- bool willNotOverflowSignedAdd(const Value *LHS, const Value *RHS,
+ bool willNotOverflowSignedAdd(const CachedBitsConstValue &LHS,
+ const CachedBitsConstValue &RHS,
const Instruction &CxtI) const {
return computeOverflowForSignedAdd(LHS, RHS, &CxtI) ==
OverflowResult::NeverOverflows;
}
- bool willNotOverflowUnsignedAdd(const Value *LHS, const Value *RHS,
+ bool willNotOverflowUnsignedAdd(const CachedBitsConstValue &LHS,
+ const CachedBitsConstValue &RHS,
const Instruction &CxtI) const {
return computeOverflowForUnsignedAdd(LHS, RHS, &CxtI) ==
OverflowResult::NeverOverflows;
>From a7366474cca3177b867fc5dcaf90aa7c854208db Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Mon, 18 Sep 2023 18:27:47 +0530
Subject: [PATCH 02/16] [CachedBitsValue] Remove extraneous constructors, use
std::optional
---
llvm/include/llvm/Analysis/CachedBitsValue.h | 162 +++++++++++++++++++
1 file changed, 162 insertions(+)
create mode 100644 llvm/include/llvm/Analysis/CachedBitsValue.h
diff --git a/llvm/include/llvm/Analysis/CachedBitsValue.h b/llvm/include/llvm/Analysis/CachedBitsValue.h
new file mode 100644
index 000000000000000..8f8dc1be77845fa
--- /dev/null
+++ b/llvm/include/llvm/Analysis/CachedBitsValue.h
@@ -0,0 +1,162 @@
+//===- llvm/Analysis/CachedBitsValue.h - Value with KnownBits - -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Store a pointer to an llvm::Value along with the KnownBits information for it
+// that is computed lazily (if required).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CACHEDBITSVALUE_H
+#define LLVM_ANALYSIS_CACHEDBITSVALUE_H
+
+#include "llvm/IR/Value.h"
+#include "llvm/Support/KnownBits.h"
+#include <type_traits>
+
+namespace llvm {
+
+class DataLayout;
+class AssumptionCache;
+class Instruction;
+class DominatorTree;
+struct SimplifyQuery;
+
+KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
+ unsigned Depth, const SimplifyQuery &Q);
+
+KnownBits computeKnownBits(const Value *V, unsigned Depth,
+ const SimplifyQuery &Q);
+
+namespace detail {
+/// Represents a pointer to an llvm::Value with known bits information
+template <bool ConstPointer = true> class ImplCachedBitsValue {
+protected:
+ using ValuePointerType =
+ std::conditional_t<ConstPointer, const Value *, Value *>;
+ using ValueReferenceType =
+ std::conditional_t<ConstPointer, const Value &, Value &>;
+
+ template <typename T>
+ constexpr static bool ValuePointerConvertible =
+ std::is_convertible_v<T, ValuePointerType>;
+
+ ValuePointerType Pointer;
+ mutable std::optional<KnownBits> Known;
+
+ void calculateKnownBits(unsigned Depth, const SimplifyQuery &Q) const {
+ Known = computeKnownBits(Pointer, Depth, Q);
+ }
+
+ void calculateKnownBits(const APInt &DemandedElts, unsigned Depth,
+ const SimplifyQuery &Q) const {
+ Known = computeKnownBits(Pointer, DemandedElts, Depth, Q);
+ }
+
+public:
+ ImplCachedBitsValue() = default;
+ ImplCachedBitsValue(ValuePointerType Pointer)
+ : Pointer(Pointer), Known(std::nullopt) {}
+ ImplCachedBitsValue(ValuePointerType Pointer, const KnownBits &Known)
+ : Pointer(Pointer), Known(Known) {}
+
+ template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
+ ImplCachedBitsValue(const T &Value)
+ : Pointer(static_cast<ValuePointerType>(Value)), Known(std::nullopt) {}
+
+ template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
+ ImplCachedBitsValue(const T &Value, const KnownBits &Known)
+ : Pointer(static_cast<ValuePointerType>(Value)), Known(Known) {}
+
+ [[nodiscard]] ValuePointerType getValue() { return Pointer; }
+ [[nodiscard]] ValuePointerType getValue() const { return Pointer; }
+
+ [[nodiscard]] const KnownBits &getKnownBits(unsigned Depth,
+ const SimplifyQuery &Q) const {
+ if (!hasKnownBits())
+ calculateKnownBits(Depth, Q);
+ return Known.value();
+ }
+
+ [[nodiscard]] KnownBits &getKnownBits(unsigned Depth,
+ const SimplifyQuery &Q) {
+ if (!hasKnownBits())
+ calculateKnownBits(Depth, Q);
+ return Known.value();
+ }
+
+ [[nodiscard]] const KnownBits &getKnownBits(const APInt &DemandedElts,
+ unsigned Depth,
+ const SimplifyQuery &Q) const {
+ if (!hasKnownBits())
+ calculateKnownBits(DemandedElts, Depth, Q);
+ return Known.value();
+ }
+
+ [[nodiscard]] KnownBits &getKnownBits(const APInt &DemandedElts,
+ unsigned Depth,
+ const SimplifyQuery &Q) {
+ if (!hasKnownBits())
+ calculateKnownBits(DemandedElts, Depth, Q);
+ return Known.value();
+ }
+
+ [[nodiscard]] bool hasKnownBits() const { return Known.has_value(); }
+
+ operator ValuePointerType() { return Pointer; }
+ ValuePointerType operator->() { return Pointer; }
+ ValueReferenceType operator*() { return *Pointer; }
+
+ operator ValuePointerType() const { return Pointer; }
+ ValuePointerType operator->() const { return Pointer; }
+ ValueReferenceType operator*() const { return *Pointer; }
+};
+} // namespace detail
+
+class CachedBitsConstValue : public detail::ImplCachedBitsValue<true> {
+public:
+ CachedBitsConstValue() = default;
+ CachedBitsConstValue(ValuePointerType Pointer)
+ : ImplCachedBitsValue(Pointer) {}
+ CachedBitsConstValue(Value *Pointer) : ImplCachedBitsValue(Pointer) {}
+ CachedBitsConstValue(ValuePointerType Pointer, const KnownBits &Known)
+ : ImplCachedBitsValue(Pointer, Known) {}
+
+ template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
+ CachedBitsConstValue(const T &Value) : ImplCachedBitsValue(Value) {}
+
+ template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
+ CachedBitsConstValue(const T &Value, const KnownBits &Known)
+ : ImplCachedBitsValue(Value, Known) {}
+};
+
+class CachedBitsNonConstValue : public detail::ImplCachedBitsValue<false> {
+public:
+ CachedBitsNonConstValue() = default;
+ CachedBitsNonConstValue(ValuePointerType Pointer)
+ : ImplCachedBitsValue(Pointer) {}
+ CachedBitsNonConstValue(ValuePointerType Pointer, const KnownBits &Known)
+ : ImplCachedBitsValue(Pointer, Known) {}
+
+ template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
+ CachedBitsNonConstValue(const T &Value) : ImplCachedBitsValue(Value) {}
+
+ template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
+ CachedBitsNonConstValue(const T &Value, const KnownBits &Known)
+ : ImplCachedBitsValue(Value, Known) {}
+
+ [[nodiscard]] CachedBitsConstValue toConst() const {
+ if (hasKnownBits())
+ return CachedBitsConstValue(getValue(), Known.value());
+ else
+ return CachedBitsConstValue(getValue());
+ }
+};
+
+} // namespace llvm
+
+#endif
>From edb53d411ebc25718dc398a3620e285aa0784a2b Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Wed, 20 Sep 2023 19:20:48 +0530
Subject: [PATCH 03/16] [CachedBitsValue] Switch from std::optional to
PointerIntPair
---
llvm/include/llvm/Analysis/CachedBitsValue.h | 51 +++++++++++---------
1 file changed, 29 insertions(+), 22 deletions(-)
diff --git a/llvm/include/llvm/Analysis/CachedBitsValue.h b/llvm/include/llvm/Analysis/CachedBitsValue.h
index 8f8dc1be77845fa..1f490850cff97d7 100644
--- a/llvm/include/llvm/Analysis/CachedBitsValue.h
+++ b/llvm/include/llvm/Analysis/CachedBitsValue.h
@@ -14,6 +14,7 @@
#ifndef LLVM_ANALYSIS_CACHEDBITSVALUE_H
#define LLVM_ANALYSIS_CACHEDBITSVALUE_H
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/KnownBits.h"
#include <type_traits>
@@ -45,48 +46,54 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
constexpr static bool ValuePointerConvertible =
std::is_convertible_v<T, ValuePointerType>;
- ValuePointerType Pointer;
- mutable std::optional<KnownBits> Known;
+ // Store the presence of the KnownBits information in one of the bits of
+ // Pointer.
+ // true -> present
+ // false -> absent
+ mutable PointerIntPair<ValuePointerType, 1, bool> Pointer;
+ mutable KnownBits Known;
void calculateKnownBits(unsigned Depth, const SimplifyQuery &Q) const {
- Known = computeKnownBits(Pointer, Depth, Q);
+ Known = computeKnownBits(Pointer.getPointer(), Depth, Q);
+ Pointer.setInt(true);
}
void calculateKnownBits(const APInt &DemandedElts, unsigned Depth,
const SimplifyQuery &Q) const {
- Known = computeKnownBits(Pointer, DemandedElts, Depth, Q);
+ Known = computeKnownBits(Pointer.getPointer(), DemandedElts, Depth, Q);
+ Pointer.setInt(false);
}
public:
ImplCachedBitsValue() = default;
ImplCachedBitsValue(ValuePointerType Pointer)
- : Pointer(Pointer), Known(std::nullopt) {}
+ : Pointer(Pointer, false) {}
ImplCachedBitsValue(ValuePointerType Pointer, const KnownBits &Known)
- : Pointer(Pointer), Known(Known) {}
+ : Pointer(Pointer, true), Known(Known) {}
template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
ImplCachedBitsValue(const T &Value)
- : Pointer(static_cast<ValuePointerType>(Value)), Known(std::nullopt) {}
+ : Pointer(static_cast<ValuePointerType>(Value), false) {}
template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
ImplCachedBitsValue(const T &Value, const KnownBits &Known)
- : Pointer(static_cast<ValuePointerType>(Value)), Known(Known) {}
+ : Pointer(static_cast<ValuePointerType>(Value), true), Known(Known) {}
- [[nodiscard]] ValuePointerType getValue() { return Pointer; }
- [[nodiscard]] ValuePointerType getValue() const { return Pointer; }
+ [[nodiscard]] ValuePointerType getValue() { return Pointer.getPointer(); }
+ [[nodiscard]] ValuePointerType getValue() const { return Pointer.getPointer(); }
[[nodiscard]] const KnownBits &getKnownBits(unsigned Depth,
const SimplifyQuery &Q) const {
if (!hasKnownBits())
calculateKnownBits(Depth, Q);
- return Known.value();
+ return Known;
}
[[nodiscard]] KnownBits &getKnownBits(unsigned Depth,
const SimplifyQuery &Q) {
if (!hasKnownBits())
calculateKnownBits(Depth, Q);
- return Known.value();
+ return Known;
}
[[nodiscard]] const KnownBits &getKnownBits(const APInt &DemandedElts,
@@ -94,7 +101,7 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
const SimplifyQuery &Q) const {
if (!hasKnownBits())
calculateKnownBits(DemandedElts, Depth, Q);
- return Known.value();
+ return Known;
}
[[nodiscard]] KnownBits &getKnownBits(const APInt &DemandedElts,
@@ -102,18 +109,18 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
const SimplifyQuery &Q) {
if (!hasKnownBits())
calculateKnownBits(DemandedElts, Depth, Q);
- return Known.value();
+ return Known;
}
- [[nodiscard]] bool hasKnownBits() const { return Known.has_value(); }
+ [[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); }
- operator ValuePointerType() { return Pointer; }
- ValuePointerType operator->() { return Pointer; }
- ValueReferenceType operator*() { return *Pointer; }
+ operator ValuePointerType() { return Pointer.getPointer(); }
+ ValuePointerType operator->() { return Pointer.getPointer(); }
+ ValueReferenceType operator*() { return *Pointer.getPointer(); }
- operator ValuePointerType() const { return Pointer; }
- ValuePointerType operator->() const { return Pointer; }
- ValueReferenceType operator*() const { return *Pointer; }
+ operator ValuePointerType() const { return Pointer.getPointer(); }
+ ValuePointerType operator->() const { return Pointer.getPointer(); }
+ ValueReferenceType operator*() const { return *Pointer.getPointer(); }
};
} // namespace detail
@@ -151,7 +158,7 @@ class CachedBitsNonConstValue : public detail::ImplCachedBitsValue<false> {
[[nodiscard]] CachedBitsConstValue toConst() const {
if (hasKnownBits())
- return CachedBitsConstValue(getValue(), Known.value());
+ return CachedBitsConstValue(getValue(), Known);
else
return CachedBitsConstValue(getValue());
}
>From 85b77d9a1d3a84c0b5da1a5e95a0bbb41b600c00 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Wed, 20 Sep 2023 19:28:17 +0530
Subject: [PATCH 04/16] [CachedBitsValue] Remove unused functions
---
llvm/include/llvm/Analysis/CachedBitsValue.h | 25 --------------------
1 file changed, 25 deletions(-)
diff --git a/llvm/include/llvm/Analysis/CachedBitsValue.h b/llvm/include/llvm/Analysis/CachedBitsValue.h
index 1f490850cff97d7..13fc8ad45dce889 100644
--- a/llvm/include/llvm/Analysis/CachedBitsValue.h
+++ b/llvm/include/llvm/Analysis/CachedBitsValue.h
@@ -27,9 +27,6 @@ class Instruction;
class DominatorTree;
struct SimplifyQuery;
-KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
- unsigned Depth, const SimplifyQuery &Q);
-
KnownBits computeKnownBits(const Value *V, unsigned Depth,
const SimplifyQuery &Q);
@@ -58,12 +55,6 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
Pointer.setInt(true);
}
- void calculateKnownBits(const APInt &DemandedElts, unsigned Depth,
- const SimplifyQuery &Q) const {
- Known = computeKnownBits(Pointer.getPointer(), DemandedElts, Depth, Q);
- Pointer.setInt(false);
- }
-
public:
ImplCachedBitsValue() = default;
ImplCachedBitsValue(ValuePointerType Pointer)
@@ -96,22 +87,6 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
return Known;
}
- [[nodiscard]] const KnownBits &getKnownBits(const APInt &DemandedElts,
- unsigned Depth,
- const SimplifyQuery &Q) const {
- if (!hasKnownBits())
- calculateKnownBits(DemandedElts, Depth, Q);
- return Known;
- }
-
- [[nodiscard]] KnownBits &getKnownBits(const APInt &DemandedElts,
- unsigned Depth,
- const SimplifyQuery &Q) {
- if (!hasKnownBits())
- calculateKnownBits(DemandedElts, Depth, Q);
- return Known;
- }
-
[[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); }
operator ValuePointerType() { return Pointer.getPointer(); }
>From 75eae190a1701f158aeac75f0687b178eff49045 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Wed, 20 Sep 2023 19:30:36 +0530
Subject: [PATCH 05/16] [CachedBitsValue] Remove Depth parameter
---
llvm/include/llvm/Analysis/CachedBitsValue.h | 14 ++++++--------
llvm/lib/Analysis/ValueTracking.cpp | 6 +++---
2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/llvm/include/llvm/Analysis/CachedBitsValue.h b/llvm/include/llvm/Analysis/CachedBitsValue.h
index 13fc8ad45dce889..c95c342e22c0588 100644
--- a/llvm/include/llvm/Analysis/CachedBitsValue.h
+++ b/llvm/include/llvm/Analysis/CachedBitsValue.h
@@ -50,8 +50,8 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
mutable PointerIntPair<ValuePointerType, 1, bool> Pointer;
mutable KnownBits Known;
- void calculateKnownBits(unsigned Depth, const SimplifyQuery &Q) const {
- Known = computeKnownBits(Pointer.getPointer(), Depth, Q);
+ void calculateKnownBits(const SimplifyQuery &Q) const {
+ Known = computeKnownBits(Pointer.getPointer(), 0, Q);
Pointer.setInt(true);
}
@@ -73,17 +73,15 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
[[nodiscard]] ValuePointerType getValue() { return Pointer.getPointer(); }
[[nodiscard]] ValuePointerType getValue() const { return Pointer.getPointer(); }
- [[nodiscard]] const KnownBits &getKnownBits(unsigned Depth,
- const SimplifyQuery &Q) const {
+ [[nodiscard]] const KnownBits &getKnownBits(const SimplifyQuery &Q) const {
if (!hasKnownBits())
- calculateKnownBits(Depth, Q);
+ calculateKnownBits(Q);
return Known;
}
- [[nodiscard]] KnownBits &getKnownBits(unsigned Depth,
- const SimplifyQuery &Q) {
+ [[nodiscard]] KnownBits &getKnownBits(const SimplifyQuery &Q) {
if (!hasKnownBits())
- calculateKnownBits(Depth, Q);
+ calculateKnownBits(Q);
return Known;
}
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3f6811c460986bc..1f44eab41bbd676 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -247,8 +247,8 @@ bool llvm::haveNoCommonBitsSet(const CachedBitsConstValue &LHSCache,
}
return KnownBits::haveNoCommonBitsSet(
- LHSCache.getKnownBits(0, SQ),
- RHSCache.getKnownBits(0, SQ));
+ LHSCache.getKnownBits(SQ),
+ RHSCache.getKnownBits(SQ));
}
bool llvm::isOnlyUsedInZeroEqualityComparison(const Instruction *I) {
@@ -6251,7 +6251,7 @@ static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
static ConstantRange computeConstantRangeIncludingKnownBits(
const CachedBitsConstValue &V, bool ForSigned, const SimplifyQuery &SQ) {
ConstantRange CR1 = ConstantRange::fromKnownBits(
- V.getKnownBits(0, SQ),
+ V.getKnownBits(SQ),
ForSigned);
ConstantRange CR2 = computeConstantRange(V, ForSigned, SQ.IIQ.UseInstrInfo);
ConstantRange::PreferredRangeType RangeType =
>From 3e138875907baf8ea842cfbd7844bb83e7be8f56 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Wed, 20 Sep 2023 19:33:12 +0530
Subject: [PATCH 06/16] [CachedBitsValue] Formatting
---
llvm/include/llvm/Analysis/CachedBitsValue.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Analysis/CachedBitsValue.h b/llvm/include/llvm/Analysis/CachedBitsValue.h
index c95c342e22c0588..53dc90fd3f435c9 100644
--- a/llvm/include/llvm/Analysis/CachedBitsValue.h
+++ b/llvm/include/llvm/Analysis/CachedBitsValue.h
@@ -57,8 +57,7 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
public:
ImplCachedBitsValue() = default;
- ImplCachedBitsValue(ValuePointerType Pointer)
- : Pointer(Pointer, false) {}
+ ImplCachedBitsValue(ValuePointerType Pointer) : Pointer(Pointer, false) {}
ImplCachedBitsValue(ValuePointerType Pointer, const KnownBits &Known)
: Pointer(Pointer, true), Known(Known) {}
@@ -71,7 +70,9 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
: Pointer(static_cast<ValuePointerType>(Value), true), Known(Known) {}
[[nodiscard]] ValuePointerType getValue() { return Pointer.getPointer(); }
- [[nodiscard]] ValuePointerType getValue() const { return Pointer.getPointer(); }
+ [[nodiscard]] ValuePointerType getValue() const {
+ return Pointer.getPointer();
+ }
[[nodiscard]] const KnownBits &getKnownBits(const SimplifyQuery &Q) const {
if (!hasKnownBits())
>From c72d7a5ee2c602a0e4d0619239671a28cf0885b1 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Wed, 20 Sep 2023 22:09:27 +0530
Subject: [PATCH 07/16] [CachedBitsValue] Undo adding void return type
computeKnownBits overloads to header
---
llvm/include/llvm/Analysis/ValueTracking.h | 6 ------
llvm/lib/Analysis/ValueTracking.cpp | 22 +++++++++++++---------
2 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index dc0736f66daf671..54f3b59e72b238a 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -91,12 +91,6 @@ KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
const DominatorTree *DT = nullptr,
bool UseInstrInfo = true);
-void computeKnownBits(const Value *V, const APInt &DemandedElts,
- KnownBits &Known, unsigned Depth, const SimplifyQuery &Q);
-
-void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
- const SimplifyQuery &Q);
-
KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
unsigned Depth, const SimplifyQuery &Q);
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 1f44eab41bbd676..d00085545bbde01 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -145,8 +145,12 @@ static bool getShuffleDemandedElts(const ShuffleVectorInst *Shuf,
DemandedElts, DemandedLHS, DemandedRHS);
}
-void llvm::computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
- const SimplifyQuery &Q) {
+static void computeKnownBits(const Value *V, const APInt &DemandedElts,
+ KnownBits &Known, unsigned Depth,
+ const SimplifyQuery &Q);
+
+static void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
+ const SimplifyQuery &Q) {
// 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.
@@ -179,7 +183,7 @@ KnownBits llvm::computeKnownBits(const Value *V, const DataLayout &DL,
unsigned Depth, AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT, bool UseInstrInfo) {
- return ::computeKnownBits(
+ return computeKnownBits(
V, Depth, SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
@@ -187,7 +191,7 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
const DataLayout &DL, unsigned Depth,
AssumptionCache *AC, const Instruction *CxtI,
const DominatorTree *DT, bool UseInstrInfo) {
- return ::computeKnownBits(
+ return computeKnownBits(
V, DemandedElts, Depth,
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
@@ -1780,7 +1784,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
unsigned Depth, const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
- computeKnownBits(V, DemandedElts, Known, Depth, Q);
+ ::computeKnownBits(V, DemandedElts, Known, Depth, Q);
return Known;
}
@@ -1789,7 +1793,7 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
KnownBits llvm::computeKnownBits(const Value *V, unsigned Depth,
const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
- computeKnownBits(V, Known, Depth, Q);
+ ::computeKnownBits(V, Known, Depth, Q);
return Known;
}
@@ -1808,9 +1812,9 @@ KnownBits llvm::computeKnownBits(const Value *V, unsigned Depth,
/// where V is a vector, 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 demanded elements in the vector specified by DemandedElts.
-void llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
- KnownBits &Known, unsigned Depth,
- const SimplifyQuery &Q) {
+void computeKnownBits(const Value *V, const APInt &DemandedElts,
+ KnownBits &Known, unsigned Depth,
+ const SimplifyQuery &Q) {
if (!DemandedElts) {
// No demanded elts, better to assume we don't know anything.
Known.resetAll();
>From 15b683aef64abfc65b158c7a017abc7d610b7c6e Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Mon, 16 Oct 2023 12:10:06 +0530
Subject: [PATCH 08/16] Make non-broken
---
llvm/include/llvm/Analysis/CachedBitsValue.h | 14 ++++++--------
llvm/include/llvm/Analysis/ValueTracking.h | 8 ++++----
llvm/lib/Analysis/ValueTracking.cpp | 18 ++++++++++++------
.../InstCombine/InstCombineAddSub.cpp | 3 +--
4 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/llvm/include/llvm/Analysis/CachedBitsValue.h b/llvm/include/llvm/Analysis/CachedBitsValue.h
index 53dc90fd3f435c9..34f0675e9816f06 100644
--- a/llvm/include/llvm/Analysis/CachedBitsValue.h
+++ b/llvm/include/llvm/Analysis/CachedBitsValue.h
@@ -19,17 +19,15 @@
#include "llvm/Support/KnownBits.h"
#include <type_traits>
-namespace llvm {
-class DataLayout;
-class AssumptionCache;
-class Instruction;
-class DominatorTree;
-struct SimplifyQuery;
+namespace llvm {
+ struct SimplifyQuery;
+}
-KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const SimplifyQuery &Q);
+llvm::KnownBits computeKnownBits(const llvm::Value *V, unsigned Depth,
+ const llvm::SimplifyQuery &Q);
+namespace llvm {
namespace detail {
/// Represents a pointer to an llvm::Value with known bits information
template <bool ConstPointer = true> class ImplCachedBitsValue {
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 54f3b59e72b238a..031afd27c7a935b 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -91,11 +91,11 @@ KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
const DominatorTree *DT = nullptr,
bool UseInstrInfo = true);
-KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
- unsigned Depth, const SimplifyQuery &Q);
+// KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
+// unsigned Depth, const SimplifyQuery &Q);
-KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const SimplifyQuery &Q);
+// KnownBits computeKnownBits(const Value *V, unsigned Depth,
+// const SimplifyQuery &Q);
/// Compute known bits from the range metadata.
/// \p KnownZero the set of bits that are known to be zero
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d00085545bbde01..21dc9c0fd5a530e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -179,11 +179,17 @@ void llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
+KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
+ unsigned Depth, const SimplifyQuery &Q);
+
+KnownBits computeKnownBits(const Value *V, unsigned Depth,
+ const SimplifyQuery &Q);
+
KnownBits llvm::computeKnownBits(const Value *V, const DataLayout &DL,
unsigned Depth, AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT, bool UseInstrInfo) {
- return computeKnownBits(
+ return ::computeKnownBits(
V, Depth, SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
@@ -191,7 +197,7 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
const DataLayout &DL, unsigned Depth,
AssumptionCache *AC, const Instruction *CxtI,
const DominatorTree *DT, bool UseInstrInfo) {
- return computeKnownBits(
+ return ::computeKnownBits(
V, DemandedElts, Depth,
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
@@ -1781,19 +1787,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,
+KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
unsigned Depth, const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
- ::computeKnownBits(V, DemandedElts, Known, Depth, Q);
+ computeKnownBits(V, DemandedElts, Known, Depth, Q);
return Known;
}
/// Determine which bits of V are known to be either zero or one and return
/// them.
-KnownBits llvm::computeKnownBits(const Value *V, unsigned Depth,
+KnownBits computeKnownBits(const Value *V, unsigned Depth,
const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
- ::computeKnownBits(V, Known, Depth, Q);
+ computeKnownBits(V, Known, Depth, Q);
return Known;
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 19bcba06d20721f..e7b4589dbf515e4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1567,8 +1567,7 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
// A+B --> A|B iff A and B have no bits set in common.
CachedBitsConstValue LHSCache(LHS), RHSCache(RHS);
- if (haveNoCommonBitsSet(LHSCache, RHSCache, SQ.getWithInstruction(&I),
- /* ComputeKnownBitsBeforeHand */ true))
+ if (haveNoCommonBitsSet(LHSCache, RHSCache, SQ.getWithInstruction(&I)))
return BinaryOperator::CreateOr(LHS, RHS);
if (Instruction *Ext = narrowMathIfNoOverflow(I))
>From cb53056987c4357f3381d57b39fc7d9352a632c9 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Mon, 16 Oct 2023 12:28:55 +0530
Subject: [PATCH 09/16] Add WithCache
---
llvm/include/llvm/Analysis/ValueTracking.h | 15 +--
llvm/include/llvm/Analysis/WithCache.h | 97 +++++++++++++++++++
.../Transforms/InstCombine/InstCombiner.h | 14 +--
llvm/lib/Analysis/ValueTracking.cpp | 46 +++++----
.../InstCombine/InstCombineAddSub.cpp | 2 +-
.../InstCombine/InstCombineInternal.h | 8 +-
6 files changed, 144 insertions(+), 38 deletions(-)
create mode 100644 llvm/include/llvm/Analysis/WithCache.h
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 031afd27c7a935b..3534e7a00524882 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -17,7 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Analysis/SimplifyQuery.h"
-#include "llvm/Analysis/CachedBitsValue.h"
+#include "llvm/Analysis/WithCache.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/FMF.h"
@@ -114,8 +114,8 @@ KnownBits analyzeKnownBitsFromAndXorOr(
bool UseInstrInfo = true);
/// Return true if LHS and RHS have no common bits set.
-bool haveNoCommonBitsSet(const CachedBitsConstValue &LHSCache,
- const CachedBitsConstValue &RHSCache,
+bool haveNoCommonBitsSet(const WithCache<const Value *> &LHSCache,
+ const WithCache<const Value *> &RHSCache,
const SimplifyQuery &SQ);
/// Return true if the given value is known to have exactly one bit set when
@@ -855,9 +855,12 @@ OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS,
const SimplifyQuery &SQ);
OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS,
const SimplifyQuery &SQ);
-OverflowResult computeOverflowForUnsignedAdd(const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
- const SimplifyQuery &SQ);
-OverflowResult computeOverflowForSignedAdd(const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
+OverflowResult
+computeOverflowForUnsignedAdd(const WithCache<const Value *> &LHS,
+ const WithCache<const Value *> &RHS,
+ const SimplifyQuery &SQ);
+OverflowResult computeOverflowForSignedAdd(const WithCache<const Value *> &LHS,
+ const WithCache<const Value *> &RHS,
const SimplifyQuery &SQ);
/// This version also leverages the sign bit of Add if known.
OverflowResult computeOverflowForSignedAdd(const AddOperator *Add,
diff --git a/llvm/include/llvm/Analysis/WithCache.h b/llvm/include/llvm/Analysis/WithCache.h
new file mode 100644
index 000000000000000..202e1145a132958
--- /dev/null
+++ b/llvm/include/llvm/Analysis/WithCache.h
@@ -0,0 +1,97 @@
+//===- llvm/Analysis/WithCache.h - KnownBits cache for pointers -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Store a pointer to any type along with the KnownBits information for it
+// that is computed lazily (if required).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_WITHCACHE_H
+#define LLVM_ANALYSIS_WITHCACHE_H
+
+#include "llvm/IR/Value.h"
+#include "llvm/Support/KnownBits.h"
+#include <type_traits>
+
+namespace llvm {
+struct SimplifyQuery;
+}
+
+llvm::KnownBits computeKnownBits(const llvm::Value *V, unsigned Depth,
+ const llvm::SimplifyQuery &Q);
+
+namespace llvm {
+template <typename Arg> class WithCache {
+ static_assert(std::is_pointer_v<Arg>, "WithCache requires a pointer type!");
+
+ using UnderlyingType = std::remove_pointer_t<Arg>;
+ constexpr static bool IsConst = std::is_const_v<Arg>;
+
+ template <typename T, bool Const>
+ using conditionally_const_t = std::conditional_t<Const, const T, T>;
+
+ using PointerType = conditionally_const_t<UnderlyingType *, IsConst>;
+ using ReferenceType = conditionally_const_t<UnderlyingType &, IsConst>;
+
+ template <typename T>
+ constexpr static bool PointerConvertible =
+ std::is_convertible_v<T, UnderlyingType>;
+
+ // Store the presence of the KnownBits information in one of the bits of
+ // Pointer.
+ // true -> present
+ // false -> absent
+ mutable PointerIntPair<PointerType, 1, bool> Pointer;
+ mutable KnownBits Known;
+
+ void calculateKnownBits(const SimplifyQuery &Q) const {
+ Known = computeKnownBits(Pointer.getPointer(), 0, Q);
+ Pointer.setInt(true);
+ }
+
+public:
+ WithCache() = default;
+ WithCache(PointerType Pointer) : Pointer(Pointer, false) {}
+ WithCache(PointerType Pointer, const KnownBits &Known)
+ : Pointer(Pointer, true), Known(Known) {}
+
+ template <typename T, std::enable_if_t<PointerConvertible<T>, int> = 0>
+ WithCache(const T &Value) : Pointer(static_cast<PointerType>(Value), false) {}
+
+ template <typename T, std::enable_if_t<PointerConvertible<T>, int> = 0>
+ WithCache(const T &Value, const KnownBits &Known)
+ : Pointer(static_cast<PointerType>(Value), true), Known(Known) {}
+
+ [[nodiscard]] PointerType getValue() { return Pointer.getPointer(); }
+ [[nodiscard]] PointerType getValue() const { return Pointer.getPointer(); }
+
+ [[nodiscard]] const KnownBits &getKnownBits(const SimplifyQuery &Q) const {
+ if (!hasKnownBits())
+ calculateKnownBits(Q);
+ return Known;
+ }
+
+ [[nodiscard]] KnownBits &getKnownBits(const SimplifyQuery &Q) {
+ if (!hasKnownBits())
+ calculateKnownBits(Q);
+ return Known;
+ }
+
+ [[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); }
+
+ operator PointerType() { return Pointer.getPointer(); }
+ PointerType operator->() { return Pointer.getPointer(); }
+ ReferenceType operator*() { return *Pointer.getPointer(); }
+
+ operator PointerType() const { return Pointer.getPointer(); }
+ PointerType operator->() const { return Pointer.getPointer(); }
+ ReferenceType operator*() const { return *Pointer.getPointer(); }
+};
+} // namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
index c93754c531c6e43..f8b3874267ded3b 100644
--- a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
+++ b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
@@ -510,16 +510,18 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
SQ.getWithInstruction(CxtI));
}
- OverflowResult computeOverflowForUnsignedAdd(const CachedBitsConstValue &LHS,
- const CachedBitsConstValue &RHS,
- const Instruction *CxtI) const {
+ OverflowResult
+ computeOverflowForUnsignedAdd(const WithCache<const Value *> &LHS,
+ const WithCache<const Value *> &RHS,
+ const Instruction *CxtI) const {
return llvm::computeOverflowForUnsignedAdd(LHS, RHS,
SQ.getWithInstruction(CxtI));
}
- OverflowResult computeOverflowForSignedAdd(const CachedBitsConstValue &LHS,
- const CachedBitsConstValue &RHS,
- const Instruction *CxtI) const {
+ OverflowResult
+ computeOverflowForSignedAdd(const WithCache<const Value *> &LHS,
+ const WithCache<const Value *> &RHS,
+ const Instruction *CxtI) const {
return llvm::computeOverflowForSignedAdd(LHS, RHS,
SQ.getWithInstruction(CxtI));
}
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 21dc9c0fd5a530e..d4f6bc541a29789 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -25,7 +25,6 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/CachedBitsValue.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/GuardUtils.h"
#include "llvm/Analysis/InstructionSimplify.h"
@@ -34,6 +33,7 @@
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/VectorUtils.h"
+#include "llvm/Analysis/WithCache.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -202,8 +202,8 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
-bool llvm::haveNoCommonBitsSet(const CachedBitsConstValue &LHSCache,
- const CachedBitsConstValue &RHSCache,
+bool llvm::haveNoCommonBitsSet(const WithCache<const Value *> &LHSCache,
+ const WithCache<const Value *> &RHSCache,
const SimplifyQuery &SQ) {
const Value *LHS = LHSCache.getValue();
const Value *RHS = RHSCache.getValue();
@@ -6258,11 +6258,12 @@ static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
}
/// Combine constant ranges from computeConstantRange() and computeKnownBits().
-static ConstantRange computeConstantRangeIncludingKnownBits(
- const CachedBitsConstValue &V, bool ForSigned, const SimplifyQuery &SQ) {
- ConstantRange CR1 = ConstantRange::fromKnownBits(
- V.getKnownBits(SQ),
- ForSigned);
+static ConstantRange
+computeConstantRangeIncludingKnownBits(const WithCache<const Value *> &V,
+ bool ForSigned,
+ const SimplifyQuery &SQ) {
+ ConstantRange CR1 =
+ ConstantRange::fromKnownBits(V.getKnownBits(SQ), ForSigned);
ConstantRange CR2 = computeConstantRange(V, ForSigned, SQ.IIQ.UseInstrInfo);
ConstantRange::PreferredRangeType RangeType =
ForSigned ? ConstantRange::Signed : ConstantRange::Unsigned;
@@ -6318,19 +6319,21 @@ OverflowResult llvm::computeOverflowForSignedMul(const Value *LHS,
return OverflowResult::MayOverflow;
}
-OverflowResult llvm::computeOverflowForUnsignedAdd(
- const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
- const SimplifyQuery &SQ) {
- ConstantRange LHSRange = computeConstantRangeIncludingKnownBits(
- LHS, /*ForSigned=*/false, SQ);
- ConstantRange RHSRange = computeConstantRangeIncludingKnownBits(
- RHS, /*ForSigned=*/false, SQ);
+OverflowResult
+llvm::computeOverflowForUnsignedAdd(const WithCache<const Value *> &LHS,
+ const WithCache<const Value *> &RHS,
+ const SimplifyQuery &SQ) {
+ ConstantRange LHSRange =
+ computeConstantRangeIncludingKnownBits(LHS, /*ForSigned=*/false, SQ);
+ ConstantRange RHSRange =
+ computeConstantRangeIncludingKnownBits(RHS, /*ForSigned=*/false, SQ);
return mapOverflowResult(LHSRange.unsignedAddMayOverflow(RHSRange));
}
-static OverflowResult computeOverflowForSignedAdd(
- const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
- const AddOperator *Add, const SimplifyQuery &SQ) {
+static OverflowResult
+computeOverflowForSignedAdd(const WithCache<const Value *> &LHS,
+ const WithCache<const Value *> &RHS,
+ const AddOperator *Add, const SimplifyQuery &SQ) {
if (Add && Add->hasNoSignedWrap()) {
return OverflowResult::NeverOverflows;
}
@@ -6946,9 +6949,10 @@ OverflowResult llvm::computeOverflowForSignedAdd(const AddOperator *Add,
Add, SQ);
}
-OverflowResult llvm::computeOverflowForSignedAdd(
- const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
- const SimplifyQuery &SQ) {
+OverflowResult
+llvm::computeOverflowForSignedAdd(const WithCache<const Value *> &LHS,
+ const WithCache<const Value *> &RHS,
+ const SimplifyQuery &SQ) {
return ::computeOverflowForSignedAdd(LHS, RHS, nullptr, SQ);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index e7b4589dbf515e4..87181650e758729 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1566,7 +1566,7 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
return replaceInstUsesWith(I, Constant::getNullValue(I.getType()));
// A+B --> A|B iff A and B have no bits set in common.
- CachedBitsConstValue LHSCache(LHS), RHSCache(RHS);
+ WithCache<const Value *> LHSCache(LHS), RHSCache(RHS);
if (haveNoCommonBitsSet(LHSCache, RHSCache, SQ.getWithInstruction(&I)))
return BinaryOperator::CreateOr(LHS, RHS);
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 0467a5583dbac09..a53d67b2899b700 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -295,15 +295,15 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
Instruction *transformSExtICmp(ICmpInst *Cmp, SExtInst &Sext);
- bool willNotOverflowSignedAdd(const CachedBitsConstValue &LHS,
- const CachedBitsConstValue &RHS,
+ bool willNotOverflowSignedAdd(const WithCache<const Value *> &LHS,
+ const WithCache<const Value *> &RHS,
const Instruction &CxtI) const {
return computeOverflowForSignedAdd(LHS, RHS, &CxtI) ==
OverflowResult::NeverOverflows;
}
- bool willNotOverflowUnsignedAdd(const CachedBitsConstValue &LHS,
- const CachedBitsConstValue &RHS,
+ bool willNotOverflowUnsignedAdd(const WithCache<const Value *> &LHS,
+ const WithCache<const Value *> &RHS,
const Instruction &CxtI) const {
return computeOverflowForUnsignedAdd(LHS, RHS, &CxtI) ==
OverflowResult::NeverOverflows;
>From a6c2f9ac22179d06d47c52300dea5742761f6c2f Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Mon, 16 Oct 2023 12:33:37 +0530
Subject: [PATCH 10/16] Remove commented lines
---
llvm/include/llvm/Analysis/ValueTracking.h | 6 ------
1 file changed, 6 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 3534e7a00524882..44f93e1fff54b52 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -91,12 +91,6 @@ KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
const DominatorTree *DT = nullptr,
bool UseInstrInfo = true);
-// KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
-// unsigned Depth, const SimplifyQuery &Q);
-
-// KnownBits computeKnownBits(const Value *V, unsigned Depth,
-// const SimplifyQuery &Q);
-
/// Compute known bits from the range metadata.
/// \p KnownZero the set of bits that are known to be zero
/// \p KnownOne the set of bits that are known to be one
>From aa399bbf4823140b360d56d1664708c57a849e81 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Mon, 16 Oct 2023 12:34:22 +0530
Subject: [PATCH 11/16] Formatting
---
llvm/include/llvm/Analysis/CachedBitsValue.h | 3 +--
llvm/lib/Analysis/ValueTracking.cpp | 13 ++++++-------
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/Analysis/CachedBitsValue.h b/llvm/include/llvm/Analysis/CachedBitsValue.h
index 34f0675e9816f06..1685e2edbb17365 100644
--- a/llvm/include/llvm/Analysis/CachedBitsValue.h
+++ b/llvm/include/llvm/Analysis/CachedBitsValue.h
@@ -19,9 +19,8 @@
#include "llvm/Support/KnownBits.h"
#include <type_traits>
-
namespace llvm {
- struct SimplifyQuery;
+struct SimplifyQuery;
}
llvm::KnownBits computeKnownBits(const llvm::Value *V, unsigned Depth,
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d4f6bc541a29789..b1d5d6a4e4c18d1 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -180,10 +180,10 @@ void llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
}
KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
- unsigned Depth, const SimplifyQuery &Q);
+ unsigned Depth, const SimplifyQuery &Q);
KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const SimplifyQuery &Q);
+ const SimplifyQuery &Q);
KnownBits llvm::computeKnownBits(const Value *V, const DataLayout &DL,
unsigned Depth, AssumptionCache *AC,
@@ -256,9 +256,8 @@ bool llvm::haveNoCommonBitsSet(const WithCache<const Value *> &LHSCache,
return true;
}
- return KnownBits::haveNoCommonBitsSet(
- LHSCache.getKnownBits(SQ),
- RHSCache.getKnownBits(SQ));
+ return KnownBits::haveNoCommonBitsSet(LHSCache.getKnownBits(SQ),
+ RHSCache.getKnownBits(SQ));
}
bool llvm::isOnlyUsedInZeroEqualityComparison(const Instruction *I) {
@@ -1788,7 +1787,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
/// Determine which bits of V are known to be either zero or one and return
/// them.
KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
- unsigned Depth, const SimplifyQuery &Q) {
+ unsigned Depth, const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
computeKnownBits(V, DemandedElts, Known, Depth, Q);
return Known;
@@ -1797,7 +1796,7 @@ KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
/// Determine which bits of V are known to be either zero or one and return
/// them.
KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const SimplifyQuery &Q) {
+ const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
computeKnownBits(V, Known, Depth, Q);
return Known;
>From 5347ffd0dd9d10704ffa68db9584aa258495969d Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Mon, 16 Oct 2023 18:08:07 +0530
Subject: [PATCH 12/16] Remove unused functions
---
llvm/include/llvm/Analysis/WithCache.h | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/llvm/include/llvm/Analysis/WithCache.h b/llvm/include/llvm/Analysis/WithCache.h
index 202e1145a132958..27b69a284c3254d 100644
--- a/llvm/include/llvm/Analysis/WithCache.h
+++ b/llvm/include/llvm/Analysis/WithCache.h
@@ -60,13 +60,6 @@ template <typename Arg> class WithCache {
WithCache(PointerType Pointer, const KnownBits &Known)
: Pointer(Pointer, true), Known(Known) {}
- template <typename T, std::enable_if_t<PointerConvertible<T>, int> = 0>
- WithCache(const T &Value) : Pointer(static_cast<PointerType>(Value), false) {}
-
- template <typename T, std::enable_if_t<PointerConvertible<T>, int> = 0>
- WithCache(const T &Value, const KnownBits &Known)
- : Pointer(static_cast<PointerType>(Value), true), Known(Known) {}
-
[[nodiscard]] PointerType getValue() { return Pointer.getPointer(); }
[[nodiscard]] PointerType getValue() const { return Pointer.getPointer(); }
@@ -76,12 +69,6 @@ template <typename Arg> class WithCache {
return Known;
}
- [[nodiscard]] KnownBits &getKnownBits(const SimplifyQuery &Q) {
- if (!hasKnownBits())
- calculateKnownBits(Q);
- return Known;
- }
-
[[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); }
operator PointerType() { return Pointer.getPointer(); }
>From 1989d10fe708cdf3e03204e40a20d99da3c1ab47 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Mon, 16 Oct 2023 19:35:02 +0530
Subject: [PATCH 13/16] Make computeKnownBits with SQ parameter public
---
llvm/include/llvm/Analysis/ValueTracking.h | 6 +++++
llvm/include/llvm/Analysis/WithCache.h | 7 ++---
llvm/lib/Analysis/ValueTracking.cpp | 30 +++++++++-------------
3 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 44f93e1fff54b52..0e02d0d5b4865da 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -91,6 +91,12 @@ KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
const DominatorTree *DT = nullptr,
bool UseInstrInfo = true);
+KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
+ unsigned Depth, const SimplifyQuery &Q);
+
+KnownBits computeKnownBits(const Value *V, unsigned Depth,
+ const SimplifyQuery &Q);
+
/// Compute known bits from the range metadata.
/// \p KnownZero the set of bits that are known to be zero
/// \p KnownOne the set of bits that are known to be one
diff --git a/llvm/include/llvm/Analysis/WithCache.h b/llvm/include/llvm/Analysis/WithCache.h
index 27b69a284c3254d..c18e5583ae6cc9d 100644
--- a/llvm/include/llvm/Analysis/WithCache.h
+++ b/llvm/include/llvm/Analysis/WithCache.h
@@ -20,12 +20,9 @@
namespace llvm {
struct SimplifyQuery;
-}
+KnownBits computeKnownBits(const Value *V, unsigned Depth,
+ const SimplifyQuery &Q);
-llvm::KnownBits computeKnownBits(const llvm::Value *V, unsigned Depth,
- const llvm::SimplifyQuery &Q);
-
-namespace llvm {
template <typename Arg> class WithCache {
static_assert(std::is_pointer_v<Arg>, "WithCache requires a pointer type!");
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index b1d5d6a4e4c18d1..1e0281b3f1bd79e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -179,17 +179,11 @@ void llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
-KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
- unsigned Depth, const SimplifyQuery &Q);
-
-KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const SimplifyQuery &Q);
-
KnownBits llvm::computeKnownBits(const Value *V, const DataLayout &DL,
unsigned Depth, AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT, bool UseInstrInfo) {
- return ::computeKnownBits(
+ return computeKnownBits(
V, Depth, SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
@@ -197,7 +191,7 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
const DataLayout &DL, unsigned Depth,
AssumptionCache *AC, const Instruction *CxtI,
const DominatorTree *DT, bool UseInstrInfo) {
- return ::computeKnownBits(
+ return computeKnownBits(
V, DemandedElts, Depth,
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
}
@@ -1786,19 +1780,19 @@ static void computeKnownBitsFromOperator(const Operator *I,
/// Determine which bits of V are known to be either zero or one and return
/// them.
-KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
- unsigned Depth, const SimplifyQuery &Q) {
+KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
+ unsigned Depth, const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
- computeKnownBits(V, DemandedElts, Known, Depth, Q);
+ ::computeKnownBits(V, DemandedElts, Known, Depth, Q);
return Known;
}
/// Determine which bits of V are known to be either zero or one and return
/// them.
-KnownBits computeKnownBits(const Value *V, unsigned Depth,
- const SimplifyQuery &Q) {
+KnownBits llvm::computeKnownBits(const Value *V, unsigned Depth,
+ const SimplifyQuery &Q) {
KnownBits Known(getBitWidth(V->getType(), Q.DL));
- computeKnownBits(V, Known, Depth, Q);
+ ::computeKnownBits(V, Known, Depth, Q);
return Known;
}
@@ -6272,8 +6266,8 @@ computeConstantRangeIncludingKnownBits(const WithCache<const Value *> &V,
OverflowResult llvm::computeOverflowForUnsignedMul(const Value *LHS,
const Value *RHS,
const SimplifyQuery &SQ) {
- KnownBits LHSKnown = ::computeKnownBits(LHS, /*Depth=*/0, SQ);
- KnownBits RHSKnown = ::computeKnownBits(RHS, /*Depth=*/0, SQ);
+ KnownBits LHSKnown = computeKnownBits(LHS, /*Depth=*/0, SQ);
+ KnownBits RHSKnown = computeKnownBits(RHS, /*Depth=*/0, SQ);
ConstantRange LHSRange = ConstantRange::fromKnownBits(LHSKnown, false);
ConstantRange RHSRange = ConstantRange::fromKnownBits(RHSKnown, false);
return mapOverflowResult(LHSRange.unsignedMulMayOverflow(RHSRange));
@@ -6310,8 +6304,8 @@ OverflowResult llvm::computeOverflowForSignedMul(const Value *LHS,
// product is exactly the minimum negative number.
// E.g. mul i16 with 17 sign bits: 0xff00 * 0xff80 = 0x8000
// For simplicity we just check if at least one side is not negative.
- KnownBits LHSKnown = ::computeKnownBits(LHS, /*Depth=*/0, SQ);
- KnownBits RHSKnown = ::computeKnownBits(RHS, /*Depth=*/0, SQ);
+ KnownBits LHSKnown = computeKnownBits(LHS, /*Depth=*/0, SQ);
+ KnownBits RHSKnown = computeKnownBits(RHS, /*Depth=*/0, SQ);
if (LHSKnown.isNonNegative() || RHSKnown.isNonNegative())
return OverflowResult::NeverOverflows;
}
>From 3675719200c8bc6d84e0ebd90a7541537d32c35f Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Mon, 16 Oct 2023 22:43:04 +0530
Subject: [PATCH 14/16] Drop CachedBitsValue.h
---
llvm/include/llvm/Analysis/CachedBitsValue.h | 140 -------------------
1 file changed, 140 deletions(-)
delete mode 100644 llvm/include/llvm/Analysis/CachedBitsValue.h
diff --git a/llvm/include/llvm/Analysis/CachedBitsValue.h b/llvm/include/llvm/Analysis/CachedBitsValue.h
deleted file mode 100644
index 1685e2edbb17365..000000000000000
--- a/llvm/include/llvm/Analysis/CachedBitsValue.h
+++ /dev/null
@@ -1,140 +0,0 @@
-//===- llvm/Analysis/CachedBitsValue.h - Value with KnownBits - -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Store a pointer to an llvm::Value along with the KnownBits information for it
-// that is computed lazily (if required).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_CACHEDBITSVALUE_H
-#define LLVM_ANALYSIS_CACHEDBITSVALUE_H
-
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/IR/Value.h"
-#include "llvm/Support/KnownBits.h"
-#include <type_traits>
-
-namespace llvm {
-struct SimplifyQuery;
-}
-
-llvm::KnownBits computeKnownBits(const llvm::Value *V, unsigned Depth,
- const llvm::SimplifyQuery &Q);
-
-namespace llvm {
-namespace detail {
-/// Represents a pointer to an llvm::Value with known bits information
-template <bool ConstPointer = true> class ImplCachedBitsValue {
-protected:
- using ValuePointerType =
- std::conditional_t<ConstPointer, const Value *, Value *>;
- using ValueReferenceType =
- std::conditional_t<ConstPointer, const Value &, Value &>;
-
- template <typename T>
- constexpr static bool ValuePointerConvertible =
- std::is_convertible_v<T, ValuePointerType>;
-
- // Store the presence of the KnownBits information in one of the bits of
- // Pointer.
- // true -> present
- // false -> absent
- mutable PointerIntPair<ValuePointerType, 1, bool> Pointer;
- mutable KnownBits Known;
-
- void calculateKnownBits(const SimplifyQuery &Q) const {
- Known = computeKnownBits(Pointer.getPointer(), 0, Q);
- Pointer.setInt(true);
- }
-
-public:
- ImplCachedBitsValue() = default;
- ImplCachedBitsValue(ValuePointerType Pointer) : Pointer(Pointer, false) {}
- ImplCachedBitsValue(ValuePointerType Pointer, const KnownBits &Known)
- : Pointer(Pointer, true), Known(Known) {}
-
- template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
- ImplCachedBitsValue(const T &Value)
- : Pointer(static_cast<ValuePointerType>(Value), false) {}
-
- template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
- ImplCachedBitsValue(const T &Value, const KnownBits &Known)
- : Pointer(static_cast<ValuePointerType>(Value), true), Known(Known) {}
-
- [[nodiscard]] ValuePointerType getValue() { return Pointer.getPointer(); }
- [[nodiscard]] ValuePointerType getValue() const {
- return Pointer.getPointer();
- }
-
- [[nodiscard]] const KnownBits &getKnownBits(const SimplifyQuery &Q) const {
- if (!hasKnownBits())
- calculateKnownBits(Q);
- return Known;
- }
-
- [[nodiscard]] KnownBits &getKnownBits(const SimplifyQuery &Q) {
- if (!hasKnownBits())
- calculateKnownBits(Q);
- return Known;
- }
-
- [[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); }
-
- operator ValuePointerType() { return Pointer.getPointer(); }
- ValuePointerType operator->() { return Pointer.getPointer(); }
- ValueReferenceType operator*() { return *Pointer.getPointer(); }
-
- operator ValuePointerType() const { return Pointer.getPointer(); }
- ValuePointerType operator->() const { return Pointer.getPointer(); }
- ValueReferenceType operator*() const { return *Pointer.getPointer(); }
-};
-} // namespace detail
-
-class CachedBitsConstValue : public detail::ImplCachedBitsValue<true> {
-public:
- CachedBitsConstValue() = default;
- CachedBitsConstValue(ValuePointerType Pointer)
- : ImplCachedBitsValue(Pointer) {}
- CachedBitsConstValue(Value *Pointer) : ImplCachedBitsValue(Pointer) {}
- CachedBitsConstValue(ValuePointerType Pointer, const KnownBits &Known)
- : ImplCachedBitsValue(Pointer, Known) {}
-
- template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
- CachedBitsConstValue(const T &Value) : ImplCachedBitsValue(Value) {}
-
- template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
- CachedBitsConstValue(const T &Value, const KnownBits &Known)
- : ImplCachedBitsValue(Value, Known) {}
-};
-
-class CachedBitsNonConstValue : public detail::ImplCachedBitsValue<false> {
-public:
- CachedBitsNonConstValue() = default;
- CachedBitsNonConstValue(ValuePointerType Pointer)
- : ImplCachedBitsValue(Pointer) {}
- CachedBitsNonConstValue(ValuePointerType Pointer, const KnownBits &Known)
- : ImplCachedBitsValue(Pointer, Known) {}
-
- template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
- CachedBitsNonConstValue(const T &Value) : ImplCachedBitsValue(Value) {}
-
- template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
- CachedBitsNonConstValue(const T &Value, const KnownBits &Known)
- : ImplCachedBitsValue(Value, Known) {}
-
- [[nodiscard]] CachedBitsConstValue toConst() const {
- if (hasKnownBits())
- return CachedBitsConstValue(getValue(), Known);
- else
- return CachedBitsConstValue(getValue());
- }
-};
-
-} // namespace llvm
-
-#endif
>From ec7c5ee58b5282502dae129ebcd4a5cd84a2f69c Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Mon, 16 Oct 2023 22:49:21 +0530
Subject: [PATCH 15/16] Delete unused code
---
llvm/include/llvm/Analysis/WithCache.h | 5 -----
1 file changed, 5 deletions(-)
diff --git a/llvm/include/llvm/Analysis/WithCache.h b/llvm/include/llvm/Analysis/WithCache.h
index c18e5583ae6cc9d..f826259f2f01b72 100644
--- a/llvm/include/llvm/Analysis/WithCache.h
+++ b/llvm/include/llvm/Analysis/WithCache.h
@@ -35,10 +35,6 @@ template <typename Arg> class WithCache {
using PointerType = conditionally_const_t<UnderlyingType *, IsConst>;
using ReferenceType = conditionally_const_t<UnderlyingType &, IsConst>;
- template <typename T>
- constexpr static bool PointerConvertible =
- std::is_convertible_v<T, UnderlyingType>;
-
// Store the presence of the KnownBits information in one of the bits of
// Pointer.
// true -> present
@@ -52,7 +48,6 @@ template <typename Arg> class WithCache {
}
public:
- WithCache() = default;
WithCache(PointerType Pointer) : Pointer(Pointer, false) {}
WithCache(PointerType Pointer, const KnownBits &Known)
: Pointer(Pointer, true), Known(Known) {}
>From 716f1fa2cda70df85503bdc83696870700e512ff Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Tue, 17 Oct 2023 17:43:34 +0530
Subject: [PATCH 16/16] Remove unusable functions
---
llvm/include/llvm/Analysis/WithCache.h | 5 -----
1 file changed, 5 deletions(-)
diff --git a/llvm/include/llvm/Analysis/WithCache.h b/llvm/include/llvm/Analysis/WithCache.h
index f826259f2f01b72..8065c45738f840b 100644
--- a/llvm/include/llvm/Analysis/WithCache.h
+++ b/llvm/include/llvm/Analysis/WithCache.h
@@ -52,7 +52,6 @@ template <typename Arg> class WithCache {
WithCache(PointerType Pointer, const KnownBits &Known)
: Pointer(Pointer, true), Known(Known) {}
- [[nodiscard]] PointerType getValue() { return Pointer.getPointer(); }
[[nodiscard]] PointerType getValue() const { return Pointer.getPointer(); }
[[nodiscard]] const KnownBits &getKnownBits(const SimplifyQuery &Q) const {
@@ -63,10 +62,6 @@ template <typename Arg> class WithCache {
[[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); }
- operator PointerType() { return Pointer.getPointer(); }
- PointerType operator->() { return Pointer.getPointer(); }
- ReferenceType operator*() { return *Pointer.getPointer(); }
-
operator PointerType() const { return Pointer.getPointer(); }
PointerType operator->() const { return Pointer.getPointer(); }
ReferenceType operator*() const { return *Pointer.getPointer(); }
More information about the llvm-commits
mailing list