From 9cf2067cb7377366a10539b543f07daca7d1c362 Mon Sep 17 00:00:00 2001 From: Bjorn Steinbrink Date: Tue, 19 Dec 2017 08:46:46 +0000 Subject: [PATCH] Treat sret arguments as being dereferenceable in getPointerDereferenceableBytes() Reviewers: rnk, hfinkel, efriedma Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D41355 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321061 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/Value.cpp | 5 +++-- .../Analysis/ValueTracking/memory-dereferenceable.ll | 12 +++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp index eae697b2e4b..d36b7cd4c64 100644 --- a/lib/IR/Value.cpp +++ b/lib/IR/Value.cpp @@ -627,9 +627,10 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL, CanBeNull = false; if (const Argument *A = dyn_cast(this)) { DerefBytes = A->getDereferenceableBytes(); - if (DerefBytes == 0 && A->hasByValAttr()) { + if (DerefBytes == 0 && (A->hasByValAttr() || A->hasStructRetAttr())) { Type *PT = cast(A->getType())->getElementType(); - DerefBytes = DL.getTypeStoreSize(PT); + if (PT->isSized()) + DerefBytes = DL.getTypeStoreSize(PT); } if (DerefBytes == 0) { DerefBytes = A->getDereferenceableOrNullBytes(); diff --git a/test/Analysis/ValueTracking/memory-dereferenceable.ll b/test/Analysis/ValueTracking/memory-dereferenceable.ll index ca16a266123..8e474e5a95c 100644 --- a/test/Analysis/ValueTracking/memory-dereferenceable.ll +++ b/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 -- 2.49.0