Index: lib/CodeGen/BranchFolding.cpp =================================================================== --- lib/CodeGen/BranchFolding.cpp +++ lib/CodeGen/BranchFolding.cpp @@ -1625,11 +1625,16 @@ // Okay, there is no really great place to put this block. If, however, // the block before this one would be a fall-through if this block were // removed, move this block to the end of the function. + // If the FallThrough block is an EH pad, we have the potential to get + // into an infinite loop where we are shuffling multiple EH blocks at the + // end of the function. To avoid that, we don't move the current block + // if FallThrough is an EH pad. MachineBasicBlock *PrevTBB = nullptr, *PrevFBB = nullptr; SmallVector PrevCond; if (FallThrough != MF.end() && !TII->analyzeBranch(PrevBB, PrevTBB, PrevFBB, PrevCond, true) && - PrevBB.isSuccessor(&*FallThrough)) { + PrevBB.isSuccessor(&*FallThrough) && + !FallThrough->isEHPad()) { MBB->moveAfter(&MF.back()); MadeChange = true; return MadeChange; Index: test/CodeGen/WinEH/wineh-noret-cleanup.ll =================================================================== --- test/CodeGen/WinEH/wineh-noret-cleanup.ll +++ test/CodeGen/WinEH/wineh-noret-cleanup.ll @@ -50,13 +50,13 @@ ; CXX-NEXT: .long 1 ; CXX-NEXT: .long .Ltmp1@IMGREL+1 ; CXX-NEXT: .long -1 -; CXX-NEXT: .long "?catch$2@?0?test@4HA"@IMGREL +; CXX-NEXT: .long "?catch$3@?0?test@4HA"@IMGREL ; CXX-NEXT: .long 2 ; CXX-NEXT: .long .Ltmp2@IMGREL+1 ; CXX-NEXT: .long 3 ; CXX-NEXT: .long .Ltmp3@IMGREL+1 ; CXX-NEXT: .long 2 -; CXX-NEXT: .long "?catch$4@?0?test@4HA"@IMGREL +; CXX-NEXT: .long "?catch$5@?0?test@4HA"@IMGREL ; CXX-NEXT: .long 4 ; SEH-LABEL: test: @@ -64,17 +64,17 @@ ; SEH-NEXT: .long .Ltmp0@IMGREL+1 ; SEH-NEXT: .long .Ltmp1@IMGREL+1 ; SEH-NEXT: .long dummy_filter@IMGREL -; SEH-NEXT: .long .LBB0_2@IMGREL +; SEH-NEXT: .long .LBB0_3@IMGREL ; SEH-NEXT: .long .Ltmp0@IMGREL+1 ; SEH-NEXT: .long .Ltmp1@IMGREL+1 ; SEH-NEXT: .long dummy_filter@IMGREL -; SEH-NEXT: .long .LBB0_4@IMGREL +; SEH-NEXT: .long .LBB0_5@IMGREL ; SEH-NEXT: .long .Ltmp2@IMGREL+1 ; SEH-NEXT: .long .Ltmp3@IMGREL+1 -; SEH-NEXT: .long "?dtor$5@?0?test@4HA"@IMGREL +; SEH-NEXT: .long "?dtor$2@?0?test@4HA"@IMGREL ; SEH-NEXT: .long 0 ; SEH-NEXT: .long .Ltmp2@IMGREL+1 ; SEH-NEXT: .long .Ltmp3@IMGREL+1 ; SEH-NEXT: .long dummy_filter@IMGREL -; SEH-NEXT: .long .LBB0_4@IMGREL +; SEH-NEXT: .long .LBB0_5@IMGREL ; SEH-NEXT: .Llsda_end0: Index: test/CodeGen/X86/branchfolding-catchpads.ll =================================================================== --- test/CodeGen/X86/branchfolding-catchpads.ll +++ test/CodeGen/X86/branchfolding-catchpads.ll @@ -93,3 +93,91 @@ ; ; CHECK-LABEL: .def test2; +declare void @g(i16*, i32, i16*, i16*, i16*) + +define void @test3() optsize personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { +entry: + switch i32 undef, label %if.end57 [ + i32 64, label %sw.bb + i32 128, label %sw.bb3 + i32 256, label %sw.bb7 + i32 512, label %sw.bb11 + i32 1024, label %sw.bb17 + i32 2048, label %sw.bb25 + i32 4096, label %sw.bb33 + i32 16, label %sw.epilog + i32 8, label %sw.bb42 + i32 4, label %sw.bb43 + i32 32, label %sw.bb44 + ] + +sw.bb: + unreachable + +sw.bb3: + br label %sw.epilog + +sw.bb7: + br label %if.then56 + +sw.bb11: + unreachable + +sw.bb17: + unreachable + +sw.bb25: + unreachable + +sw.bb33: + br i1 undef, label %lor.lhs.false3.i157, label %while.cond.i163.preheader + +while.cond.i163.preheader: + unreachable + +lor.lhs.false3.i157: + br label %if.end57 + +sw.bb42: + br label %sw.epilog + +sw.bb43: + unreachable + +sw.bb44: + %temp0 = load void ()*, void ()** undef + invoke void %temp0() + to label %if.end57 unwind label %catch.dispatch + +sw.epilog: + %temp1 = load i8*, i8** undef + br label %if.end57 + +catch.dispatch: + %cs = catchswitch within none [label %catch1, label %catch2, label %catch3] unwind to caller + +catch1: + %c1 = catchpad within %cs [i8* null, i32 8, i8* null] + unreachable + +catch2: + %c2 = catchpad within %cs [i8* null, i32 32, i8* null] + unreachable + +catch3: + %c3 = catchpad within %cs [i8* null, i32 64, i8* null] + unreachable + +if.then56: + tail call void @g(i16* undef, i32 82, i16* undef, i16* undef, i16* null) + br label %if.end57 + +if.end57: + ret void +} + +; This test exercises a complex case that produced an infinite loop during +; compilation when the two cases above did not. +; +; CHECK-LABEL: .def test3; +