1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[SimplifyCFG] Replace calls to null/undef with unreachable

Calling null is undefined behavior, a call to undef can be trivially
treated as a call to null.

llvm-svn: 273776
This commit is contained in:
David Majnemer 2016-06-25 07:37:27 +00:00
parent 44505218ac
commit a8dc7a78cf
3 changed files with 42 additions and 1 deletions

View File

@ -1414,6 +1414,12 @@ static bool markAliveBlocks(Function &F,
}
if (CallInst *CI = dyn_cast<CallInst>(BBI)) {
Value *Callee = CI->getCalledValue();
if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee)) {
changeToUnreachable(CI, /*UseLLVMTrap=*/false);
Changed = true;
break;
}
if (CI->doesNotReturn()) {
// If we found a call to a no-return function, insert an unreachable
// instruction after it. Make sure there isn't *already* one there

View File

@ -5388,7 +5388,7 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I) {
if (I->use_empty())
return false;
if (C->isNullValue()) {
if (C->isNullValue() || isa<UndefValue>(C)) {
// Only look at the first use, avoid hurting compile time with long uselists
User *Use = *I->user_begin();
@ -5417,6 +5417,10 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I) {
if (!SI->isVolatile())
return SI->getPointerAddressSpace() == 0 &&
SI->getPointerOperand() == I;
// A call to null is undefined.
if (auto CS = CallSite(Use))
return CS.getCalledValue() == I;
}
return false;
}

View File

@ -96,3 +96,34 @@ bb2:
store i8 2, i8* %ptr.2, align 8
ret void
}
define i32 @test7(i1 %X) {
entry:
br i1 %X, label %if, label %else
if:
call void undef()
br label %else
else:
%phi = phi i32 [ 0, %entry ], [ 1, %if ]
ret i32 %phi
}
; CHECK-LABEL: define i32 @test7(
; CHECK-NOT: call
; CHECK: ret i32 0
define void @test8(i1 %X, void ()* %Y) {
entry:
br i1 %X, label %if, label %else
if:
br label %else
else:
%phi = phi void ()* [ %Y, %entry ], [ null, %if ]
call void %phi()
ret void
}
; CHECK-LABEL: define void @test8(
; CHECK: call void %Y(