mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[BuildLibCalls] Add noundef to allocator fns' size
This is a patch to explicitly mark the size parameter of allocator functions like malloc/realloc/... as noundef. For C/C++: undef can be created from reading an uninitialized variable or padding. Calling a function with uninitialized variable is already UB. Calling malloc with padding value is.. something that's not expected. Padding bits may appear in a coerced aggregate, which doesn't apply to malloc's size. Therefore, malloc's size can be marked as noundef. For transformations that introduce malloc/realloc/..: I ran LLVM unit tests with an updated Alive2 semantics, and found no regression, so it seems okay. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D97045
This commit is contained in:
parent
c850e840c4
commit
adc1951f3a
@ -166,6 +166,14 @@ static bool setArgsNoUndef(Function &F) {
|
||||
return Changed;
|
||||
}
|
||||
|
||||
static bool setArgNoUndef(Function &F, unsigned ArgNo) {
|
||||
if (F.hasParamAttribute(ArgNo, Attribute::NoUndef))
|
||||
return false;
|
||||
F.addParamAttr(ArgNo, Attribute::NoUndef);
|
||||
++NumNoUndef;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool setRetAndArgsNoUndef(Function &F) {
|
||||
return setRetNoUndef(F) | setArgsNoUndef(F);
|
||||
}
|
||||
@ -323,8 +331,10 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setDoesNotCapture(F, 0);
|
||||
return Changed;
|
||||
case LibFunc_strdup:
|
||||
case LibFunc_strndup:
|
||||
Changed |= setArgNoUndef(F, 1);
|
||||
LLVM_FALLTHROUGH;
|
||||
case LibFunc_strdup:
|
||||
Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setRetDoesNotAlias(F);
|
||||
@ -383,7 +393,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
|
||||
case LibFunc_malloc:
|
||||
case LibFunc_vec_malloc:
|
||||
Changed |= setOnlyAccessesInaccessibleMemory(F);
|
||||
Changed |= setRetNoUndef(F);
|
||||
Changed |= setRetAndArgsNoUndef(F);
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setRetDoesNotAlias(F);
|
||||
Changed |= setWillReturn(F);
|
||||
@ -471,10 +481,12 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
|
||||
Changed |= setRetDoesNotAlias(F);
|
||||
Changed |= setWillReturn(F);
|
||||
Changed |= setDoesNotCapture(F, 0);
|
||||
Changed |= setArgNoUndef(F, 1);
|
||||
return Changed;
|
||||
case LibFunc_reallocf:
|
||||
Changed |= setRetNoUndef(F);
|
||||
Changed |= setWillReturn(F);
|
||||
Changed |= setArgNoUndef(F, 1);
|
||||
return Changed;
|
||||
case LibFunc_read:
|
||||
// May throw; "read" is a valid pthread cancellation point.
|
||||
@ -517,7 +529,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
|
||||
return Changed;
|
||||
case LibFunc_aligned_alloc:
|
||||
Changed |= setOnlyAccessesInaccessibleMemory(F);
|
||||
Changed |= setRetNoUndef(F);
|
||||
Changed |= setRetAndArgsNoUndef(F);
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setRetDoesNotAlias(F);
|
||||
Changed |= setWillReturn(F);
|
||||
@ -549,7 +561,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
|
||||
case LibFunc_calloc:
|
||||
case LibFunc_vec_calloc:
|
||||
Changed |= setOnlyAccessesInaccessibleMemory(F);
|
||||
Changed |= setRetNoUndef(F);
|
||||
Changed |= setRetAndArgsNoUndef(F);
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setRetDoesNotAlias(F);
|
||||
Changed |= setWillReturn(F);
|
||||
@ -833,7 +845,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
|
||||
return Changed;
|
||||
case LibFunc_valloc:
|
||||
Changed |= setOnlyAccessesInaccessibleMemory(F);
|
||||
Changed |= setRetNoUndef(F);
|
||||
Changed |= setRetAndArgsNoUndef(F);
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setRetDoesNotAlias(F);
|
||||
Changed |= setWillReturn(F);
|
||||
@ -908,8 +920,10 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
|
||||
Changed |= setRetAndArgsNoUndef(F);
|
||||
Changed |= setDoesNotCapture(F, 3);
|
||||
return Changed;
|
||||
case LibFunc_dunder_strdup:
|
||||
case LibFunc_dunder_strndup:
|
||||
Changed |= setArgNoUndef(F, 1);
|
||||
LLVM_FALLTHROUGH;
|
||||
case LibFunc_dunder_strdup:
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setRetDoesNotAlias(F);
|
||||
Changed |= setWillReturn(F);
|
||||
|
@ -178,7 +178,7 @@ declare x86_fp80 @acoshl(x86_fp80)
|
||||
; CHECK: declare x86_fp80 @acosl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare x86_fp80 @acosl(x86_fp80)
|
||||
|
||||
; CHECK: declare noalias noundef i8* @aligned_alloc(i64, i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND:#[0-9]+]]
|
||||
; CHECK: declare noalias noundef i8* @aligned_alloc(i64 noundef, i64 noundef) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND:#[0-9]+]]
|
||||
declare i8* @aligned_alloc(i64, i64)
|
||||
|
||||
; CHECK: declare double @asin(double) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
@ -250,7 +250,7 @@ declare void @bcopy(i8*, i8*, i64)
|
||||
; CHECK: declare void @bzero(i8* nocapture writeonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND:#[0-9]+]]
|
||||
declare void @bzero(i8*, i64)
|
||||
|
||||
; CHECK: declare noalias noundef i8* @calloc(i64, i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
|
||||
; CHECK: declare noalias noundef i8* @calloc(i64 noundef, i64 noundef) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
|
||||
declare i8* @calloc(i64, i64)
|
||||
|
||||
; CHECK: declare double @cbrt(double) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
@ -610,7 +610,7 @@ declare i32 @lstat(i8*, %opaque*)
|
||||
; CHECK-LINUX: declare noundef i32 @lstat64(i8* nocapture noundef readonly, %opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
|
||||
declare i32 @lstat64(i8*, %opaque*)
|
||||
|
||||
; CHECK: declare noalias noundef i8* @malloc(i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare noalias noundef i8* @malloc(i64 noundef) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare i8* @malloc(i64)
|
||||
|
||||
; CHECK-LINUX: declare noalias noundef i8* @memalign(i64, i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
@ -727,10 +727,10 @@ declare i64 @read(i32, i8*, i64)
|
||||
; CHECK: declare noundef i64 @readlink(i8* nocapture noundef readonly, i8* nocapture noundef, i64 noundef) [[NOFREE_NOUNWIND]]
|
||||
declare i64 @readlink(i8*, i8*, i64)
|
||||
|
||||
; CHECK: declare noalias noundef i8* @realloc(i8* nocapture, i64) [[NOUNWIND]]
|
||||
; CHECK: declare noalias noundef i8* @realloc(i8* nocapture, i64 noundef) [[NOUNWIND]]
|
||||
declare i8* @realloc(i8*, i64)
|
||||
|
||||
; CHECK: declare noundef i8* @reallocf(i8*, i64)
|
||||
; CHECK: declare noundef i8* @reallocf(i8*, i64 noundef)
|
||||
declare i8* @reallocf(i8*, i64)
|
||||
|
||||
; CHECK: declare noundef i8* @realpath(i8* nocapture noundef readonly, i8* noundef) [[NOFREE_NOUNWIND]]
|
||||
@ -871,7 +871,7 @@ declare i32 @strncmp(i8*, i8*, i64)
|
||||
; CHECK: declare i8* @strncpy(i8* noalias returned writeonly, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]]
|
||||
declare i8* @strncpy(i8*, i8*, i64)
|
||||
|
||||
; CHECK: declare noalias i8* @strndup(i8* nocapture readonly, i64) [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare noalias i8* @strndup(i8* nocapture readonly, i64 noundef) [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare i8* @strndup(i8*, i64)
|
||||
|
||||
; CHECK: declare i64 @strnlen(i8*, i64) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
@ -979,7 +979,7 @@ declare i32 @utime(i8*, %opaque*)
|
||||
; CHECK: declare noundef i32 @utimes(i8* nocapture noundef readonly, %opaque* nocapture noundef readonly) [[NOFREE_NOUNWIND]]
|
||||
declare i32 @utimes(i8*, %opaque*)
|
||||
|
||||
; CHECK: declare noalias noundef i8* @valloc(i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare noalias noundef i8* @valloc(i64 noundef) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare i8* @valloc(i64)
|
||||
|
||||
; CHECK: declare noundef i32 @vfprintf(%opaque* nocapture noundef, i8* nocapture noundef readonly, %opaque* noundef) [[NOFREE_NOUNWIND]]
|
||||
|
Loading…
Reference in New Issue
Block a user