Index: llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -876,7 +876,9 @@ Value *LibCallSimplifier::optimizeMemChr(CallInst *CI, IRBuilderBase &B) { Value *SrcStr = CI->getArgOperand(0); Value *Size = CI->getArgOperand(2); - annotateNonNullAndDereferenceable(CI, 0, Size, DL); + if (isKnownNonZero(Size, DL)) + annotateNonNullNoUndefBasedOnAccess(CI, 0); + Value *CharVal = CI->getArgOperand(1); ConstantInt *CharC = dyn_cast(CharVal); ConstantInt *LenC = dyn_cast(Size); Index: llvm/test/Transforms/InstCombine/mem-deref-bytes.ll =================================================================== --- llvm/test/Transforms/InstCombine/mem-deref-bytes.ll +++ llvm/test/Transforms/InstCombine/mem-deref-bytes.ll @@ -102,7 +102,7 @@ define i8* @memcpy_const_size_set_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) { ; CHECK-LABEL: @memcpy_const_size_set_deref( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(64) [[D:%.*]], i8* noundef nonnull align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(64) [[D:%.*]], i8* noundef nonnull align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false) ; CHECK-NEXT: ret i8* [[D]] ; %call = tail call i8* @memcpy(i8* %d, i8* %s, i64 64) @@ -111,7 +111,7 @@ define i8* @memmove_const_size_set_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) { ; CHECK-LABEL: @memmove_const_size_set_deref( -; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(64) [[D:%.*]], i8* noundef nonnull align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false) +; CHECK-NEXT: tail call void @llvm.memmove.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(64) [[D:%.*]], i8* noundef nonnull align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false) ; CHECK-NEXT: ret i8* [[D]] ; %call = tail call i8* @memmove(i8* %d, i8* %s, i64 64) @@ -120,7 +120,7 @@ define i8* @memset_const_size_set_deref(i8* nocapture readonly %s, i8 %c) { ; CHECK-LABEL: @memset_const_size_set_deref( -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(64) [[S:%.*]], i8 [[C:%.*]], i64 64, i1 false) +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(64) [[S:%.*]], i8 [[C:%.*]], i64 64, i1 false) ; CHECK-NEXT: ret i8* [[S]] ; %call = tail call i8* @memset(i8* %s, i8 %c, i64 64) @@ -129,7 +129,7 @@ define i8* @memchr_const_size_set_deref(i8* nocapture readonly %s, i32 %c) { ; CHECK-LABEL: @memchr_const_size_set_deref( -; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @memchr(i8* noundef nonnull dereferenceable(64) [[S:%.*]], i32 [[C:%.*]], i64 64) +; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @memchr(i8* noundef nonnull dereferenceable(1) [[S:%.*]], i32 [[C:%.*]], i64 64) ; CHECK-NEXT: ret i8* [[CALL]] ; %call = tail call i8* @memchr(i8* %s, i32 %c, i64 64) Index: llvm/test/Transforms/InstCombine/memchr.ll =================================================================== --- llvm/test/Transforms/InstCombine/memchr.ll +++ llvm/test/Transforms/InstCombine/memchr.ll @@ -50,7 +50,7 @@ define void @test4(i32 %chr) { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(14) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]], i32 14) +; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]], i32 14) ; CHECK-NEXT: store i8* [[DST]], i8** @chp, align 4 ; CHECK-NEXT: ret void ; @@ -148,7 +148,7 @@ ; No 64 bits here define i1 @test12(i32 %C) { ; CHECK-LABEL: @test12( -; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(3) getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i32 0, i32 0), i32 [[C:%.*]], i32 3) +; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i32 0, i32 0), i32 [[C:%.*]], i32 3) ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[DST]], null ; CHECK-NEXT: ret i1 [[CMP]] ; @@ -185,7 +185,7 @@ define i1 @test15(i32 %C) { ; CHECK-LABEL: @test15( -; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(3) getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i32 0, i32 0), i32 [[C:%.*]], i32 3) +; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i32 0, i32 0), i32 [[C:%.*]], i32 3) ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[DST]], null ; CHECK-NEXT: ret i1 [[CMP]] ; @@ -225,7 +225,7 @@ define i8* @test18(i8* %str, i32 %c) { ; CHECK-LABEL: @test18( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(5) [[STR:%.*]], i32 [[C:%.*]], i32 5) +; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) [[STR:%.*]], i32 [[C:%.*]], i32 5) ; CHECK-NEXT: ret i8* [[RET]] ; @@ -235,7 +235,7 @@ define i8* @test19(i8* %str, i32 %c) null_pointer_is_valid { ; CHECK-LABEL: @test19( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef dereferenceable(5) [[STR:%.*]], i32 [[C:%.*]], i32 5) +; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef [[STR:%.*]], i32 [[C:%.*]], i32 5) ; CHECK-NEXT: ret i8* [[RET]] ; Index: llvm/test/Transforms/InstCombine/strchr-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strchr-1.ll +++ llvm/test/Transforms/InstCombine/strchr-1.ll @@ -49,7 +49,7 @@ define void @test_simplify4(i32 %chr) { ; CHECK-LABEL: @test_simplify4( -; CHECK-NEXT: [[MEMCHR:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(14) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]], i32 14) +; CHECK-NEXT: [[MEMCHR:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]], i32 14) ; CHECK-NEXT: store i8* [[MEMCHR]], i8** @chp, align 4 ; CHECK-NEXT: ret void ;