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
This commit is contained in:
Chandler Carruth 2011-11-24 08:46:04 +00:00
parent 2552de030b
commit a2deea1dcf
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
}