diff options
author | Arnold Schwaighofer <aschwaighofer@apple.com> | 2015-10-05 17:26:36 +0000 |
---|---|---|
committer | Arnold Schwaighofer <aschwaighofer@apple.com> | 2015-10-05 17:26:36 +0000 |
commit | 0591c5d719eccc127dae01ea4f586dc5c6e89478 (patch) | |
tree | 84437b030f35509c301067106f01bcb39e8532f8 | |
parent | d1cf421bd560cac836c064a03032f62bdf49052e (diff) | |
download | bcm5719-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.cpp | 4 | ||||
-rw-r--r-- | llvm/test/Transforms/MergeFunc/crash2.ll | 54 |
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 +} |