[llvm] r289486 - Avoid infinite loops in branch folding

Andrew Kaylor via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 12 15:05:38 PST 2016


Author: akaylor
Date: Mon Dec 12 17:05:38 2016
New Revision: 289486

URL: http://llvm.org/viewvc/llvm-project?rev=289486&view=rev
Log:
Avoid infinite loops in branch folding

Differential Revision: https://reviews.llvm.org/D27582


Modified:
    llvm/trunk/lib/CodeGen/BranchFolding.cpp
    llvm/trunk/test/CodeGen/WinEH/wineh-noret-cleanup.ll
    llvm/trunk/test/CodeGen/X86/branchfolding-catchpads.ll

Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=289486&r1=289485&r2=289486&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original)
+++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Mon Dec 12 17:05:38 2016
@@ -1624,10 +1624,22 @@ ReoptimizeBlock:
 
       // 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.
+      // removed, move this block to the end of the function. There is no real
+      // advantage in "falling through" to an EH block, so we don't want to
+      // perform this transformation for that case.
+      //
+      // Also, Windows EH introduced the possibility of an arbitrary number of
+      // successors to a given block.  The analyzeBranch call does not consider
+      // exception handling and so we can get in a state where a block
+      // containing a call is followed by multiple EH blocks that would be
+      // rotated infinitely at the end of the function if the transformation
+      // below were performed for EH "FallThrough" blocks.  Therefore, even if
+      // that appears not to be happening anymore, we should assume that it is
+      // possible and not remove the "!FallThrough()->isEHPad" condition below.
       MachineBasicBlock *PrevTBB = nullptr, *PrevFBB = nullptr;
       SmallVector<MachineOperand, 4> PrevCond;
       if (FallThrough != MF.end() &&
+          !FallThrough->isEHPad() &&
           !TII->analyzeBranch(PrevBB, PrevTBB, PrevFBB, PrevCond, true) &&
           PrevBB.isSuccessor(&*FallThrough)) {
         MBB->moveAfter(&MF.back());

Modified: llvm/trunk/test/CodeGen/WinEH/wineh-noret-cleanup.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/wineh-noret-cleanup.ll?rev=289486&r1=289485&r2=289486&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/wineh-noret-cleanup.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/wineh-noret-cleanup.ll Mon Dec 12 17:05:38 2016
@@ -50,13 +50,13 @@ catch.body.2:
 ; CXX-NEXT:   .long   1
 ; CXX-NEXT:   .long   .Ltmp1 at IMGREL+1
 ; CXX-NEXT:   .long   -1
-; CXX-NEXT:   .long   "?catch$2@?0?test at 4HA"@IMGREL
+; CXX-NEXT:   .long   "?catch$3@?0?test at 4HA"@IMGREL
 ; CXX-NEXT:   .long   2
 ; CXX-NEXT:   .long   .Ltmp2 at IMGREL+1
 ; CXX-NEXT:   .long   3
 ; CXX-NEXT:   .long   .Ltmp3 at IMGREL+1
 ; CXX-NEXT:   .long   2
-; CXX-NEXT:   .long   "?catch$4@?0?test at 4HA"@IMGREL
+; CXX-NEXT:   .long   "?catch$5@?0?test at 4HA"@IMGREL
 ; CXX-NEXT:   .long   4
 
 ; SEH-LABEL: test:
@@ -64,17 +64,17 @@ catch.body.2:
 ; SEH-NEXT:    .long   .Ltmp0 at IMGREL+1
 ; SEH-NEXT:    .long   .Ltmp1 at IMGREL+1
 ; SEH-NEXT:    .long   dummy_filter at IMGREL
-; SEH-NEXT:    .long   .LBB0_2 at IMGREL
+; SEH-NEXT:    .long   .LBB0_3 at IMGREL
 ; SEH-NEXT:    .long   .Ltmp0 at IMGREL+1
 ; SEH-NEXT:    .long   .Ltmp1 at IMGREL+1
 ; SEH-NEXT:    .long   dummy_filter at IMGREL
-; SEH-NEXT:    .long   .LBB0_4 at IMGREL
+; SEH-NEXT:    .long   .LBB0_5 at IMGREL
 ; SEH-NEXT:    .long   .Ltmp2 at IMGREL+1
 ; SEH-NEXT:    .long   .Ltmp3 at IMGREL+1
-; SEH-NEXT:    .long   "?dtor$5@?0?test at 4HA"@IMGREL
+; SEH-NEXT:    .long   "?dtor$2@?0?test at 4HA"@IMGREL
 ; SEH-NEXT:    .long   0
 ; SEH-NEXT:    .long   .Ltmp2 at IMGREL+1
 ; SEH-NEXT:    .long   .Ltmp3 at IMGREL+1
 ; SEH-NEXT:    .long   dummy_filter at IMGREL
-; SEH-NEXT:    .long   .LBB0_4 at IMGREL
+; SEH-NEXT:    .long   .LBB0_5 at IMGREL
 ; SEH-NEXT:  .Llsda_end0:

Modified: llvm/trunk/test/CodeGen/X86/branchfolding-catchpads.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/branchfolding-catchpads.ll?rev=289486&r1=289485&r2=289486&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/branchfolding-catchpads.ll (original)
+++ llvm/trunk/test/CodeGen/X86/branchfolding-catchpads.ll Mon Dec 12 17:05:38 2016
@@ -93,3 +93,67 @@ unreachable:
 ;
 ; CHECK-LABEL: .def     test2;
 
+declare void @g()
+
+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.epilog
+    i32 256, label %if.then56
+    i32 1024, label %sw.bb
+    i32 4096, label %sw.bb33
+    i32 16, label %sw.epilog
+    i32 8, label %sw.epilog
+    i32 32, label %sw.bb44
+  ]
+
+sw.bb:
+  unreachable
+
+sw.bb33:
+  br i1 undef, label %if.end57, label %while.cond.i163.preheader
+
+while.cond.i163.preheader:
+  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:
+  call void @g()
+  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. The multiple targets from the
+; entry switch are not actually fundamental to the failure, but they are
+; necessary to suppress various control flow optimizations that would prevent
+; the conditions that lead to the failure.
+;
+; CHECK-LABEL: .def     test3;
+




More information about the llvm-commits mailing list