[llvm] r327942 - [ShrinkWrap] Take into account landing pad

Quentin Colombet via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 19 19:44:40 PDT 2018


Author: qcolombet
Date: Mon Mar 19 19:44:40 2018
New Revision: 327942

URL: http://llvm.org/viewvc/llvm-project?rev=327942&view=rev
Log:
[ShrinkWrap] Take into account landing pad

When scanning the function for CSRs uses and defs, also check if
the basic block are landing pads.
Consider that landing pads needs the CSRs to be properly set.
That way we force the prologue/epilogue to always be pushed out
of the problematic "throw" region. The "throw" region is
problematic because the jumps are not properly modeled.

Fixes PR36513

Modified:
    llvm/trunk/lib/CodeGen/ShrinkWrap.cpp
    llvm/trunk/test/CodeGen/X86/x86-shrink-wrap-unwind.ll

Modified: llvm/trunk/lib/CodeGen/ShrinkWrap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ShrinkWrap.cpp?rev=327942&r1=327941&r2=327942&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ShrinkWrap.cpp (original)
+++ llvm/trunk/lib/CodeGen/ShrinkWrap.cpp Mon Mar 19 19:44:40 2018
@@ -447,6 +447,22 @@ bool ShrinkWrap::runOnMachineFunction(Ma
       return false;
     }
 
+    if (MBB.isEHPad()) {
+      // Push the prologue and epilogue outside of
+      // the region that may throw by making sure
+      // that all the landing pads are at least at the
+      // boundary of the save and restore points.
+      // The problem with exceptions is that the throw
+      // is not properly modeled and in particular, a
+      // basic block can jump out from the middle.
+      updateSaveRestorePoints(MBB, RS.get());
+      if (!ArePointsInteresting()) {
+        DEBUG(dbgs() << "EHPad prevents shrink-wrapping\n");
+        return false;
+      }
+      continue;
+    }
+
     for (const MachineInstr &MI : MBB) {
       if (!useOrDefCSROrFI(MI, RS.get()))
         continue;

Modified: llvm/trunk/test/CodeGen/X86/x86-shrink-wrap-unwind.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/x86-shrink-wrap-unwind.ll?rev=327942&r1=327941&r2=327942&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/x86-shrink-wrap-unwind.ll (original)
+++ llvm/trunk/test/CodeGen/X86/x86-shrink-wrap-unwind.ll Mon Mar 19 19:44:40 2018
@@ -222,3 +222,105 @@ __go_ptr_strings_equal.exit:
 declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) #5
 
 attributes #5 = { nounwind readonly ssp uwtable "split-stack" }
+
+; Check that correctly take into account the jumps to landing pad.
+; We used to consider function that may throw like regular
+; function calls.
+; Therefore, in this example, we were happily inserting the epilogue
+; right after the call to throw_exception. Because of that we would not
+; execute the epilogue when an execption occur and bad things will
+; happen.
+; PR36513
+;
+; CHECK-LABEL: with_nounwind:
+; Prologue
+; CHECK: push
+;
+; Jump to throw_exception:
+; CHECK-NEXT: testb $1, %dil
+; CHECK-NEXT: jne [[THROW_LABEL:LBB[0-9_]+]]
+; Else return exit
+; CHECK: popq
+; CHECK-NEXT: retq
+;
+; CHECK-NEXT: [[THROW_LABEL]]:
+; CHECK: callq	_throw_exception
+; Unreachable block...
+;
+; Epilogue must be after the landing pad.
+; CHECK-NOT: popq
+;
+; Look for the landing pad label.
+; CHECK: LBB{{[0-9_]+}}:
+; Epilogue on the landing pad
+; CHECK: popq
+; CHECK-NEXT: retq
+define void @with_nounwind(i1 %cond) nounwind personality i32 (...)* @my_personality {
+entry:
+  br i1 %cond, label %throw, label %return
+
+throw:
+  invoke void @throw_exception()
+          to label %unreachable unwind label %landing
+
+unreachable:
+  unreachable
+
+landing:
+  %pad = landingpad { i8*, i32 }
+          catch i8* null
+  ret void
+
+return:
+  ret void
+}
+
+; Check landing pad again.
+; This time checks that we can shrink-wrap when the epilogue does not
+; span accross several blocks.
+;
+; CHECK-LABEL: with_nounwind_same_succ:
+;
+; Jump to throw_exception:
+; CHECK: testb $1, %dil
+; CHECK-NEXT: je [[RET_LABEL:LBB[0-9_]+]]
+;
+; Prologue
+; CHECK: push
+; CHECK: callq	_throw_exception
+;
+; Fallthrough label
+; CHECK: [[FALLTHROUGH_LABEL:LBB[0-9_]+]]
+; CHECK: nop
+; CHECK: popq
+;
+; CHECK: [[RET_LABEL]]
+; CHECK: retq
+;
+; Look for the landing pad label.
+; CHECK: LBB{{[0-9_]+}}:
+; Landing pad jumps to fallthrough
+; CHECK: jmp [[FALLTHROUGH_LABEL]]
+define void @with_nounwind_same_succ(i1 %cond) nounwind personality i32 (...)* @my_personality2 {
+entry:
+  br i1 %cond, label %throw, label %return
+
+throw:
+  invoke void @throw_exception()
+          to label %fallthrough unwind label %landing
+landing:
+  %pad = landingpad { i8*, i32 }
+          catch i8* null
+  br label %fallthrough
+
+fallthrough:
+  tail call void asm "nop", ""()
+  br label %return
+
+return:
+  ret void
+}
+
+declare void @throw_exception()
+declare i32 @my_personality(...)
+declare i32 @my_personality2(...)




More information about the llvm-commits mailing list