diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2016-04-01 17:28:17 +0000 | 
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2016-04-01 17:28:17 +0000 | 
| commit | fe3f9d1721002dcd7b7b6bd0a8223ed31131e2d5 (patch) | |
| tree | 96f2ff328edef427ae0d6e34e8e5e4e97b08f9cb | |
| parent | 6f1f85f0e1bc88b1151080edddbe4794a0b81b32 (diff) | |
| download | bcm5719-llvm-fe3f9d1721002dcd7b7b6bd0a8223ed31131e2d5.tar.gz bcm5719-llvm-fe3f9d1721002dcd7b7b6bd0a8223ed31131e2d5.zip  | |
[InstCombine] Don't sink an instr after a catchswitch
A catchswitch is a terminator, instructions cannot be inserted after it.
llvm-svn: 265158
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 6 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/sink-into-catchswitch.ll | 45 | 
2 files changed, 50 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 8f7fd2e1bb6..3eebf5b9487 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2724,12 +2724,15 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {          &DestBlock->getParent()->getEntryBlock())      return false; +  // Do not sink into catchswitch blocks. +  if (isa<CatchSwitchInst>(DestBlock->getTerminator())) +    return false; +    // Do not sink convergent call instructions.    if (auto *CI = dyn_cast<CallInst>(I)) {      if (CI->isConvergent())        return false;    } -    // We can only sink load instructions if there is nothing between the load and    // the end of block that could change the value.    if (I->mayReadFromMemory()) { @@ -2823,6 +2826,7 @@ bool InstCombiner::run() {          if (UserIsSuccessor && UserParent->getSinglePredecessor()) {            // Okay, the CFG is simple enough, try to sink this instruction.            if (TryToSinkInstruction(I, UserParent)) { +            DEBUG(dbgs() << "IC: Sink: " << *I << '\n');              MadeIRChange = true;              // We'll add uses of the sunk instruction below, but since sinking              // can expose opportunities for it's *operands* add them to the diff --git a/llvm/test/Transforms/InstCombine/sink-into-catchswitch.ll b/llvm/test/Transforms/InstCombine/sink-into-catchswitch.ll new file mode 100644 index 00000000000..04a62250fc5 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/sink-into-catchswitch.ll @@ -0,0 +1,45 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc18.0.0" + +%struct.B = type { i64, i64 } + +define void @test1(%struct.B* %p) personality i32 (...)* @__CxxFrameHandler3 { +invoke.cont: +  %0 = bitcast %struct.B* %p to <2 x i64>* +  %1 = load <2 x i64>, <2 x i64>* %0, align 8 +  %2 = extractelement <2 x i64> %1, i32 0 +  invoke void @throw() +          to label %unreachable unwind label %catch.dispatch + +catch.dispatch:                                   ; preds = %invoke.cont +  %cs = catchswitch within none [label %invoke.cont1] unwind label %ehcleanup + +invoke.cont1:                                     ; preds = %catch.dispatch +  %catch = catchpad within %cs [i8* null, i32 64, i8* null] +  invoke void @throw() [ "funclet"(token %catch) ] +          to label %unreachable unwind label %ehcleanup + +ehcleanup:                                        ; preds = %invoke.cont1, %catch.dispatch +  %phi = phi i64 [ %2, %catch.dispatch ], [ 9, %invoke.cont1 ] +  %cleanup = cleanuppad within none [] +  call void @release(i64 %phi) [ "funclet"(token %cleanup) ] +  cleanupret from %cleanup unwind to caller + +unreachable:                                      ; preds = %invoke.cont1, %invoke.cont +  unreachable +} + +; CHECK-LABEL: define void @test1( +; CHECK: %[[bc:.*]] = bitcast %struct.B* %p to <2 x i64>* +; CHECK: %[[ld:.*]] = load <2 x i64>, <2 x i64>* %[[bc]], align 8 +; CHECK: %[[ee:.*]] = extractelement <2 x i64> %[[ld]], i32 0 + +; CHECK: %[[phi:.*]] = phi i64 [ %[[ee]], {{.*}} ], [ 9, {{.*}} ] +; CHECK: call void @release(i64 %[[phi]]) + +declare i32 @__CxxFrameHandler3(...) + +declare void @throw() + +declare void @release(i64)  | 

