[PATCH] D32715: shrink-wrap: fix shrink-wrapping for no-return paths
Francis Visoiu Mistrih via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon May 1 12:24:29 PDT 2017
thegameg created this revision.
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. I am actually guessing this from some comments: include/llvm/Support/GenericDomTree.h:423 <https://github.com/llvm-mirror/llvm/blob/74d2cb54e4d2d008fb0428510924ba7545a1c912/include/llvm/Support/GenericDomTree.h#L423>,
So, an unreachable node is dominated by anything: include/llvm/Support/GenericDomTree.h:467 <https://github.com/llvm-mirror/llvm/blob/74d2cb54e4d2d008fb0428510924ba7545a1c912/include/llvm/Support/GenericDomTree.h#L467>.
There seems to be an explanation that an unreachable block may or may not appear in the dominator tree: include/llvm/IR/Dominators.h:103 <https://github.com/llvm-mirror/llvm/blob/74d2cb54e4d2d008fb0428510924ba7545a1c912/include/llvm/IR/Dominators.h#L103>:
/// A forward unreachable block may appear in the dominator tree, or it may
/// not. If it does, dominance queries will return results as if all reachable
/// blocks dominate it. When asking for a Node corresponding to a potentially
/// unreachable block, calling code must handle the case where the block was
/// unreachable and the result of getNode() is nullptr.
///
/// Generally, a block known to be unreachable when the dominator tree is
/// constructed will not be in the tree. One which becomes unreachable after
/// the dominator tree is initially constructed may still exist in the tree,
/// even if the tree is properly updated. Calling code should not rely on the
/// preceding statements; this is stated only to assist human understanding.
From that, I assume the MachineDominators might work in the same way.
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.
I suggest that if we find such a node, we bail out since there is no good restore point.
https://reviews.llvm.org/D32715
Files:
lib/CodeGen/ShrinkWrap.cpp
test/CodeGen/X86/x86-shrink-wrapping.ll
Index: test/CodeGen/X86/x86-shrink-wrapping.ll
===================================================================
--- test/CodeGen/X86/x86-shrink-wrapping.ll
+++ test/CodeGen/X86/x86-shrink-wrapping.ll
@@ -270,8 +270,6 @@
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:
@@ -982,3 +980,54 @@
}
attributes #4 = { "no-frame-pointer-elim"="true" }
+
+ at x = external global i32, align 4
+ at 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" }
Index: lib/CodeGen/ShrinkWrap.cpp
===================================================================
--- lib/CodeGen/ShrinkWrap.cpp
+++ lib/CodeGen/ShrinkWrap.cpp
@@ -282,8 +282,14 @@
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;
// Make sure we would be able to insert the restore code before the
// terminator.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32715.97330.patch
Type: text/x-patch
Size: 2546 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170501/089b04f8/attachment.bin>
More information about the llvm-commits
mailing list