From 01cf7ec623a32d1b028e7bf761b0b9e74a195e40 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Mon, 5 Oct 2015 17:26:36 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249327 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/MergeFunctions.cpp | 4 ++ test/Transforms/MergeFunc/crash2.ll | 54 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 test/Transforms/MergeFunc/crash2.ll diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp index 2b0bcdff72f..d7bfed105a9 100644 --- a/lib/Transforms/IPO/MergeFunctions.cpp +++ b/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/test/Transforms/MergeFunc/crash2.ll b/test/Transforms/MergeFunc/crash2.ll new file mode 100644 index 00000000000..5d3e7069dda --- /dev/null +++ b/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 +} -- 2.34.1