diff --git a/llvm/lib/Transforms/Scalar/GVNHoist.cpp b/llvm/lib/Transforms/Scalar/GVNHoist.cpp --- a/llvm/lib/Transforms/Scalar/GVNHoist.cpp +++ b/llvm/lib/Transforms/Scalar/GVNHoist.cpp @@ -883,12 +883,15 @@ // accumulate hoistable candidates in HPL. for (std::pair> &A : CHIBBs) { BasicBlock *BB = A.first; + auto TI = BB->getTerminator(); + // Don't hoist into CallBr terminated blocks. + if (isa(TI)) + continue; SmallVectorImpl &CHIs = A.second; // Vector of PHIs contains PHIs for different instructions. // Sort the args according to their VNs, such that identical // instructions are together. llvm::stable_sort(CHIs, cmpVN); - auto TI = BB->getTerminator(); auto B = CHIs.begin(); // [PreIt, PHIIt) form a range of CHIs which have identical VNs. auto PHIIt = llvm::find_if(CHIs, [B](CHIArg &A) { return A != *B; }); diff --git a/llvm/test/Transforms/GVNHoist/hoist-call.ll b/llvm/test/Transforms/GVNHoist/hoist-call.ll --- a/llvm/test/Transforms/GVNHoist/hoist-call.ll +++ b/llvm/test/Transforms/GVNHoist/hoist-call.ll @@ -26,3 +26,24 @@ } declare float @llvm.fabs.f32(float) + +; Check that extractvalues are not hoisted into entry. +define void @foo() { +; CHECK-LABEL: define void @foo( +; CHECK-NEXT: entry +; CHECK-NEXT: %0 = callbr +; CHECK-NEXT: to label +; CHECK-EMPTY: +; CHECK-NEXT: asm.fallthrough: +entry: + %0 = callbr { i32, i32 } asm sideeffect "somestuff", "=r,=r,!i"() + to label %asm.fallthrough [label %err.split] + +asm.fallthrough: ; preds = %entry + %asmresult = extractvalue { i32, i32 } %0, 0 + ret void + +err.split: ; preds = %entry + %asmresult2 = extractvalue { i32, i32 } %0, 0 + ret void +}