diff options
author | Bjorn Steinbrink <bsteinbr@gmail.com> | 2017-12-19 08:46:46 +0000 |
---|---|---|
committer | Bjorn Steinbrink <bsteinbr@gmail.com> | 2017-12-19 08:46:46 +0000 |
commit | 2da4d9d86d1c043d122fbd00a4fab265c0cae85b (patch) | |
tree | 5afc2695059da04fc7949731b44445497988bf44 | |
parent | e21475e54a377fe177ef5a5b4839f7107015133f (diff) | |
download | bcm5719-llvm-2da4d9d86d1c043d122fbd00a4fab265c0cae85b.tar.gz bcm5719-llvm-2da4d9d86d1c043d122fbd00a4fab265c0cae85b.zip |
Treat sret arguments as being dereferenceable in getPointerDereferenceableBytes()
Reviewers: rnk, hfinkel, efriedma
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D41355
llvm-svn: 321061
-rw-r--r-- | llvm/lib/IR/Value.cpp | 5 | ||||
-rw-r--r-- | llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll | 12 |
2 files changed, 14 insertions, 3 deletions
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index eae697b2e4b..d36b7cd4c64 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -627,9 +627,10 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL, CanBeNull = false; if (const Argument *A = dyn_cast<Argument>(this)) { DerefBytes = A->getDereferenceableBytes(); - if (DerefBytes == 0 && A->hasByValAttr()) { + if (DerefBytes == 0 && (A->hasByValAttr() || A->hasStructRetAttr())) { Type *PT = cast<PointerType>(A->getType())->getElementType(); - DerefBytes = DL.getTypeStoreSize(PT); + if (PT->isSized()) + DerefBytes = DL.getTypeStoreSize(PT); } if (DerefBytes == 0) { DerefBytes = A->getDereferenceableOrNullBytes(); diff --git a/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll b/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll index ca16a266123..8e474e5a95c 100644 --- a/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll +++ b/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll @@ -20,7 +20,8 @@ declare i32* @foo() @globalptr.align16 = external global i8, align 16 ; CHECK-LABEL: 'test' -define void @test(i32 addrspace(1)* dereferenceable(8) %dparam, +define void @test(%struct.A* sret %result, + i32 addrspace(1)* dereferenceable(8) %dparam, i8 addrspace(1)* dereferenceable(32) align 1 %dparam.align1, i8 addrspace(1)* dereferenceable(32) align 16 %dparam.align16, i8* byval %i8_byval, @@ -53,6 +54,15 @@ entry: %baa_cast = bitcast i8* %big_array_alloca to i32* %baa_load = load i32, i32* %baa_cast + ; Loads from sret arguments +; CHECK: %sret_gep{{.*}}(aligned) + %sret_gep = getelementptr inbounds %struct.A, %struct.A* %result, i64 0, i32 1, i64 2 + load i8, i8* %sret_gep + +; CHECK-NOT: %sret_gep_outside + %sret_gep_outside = getelementptr %struct.A, %struct.A* %result, i64 0, i32 1, i64 7 + load i8, i8* %sret_gep_outside + ; CHECK: %dparam{{.*}}(aligned) %load3 = load i32, i32 addrspace(1)* %dparam |