Skip to content

Commit 3e7ee54

Browse files
committed
[InferAttrs] Do not mark first argument of str(n)cat as writeonly.
str(n)cat appends a copy of the second argument to the end of the first argument. To find the end of the first argument, str(n)cat has to read from it until it finds the terminating 0. So it should not be marked as writeonly. I think this means the argument should not be marked as writeonly. (This is causing a mis-compile with legacy DSE, before it got removed) Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D100601
1 parent f9d932e commit 3e7ee54

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

llvm/lib/Transforms/Utils/BuildLibCalls.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,19 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
257257
Changed |= setDoesNotCapture(F, 1);
258258
Changed |= setOnlyReadsMemory(F, 0);
259259
return Changed;
260-
case LibFunc_strcpy:
261-
case LibFunc_strncpy:
262260
case LibFunc_strcat:
263261
case LibFunc_strncat:
262+
Changed |= setOnlyAccessesArgMemory(F);
263+
Changed |= setDoesNotThrow(F);
264264
Changed |= setWillReturn(F);
265+
Changed |= setReturnedArg(F, 0);
266+
Changed |= setDoesNotCapture(F, 1);
267+
Changed |= setOnlyReadsMemory(F, 1);
268+
Changed |= setDoesNotAlias(F, 0);
269+
Changed |= setDoesNotAlias(F, 1);
270+
return Changed;
271+
case LibFunc_strcpy:
272+
case LibFunc_strncpy:
265273
Changed |= setReturnedArg(F, 0);
266274
LLVM_FALLTHROUGH;
267275
case LibFunc_stpcpy:

llvm/test/Transforms/InferFunctionAttrs/annotate.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ declare i8* @stpncpy(i8*, i8*, i64)
839839
; CHECK: declare i32 @strcasecmp(i8* nocapture, i8* nocapture) [[NOFREE_NOUNWIND_READONLY_WILLRETURN:#[0-9]+]]
840840
declare i32 @strcasecmp(i8*, i8*)
841841

842-
; CHECK: declare i8* @strcat(i8* noalias returned writeonly, i8* noalias nocapture readonly) [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
842+
; CHECK: declare i8* @strcat(i8* noalias returned, i8* noalias nocapture readonly) [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
843843
declare i8* @strcat(i8*, i8*)
844844

845845
; CHECK: declare i8* @strchr(i8*, i32) [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]]
@@ -866,7 +866,7 @@ declare i64 @strlen(i8*)
866866
; CHECK: declare i32 @strncasecmp(i8* nocapture, i8* nocapture, i64) [[NOFREE_NOUNWIND_READONLY_WILLRETURN]]
867867
declare i32 @strncasecmp(i8*, i8*, i64)
868868

869-
; CHECK: declare i8* @strncat(i8* noalias returned writeonly, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
869+
; CHECK: declare i8* @strncat(i8* noalias returned, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
870870
declare i8* @strncat(i8*, i8*, i64)
871871

872872
; CHECK: declare i32 @strncmp(i8* nocapture, i8* nocapture, i64) [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]]

0 commit comments

Comments
 (0)