From 4a4d245b194d56b74bbb9012d25b44aaba753e36 Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Wed, 8 Mar 2017 01:54:50 +0000 Subject: [PATCH] Handle UnreachableInst in isGuaranteedToTransferExecutionToSuccessor A block with an UnreachableInst does not transfer execution to a successor. The problem was exposed by GVN-hoist. This patch fixes bug 32153. Patch by Aditya Kumar. Differential Revision: https://reviews.llvm.org/D30667 llvm-svn: 297254 --- llvm/lib/Analysis/ValueTracking.cpp | 2 ++ .../Transforms/GVNHoist/hoist-very-busy.ll | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 llvm/test/Transforms/GVNHoist/hoist-very-busy.ll diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 70fab29087f9..1761dac269d0 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3781,6 +3781,8 @@ bool llvm::isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) { return false; if (isa(I)) return false; + if (isa(I)) + return false; // Calls can throw, or contain an infinite loop, or kill the process. if (auto CS = ImmutableCallSite(I)) { diff --git a/llvm/test/Transforms/GVNHoist/hoist-very-busy.ll b/llvm/test/Transforms/GVNHoist/hoist-very-busy.ll new file mode 100644 index 000000000000..b2751fb6feb6 --- /dev/null +++ b/llvm/test/Transforms/GVNHoist/hoist-very-busy.ll @@ -0,0 +1,34 @@ +; RUN: opt -S -gvn-hoist < %s | FileCheck %s + +%struct.__jmp_buf_tag = type { [8 x i64], i32 } + +; Check that hoisting only happens when the expression is very busy. +; CHECK: store +; CHECK: store + +@test_exit_buf = global %struct.__jmp_buf_tag zeroinitializer +@G = global i32 0 + +define void @test_command(i32 %c1) { +entry: + switch i32 %c1, label %exit [ + i32 0, label %sw0 + i32 1, label %sw1 + ] + +sw0: + store i32 1, i32* @G + br label %exit + +sw1: + store i32 1, i32* @G + br label %exit + +exit: + call void @longjmp(%struct.__jmp_buf_tag* @test_exit_buf, i32 1) #0 + unreachable +} + +declare void @longjmp(%struct.__jmp_buf_tag*, i32) #0 + +attributes #0 = { noreturn nounwind }