summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold Schwaighofer <aschwaighofer@apple.com>2015-10-05 17:26:36 +0000
committerArnold Schwaighofer <aschwaighofer@apple.com>2015-10-05 17:26:36 +0000
commit0591c5d719eccc127dae01ea4f586dc5c6e89478 (patch)
tree84437b030f35509c301067106f01bcb39e8532f8
parentd1cf421bd560cac836c064a03032f62bdf49052e (diff)
downloadbcm5719-llvm-0591c5d719eccc127dae01ea4f586dc5c6e89478.tar.gz
bcm5719-llvm-0591c5d719eccc127dae01ea4f586dc5c6e89478.zip
MergeFunctions: Clear GlobalNumbers ValueMap
Otherwise, the map will observe changes as long as MergeFunctions is alive. This is bad because follow-up passes could replace-all-uses-with on the key of an entry in the map. The value handle callback of ValueMap however asserts that the key type matches. rdar://22971893 llvm-svn: 249327
-rw-r--r--llvm/lib/Transforms/IPO/MergeFunctions.cpp4
-rw-r--r--llvm/test/Transforms/MergeFunc/crash2.ll54
2 files changed, 58 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
index 2b0bcdff72f..d7bfed105a9 100644
--- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
@@ -164,6 +164,9 @@ class GlobalNumberState {
NextNumber++;
return MapIter->second;
}
+ void clear() {
+ GlobalNumbers.clear();
+ }
};
/// FunctionComparator - Compares two functions to determine whether or not
@@ -1546,6 +1549,7 @@ bool MergeFunctions::runOnModule(Module &M) {
} while (!Deferred.empty());
FnTree.clear();
+ GlobalNumbers.clear();
return Changed;
}
diff --git a/llvm/test/Transforms/MergeFunc/crash2.ll b/llvm/test/Transforms/MergeFunc/crash2.ll
new file mode 100644
index 00000000000..5d3e7069dda
--- /dev/null
+++ b/llvm/test/Transforms/MergeFunc/crash2.ll
@@ -0,0 +1,54 @@
+; RUN: opt %s -mergefunc -globalopt -S -o - | FileCheck %s
+
+; Make sure we don't crash on this example. This test is supposed to test that
+; MergeFunctions clears its GlobalNumbers value map. If this map still contains
+; entries when running globalopt and the MergeFunctions instance is still alive
+; the optimization of @G would cause an assert because globalopt would do an
+; RAUW on @G which still exists as an entry in the GlobalNumbers ValueMap which
+; causes an assert in the ValueHandle call back because we are RAUWing with a
+; different type (AllocaInst) than its key type (GlobalValue).
+
+@G = internal global i8** null
+@G2 = internal global i8** null
+
+define i32 @main(i32 %argc, i8** %argv) {
+; CHECK: alloca
+ store i8** %argv, i8*** @G
+ ret i32 0
+}
+
+define internal i8** @dead1(i64 %p) {
+ call void @right(i64 %p)
+ call void @right(i64 %p)
+ call void @right(i64 %p)
+ call void @right(i64 %p)
+ %tmp = load i8**, i8*** @G
+ ret i8** %tmp
+}
+
+define internal i8** @dead2(i64 %p) {
+ call void @right(i64 %p)
+ call void @right(i64 %p)
+ call void @right(i64 %p)
+ call void @right(i64 %p)
+ %tmp = load i8**, i8*** @G2
+ ret i8** %tmp
+}
+
+define void @left(i64 %p) {
+entry-block:
+ call void @right(i64 %p)
+ call void @right(i64 %p)
+ call void @right(i64 %p)
+ call void @right(i64 %p)
+ ret void
+}
+
+define void @right(i64 %p) {
+entry-block:
+ call void @left(i64 %p)
+ call void @left(i64 %p)
+ call void @left(i64 %p)
+ call void @left(i64 %p)
+ ret void
+}
OpenPOWER on IntegriCloud