Skip to content

Commit da69147

Browse files
[InferAttrs] Refine attributes for a few libc routines
Attributes inference has been improved for a few functions. Particularly, ldexp and variants, as well as abort, may be marked as `nounwind`, as they do not propagate any exceptions to the caller, neither they unwind the stack. Besides, fwrite and fread first argument should be respectively readonly and writeonly.
1 parent 1eb5588 commit da69147

File tree

2 files changed

+16
-16
lines changed

2 files changed

+16
-16
lines changed

llvm/lib/Transforms/Utils/BuildLibCalls.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -802,21 +802,23 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
802802
Changed |= setRetAndArgsNoUndef(F);
803803
Changed |= setDoesNotThrow(F);
804804
Changed |= setDoesNotCapture(F, 2);
805+
Changed |= setOnlyWritesMemory(F, 0);
805806
break;
806807
case LibFunc_fread:
807808
case LibFunc_fread_unlocked:
808809
Changed |= setRetAndArgsNoUndef(F);
809810
Changed |= setDoesNotThrow(F);
810811
Changed |= setDoesNotCapture(F, 0);
811812
Changed |= setDoesNotCapture(F, 3);
813+
Changed |= setOnlyWritesMemory(F, 0);
812814
break;
813815
case LibFunc_fwrite:
814816
case LibFunc_fwrite_unlocked:
815817
Changed |= setRetAndArgsNoUndef(F);
816818
Changed |= setDoesNotThrow(F);
817819
Changed |= setDoesNotCapture(F, 0);
818820
Changed |= setDoesNotCapture(F, 3);
819-
// FIXME: readonly #1?
821+
Changed |= setOnlyReadsMemory(F, 0);
820822
break;
821823
case LibFunc_fputs:
822824
case LibFunc_fputs_unlocked:
@@ -1150,6 +1152,8 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
11501152
break;
11511153
case LibFunc_abort:
11521154
Changed |= setIsCold(F);
1155+
Changed |= setNoReturn(F);
1156+
Changed |= setDoesNotThrow(F);
11531157
break;
11541158
case LibFunc_terminate:
11551159
Changed |= setIsCold(F);
@@ -1166,12 +1170,6 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
11661170
Changed |= setDoesNotAccessMemory(F);
11671171
Changed |= setDoesNotThrow(F);
11681172
break;
1169-
case LibFunc_ldexp:
1170-
case LibFunc_ldexpf:
1171-
case LibFunc_ldexpl:
1172-
Changed |= setOnlyWritesErrnoMemory(F);
1173-
Changed |= setWillReturn(F);
1174-
break;
11751173
case LibFunc_acos:
11761174
case LibFunc_acosf:
11771175
case LibFunc_acosh:
@@ -1228,6 +1226,9 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
12281226
case LibFunc_hypot:
12291227
case LibFunc_hypotf:
12301228
case LibFunc_hypotl:
1229+
case LibFunc_ldexp:
1230+
case LibFunc_ldexpf:
1231+
case LibFunc_ldexpl:
12311232
case LibFunc_log:
12321233
case LibFunc_log10:
12331234
case LibFunc_log10f:

