Teach isDereferenceablePointer to look through returned-argument functions

For functions which are known to return their argument,
isDereferenceableAndAlignedPointer can examine the argument value.

Differential Revision: http://reviews.llvm.org/D9384

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275038 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hal Finkel 2016-07-11 03:08:49 +00:00
parent 837551f8d6
commit 0017f3683d
2 changed files with 9 additions and 1 deletions

View File

@ -101,6 +101,11 @@ static bool isDereferenceableAndAlignedPointer(
return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Align, Size,
DL, CtxI, DT, Visited);
if (auto CS = ImmutableCallSite(V))
if (const Value *RV = CS.getReturnedArgOperand())
return isDereferenceableAndAlignedPointer(RV, Align, Size, DL, CtxI, DT,
Visited);
// If we don't know, assume the worst.
return false;
}

View File

@ -43,7 +43,8 @@ entry:
%load4 = load i32, i32 addrspace(1)* %relocate
; CHECK-NOT: %nparam
%nparam = getelementptr i32, i32 addrspace(1)* %dparam, i32 5
%dpa = call i32 addrspace(1)* @func1(i32 addrspace(1)* %dparam)
%nparam = getelementptr i32, i32 addrspace(1)* %dpa, i32 5
%load5 = load i32, i32 addrspace(1)* %nparam
; Load from a non-dereferenceable load
@ -162,6 +163,8 @@ if.end:
declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
declare i32 addrspace(1)* @func1(i32 addrspace(1)* returned) nounwind argmemonly
!0 = !{i64 4}
!1 = !{i64 2}
!2 = !{}