Fix a crash in block placement due to an inner loop that happened to be

reversed in the function's original ordering, and we happened to
encounter it while handling an outer unnatural CFG structure.

Thanks to the test case reduced from GCC's source by Benjamin Kramer.
This may also fix a crasher in gzip that Duncan reduced for me, but
I haven't yet gotten to testing that one.

llvm-svn: 145094
This commit is contained in:
Chandler Carruth 2011-11-23 03:03:21 +00:00
parent 514f7e9cb9
commit 4a87aa0c31
2 changed files with 45 additions and 1 deletions

View File

@ -488,7 +488,10 @@ MachineBasicBlock *MachineBlockPlacement::getFirstUnplacedBlock(
continue;
if (BlockToChain[I] != &PlacedChain) {
PrevUnplacedBlockIt = I;
return I;
// Now select the head of the chain to which the unplaced block belongs
// as the block to place. This will force the entire chain to be placed,
// and satisfies the requirements of merging chains.
return *BlockToChain[I]->begin();
}
}
return 0;

View File

@ -503,3 +503,44 @@ lpad:
loop:
br label %loop
}
define void @test_unnatural_cfg_backwards_inner_loop() {
; Test that when we encounter an unnatural CFG structure after having formed
; a chain for an inner loop which happened to be laid out backwards we don't
; attempt to merge onto the wrong end of the inner loop just because we find it
; first. This was reduced from a crasher in GCC's single source.
;
; CHECK: test_unnatural_cfg_backwards_inner_loop
; CHECK: %entry
; CHECK: %body
; CHECK: %loop1
; CHECK: %loop2b
; CHECK: %loop2a
entry:
br i1 undef, label %loop2a, label %body
body:
br label %loop2a
loop1:
%next.load = load i32** undef
br i1 %comp.a, label %loop2a, label %loop2b
loop2a:
%var = phi i32* [ null, %entry ], [ null, %body ], [ %next.phi, %loop1 ]
%next.var = phi i32* [ null, %entry ], [ undef, %body ], [ %next.load, %loop1 ]
%comp.a = icmp eq i32* %var, null
br label %loop3
loop2b:
%gep = getelementptr inbounds i32* %var.phi, i32 0
%next.ptr = bitcast i32* %gep to i32**
store i32* %next.phi, i32** %next.ptr
br label %loop3
loop3:
%var.phi = phi i32* [ %next.phi, %loop2b ], [ %var, %loop2a ]
%next.phi = phi i32* [ %next.load, %loop2b ], [ %next.var, %loop2a ]
br label %loop1
}