llvm/test/Transforms/InferFunctionAttrs/annotate.ll

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ declare i32 @fgetc(ptr)
428428
; CHECK: declare noundef i32 @fgetpos(ptr noundef captures(none), ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
429429
declare i32 @fgetpos(ptr, ptr)
430430

431-
; CHECK: declare noundef ptr @fgets(ptr noundef, i32 noundef, ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
431+
; CHECK: declare noundef ptr @fgets(ptr noundef writeonly, i32 noundef, ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
432432
declare ptr @fgets(ptr, i32, ptr)
433433

434434
; CHECK: declare noundef i32 @fileno(ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
@@ -494,7 +494,7 @@ declare i32 @fputc(i32, ptr)
494494
; CHECK: declare noundef i32 @fputs(ptr noundef readonly captures(none), ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
495495
declare i32 @fputs(ptr, ptr)
496496

497-
; CHECK: declare noundef i64 @fread(ptr noundef captures(none), i64 noundef, i64 noundef, ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
497+
; CHECK: declare noundef i64 @fread(ptr noundef writeonly captures(none), i64 noundef, i64 noundef, ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
498498
declare i64 @fread(ptr, i64, i64, ptr)
499499

500500
; CHECK: declare void @free(ptr allocptr noundef captures(none)) [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_FREE_FAMILY_MALLOC:#[0-9]+]]
@@ -554,7 +554,7 @@ declare i32 @ftrylockfile(ptr)
554554
; CHECK: declare void @funlockfile(ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
555555
declare void @funlockfile(ptr)
556556

557-
; CHECK: declare noundef i64 @fwrite(ptr noundef captures(none), i64 noundef, i64 noundef, ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
557+
; CHECK: declare noundef i64 @fwrite(ptr noundef readonly captures(none), i64 noundef, i64 noundef, ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
558558
declare i64 @fwrite(ptr, i64, i64, ptr)
559559

560560
; CHECK: declare noundef i32 @getc(ptr noundef captures(none)) [[NOFREE_NOUNWIND]]
@@ -610,13 +610,13 @@ declare i64 @labs(i64)
610610
; CHECK: declare noundef i32 @lchown(ptr noundef readonly captures(none), i32 noundef, i32 noundef) [[NOFREE_NOUNWIND]]
611611
declare i32 @lchown(ptr, i32, i32)
612612

613-
; CHECK: declare double @ldexp(double, i32) [[ERRNOMEMONLY_NOFREE_WILLRETURN:#[0-9]+]]
613+
; CHECK: declare double @ldexp(double, i32) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
614614
declare double @ldexp(double, i32)
615615

616-
; CHECK: declare float @ldexpf(float, i32) [[ERRNOMEMONLY_NOFREE_WILLRETURN:#[0-9]+]]
616+
; CHECK: declare float @ldexpf(float, i32) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
617617
declare float @ldexpf(float, i32)
618618

619-
; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32) [[ERRNOMEMONLY_NOFREE_WILLRETURN:#[0-9]+]]
619+
; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
620620
declare x86_fp80 @ldexpl(x86_fp80, i32)
621621

622622
; CHECK: declare i64 @llabs(i64) [[MEMNONE_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
@@ -1155,7 +1155,7 @@ declare i32 @vsscanf(ptr, ptr, ptr)
11551155
; CHECK: declare noundef i64 @write(i32 noundef, ptr noundef readonly captures(none), i64 noundef) [[NOFREE]]
11561156
declare i64 @write(i32, ptr, i64)
11571157

1158-
; CHECK: declare void @abort() [[NOFREE_COLD:#[0-9]+]]
1158+
; CHECK: declare void @abort() [[NOFREE_COLD_NORETURN_NOUNWIND:#[0-9]+]]
11591159
declare void @abort()
11601160

11611161
; CHECK: declare void @__cxa_throw(ptr, ptr, ptr) [[COLD_NORETURN:#[0-9]+]]
@@ -1193,15 +1193,14 @@ declare void @memset_pattern16(ptr, ptr, i64)
11931193
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(argmem: readwrite) }
11941194
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind memory(read) }
11951195
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_FREE_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
1196-
; CHECK-DAG: attributes [[ERRNOMEMONLY_NOFREE_WILLRETURN]] = { mustprogress nofree willreturn memory(errnomem: write) }
11971196
; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE0_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
11981197
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(argmem: read) }
11991198
; CHECK-DAG: attributes [[NOFREE]] = { nofree }
12001199
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { nofree nounwind memory(argmem: readwrite) }
12011200
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE1_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("realloc") allocsize(1) memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
12021201
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE12_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("realloc") allocsize(1,2) memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
12031202
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
1204-
; CHECK-DAG: attributes [[NOFREE_COLD]] = { cold nofree }
1203+
; CHECK-DAG: attributes [[NOFREE_COLD_NORETURN_NOUNWIND]] = { cold nofree noreturn nounwind }
12051204
; CHECK-DAG: attributes [[NOFREE_COLD_NORETURN]] = { cold nofree noreturn }
12061205
; CHECK-DAG: attributes [[COLD_NORETURN]] = { cold noreturn }
12071206

0 commit comments

Comments
 (0)