1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[llvm-reduce] extractGVsFromModule(): don't crash when deleting instr twice

As it can be seen in newly-added (previously-crashing) test-case,
there can be a situation where multiple GV's are used in instr,
and we would schedule the same instruction to be deleted several times,
crashing when trying to delete it the second time.

We could either store WeakVH (done here), or use something set-like.
I think using WeakVH is prevalent in these cases elsewhere.
This commit is contained in:
Roman Lebedev 2020-07-05 01:01:46 +03:00
parent f794b74374
commit a24529a504
3 changed files with 43 additions and 3 deletions

View File

@ -0,0 +1,13 @@
import sys
FunctionCallPresent = False
input = open(sys.argv[1], "r")
for line in input:
if "call void @use" in line:
FunctionCallPresent = True
if FunctionCallPresent:
sys.exit(0) # Interesting!
sys.exit(1)

View File

@ -0,0 +1,24 @@
; Test that llvm-reduce can remove uninteresting function arguments from function definitions as well as their calls.
;
; RUN: rm -rf %t
; RUN: llvm-reduce --test %python --test-arg %p/Inputs/remove-multiple-use-of-global-vars-in-same-instruction.py %s -o %t
; RUN: cat %t | FileCheck -implicit-check-not=uninteresting %s
; CHECK: @uninteresting1 = global
; CHECK: @uninteresting2 = global
; CHECK: @uninteresting3 = global
@uninteresting1 = global i32 0, align 4
@uninteresting2 = global i32 0, align 4
@uninteresting3 = global i32 0, align 4
declare void @use(i32*, i32*, i32*)
; CHECK-LABEL: @interesting()
define void @interesting() {
entry:
; CHECK: call void @use(i32* @uninteresting1, i32* @uninteresting2, i32* @uninteresting3)
call void @use(i32* @uninteresting1, i32* @uninteresting2, i32* @uninteresting3)
call void @use(i32* @uninteresting1, i32* @uninteresting2, i32* @uninteresting3)
call void @use(i32* @uninteresting1, i32* @uninteresting2, i32* @uninteresting3)
ret void
}

View File

@ -33,7 +33,7 @@ static void extractGVsFromModule(std::vector<Chunk> ChunksToKeep,
// Delete out-of-chunk GVs and their uses
std::vector<GlobalVariable *> ToRemove;
std::vector<Instruction *> InstToRemove;
std::vector<WeakVH> InstToRemove;
for (auto &GV : Program->globals())
if (GV.hasInitializer() && !GVsToKeep.count(&GV)) {
for (auto U : GV.users())
@ -44,8 +44,11 @@ static void extractGVsFromModule(std::vector<Chunk> ChunksToKeep,
ToRemove.push_back(&GV);
}
// Delete Instruction uses of unwanted GVs
for (auto *Inst : InstToRemove) {
// Delete (unique) Instruction uses of unwanted GVs
for (Value *V : InstToRemove) {
if (!V)
continue;
auto *Inst = cast<Instruction>(V);
Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
Inst->eraseFromParent();
}