Skip to content

Commit b63524b

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 (cherry-picked from 3e7ee54)
1 parent 844fff6 commit b63524b

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
@@ -239,11 +239,19 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
239239
Changed |= setDoesNotCapture(F, 1);
240240
Changed |= setOnlyReadsMemory(F, 0);
241241
return Changed;
242-
case LibFunc_strcpy:
243-
case LibFunc_strncpy:
244242
case LibFunc_strcat:
245243
case LibFunc_strncat:
244+
Changed |= setOnlyAccessesArgMemory(F);
245+
Changed |= setDoesNotThrow(F);
246246
Changed |= setWillReturn(F);
247+
Changed |= setReturnedArg(F, 0);
248+
Changed |= setDoesNotCapture(F, 1);
249+
Changed |= setOnlyReadsMemory(F, 1);
250+
Changed |= setDoesNotAlias(F, 0);
251+
Changed |= setDoesNotAlias(F, 1);
252+
return Changed;
253+
case LibFunc_strcpy:
254+
case LibFunc_strncpy:
247255
Changed |= setReturnedArg(F, 0);
248256
LLVM_FALLTHROUGH;
249257
case LibFunc_stpcpy:

llvm/test/Transforms/InferFunctionAttrs/annotate.ll

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

841-
; CHECK: declare i8* @strcat(i8* noalias returned writeonly, i8* noalias nocapture readonly) [[ARGMEMONLY_NOFREE_NOUNWIND]]
841+
; CHECK: declare i8* @strcat(i8* noalias returned, i8* noalias nocapture readonly) [[ARGMEMONLY_NOFREE_NOUNWIND]]
842842
declare i8* @strcat(i8*, i8*)
843843

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

868-
; CHECK: declare i8* @strncat(i8* noalias returned writeonly, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]]
868+
; CHECK: declare i8* @strncat(i8* noalias returned, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]]
869869
declare i8* @strncat(i8*, i8*, i64)
870870

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

0 commit comments

Comments
 (0)