diff options
-rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/Reassociate/erase_inst_made_change.ll | 29 |
2 files changed, 31 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index 6da551bd7ef..cdba0062953 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -1894,6 +1894,8 @@ void ReassociatePass::EraseInst(Instruction *I) { Op = Op->user_back(); RedoInsts.insert(Op); } + + MadeChange = true; } // Canonicalize expressions of the following form: diff --git a/llvm/test/Transforms/Reassociate/erase_inst_made_change.ll b/llvm/test/Transforms/Reassociate/erase_inst_made_change.ll new file mode 100644 index 00000000000..febb9447e2b --- /dev/null +++ b/llvm/test/Transforms/Reassociate/erase_inst_made_change.ll @@ -0,0 +1,29 @@ +; RUN: opt < %s -inline -reassociate -S | FileCheck %s + +; This test case exposed a bug in reassociate where EraseInst's +; removal of a dead call wasn't recognized as changing the IR. +; So when runOnFunction propagated the "made changes" upwards +; to the CallGraphSCCPass it signalled that no changes had been +; made, so CallGraphSCCPass assumed that the old CallGraph, +; as known by that pass manager, still was up-to-date. +; +; This was detected as an assert when trying to remove the +; no longer used function 'bar' (due to incorrect reference +; count in the CallGraph). + +define void @foo() { +; CHECK-LABEL: @foo( +; CHECK-NEXT: entry: +; CHECK-NEXT: ret void +entry: + call void @bar() + ret void +} + +define internal void @bar() noinline nounwind readnone { +; CHECK-NOT: bar +entry: + ret void +} + + |