From 4f051fe37438632d10480c346520a0de624dbebf Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 10 Dec 2020 13:06:23 -0500 Subject: [PATCH] [InstCombine] avoid crash sinking to unreachable block The test is reduced from the example in D82005. Similar to 94f6d365e, the test here would assert in the DomTree when we tried to convert a select to a phi with an unreachable block operand. We may want to add some kind of guard code in DomTree itself to avoid this sort of problem. --- .../Transforms/InstCombine/InstructionCombining.cpp | 4 +++- .../Transforms/InstCombine/phi-select-constant.ll | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index cab6f1e..bbc7632 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3640,7 +3640,9 @@ bool InstCombinerImpl::run() { else UserParent = UserInst->getParent(); - if (UserParent != BB) { + // Try sinking to another block. If that block is unreachable, then do + // not bother. SimplifyCFG should handle it. + if (UserParent != BB && DT.isReachableFromEntry(UserParent)) { // See if the user is one of our successors that has only one // predecessor, so that we don't have to split the critical edge. bool ShouldSink = UserParent->getUniquePredecessor() == BB; diff --git a/llvm/test/Transforms/InstCombine/phi-select-constant.ll b/llvm/test/Transforms/InstCombine/phi-select-constant.ll index c65be75..e3f35d2 100644 --- a/llvm/test/Transforms/InstCombine/phi-select-constant.ll +++ b/llvm/test/Transforms/InstCombine/phi-select-constant.ll @@ -137,3 +137,24 @@ deadbb: end: ret void } + +define i16 @sink_to_unreachable_crash(i1 %a) { +; CHECK-LABEL: @sink_to_unreachable_crash( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[S:%.*]] = select i1 [[A:%.*]], i16 0, i16 5 +; CHECK-NEXT: br label [[INF_LOOP:%.*]] +; CHECK: inf_loop: +; CHECK-NEXT: br label [[INF_LOOP]] +; CHECK: unreachable: +; CHECK-NEXT: ret i16 [[S]] +; +entry: + %s = select i1 %a, i16 0, i16 5 + br label %inf_loop + +inf_loop: + br label %inf_loop + +unreachable: ; No predecessors! + ret i16 %s +} -- 2.7.4