-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Reapply "IR: Remove uselist for constantdata (#137313)" #138961
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reapply "IR: Remove uselist for constantdata (#137313)" #138961
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-llvm-ir Author: Matt Arsenault (arsenm) ChangesReapply "IR: Remove uselist for constantdata (#137313)" This reverts commit 5936c02. Fix checking uselists of constants in assume bundle queries Patch is 31.47 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138961.diff 28 Files Affected:
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 0ed1675533d03..504db733308c1 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -56,6 +56,8 @@ Makes programs 10x faster by doing Special New Thing.
Changes to the LLVM IR
----------------------
+* It is no longer permitted to inspect the uses of ConstantData
+
* The `nocapture` attribute has been replaced by `captures(none)`.
* The constant expression variants of the following instructions have been
removed:
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index 88d005d1adbb1..ff51f59b6ec68 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -50,6 +50,8 @@ template <class ConstantClass> struct ConstantAggrKeyType;
/// These constants have no operands; they represent their data directly.
/// Since they can be in use by unrelated modules (and are never based on
/// GlobalValues), it never makes sense to RAUW them.
+///
+/// These do not have use lists. It is illegal to inspect the uses.
class ConstantData : public Constant {
constexpr static IntrusiveOperandsAllocMarker AllocMarker{0};
diff --git a/llvm/include/llvm/IR/Use.h b/llvm/include/llvm/IR/Use.h
index a86b9c46c1f69..bcd1fd6677497 100644
--- a/llvm/include/llvm/IR/Use.h
+++ b/llvm/include/llvm/IR/Use.h
@@ -23,6 +23,7 @@
namespace llvm {
template <typename> struct simplify_type;
+class ConstantData;
class User;
class Value;
@@ -42,10 +43,7 @@ class Use {
private:
/// Destructor - Only for zap()
- ~Use() {
- if (Val)
- removeFromList();
- }
+ ~Use();
/// Constructor
Use(User *Parent) : Parent(Parent) {}
@@ -87,19 +85,10 @@ class Use {
Use **Prev = nullptr;
User *Parent = nullptr;
- void addToList(Use **List) {
- Next = *List;
- if (Next)
- Next->Prev = &Next;
- Prev = List;
- *Prev = this;
- }
-
- void removeFromList() {
- *Prev = Next;
- if (Next)
- Next->Prev = Prev;
- }
+ inline void addToList(unsigned &Count);
+ inline void addToList(Use *&List);
+ inline void removeFromList(unsigned &Count);
+ inline void removeFromList(Use *&List);
};
/// Allow clients to treat uses just like values when using
diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h
index bf1de7eef9932..180b6238eda6c 100644
--- a/llvm/include/llvm/IR/Value.h
+++ b/llvm/include/llvm/IR/Value.h
@@ -116,7 +116,10 @@ class Value {
private:
Type *VTy;
- Use *UseList;
+ union {
+ Use *List = nullptr;
+ unsigned Count;
+ } Uses;
friend class ValueAsMetadata; // Allow access to IsUsedByMD.
friend class ValueHandleBase; // Allow access to HasValueHandle.
@@ -339,21 +342,28 @@ class Value {
#endif
}
+ /// Check if this Value has a use-list.
+ bool hasUseList() const { return !isa<ConstantData>(this); }
+
bool use_empty() const {
assertModuleIsMaterialized();
- return UseList == nullptr;
+ return hasUseList() ? Uses.List == nullptr : Uses.Count == 0;
}
bool materialized_use_empty() const {
- return UseList == nullptr;
+ return hasUseList() ? Uses.List == nullptr : !Uses.Count;
}
using use_iterator = use_iterator_impl<Use>;
using const_use_iterator = use_iterator_impl<const Use>;
- use_iterator materialized_use_begin() { return use_iterator(UseList); }
+ use_iterator materialized_use_begin() {
+ assert(hasUseList());
+ return use_iterator(Uses.List);
+ }
const_use_iterator materialized_use_begin() const {
- return const_use_iterator(UseList);
+ assert(hasUseList());
+ return const_use_iterator(Uses.List);
}
use_iterator use_begin() {
assertModuleIsMaterialized();
@@ -380,17 +390,18 @@ class Value {
return materialized_uses();
}
- bool user_empty() const {
- assertModuleIsMaterialized();
- return UseList == nullptr;
- }
+ bool user_empty() const { return use_empty(); }
using user_iterator = user_iterator_impl<User>;
using const_user_iterator = user_iterator_impl<const User>;
- user_iterator materialized_user_begin() { return user_iterator(UseList); }
+ user_iterator materialized_user_begin() {
+ assert(hasUseList());
+ return user_iterator(Uses.List);
+ }
const_user_iterator materialized_user_begin() const {
- return const_user_iterator(UseList);
+ assert(hasUseList());
+ return const_user_iterator(Uses.List);
}
user_iterator user_begin() {
assertModuleIsMaterialized();
@@ -429,7 +440,11 @@ class Value {
///
/// This is specialized because it is a common request and does not require
/// traversing the whole use list.
- bool hasOneUse() const { return hasSingleElement(uses()); }
+ bool hasOneUse() const {
+ if (!hasUseList())
+ return Uses.Count == 1;
+ return hasSingleElement(uses());
+ }
/// Return true if this Value has exactly N uses.
bool hasNUses(unsigned N) const;
@@ -491,6 +506,8 @@ class Value {
static void dropDroppableUse(Use &U);
/// Check if this value is used in the specified basic block.
+ ///
+ /// Not supported for ConstantData.
bool isUsedInBasicBlock(const BasicBlock *BB) const;
/// This method computes the number of uses of this Value.
@@ -500,7 +517,19 @@ class Value {
unsigned getNumUses() const;
/// This method should only be used by the Use class.
- void addUse(Use &U) { U.addToList(&UseList); }
+ void addUse(Use &U) {
+ if (hasUseList())
+ U.addToList(Uses.List);
+ else
+ U.addToList(Uses.Count);
+ }
+
+ void removeUse(Use &U) {
+ if (hasUseList())
+ U.removeFromList(Uses.List);
+ else
+ U.removeFromList(Uses.Count);
+ }
/// Concrete subclass of this.
///
@@ -841,7 +870,8 @@ class Value {
///
/// \return the first element in the list.
///
- /// \note Completely ignores \a Use::Prev (doesn't read, doesn't update).
+ /// \note Completely ignores \a Use::PrevOrCount (doesn't read, doesn't
+ /// update).
template <class Compare>
static Use *mergeUseLists(Use *L, Use *R, Compare Cmp) {
Use *Merged;
@@ -887,10 +917,50 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {
return OS;
}
+inline Use::~Use() {
+ if (Val)
+ Val->removeUse(*this);
+}
+
+void Use::addToList(unsigned &Count) {
+ assert(isa<ConstantData>(Val) && "Only ConstantData is ref-counted");
+ ++Count;
+
+ // We don't have a uselist - clear the remnant if we are replacing a
+ // non-constant value.
+ Prev = nullptr;
+ Next = nullptr;
+}
+
+void Use::addToList(Use *&List) {
+ assert(!isa<ConstantData>(Val) && "ConstantData has no use-list");
+
+ Next = List;
+ if (Next)
+ Next->Prev = &Next;
+ Prev = &List;
+ List = this;
+}
+
+void Use::removeFromList(unsigned &Count) {
+ assert(isa<ConstantData>(Val));
+ assert(Count > 0 && "reference count underflow");
+ assert(!Prev && !Next && "should not have uselist remnant");
+ --Count;
+}
+
+void Use::removeFromList(Use *&List) {
+ *Prev = Next;
+ if (Next)
+ Next->Prev = Prev;
+}
+
void Use::set(Value *V) {
- if (Val) removeFromList();
+ if (Val)
+ Val->removeUse(*this);
Val = V;
- if (V) V->addUse(*this);
+ if (V)
+ V->addUse(*this);
}
Value *Use::operator=(Value *RHS) {
@@ -904,7 +974,7 @@ const Use &Use::operator=(const Use &RHS) {
}
template <class Compare> void Value::sortUseList(Compare Cmp) {
- if (!UseList || !UseList->Next)
+ if (!hasUseList() || !Uses.List || !Uses.List->Next)
// No need to sort 0 or 1 uses.
return;
@@ -917,10 +987,10 @@ template <class Compare> void Value::sortUseList(Compare Cmp) {
Use *Slots[MaxSlots];
// Collect the first use, turning it into a single-item list.
- Use *Next = UseList->Next;
- UseList->Next = nullptr;
+ Use *Next = Uses.List->Next;
+ Uses.List->Next = nullptr;
unsigned NumSlots = 1;
- Slots[0] = UseList;
+ Slots[0] = Uses.List;
// Collect all but the last use.
while (Next->Next) {
@@ -956,15 +1026,15 @@ template <class Compare> void Value::sortUseList(Compare Cmp) {
// Merge all the lists together.
assert(Next && "Expected one more Use");
assert(!Next->Next && "Expected only one Use");
- UseList = Next;
+ Uses.List = Next;
for (unsigned I = 0; I < NumSlots; ++I)
if (Slots[I])
- // Since the uses in Slots[I] originally preceded those in UseList, send
+ // Since the uses in Slots[I] originally preceded those in Uses.List, send
// Slots[I] in as the left parameter to maintain a stable sort.
- UseList = mergeUseLists(Slots[I], UseList, Cmp);
+ Uses.List = mergeUseLists(Slots[I], Uses.List, Cmp);
// Fix the Prev pointers.
- for (Use *I = UseList, **Prev = &UseList; I; I = I->Next) {
+ for (Use *I = Uses.List, **Prev = &Uses.List; I; I = I->Next) {
I->Prev = Prev;
Prev = &I->Next;
}
diff --git a/llvm/lib/Analysis/AssumeBundleQueries.cpp b/llvm/lib/Analysis/AssumeBundleQueries.cpp
index c27bfa6f3cc2c..b37b2270bbec5 100644
--- a/llvm/lib/Analysis/AssumeBundleQueries.cpp
+++ b/llvm/lib/Analysis/AssumeBundleQueries.cpp
@@ -180,6 +180,10 @@ llvm::getKnowledgeForValue(const Value *V,
}
return RetainedKnowledge::none();
}
+
+ if (!V->hasUseList())
+ return RetainedKnowledge::none();
+
for (const auto &U : V->uses()) {
CallInst::BundleOpInfo* Bundle = getBundleFromUse(&U);
if (!Bundle)
diff --git a/llvm/lib/Analysis/TypeMetadataUtils.cpp b/llvm/lib/Analysis/TypeMetadataUtils.cpp
index 9ec0785eb5034..8099fbc3daeda 100644
--- a/llvm/lib/Analysis/TypeMetadataUtils.cpp
+++ b/llvm/lib/Analysis/TypeMetadataUtils.cpp
@@ -54,6 +54,9 @@ findCallsAtConstantOffset(SmallVectorImpl<DevirtCallSite> &DevirtCalls,
static void findLoadCallsAtConstantOffset(
const Module *M, SmallVectorImpl<DevirtCallSite> &DevirtCalls, Value *VPtr,
int64_t Offset, const CallInst *CI, DominatorTree &DT) {
+ if (!VPtr->hasUseList())
+ return;
+
for (const Use &U : VPtr->uses()) {
Value *User = U.getUser();
if (isa<BitCastInst>(User)) {
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index fc7f4601331df..96f86eb52f15c 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -8869,6 +8869,8 @@ bool LLParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
//===----------------------------------------------------------------------===//
bool LLParser::sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes,
SMLoc Loc) {
+ if (!V->hasUseList())
+ return false;
if (V->use_empty())
return error(Loc, "value has no uses");
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 4074ed65885c7..e5103201cac01 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -3860,6 +3860,10 @@ Error BitcodeReader::parseUseLists() {
V = FunctionBBs[ID];
} else
V = ValueList[ID];
+
+ if (!V->hasUseList())
+ break;
+
unsigned NumUses = 0;
SmallDenseMap<const Use *, unsigned, 16> Order;
for (const Use &U : V->materialized_uses()) {
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index 9f735f77d29dc..1fdb8080eab0a 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -230,6 +230,9 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F,
static void predictValueUseListOrder(const Value *V, const Function *F,
OrderMap &OM, UseListOrderStack &Stack) {
+ if (!V->hasUseList())
+ return;
+
auto &IDPair = OM[V];
assert(IDPair.first && "Unmapped value");
if (IDPair.second)
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index eb076960a5def..889e24a3f70ad 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -4004,7 +4004,7 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
// Globals with sub-elements such as combinations of arrays and structs
// are handled recursively by emitGlobalConstantImpl. Keep track of the
// constant symbol base and the current position with BaseCV and Offset.
- if (!BaseCV && CV->hasOneUse())
+ if (!isa<ConstantData>(CV) && !BaseCV && CV->hasOneUse())
BaseCV = dyn_cast<Constant>(CV->user_back());
if (isa<ConstantAggregateZero>(CV)) {
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index f9dcb472ed1d2..2c53a9c27ccb2 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -8591,6 +8591,9 @@ static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI,
return false;
Value *X = Cmp->getOperand(0);
+ if (!X->hasUseList())
+ return false;
+
APInt CmpC = cast<ConstantInt>(Cmp->getOperand(1))->getValue();
for (auto *U : X->users()) {
diff --git a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
index f4fe0b3970d4c..90c6c28c3c706 100644
--- a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
+++ b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
@@ -1034,6 +1034,9 @@ ComplexDeinterleavingGraph::identifyPartialReduction(Value *R, Value *I) {
if (!isa<VectorType>(R->getType()) || !isa<VectorType>(I->getType()))
return nullptr;
+ if (!R->hasUseList() || !I->hasUseList())
+ return nullptr;
+
auto CommonUser =
findCommonBetweenCollections<Value *>(R->users(), I->users());
if (!CommonUser)
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 12edf6fcd510c..610cbcb1a9b6b 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -125,11 +125,15 @@ static void orderValue(const Value *V, OrderMap &OM) {
if (OM.lookup(V))
return;
- if (const Constant *C = dyn_cast<Constant>(V))
+ if (const Constant *C = dyn_cast<Constant>(V)) {
+ if (isa<ConstantData>(C))
+ return;
+
if (C->getNumOperands() && !isa<GlobalValue>(C))
for (const Value *Op : C->operands())
if (!isa<BasicBlock>(Op) && !isa<GlobalValue>(Op))
orderValue(Op, OM);
+ }
// Note: we cannot cache this lookup above, since inserting into the map
// changes the map's size, and thus affects the other IDs.
@@ -275,7 +279,8 @@ static UseListOrderMap predictUseListOrder(const Module *M) {
UseListOrderMap ULOM;
for (const auto &Pair : OM) {
const Value *V = Pair.first;
- if (V->use_empty() || std::next(V->use_begin()) == V->use_end())
+ if (!V->hasUseList() || V->use_empty() ||
+ std::next(V->use_begin()) == V->use_end())
continue;
std::vector<unsigned> Shuffle =
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 6f858110fb8ce..258681382f9e5 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -373,7 +373,9 @@ std::optional<BasicBlock::iterator> Instruction::getInsertionPointAfterDef() {
}
bool Instruction::isOnlyUserOfAnyOperand() {
- return any_of(operands(), [](Value *V) { return V->hasOneUser(); });
+ return any_of(operands(), [](const Value *V) {
+ return V->hasUseList() && V->hasOneUser();
+ });
}
void Instruction::setHasNoUnsignedWrap(bool b) {
diff --git a/llvm/lib/IR/Use.cpp b/llvm/lib/IR/Use.cpp
index 99a89386d75f9..67882ba0144b4 100644
--- a/llvm/lib/IR/Use.cpp
+++ b/llvm/lib/IR/Use.cpp
@@ -19,11 +19,15 @@ void Use::swap(Use &RHS) {
std::swap(Next, RHS.Next);
std::swap(Prev, RHS.Prev);
- *Prev = this;
+ if (Prev)
+ *Prev = this;
+
if (Next)
Next->Prev = &Next;
- *RHS.Prev = &RHS;
+ if (RHS.Prev)
+ *RHS.Prev = &RHS;
+
if (RHS.Next)
RHS.Next->Prev = &RHS.Next;
}
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index aa97b70f21aeb..74a96051f33af 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -53,7 +53,7 @@ static inline Type *checkType(Type *Ty) {
Value::Value(Type *ty, unsigned scid)
: SubclassID(scid), HasValueHandle(0), SubclassOptionalData(0),
SubclassData(0), NumUserOperands(0), IsUsedByMD(false), HasName(false),
- HasMetadata(false), VTy(checkType(ty)), UseList(nullptr) {
+ HasMetadata(false), VTy(checkType(ty)) {
static_assert(ConstantFirstVal == 0, "!(SubclassID < ConstantFirstVal)");
// FIXME: Why isn't this in the subclass gunk??
// Note, we cannot call isa<CallInst> before the CallInst has been
@@ -148,10 +148,14 @@ void Value::destroyValueName() {
}
bool Value::hasNUses(unsigned N) const {
+ if (!hasUseList())
+ return Uses.Count == N;
return hasNItems(use_begin(), use_end(), N);
}
bool Value::hasNUsesOrMore(unsigned N) const {
+ if (!hasUseList())
+ return Uses.Count >= N;
return hasNItemsOrMore(use_begin(), use_end(), N);
}
@@ -232,6 +236,8 @@ void Value::dropDroppableUse(Use &U) {
}
bool Value::isUsedInBasicBlock(const BasicBlock *BB) const {
+ assert(hasUseList() && "ConstantData has no use-list");
+
// This can be computed either by scanning the instructions in BB, or by
// scanning the use list of this Value. Both lists can be very long, but
// usually one is quite short.
@@ -253,6 +259,9 @@ bool Value::isUsedInBasicBlock(const BasicBlock *BB) const {
}
unsigned Value::getNumUses() const {
+ if (!hasUseList())
+ return Uses.Count;
+
return (unsigned)std::distance(use_begin(), use_end());
}
@@ -499,6 +508,7 @@ static bool contains(Value *Expr, Value *V) {
#endif // NDEBUG
void Value::doRAUW(Value *New, ReplaceMetadataUses ReplaceMetaUses) {
+ assert(hasUseList() && "Cannot replace constant data");
assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
assert(!contains(New, this) &&
"this->replaceAllUsesWith(expr(this)) is NOT valid!");
@@ -512,7 +522,7 @@ void Value::doRAUW(Value *New, ReplaceMetadataUses ReplaceMetaUses) {
ValueAsMetadata::handleRAUW(this, New);
while (!materialized_use_empty()) {
- Use &U = *UseList;
+ Use &U = *Uses.List;
// Must handle Constants specially, we cannot call replaceUsesOfWith on a
// constant because they are uniqued.
if (auto *C = dyn_cast<Constant>(U.getUser())) {
@@ -844,7 +854,7 @@ bool Value::canBeFreed() const {
// which is why we need the explicit opt in on a per collector basis.
if (!F->hasGC())
return true;
-
+
const auto &GCName = F->getGC();
if (GCName == "statepoint-example") {
auto *PT = cast<PointerType>(this->getType());
@@ -1092,12 +1102,12 @@ const Value *Value::DoPHITranslation(const BasicBlock *CurBB,
LLVMContext &Value::getContext() const { return VTy->getContext(); }
void Value::reverseUseList() {
- if (!UseList || !UseList->Next)
+ if (!Uses.List || !Uses.List->Next || !hasUseList())
// No need to reverse 0 or 1 uses.
return;
- Use *Head = UseList;
- Use *Current = UseList->Next;
+ Use *Head = Uses.List;
+ Use *Current = Uses.List->Next;
Head->Next = nullptr;
while (Current) {
Use *Next = Current->Next;
@@ -1106,8 +1116,8 @@ void Value::reverseUseList() {
Head = Current;
Current = Next;
}
- UseList = Head;
- Head->Prev = &UseList;
+ Uses.List = Head;
+ Head->Prev = &Uses.List;
}
bool Value::isSwiftError() const {
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 8d83fef265e6f..6bd3fd182485d 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -633,7 +633,7 @@ bool AArch64RegisterBankInfo::isLoadFromFPType(const MachineInstr &MI) const {
// Look at the first element of the array to determine its type
if (isa<ArrayType>(EltTy))
EltTy = EltTy->getArrayElementType();
- } else {
+ } else if (!isa<Constant>(LdVal)) {
// FIXME: grubbing around uses is pretty ugly, but with no more
// `getPointerElementType` there's not much else we can do.
for (const auto *LdUser : LdVal->users()) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 4325023406c7c..22fc1ca2c4c2d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SP...
[truncated]
|
@@ -180,6 +180,10 @@ llvm::getKnowledgeForValue(const Value *V, | |||
} | |||
return RetainedKnowledge::none(); | |||
} | |||
|
|||
if (!V->hasUseList()) | |||
return RetainedKnowledge::none(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a followup, we should completely remove the non-AC code in this function. We shouldn't be querying assumes without AC.
59ae795
to
516db0b
Compare
4fb5018
to
38540d2
Compare
) Reapply "IR: Remove uselist for constantdata (llvm#137313)" This reverts commit 5936c02. Fix checking uselists of constants in assume bundle queries
…rValue (#139232) As requested in llvm/llvm-project#138961 (comment)
We've bisected an assertion failure to this commit:
There's a stack and reproducer at https://crbug.com/417175765#comment3 Can you take a look? I've started a creduce run, but it might take a while. |
Use llvm-reduce and it won't |
Reduced reproducer:
|
Fix in #139609 |
Reapply "IR: Remove uselist for constantdata (#137313)"
This reverts commit 5936c02.
Fix checking uselists of constants in assume bundle queries