summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2015-07-14 21:03:18 +0000
committerTim Northover <tnorthover@apple.com>2015-07-14 21:03:18 +0000
commitd5fdef016d0d957d8712b07e9e5828b9dae5c944 (patch)
treec85eb355ff9cadeb617ed19c532d373dcd347af5
parentd30e2eefc3cf8dfd2210aefd62f13a6e7c011b43 (diff)
downloadbcm5719-llvm-d5fdef016d0d957d8712b07e9e5828b9dae5c944.tar.gz
bcm5719-llvm-d5fdef016d0d957d8712b07e9e5828b9dae5c944.zip
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. llvm-svn: 242199
-rw-r--r--llvm/lib/Transforms/Scalar/GVN.cpp5
-rw-r--r--llvm/test/Transforms/GVN/pre-new-inst.ll29
2 files changed, 33 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 2c47a8ab783..b1a0db356a1 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -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 {
diff --git a/llvm/test/Transforms/GVN/pre-new-inst.ll b/llvm/test/Transforms/GVN/pre-new-inst.ll
new file mode 100644
index 00000000000..238b8a687cc
--- /dev/null
+++ b/llvm/test/Transforms/GVN/pre-new-inst.ll
@@ -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()
OpenPOWER on IntegriCloud