Index: llvm/trunk/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/trunk/lib/Analysis/ValueTracking.cpp +++ llvm/trunk/lib/Analysis/ValueTracking.cpp @@ -3781,6 +3781,8 @@ 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)) { Index: llvm/trunk/test/Transforms/GVNHoist/hoist-very-busy.ll =================================================================== --- llvm/trunk/test/Transforms/GVNHoist/hoist-very-busy.ll +++ llvm/trunk/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 }