diff options
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/GVNHoist/hoist-very-busy.ll | 34 |
2 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 70fab29087f..1761dac269d 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<ReturnInst>(I)) return false; + if (isa<UnreachableInst>(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 00000000000..b2751fb6feb --- /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 } |