Handle value uses wrapped in metadata for the use-list order
When generating the use-list order, also consider value uses that are operands which are wrapped in metadata; e.g. llvm.dbg.value operands. This fixes PR36778. The test case is based on the reproducer from that report. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D53758
This commit is contained in:
@@ -78,6 +78,16 @@ struct OrderMap {
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// Look for a value that might be wrapped as metadata, e.g. a value in a
|
||||
/// metadata operand. Returns nullptr for a non-wrapped input value if
|
||||
/// OnlyWrapped is true, or it returns the input value as-is if false.
|
||||
static const Value *skipMetadataWrapper(const Value *V, bool OnlyWrapped) {
|
||||
if (const auto *MAV = dyn_cast<MetadataAsValue>(V))
|
||||
if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata()))
|
||||
return VAM->getValue();
|
||||
return OnlyWrapped ? nullptr : V;
|
||||
}
|
||||
|
||||
static void orderValue(const Value *V, OrderMap &OM) {
|
||||
if (OM.lookup(V).first)
|
||||
return;
|
||||
@@ -123,6 +133,25 @@ static OrderMap orderModule(const Module &M) {
|
||||
if (!isa<GlobalValue>(U.get()))
|
||||
orderValue(U.get(), OM);
|
||||
}
|
||||
|
||||
// As constants used in metadata operands are emitted as module-level
|
||||
// constants, we must order them before other operands. Also, we must order
|
||||
// these before global values, as these will be read before setting the
|
||||
// global values' initializers. The latter matters for constants which have
|
||||
// uses towards other constants that are used as initializers.
|
||||
for (const Function &F : M) {
|
||||
if (F.isDeclaration())
|
||||
continue;
|
||||
for (const BasicBlock &BB : F)
|
||||
for (const Instruction &I : BB)
|
||||
for (const Value *V : I.operands()) {
|
||||
if (const Value *Op = skipMetadataWrapper(V, true)) {
|
||||
if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
|
||||
isa<InlineAsm>(*Op))
|
||||
orderValue(Op, OM);
|
||||
}
|
||||
}
|
||||
}
|
||||
OM.LastGlobalConstantID = OM.size();
|
||||
|
||||
// Initializers of GlobalValues are processed in
|
||||
|
||||
Reference in New Issue
Block a user