GVN: tolerate an instruction being replaced without existing in the leaderboard

Sometimes an incidentally created instruction can duplicate a Value used
elsewhere. It then often doesn't end up in the leader table. If it's later
removed, we attempt to remove it from the leader table and segfault.

Instead we should just ignore the removal request, which won't cause any
problems. The reverse situation, where the original instruction is replaced by
the new one (which you might think could leave the leader table empty) cannot
occur, because the incidental instruction will never be found in the first
place.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242199 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tim Northover 2015-07-14 21:03:18 +00:00
parent e1bb535422
commit 0e34491fef
2 changed files with 33 additions and 1 deletions

View File

@ -656,11 +656,14 @@ namespace {
LeaderTableEntry* Prev = nullptr;
LeaderTableEntry* Curr = &LeaderTable[N];
while (Curr->Val != I || Curr->BB != BB) {
while (Curr && (Curr->Val != I || Curr->BB != BB)) {
Prev = Curr;
Curr = Curr->Next;
}
if (!Curr)
return;
if (Prev) {
Prev->Next = Curr->Next;
} else {

View File

@ -0,0 +1,29 @@
; RUN: opt -basicaa -gvn -S %s | FileCheck %s
%MyStruct = type { i32, i32 }
define i8 @foo(i64 %in, i8* %arr) {
%addr = alloca %MyStruct
%dead = trunc i64 %in to i32
br i1 undef, label %next, label %tmp
tmp:
call void @bar()
br label %next
next:
%addr64 = bitcast %MyStruct* %addr to i64*
store i64 %in, i64* %addr64
br label %final
final:
%addr32 = getelementptr %MyStruct, %MyStruct* %addr, i32 0, i32 0
%idx32 = load i32, i32* %addr32
; CHECK: %resptr = getelementptr i8, i8* %arr, i32 %dead
%resptr = getelementptr i8, i8* %arr, i32 %idx32
%res = load i8, i8* %resptr
ret i8 %res
}
declare void @bar()