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.

llvm-svn: 145119
This commit is contained in:
Chandler Carruth 2011-11-24 08:46:04 +00:00
parent 22c7ad08ab
commit 1d3f68ffd0
2 changed files with 59 additions and 3 deletions

View File

@ -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()];

View File

@ -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
}