Index: llvm/trunk/lib/Transforms/IPO/Attributor.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/Attributor.cpp +++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp @@ -1985,6 +1985,12 @@ 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())); Index: llvm/trunk/test/Transforms/FunctionAttrs/dereferenceable.ll =================================================================== --- llvm/trunk/test/Transforms/FunctionAttrs/dereferenceable.ll +++ llvm/trunk/test/Transforms/FunctionAttrs/dereferenceable.ll @@ -50,3 +50,33 @@ 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 +}