Skip to content

Commit 28a896d

Browse files
committed
CloneModule: Map global initializers after mapping the function
Global initializers may contain references to blockaddresses, which won't have their VMap entries until after the function body is processed. Fixes emitting broken initializers in llvm-reduce when functions using blockaddress are deleted.
1 parent 9356091 commit 28a896d

File tree

2 files changed

+28
-32
lines changed

2 files changed

+28
-32
lines changed

llvm/lib/Transforms/Utils/CloneModule.cpp

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -124,32 +124,6 @@ std::unique_ptr<Module> llvm::CloneModule(
124124
VMap[&I] = GI;
125125
}
126126

127-
// Now that all of the things that global variable initializer can refer to
128-
// have been created, loop through and copy the global variable referrers
129-
// over... We also set the attributes on the global now.
130-
//
131-
for (const GlobalVariable &G : M.globals()) {
132-
GlobalVariable *GV = cast<GlobalVariable>(VMap[&G]);
133-
134-
SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
135-
G.getAllMetadata(MDs);
136-
for (auto MD : MDs)
137-
GV->addMetadata(MD.first, *MapMetadata(MD.second, VMap));
138-
139-
if (G.isDeclaration())
140-
continue;
141-
142-
if (!ShouldCloneDefinition(&G)) {
143-
// Skip after setting the correct linkage for an external reference.
144-
GV->setLinkage(GlobalValue::ExternalLinkage);
145-
continue;
146-
}
147-
if (G.hasInitializer())
148-
GV->setInitializer(MapValue(G.getInitializer(), VMap));
149-
150-
copyComdat(GV, &G);
151-
}
152-
153127
// Similarly, copy over function bodies now...
154128
//
155129
for (const Function &I : M) {
@@ -212,6 +186,32 @@ std::unique_ptr<Module> llvm::CloneModule(
212186
NewNMD->addOperand(MapMetadata(N, VMap));
213187
}
214188

189+
// Now that all of the things that global variable initializer can refer to
190+
// have been created, loop through and copy the global variable referrers
191+
// over... We also set the attributes on the global now.
192+
//
193+
for (const GlobalVariable &G : M.globals()) {
194+
GlobalVariable *GV = cast<GlobalVariable>(VMap[&G]);
195+
196+
SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
197+
G.getAllMetadata(MDs);
198+
for (auto MD : MDs)
199+
GV->addMetadata(MD.first, *MapMetadata(MD.second, VMap));
200+
201+
if (G.isDeclaration())
202+
continue;
203+
204+
if (!ShouldCloneDefinition(&G)) {
205+
// Skip after setting the correct linkage for an external reference.
206+
GV->setLinkage(GlobalValue::ExternalLinkage);
207+
continue;
208+
}
209+
if (G.hasInitializer())
210+
GV->setInitializer(MapValue(G.getInitializer(), VMap));
211+
212+
copyComdat(GV, &G);
213+
}
214+
215215
return New;
216216
}
217217

llvm/test/tools/llvm-reduce/reduce-functions-blockaddress-wrong-function.ll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=functions --test FileCheck --test-arg --check-prefixes=INTERESTING --test-arg %s --test-arg --input-file %s -o %t
22
; RUN: FileCheck --check-prefixes=RESULT --input-file=%t %s
33

4-
; FIXME: This testcase exhibits nonsensical behavior. The first
5-
; function has blockaddress references. When the second function is
6-
; deleted, it causes the blockreferences from the first to be replaced
7-
; with inttoptr.
8-
94
; INTERESTING: @blockaddr.table.other
105

11-
; RESULT: @blockaddr.table.other = private unnamed_addr constant [2 x ptr] [ptr inttoptr (i32 1 to ptr), ptr inttoptr (i32 1 to ptr)]
6+
; RESULT: @blockaddr.table.other = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@bar, %L1), ptr blockaddress(@bar, %L2)]
7+
128

139
@blockaddr.table.other = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@bar, %L1), ptr blockaddress(@bar, %L2)]
1410

0 commit comments

Comments
 (0)