From 780c4178615cb1ea219c8e26938c5fcc99d44ef1 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Fri, 6 Nov 2015 23:59:23 +0000 Subject: [PATCH] [InstCombine] Don't insert an instruction after a terminator We tried to insert a cast of a phi in a block whose terminator is an EHPad. This is invalid. Do not attempt the transform in these circumstances. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252370 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombinePHI.cpp | 6 +++ test/Transforms/InstCombine/token.ll | 40 ++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombinePHI.cpp b/lib/Transforms/InstCombine/InstCombinePHI.cpp index 1d3b837f124..a9f8f49d2f1 100644 --- a/lib/Transforms/InstCombine/InstCombinePHI.cpp +++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp @@ -469,6 +469,12 @@ Instruction *InstCombiner::FoldPHIArgZextsIntoPHI(PHINode &Phi) { /// only used by the PHI, PHI together their inputs, and do the operation once, /// to the result of the PHI. Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { + // We cannot create a new instruction after the PHI if the terminator is an + // EHPad because there is no valid insertion point. + if (TerminatorInst *TI = PN.getParent()->getTerminator()) + if (TI->isEHPad()) + return nullptr; + Instruction *FirstInst = cast(PN.getIncomingValue(0)); if (isa(FirstInst)) diff --git a/test/Transforms/InstCombine/token.ll b/test/Transforms/InstCombine/token.ll index bb35d156064..c8f1dc1bc31 100644 --- a/test/Transforms/InstCombine/token.ll +++ b/test/Transforms/InstCombine/token.ll @@ -4,7 +4,7 @@ target triple = "x86_64-pc-windows-msvc18.0.0" declare i32 @__CxxFrameHandler3(...) -define i8* @f() personality i32 (...)* @__CxxFrameHandler3 { +define void @test1() personality i32 (...)* @__CxxFrameHandler3 { bb: unreachable @@ -13,9 +13,45 @@ unreachable: cleanupret %cl unwind to caller } +; CHECK-LABEL: define void @test1( ; CHECK: unreachable: ; CHECK: %cl = cleanuppad [] ; CHECK: cleanupret %cl unwind to caller +define void @test2(i8 %A, i8 %B) personality i32 (...)* @__CxxFrameHandler3 { +bb: + %X = zext i8 %A to i32 + invoke void @g(i32 0) + to label %cont + unwind label %catch + +cont: + %Y = zext i8 %B to i32 + invoke void @g(i32 0) + to label %unreachable + unwind label %catch + +catch: + %phi = phi i32 [ %X, %bb ], [ %Y, %cont ] + %cl = catchpad [] + to label %doit + unwind label %endpad + +doit: + call void @g(i32 %phi) + unreachable + +unreachable: + unreachable + +endpad: + catchendpad unwind to caller +} + + +; CHECK-LABEL: define void @test2( +; CHECK: %X = zext i8 %A to i32 +; CHECK: %Y = zext i8 %B to i32 +; CHECK: %phi = phi i32 [ %X, %bb ], [ %Y, %cont ] -declare void @g(i8*) +declare void @g(i32) -- 2.34.1