aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
diff options
context:
space:
mode:
authorDavid Stenberg <david.stenberg@ericsson.com>2020-10-20 19:30:39 +0200
committerDavid Stenberg <david.stenberg@ericsson.com>2020-10-20 20:05:59 +0200
commit0c0fcea557e4a7cfd51216ad20aa67c82733ab52 (patch)
tree90a23ba322ba982ff4e4e7319a88dc267f7bc56c /llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
parentcf9e54ef49c689772112c377ecce358ec66d0e59 (diff)
downloadllvm-0c0fcea557e4a7cfd51216ad20aa67c82733ab52.zip
llvm-0c0fcea557e4a7cfd51216ad20aa67c82733ab52.tar.gz
llvm-0c0fcea557e4a7cfd51216ad20aa67c82733ab52.tar.bz2
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
Diffstat (limited to 'llvm/lib/Bitcode/Writer/ValueEnumerator.cpp')
-rw-r--r--llvm/lib/Bitcode/Writer/ValueEnumerator.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index 4ae25f7..bbee8b3 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -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