Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -189,10 +189,15 @@ static void annotateDereferenceableBytes(CallInst *CI, ArrayRef ArgNos, uint64_t DereferenceableBytes) { + Function *F = CI->getFunction(); + if (!F) + return; for (unsigned ArgNo : ArgNos) { - uint64_t DerefBytes = std::max( - CI->getDereferenceableOrNullBytes(ArgNo + AttributeList::FirstArgIndex), - DereferenceableBytes); + uint64_t DerefBytes = DereferenceableBytes; + if (!F->nullPointerIsDefined()) + std::max(CI->getDereferenceableOrNullBytes(ArgNo + + AttributeList::FirstArgIndex), + DereferenceableBytes); if (CI->getDereferenceableBytes(ArgNo + AttributeList::FirstArgIndex) < DerefBytes) { Index: test/Transforms/InstCombine/mem-deref-bytes.ll =================================================================== --- test/Transforms/InstCombine/mem-deref-bytes.ll +++ test/Transforms/InstCombine/mem-deref-bytes.ll @@ -57,7 +57,7 @@ define i32 @memcmp_const_size_update_deref5(i8* nocapture readonly %d, i8* nocapture readonly %s) { ; CHECK-LABEL: @memcmp_const_size_update_deref5( -; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(40) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16) +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(16) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16) ; CHECK-NEXT: ret i32 [[CALL]] ; %call = tail call i32 @memcmp(i8* dereferenceable_or_null(40) %d, i8* %s, i64 16) @@ -66,6 +66,15 @@ define i32 @memcmp_const_size_no_update_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) { ; CHECK-LABEL: @memcmp_const_size_no_update_deref( +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(16) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16) #1 +; CHECK-NEXT: ret i32 [[CALL]] +; + %call = tail call i32 @memcmp(i8* dereferenceable_or_null(40) %d, i8* %s, i64 16) #0 + ret i32 %call +} + +define i32 @memcmp_const_size_no_update_deref2(i8* nocapture readonly %d, i8* nocapture readonly %s) { +; CHECK-LABEL: @memcmp_const_size_no_update_deref2( ; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(40) [[D:%.*]], i8* dereferenceable(20) [[S:%.*]], i64 16) ; CHECK-NEXT: ret i32 [[CALL]] ; @@ -143,3 +152,5 @@ call void @llvm.memset.p0i8.i64(i8* align 1 %s, i8 %c, i64 16, i1 false) ret i8* %s } + +attributes #0 = { "null-pointer-is-valid"="true" }