aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-11-24 08:46:04 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-11-24 08:46:04 +0000
commita2deea1dcf8363f46bda8935283c5c701b5a278d (patch)
tree6e743ad6e90eda9e3509dff4b9f50038fa8733c7
parent2552de030bb50ab793ff8851401214187d35b542 (diff)
When adding blocks to the list of those which no longer have any CFG
conflicts, we should only be adding the first block of the chain to the list, lest we try to merge into the middle of that chain. Most of the places we were doing this we already happened to be looking at the first block, but there is no reason to assume that, and in some cases it was clearly wrong. I've added a couple of tests here. One already worked, but I like having an explicit test for it. The other is reduced from a test case Duncan reduced for me and used to crash. Now it is handled correctly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145119 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/MachineBlockPlacement.cpp6
-rw-r--r--test/CodeGen/X86/block-placement.ll56
2 files changed, 59 insertions, 3 deletions
diff --git a/lib/CodeGen/MachineBlockPlacement.cpp b/lib/CodeGen/MachineBlockPlacement.cpp
index 45d5af2930..870e24884a 100644
--- a/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/lib/CodeGen/MachineBlockPlacement.cpp
@@ -315,7 +315,7 @@ void MachineBlockPlacement::markChainSuccessors(
// This is a cross-chain edge that is within the loop, so decrement the
// loop predecessor count of the destination chain.
if (SuccChain.LoopPredecessors > 0 && --SuccChain.LoopPredecessors == 0)
- BlockWorkList.push_back(*SI);
+ BlockWorkList.push_back(*SuccChain.begin());
}
}
}
@@ -594,7 +594,7 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F,
}
if (Chain.LoopPredecessors == 0)
- BlockWorkList.push_back(*BI);
+ BlockWorkList.push_back(*Chain.begin());
}
buildChain(*L.block_begin(), LoopChain, BlockWorkList, &LoopBlockSet);
@@ -692,7 +692,7 @@ void MachineBlockPlacement::buildCFGChains(MachineFunction &F) {
}
if (Chain.LoopPredecessors == 0)
- BlockWorkList.push_back(BB);
+ BlockWorkList.push_back(*Chain.begin());
}
BlockChain &FunctionChain = *BlockToChain[&F.front()];
diff --git a/test/CodeGen/X86/block-placement.ll b/test/CodeGen/X86/block-placement.ll
index 891db5a8ce..a6ddc4d68e 100644
--- a/test/CodeGen/X86/block-placement.ll
+++ b/test/CodeGen/X86/block-placement.ll
@@ -593,3 +593,59 @@ exit:
ret void
}
+define void @unanalyzable_branch_to_best_succ(i1 %cond) {
+; Ensure that we can handle unanalyzable branches where the destination block
+; gets selected as the optimal sucessor to merge.
+;
+; CHECK: unanalyzable_branch_to_best_succ
+; CHECK: %entry
+; CHECK: %foo
+; CHECK: %bar
+; CHECK: %exit
+
+entry:
+ ; Bias this branch toward bar to ensure we form that chain.
+ br i1 %cond, label %bar, label %foo, !prof !1
+
+foo:
+ %cmp = fcmp une double 0.000000e+00, undef
+ br i1 %cmp, label %bar, label %exit
+
+bar:
+ call i32 @f()
+ br label %exit
+
+exit:
+ ret void
+}
+
+define void @unanalyzable_branch_to_free_block(float %x) {
+; Ensure that we can handle unanalyzable branches where the destination block
+; gets selected as the best free block in the CFG.
+;
+; CHECK: unanalyzable_branch_to_free_block
+; CHECK: %entry
+; CHECK: %a
+; CHECK: %b
+; CHECK: %c
+; CHECK: %exit
+
+entry:
+ br i1 undef, label %a, label %b
+
+a:
+ call i32 @f()
+ br label %c
+
+b:
+ %cmp = fcmp une float %x, undef
+ br i1 %cmp, label %c, label %exit
+
+c:
+ call i32 @g()
+ br label %exit
+
+exit:
+ ret void
+}
+