From: Johannes Doerfert Date: Fri, 23 Aug 2019 15:45:46 +0000 (+0000) Subject: [Attributor][Fix] Deal with "growing" dereferenceability X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=44404116d08aea68af7fdd798d46fa135c0c4318;p=llvm [Attributor][Fix] Deal with "growing" dereferenceability Summary: If we have a negative inbounds offset dereferenceabily "grows". However, until we do not handle the overflow that can occur in the dereferenceable bytes and the problem with loops, we simply do not grow the state. Reviewers: sstefan1, uenoku Subscribers: hiraditya, bollu, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66557 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369771 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/IPO/Attributor.cpp b/lib/Transforms/IPO/Attributor.cpp index ea897d7e361..e518994f153 100644 --- a/lib/Transforms/IPO/Attributor.cpp +++ b/lib/Transforms/IPO/Attributor.cpp @@ -1985,6 +1985,12 @@ struct AADereferenceableFloating : AADereferenceableImpl { T.GlobalState &= DS.GlobalState; } + // For now we do not try to "increase" dereferenceability due to negative + // indices as we first have to come up with code to deal with loops and + // for overflows of the dereferenceable bytes. + if (Offset.getSExtValue() < 0) + Offset = 0; + T.takeAssumedDerefBytesMinimum( std::max(int64_t(0), DerefBytes - Offset.getSExtValue())); diff --git a/test/Transforms/FunctionAttrs/dereferenceable.ll b/test/Transforms/FunctionAttrs/dereferenceable.ll index f75f9203e84..f61b62e9e23 100644 --- a/test/Transforms/FunctionAttrs/dereferenceable.ll +++ b/test/Transforms/FunctionAttrs/dereferenceable.ll @@ -50,3 +50,33 @@ define dereferenceable(4) i32* @test4(i32* dereferenceable(8) %0) local_unnamed_ ret i32* %0 } +; TEST 5 +; loop in which dereferenceabily "grows" +declare void @deref_phi_user(i32* %a); +define void @deref_phi(i32* dereferenceable(4000) %a) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] + %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ] +; CHECK: call void @deref_phi_user(i32* dereferenceable(4000) %a.addr.0) + call void @deref_phi_user(i32* %a.addr.0) + %tmp = load i32, i32* %a.addr.0, align 4 + %cmp = icmp slt i32 %i.0, %tmp + br i1 %cmp, label %for.body, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.cond + br label %for.end + +for.body: ; preds = %for.cond + br label %for.inc + +for.inc: ; preds = %for.body + %incdec.ptr = getelementptr inbounds i32, i32* %a.addr.0, i64 -1 + %inc = add nuw nsw i32 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond.cleanup + ret void +}