Skip to content

Commit

Permalink
[ShrinkWrapping] Handle restores on no-return paths
Browse files Browse the repository at this point in the history
Shrink-wrapping uses post-dominators to find a restore point that
post-dominates all the uses of CSR / stack.

The way dominator trees are modeled in LLVM today is that unreachable
blocks are not present in a generic dominator tree, so, an unreachable node is
dominated by anything: include/llvm/Support/GenericDomTree.h:467.

Since for post-dominators, a no-return block is considered
"unreachable", calling findNearestCommonDominator on an unreachable node
A and a non-unreachable node B, will return B, which can be false. If we
find such node, we bail out since there is no good restore point
available.

rdar://problem/30186931

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303130 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Francis Visoiu Mistrih committed May 15, 2017
1 parent 4e4a48b commit cc8486f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
10 changes: 8 additions & 2 deletions lib/CodeGen/ShrinkWrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,14 @@ void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB,

if (!Restore)
Restore = &MBB;
else
else if (MPDT->getNode(&MBB)) // If the block is not in the post dom tree, it
// means the block never returns. If that's the
// case, we don't want to call
// `findNearestCommonDominator`, which will
// return `Restore`.
Restore = MPDT->findNearestCommonDominator(Restore, &MBB);
else
Restore = nullptr; // Abort, we can't find a restore point in this case.

// Make sure we would be able to insert the restore code before the
// terminator.
Expand All @@ -293,7 +299,7 @@ void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB,
continue;
// One of the terminator needs to happen before the restore point.
if (MBB.succ_empty()) {
Restore = nullptr;
Restore = nullptr; // Abort, we can't find a restore point in this case.
break;
}
// Look for a restore point that post-dominates all the successors.
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/Thumb2/v8_IT_5.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
; CHECK-NEXT: b
; CHECK: [[JUMPTARGET]]:{{.*}}%if.else173
; CHECK-NEXT: mov.w
; CHECK-NEXT: bx lr
; CHECK-NEXT: pop
; CHECK-NEXT: %if.else145
; CHECK-NEXT: mov.w

Expand Down
53 changes: 51 additions & 2 deletions test/CodeGen/X86/x86-shrink-wrapping.ll
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,6 @@ if.end: ; preds = %if.else, %for.end
ret i32 %sum.1
}

declare void @somethingElse(...)

; Check with a more complex case that we do not have restore within the loop and
; save outside.
; CHECK-LABEL: loopInfoRestoreOutsideLoop:
Expand Down Expand Up @@ -982,3 +980,54 @@ for.inc:
}

attributes #4 = { "no-frame-pointer-elim"="true" }

@x = external global i32, align 4
@y = external global i32, align 4

; The post-dominator tree does not include the branch containing the infinite
; loop, which can occur into a misplacement of the restore block, if we're
; looking for the nearest common post-dominator of an "unreachable" block.

; CHECK-LABEL: infiniteLoopNoSuccessor:
; CHECK: ## BB#0:
; Make sure the prologue happens in the entry block.
; CHECK-NEXT: pushq %rbp
; ...
; Make sure we don't shrink-wrap.
; CHECK: ## BB#1
; CHECK-NOT: pushq %rbp
; ...
; Make sure the epilogue happens in the exit block.
; CHECK: ## BB#5
; CHECK: popq %rbp
; CHECK-NEXT: retq
define void @infiniteLoopNoSuccessor() #5 {
%1 = load i32, i32* @x, align 4
%2 = icmp ne i32 %1, 0
br i1 %2, label %3, label %4

; <label>:3:
store i32 0, i32* @x, align 4
br label %4

; <label>:4:
call void (...) @somethingElse()
%5 = load i32, i32* @y, align 4
%6 = icmp ne i32 %5, 0
br i1 %6, label %10, label %7

; <label>:7:
%8 = call i32 (...) @something()
br label %9

; <label>:9:
call void (...) @somethingElse()
br label %9

; <label>:10:
ret void
}

declare void @somethingElse(...)

attributes #5 = { nounwind "no-frame-pointer-elim-non-leaf" }

0 comments on commit cc8486f

Please sign in to comment.