[llvm] [InstCombine] Create a class to lazily track computed known bits (PR #66611)
Dhruv Chawla via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 17 22:23:09 PDT 2023
https://github.com/dc03 created https://github.com/llvm/llvm-project/pull/66611
This patch adds a new class "CachedBitsValue" which stores a pointer to
a Value along with KnownBits information which is computed on-demand
when getKnownBits() is called. This allows reusing the known bits
information for a Value when it is passed to multiple functions where it
is required.
It also 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
>From 2ea51b5319fb5e8f62492b737a579dd70b75515c Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <44582521+dc03 at users.noreply.github.com>
Date: Tue, 8 Aug 2023 18:46:18 +0530
Subject: [PATCH 1/2] [InstCombine] Create a class to lazily track computed
known bits
This patch adds a new class "CachedBitsValue" which stores a pointer to
a Value along with KnownBits information which is computed on-demand
when getKnownBits() is called. This allows reusing the known bits
information for a Value when it is passed to multiple functions where it
is required.
---
llvm/include/llvm/Analysis/CachedBitsValue.h | 188 +++++++++++++++++++
1 file changed, 188 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..0e13afc810da111
--- /dev/null
+++ b/llvm/include/llvm/Analysis/CachedBitsValue.h
@@ -0,0 +1,188 @@
+//===- 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_VALUEWITHINFOCACHE_H
+#define LLVM_ANALYSIS_VALUEWITHINFOCACHE_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 KnownBits Known;
+ mutable bool HasKnownBits;
+
+ void calculateKnownBits(unsigned Depth, const SimplifyQuery &Q) const {
+ HasKnownBits = true;
+ Known = computeKnownBits(Pointer, Depth, Q);
+ }
+
+ void calculateKnownBits(const APInt &DemandedElts, unsigned Depth,
+ const SimplifyQuery &Q) const {
+ HasKnownBits = true;
+ Known = computeKnownBits(Pointer, DemandedElts, Depth, Q);
+ }
+
+public:
+ ImplCachedBitsValue() = default;
+ ImplCachedBitsValue(ValuePointerType Pointer)
+ : Pointer(Pointer), Known(), HasKnownBits(false) {}
+ ImplCachedBitsValue(ValuePointerType Pointer, const KnownBits &Known)
+ : Pointer(Pointer), Known(Known), HasKnownBits(true) {}
+
+ template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
+ ImplCachedBitsValue(const T &Value)
+ : Pointer(static_cast<ValuePointerType>(Value)), Known(),
+ HasKnownBits(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),
+ HasKnownBits(true) {}
+
+ ImplCachedBitsValue(ImplCachedBitsValue &&) = default;
+ ImplCachedBitsValue &operator=(ImplCachedBitsValue &&) = default;
+ ImplCachedBitsValue(const ImplCachedBitsValue &) = default;
+ ImplCachedBitsValue &operator=(const ImplCachedBitsValue &) = default;
+
+ ~ImplCachedBitsValue() = default;
+
+ [[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;
+ }
+
+ [[nodiscard]] KnownBits &getKnownBits(unsigned Depth,
+ const SimplifyQuery &Q) {
+ if (!hasKnownBits())
+ calculateKnownBits(Depth, Q);
+ 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 HasKnownBits; }
+
+ 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) {}
+
+ CachedBitsConstValue(CachedBitsConstValue &&) = default;
+ CachedBitsConstValue &operator=(CachedBitsConstValue &&) = default;
+ CachedBitsConstValue(const CachedBitsConstValue &) = default;
+ CachedBitsConstValue &operator=(const CachedBitsConstValue &) = default;
+
+ ~CachedBitsConstValue() = default;
+};
+
+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) {}
+
+ CachedBitsNonConstValue(CachedBitsNonConstValue &&) = default;
+ CachedBitsNonConstValue &operator=(CachedBitsNonConstValue &&) = default;
+ CachedBitsNonConstValue(const CachedBitsNonConstValue &) = default;
+ CachedBitsNonConstValue &operator=(const CachedBitsNonConstValue &) = default;
+
+ ~CachedBitsNonConstValue() = default;
+
+ [[nodiscard]] CachedBitsConstValue toConst() const {
+ if (hasKnownBits())
+ return CachedBitsConstValue(getValue(), Known);
+ else
+ return CachedBitsConstValue(getValue());
+ }
+};
+
+} // namespace llvm
+
+#endif
>From 06f6f21c220fbb82750274794104d6f8aebf7a58 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 2/2] [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 | 29 ++++--
.../Transforms/InstCombine/InstCombiner.h | 7 +-
llvm/lib/Analysis/ValueTracking.cpp | 88 +++++++++----------
.../InstCombine/InstCombineAddSub.cpp | 9 +-
.../InstCombine/InstCombineInternal.h | 6 +-
5 files changed, 76 insertions(+), 63 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 695f2fecae885b7..40827c5119f62bf 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallSet.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 DataLayout &DL, AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr,
@@ -858,13 +872,12 @@ OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS,
const Instruction *CxtI,
const DominatorTree *DT,
bool UseInstrInfo = true);
-OverflowResult computeOverflowForUnsignedAdd(const Value *LHS, const Value *RHS,
- const DataLayout &DL,
- AssumptionCache *AC,
- const Instruction *CxtI,
- const DominatorTree *DT,
- bool UseInstrInfo = true);
-OverflowResult computeOverflowForSignedAdd(const Value *LHS, const Value *RHS,
+OverflowResult computeOverflowForUnsignedAdd(
+ const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
+ const DataLayout &DL, AssumptionCache *AC, const Instruction *CxtI,
+ const DominatorTree *DT, bool UseInstrInfo = true);
+OverflowResult computeOverflowForSignedAdd(const CachedBitsConstValue &LHS,
+ const CachedBitsConstValue &RHS,
const DataLayout &DL,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
diff --git a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
index b16a60c423ab103..e5f3d07fe2c1412 100644
--- a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
+++ b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
@@ -505,13 +505,14 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
return llvm::computeOverflowForSignedMul(LHS, RHS, DL, &AC, CxtI, &DT);
}
- 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, DL, &AC, CxtI, &DT);
}
- 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, DL, &AC, CxtI, &DT);
}
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index c4153b824c37e0a..90233788331f41b 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,
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,
@@ -202,10 +193,14 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
safeCxtI(V, CxtI), UseInstrInfo));
}
-bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
+bool llvm::haveNoCommonBitsSet(const CachedBitsConstValue &LHSCache,
+ const CachedBitsConstValue &RHSCache,
const DataLayout &DL, AssumptionCache *AC,
const Instruction *CxtI, const DominatorTree *DT,
bool UseInstrInfo) {
+ 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() &&
@@ -253,12 +248,14 @@ 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, DL, 0, AC, CxtI, DT, UseInstrInfo);
- computeKnownBits(RHS, RHSKnown, DL, 0, AC, CxtI, DT, UseInstrInfo);
- return KnownBits::haveNoCommonBitsSet(LHSKnown, RHSKnown);
+
+ return KnownBits::haveNoCommonBitsSet(
+ LHSCache.getKnownBits(0, SimplifyQuery(DL, /*TLI*/ nullptr, DT, AC,
+ safeCxtI(LHSCache, CxtI),
+ UseInstrInfo)),
+ RHSCache.getKnownBits(0, SimplifyQuery(DL, /*TLI*/ nullptr, DT, AC,
+ safeCxtI(RHSCache, CxtI),
+ UseInstrInfo)));
}
bool llvm::isOnlyUsedInZeroEqualityComparison(const Instruction *I) {
@@ -1778,8 +1775,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;
@@ -1787,8 +1784,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;
@@ -1809,9 +1806,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();
@@ -6251,11 +6248,13 @@ static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
/// Combine constant ranges from computeConstantRange() and computeKnownBits().
static ConstantRange computeConstantRangeIncludingKnownBits(
- const Value *V, bool ForSigned, const DataLayout &DL, unsigned Depth,
- AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT,
- bool UseInstrInfo = true) {
- KnownBits Known = computeKnownBits(V, DL, Depth, AC, CxtI, DT, UseInstrInfo);
- ConstantRange CR1 = ConstantRange::fromKnownBits(Known, ForSigned);
+ const CachedBitsConstValue &V, bool ForSigned, const DataLayout &DL,
+ unsigned Depth, AssumptionCache *AC, const Instruction *CxtI,
+ const DominatorTree *DT, bool UseInstrInfo = true) {
+ ConstantRange CR1 = ConstantRange::fromKnownBits(
+ V.getKnownBits(Depth, SimplifyQuery(DL, /*TLI*/ nullptr, DT, AC,
+ safeCxtI(V, CxtI), UseInstrInfo)),
+ ForSigned);
ConstantRange CR2 = computeConstantRange(V, ForSigned, UseInstrInfo);
ConstantRange::PreferredRangeType RangeType =
ForSigned ? ConstantRange::Signed : ConstantRange::Unsigned;
@@ -6319,9 +6318,9 @@ llvm::computeOverflowForSignedMul(const Value *LHS, const Value *RHS,
}
OverflowResult llvm::computeOverflowForUnsignedAdd(
- const Value *LHS, const Value *RHS, const DataLayout &DL,
- AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT,
- bool UseInstrInfo) {
+ const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
+ const DataLayout &DL, AssumptionCache *AC, const Instruction *CxtI,
+ const DominatorTree *DT, bool UseInstrInfo) {
ConstantRange LHSRange = computeConstantRangeIncludingKnownBits(
LHS, /*ForSigned=*/false, DL, /*Depth=*/0, AC, CxtI, DT, UseInstrInfo);
ConstantRange RHSRange = computeConstantRangeIncludingKnownBits(
@@ -6329,13 +6328,10 @@ OverflowResult llvm::computeOverflowForUnsignedAdd(
return mapOverflowResult(LHSRange.unsignedAddMayOverflow(RHSRange));
}
-static OverflowResult computeOverflowForSignedAdd(const Value *LHS,
- const Value *RHS,
- const AddOperator *Add,
- const DataLayout &DL,
- AssumptionCache *AC,
- const Instruction *CxtI,
- const DominatorTree *DT) {
+static OverflowResult computeOverflowForSignedAdd(
+ const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
+ const AddOperator *Add, const DataLayout &DL, AssumptionCache *AC,
+ const Instruction *CxtI, const DominatorTree *DT) {
if (Add && Add->hasNoSignedWrap()) {
return OverflowResult::NeverOverflows;
}
@@ -6962,12 +6958,10 @@ OverflowResult llvm::computeOverflowForSignedAdd(const AddOperator *Add,
Add, DL, AC, CxtI, DT);
}
-OverflowResult llvm::computeOverflowForSignedAdd(const Value *LHS,
- const Value *RHS,
- const DataLayout &DL,
- AssumptionCache *AC,
- const Instruction *CxtI,
- const DominatorTree *DT) {
+OverflowResult llvm::computeOverflowForSignedAdd(
+ const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
+ const DataLayout &DL, AssumptionCache *AC, const Instruction *CxtI,
+ const DominatorTree *DT) {
return ::computeOverflowForSignedAdd(LHS, RHS, nullptr, DL, AC, CxtI, DT);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index e08d41de87d40a2..ee62ecf52794808 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, DL, &AC, &I, &DT))
+ CachedBitsConstValue LHSCache(LHS), RHSCache(RHS);
+ if (haveNoCommonBitsSet(LHSCache, RHSCache, DL, &AC, &I, &DT,
+ /* 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 40c24d87bfec508..2ed1ffd199331dc 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -278,13 +278,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;
More information about the llvm-commits
mailing list