first step to fixing PR8642: don't fold away empty basic blocks

which have trapping constant exprs in them due to PHI nodes.
Eliminating them can cause the constant expr to be evalutated
on new paths if the input edges are critical.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122164 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-12-19 03:02:34 +00:00
parent 78d0094e4c
commit 140f4a315b
2 changed files with 42 additions and 0 deletions

View File

@ -211,6 +211,17 @@ bool CodeGenPrepare::CanMergeBlocks(const BasicBlock *BB,
const PHINode *DestBBPN = dyn_cast<PHINode>(DestBB->begin());
if (!DestBBPN) return true; // no conflict.
// Walk all the PHI nodes in DestBB. If any of the input values to the PHI
// are trapping constant exprs, then merging this block would introduce the
// possible trap into new control flow if we have any critical predecessor
// edges.
for (BasicBlock::const_iterator I = DestBB->begin(); isa<PHINode>(I); ++I) {
const PHINode *PN = cast<PHINode>(I);
if (const Constant *C =dyn_cast<Constant>(PN->getIncomingValueForBlock(BB)))
if (C->canTrap())
return false;
}
// Collect the preds of BB.
SmallPtrSet<const BasicBlock*, 16> BBPreds;
if (const PHINode *BBPN = dyn_cast<PHINode>(BB->begin())) {

View File

@ -0,0 +1,31 @@
; RUN: opt -codegenprepare %s -S | FileCheck %s
; PR8642
%0 = type <{ %1, %1 }>
%1 = type { i8, i8, i8, i8 }
@g_2 = global %0 <{ %1 { i8 1, i8 0, i8 0, i8 undef }, %1 { i8 2, i8 0, i8 0, i8 undef } }>, align 4
@g_4 = global %1 { i8 3, i8 0, i8 0, i8 undef }, align 4
; CGP shouldn't fold away the empty cond.false.i block, because the constant
; expr that will get dropped into it could trap.
define i16 @test1(i8** %argv, i1 %c) nounwind ssp {
entry:
br i1 %c, label %cond.end.i, label %cond.false.i
cond.false.i: ; preds = %entry
br label %foo.exit
cond.end.i: ; preds = %entry
store i8* null, i8** %argv
br label %foo.exit
foo.exit: ; preds = %cond.end.i, %cond.false.i
%call1 = phi i16 [ trunc (i32 srem (i32 1, i32 zext (i1 icmp eq (%1* bitcast (i8* getelementptr inbounds (%0* @g_2, i64 0, i32 1, i32 0) to %1*), %1* @g_4) to i32)) to i16), %cond.false.i ], [ 1, %cond.end.i ]
ret i16 %call1
; CHECK: @test1
; CHECK: cond.false.i:
; CHECK-NEXT: br label %foo.exit
}