1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

[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

llvm-svn: 327942
This commit is contained in:
Quentin Colombet 2018-03-20 02:44:40 +00:00
parent b224768f51
commit d94de4cf58
2 changed files with 118 additions and 0 deletions

View File

@ -447,6 +447,22 @@ bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) {
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;

View File

@ -222,3 +222,105 @@ __go_ptr_strings_equal.exit: ; preds = %land.rhs.i.i, %if.e
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(...)