SimplifyCFG: Enhance the "remove CFG edge that leads to null pointer dereference" optimization to also handle instructions with multiple uses.

We conservatively only check the first use to avoid walking long use chains.
This catches the common case of having both a load and a store to a pointer
supplied by a PHI node.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165232 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2012-10-04 16:11:49 +00:00
parent 7508f946bc
commit 1e21db6e83
2 changed files with 31 additions and 2 deletions

View File

@ -3786,11 +3786,12 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I) {
if (!C)
return false;
if (!I->hasOneUse()) // Only look at single-use instructions, for compile time
if (I->use_empty())
return false;
if (C->isNullValue()) {
Instruction *Use = I->use_back();
// Only look at the first use, avoid hurting compile time with long uselists
User *Use = *I->use_begin();
// Now make sure that there are no instructions in between that can alter
// control flow (eg. calls)

View File

@ -85,3 +85,31 @@ if.end7: ; preds = %if.else, %if.then4,
; CHECK: if.end7:
; CHECK: phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
}
define i32 @test4(i32* %a, i32 %b, i32* %c, i32 %d) nounwind {
entry:
%tobool = icmp eq i32 %b, 0
br i1 %tobool, label %if.else, label %if.then
if.then: ; preds = %entry
tail call void @bar() nounwind
br label %if.end7
if.else: ; preds = %entry
%tobool3 = icmp eq i32 %d, 0
br i1 %tobool3, label %if.end7, label %if.then4
if.then4: ; preds = %if.else
tail call void @bar() nounwind
br label %if.end7
if.end7: ; preds = %if.else, %if.then4, %if.then
%x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
%gep = getelementptr i32* %x.0, i32 10
%tmp9 = load i32* %gep
%tmp10 = or i32 %tmp9, 1
store i32 %tmp10, i32* %gep
ret i32 %tmp9
; CHECK: @test4
; CHECK-NOT: phi
}