aqjune updated this revision to Diff 284246. aqjune added a comment. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Update PR3589-freestanding-libcalls.c Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D85345/new/ https://reviews.llvm.org/D85345 Files: clang/test/CodeGen/PR3589-freestanding-libcalls.c llvm/lib/Transforms/Utils/BuildLibCalls.cpp llvm/test/CodeGen/X86/no-plt-libcalls.ll llvm/test/Transforms/InferFunctionAttrs/annotate.ll
Index: llvm/test/Transforms/InferFunctionAttrs/annotate.ll =================================================================== --- llvm/test/Transforms/InferFunctionAttrs/annotate.ll +++ llvm/test/Transforms/InferFunctionAttrs/annotate.ll @@ -352,19 +352,19 @@ ; CHECK: declare x86_fp80 @fabsl(x86_fp80) [[G0]] declare x86_fp80 @fabsl(x86_fp80) -; CHECK: declare i32 @fclose(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @fclose(%opaque* nocapture noundef) [[G1]] declare i32 @fclose(%opaque*) -; CHECK: declare noalias %opaque* @fdopen(i32, i8* nocapture readonly) [[G1]] +; CHECK: declare noalias noundef %opaque* @fdopen(i32 noundef, i8* nocapture noundef readonly) [[G1]] declare %opaque* @fdopen(i32, i8*) -; CHECK: declare i32 @feof(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @feof(%opaque* nocapture noundef) [[G1]] declare i32 @feof(%opaque*) -; CHECK: declare i32 @ferror(%opaque* nocapture) [[G2]] +; CHECK: declare noundef i32 @ferror(%opaque* nocapture noundef) [[G2]] declare i32 @ferror(%opaque*) -; CHECK: declare i32 @fflush(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @fflush(%opaque* nocapture noundef) [[G1]] declare i32 @fflush(%opaque*) ; CHECK: declare i32 @ffs(i32) [[G0]] @@ -376,19 +376,19 @@ ; CHECK: declare i32 @ffsll(i64) [[G0]] declare i32 @ffsll(i64) -; CHECK: declare i32 @fgetc(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @fgetc(%opaque* nocapture noundef) [[G1]] declare i32 @fgetc(%opaque*) -; CHECK: declare i32 @fgetpos(%opaque* nocapture, i64* nocapture) [[G1]] +; CHECK: declare noundef i32 @fgetpos(%opaque* nocapture noundef, i64* nocapture noundef) [[G1]] declare i32 @fgetpos(%opaque*, i64*) -; CHECK: declare i8* @fgets(i8*, i32, %opaque* nocapture) [[G1]] +; CHECK: declare noundef i8* @fgets(i8* noundef, i32 noundef, %opaque* nocapture noundef) [[G1]] declare i8* @fgets(i8*, i32, %opaque*) -; CHECK: declare i32 @fileno(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @fileno(%opaque* nocapture noundef) [[G1]] declare i32 @fileno(%opaque*) -; CHECK: declare void @flockfile(%opaque* nocapture) [[G1]] +; CHECK: declare void @flockfile(%opaque* nocapture noundef) [[G1]] declare void @flockfile(%opaque*) ; CHECK: declare double @floor(double) [[G0]] @@ -436,19 +436,19 @@ ; CHECK: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[G0]] declare x86_fp80 @fmodl(x86_fp80, x86_fp80) -; CHECK: declare noalias %opaque* @fopen(i8* nocapture readonly, i8* nocapture readonly) [[G1]] +; CHECK: declare noalias noundef %opaque* @fopen(i8* nocapture noundef readonly, i8* nocapture noundef readonly) [[G1]] declare %opaque* @fopen(i8*, i8*) -; CHECK: declare i32 @fprintf(%opaque* nocapture, i8* nocapture readonly, ...) [[G1]] +; CHECK: declare noundef i32 @fprintf(%opaque* nocapture noundef, i8* nocapture noundef readonly, ...) [[G1]] declare i32 @fprintf(%opaque*, i8*, ...) -; CHECK: declare i32 @fputc(i32, %opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @fputc(i32 noundef, %opaque* nocapture noundef) [[G1]] declare i32 @fputc(i32, %opaque*) -; CHECK: declare i32 @fputs(i8* nocapture readonly, %opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @fputs(i8* nocapture noundef readonly, %opaque* nocapture noundef) [[G1]] declare i32 @fputs(i8*, %opaque*) -; CHECK: declare i64 @fread(i8* nocapture, i64, i64, %opaque* nocapture) [[G1]] +; CHECK: declare noundef i64 @fread(i8* nocapture noundef, i64 noundef, i64 noundef, %opaque* nocapture noundef) [[G1]] declare i64 @fread(i8*, i64, i64, %opaque*) ; CHECK: declare void @free(i8* nocapture) [[G3:#[0-9]+]] @@ -463,61 +463,61 @@ ; CHECK: declare x86_fp80 @frexpl(x86_fp80, i32* nocapture) [[G1]] declare x86_fp80 @frexpl(x86_fp80, i32*) -; CHECK: declare i32 @fscanf(%opaque* nocapture, i8* nocapture readonly, ...) [[G1]] +; CHECK: declare noundef i32 @fscanf(%opaque* nocapture noundef, i8* nocapture noundef readonly, ...) [[G1]] declare i32 @fscanf(%opaque*, i8*, ...) -; CHECK: declare i32 @fseek(%opaque* nocapture, i64, i32) [[G1]] +; CHECK: declare noundef i32 @fseek(%opaque* nocapture noundef, i64 noundef, i32 noundef) [[G1]] declare i32 @fseek(%opaque*, i64, i32) -; CHECK: declare i32 @fseeko(%opaque* nocapture, i64, i32) [[G1]] +; CHECK: declare noundef i32 @fseeko(%opaque* nocapture noundef, i64 noundef, i32 noundef) [[G1]] declare i32 @fseeko(%opaque*, i64, i32) -; CHECK-LINUX: declare i32 @fseeko64(%opaque* nocapture, i64, i32) [[G1]] +; CHECK-LINUX: declare noundef i32 @fseeko64(%opaque* nocapture noundef, i64 noundef, i32 noundef) [[G1]] declare i32 @fseeko64(%opaque*, i64, i32) -; CHECK: declare i32 @fsetpos(%opaque* nocapture, i64*) [[G1]] +; CHECK: declare noundef i32 @fsetpos(%opaque* nocapture noundef, i64* noundef) [[G1]] declare i32 @fsetpos(%opaque*, i64*) -; CHECK: declare i32 @fstat(i32, %opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @fstat(i32 noundef, %opaque* nocapture noundef) [[G1]] declare i32 @fstat(i32, %opaque*) -; CHECK-LINUX: declare i32 @fstat64(i32, %opaque* nocapture) [[G1]] +; CHECK-LINUX: declare noundef i32 @fstat64(i32 noundef, %opaque* nocapture noundef) [[G1]] declare i32 @fstat64(i32, %opaque*) -; CHECK: declare i32 @fstatvfs(i32, %opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @fstatvfs(i32 noundef, %opaque* nocapture noundef) [[G1]] declare i32 @fstatvfs(i32, %opaque*) -; CHECK-LINUX: declare i32 @fstatvfs64(i32, %opaque* nocapture) [[G1]] +; CHECK-LINUX: declare noundef i32 @fstatvfs64(i32 noundef, %opaque* nocapture noundef) [[G1]] declare i32 @fstatvfs64(i32, %opaque*) -; CHECK: declare i64 @ftell(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i64 @ftell(%opaque* nocapture noundef) [[G1]] declare i64 @ftell(%opaque*) -; CHECK: declare i64 @ftello(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i64 @ftello(%opaque* nocapture noundef) [[G1]] declare i64 @ftello(%opaque*) -; CHECK-LINUX: declare i64 @ftello64(%opaque* nocapture) [[G1]] +; CHECK-LINUX: declare noundef i64 @ftello64(%opaque* nocapture noundef) [[G1]] declare i64 @ftello64(%opaque*) -; CHECK: declare i32 @ftrylockfile(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @ftrylockfile(%opaque* nocapture noundef) [[G1]] declare i32 @ftrylockfile(%opaque*) -; CHECK: declare void @funlockfile(%opaque* nocapture) [[G1]] +; CHECK: declare void @funlockfile(%opaque* nocapture noundef) [[G1]] declare void @funlockfile(%opaque*) -; CHECK: declare i64 @fwrite(i8* nocapture, i64, i64, %opaque* nocapture) [[G1]] +; CHECK: declare noundef i64 @fwrite(i8* nocapture noundef, i64 noundef, i64 noundef, %opaque* nocapture noundef) [[G1]] declare i64 @fwrite(i8*, i64, i64, %opaque*) -; CHECK: declare i32 @getc(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @getc(%opaque* nocapture noundef) [[G1]] declare i32 @getc(%opaque*) -; CHECK: declare i32 @getc_unlocked(%opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @getc_unlocked(%opaque* nocapture noundef) [[G1]] declare i32 @getc_unlocked(%opaque*) -; CHECK: declare i32 @getchar() [[G1]] +; CHECK: declare noundef i32 @getchar() [[G1]] declare i32 @getchar() -; CHECK: declare i32 @getchar_unlocked() [[G1]] +; CHECK: declare noundef i32 @getchar_unlocked() [[G1]] declare i32 @getchar_unlocked() ; CHECK: declare i8* @getenv(i8* nocapture) [[G2]] @@ -532,7 +532,7 @@ ; CHECK: declare %opaque* @getpwnam(i8* nocapture readonly) [[G1]] declare %opaque* @getpwnam(i8*) -; CHECK: declare i8* @gets(i8*) [[G1]] +; CHECK: declare noundef i8* @gets(i8* noundef) [[G1]] declare i8* @gets(i8*) ; CHECK: declare i32 @gettimeofday(%opaque* nocapture, i8* nocapture) [[G1]] @@ -664,10 +664,10 @@ ; CHECK: declare x86_fp80 @nearbyintl(x86_fp80) [[G0]] declare x86_fp80 @nearbyintl(x86_fp80) -; CHECK: declare i32 @open(i8* nocapture readonly, i32, ...) [[G0]] +; CHECK: declare noundef i32 @open(i8* nocapture noundef readonly, i32 noundef, ...) [[G0]] declare i32 @open(i8*, i32, ...) -; CHECK-LINUX: declare i32 @open64(i8* nocapture readonly, i32, ...) [[G0]] +; CHECK-LINUX: declare noundef i32 @open64(i8* nocapture noundef readonly, i32 noundef, ...) [[G0]] declare i32 @open64(i8*, i32, ...) ; CHECK: declare noalias %opaque* @opendir(i8* nocapture readonly) [[G1]] @@ -676,7 +676,7 @@ ; CHECK: declare i32 @pclose(%opaque* nocapture) [[G1]] declare i32 @pclose(%opaque*) -; CHECK: declare void @perror(i8* nocapture readonly) [[G1]] +; CHECK: declare void @perror(i8* nocapture noundef readonly) [[G1]] declare void @perror(i8*) ; CHECK: declare noalias %opaque* @popen(i8* nocapture readonly, i8* nocapture readonly) [[G1]] @@ -694,31 +694,31 @@ ; CHECK: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[G0]] declare x86_fp80 @powl(x86_fp80, x86_fp80) -; CHECK: declare i64 @pread(i32, i8* nocapture, i64, i64) [[G0]] +; CHECK: declare noundef i64 @pread(i32 noundef, i8* nocapture noundef, i64 noundef, i64 noundef) [[G0]] declare i64 @pread(i32, i8*, i64, i64) -; CHECK: declare i32 @printf(i8* nocapture readonly, ...) [[G1]] +; CHECK: declare noundef i32 @printf(i8* nocapture noundef readonly, ...) [[G1]] declare i32 @printf(i8*, ...) -; CHECK: declare i32 @putc(i32, %opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @putc(i32 noundef, %opaque* nocapture noundef) [[G1]] declare i32 @putc(i32, %opaque*) -; CHECK: declare i32 @putchar(i32) [[G1]] +; CHECK: declare noundef i32 @putchar(i32 noundef) [[G1]] declare i32 @putchar(i32) -; CHECK: declare i32 @putchar_unlocked(i32) [[G1]] +; CHECK: declare noundef i32 @putchar_unlocked(i32 noundef) [[G1]] declare i32 @putchar_unlocked(i32) -; CHECK: declare i32 @puts(i8* nocapture readonly) [[G1]] +; CHECK: declare noundef i32 @puts(i8* nocapture noundef readonly) [[G1]] declare i32 @puts(i8*) -; CHECK: declare i64 @pwrite(i32, i8* nocapture readonly, i64, i64) [[G0]] +; CHECK: declare noundef i64 @pwrite(i32 noundef, i8* nocapture noundef readonly, i64 noundef, i64 noundef) [[G0]] declare i64 @pwrite(i32, i8*, i64, i64) ; CHECK: declare void @qsort(i8*, i64, i64, i32 (i8*, i8*)* nocapture) [[G0]] declare void @qsort(i8*, i64, i64, i32 (i8*, i8*)*) -; CHECK: declare i64 @read(i32, i8* nocapture, i64) [[G0]] +; CHECK: declare noundef i64 @read(i32 noundef, i8* nocapture noundef, i64 noundef) [[G0]] declare i64 @read(i32, i8*, i64) ; CHECK: declare i64 @readlink(i8* nocapture readonly, i8* nocapture, i64) [[G1]] @@ -739,7 +739,7 @@ ; CHECK: declare i32 @rename(i8* nocapture readonly, i8* nocapture readonly) [[G1]] declare i32 @rename(i8*, i8*) -; CHECK: declare void @rewind(%opaque* nocapture) [[G1]] +; CHECK: declare void @rewind(%opaque* nocapture noundef) [[G1]] declare void @rewind(%opaque*) ; CHECK: declare double @rint(double) [[G0]] @@ -763,7 +763,7 @@ ; CHECK: declare x86_fp80 @roundl(x86_fp80) [[G0]] declare x86_fp80 @roundl(x86_fp80) -; CHECK: declare i32 @scanf(i8* nocapture readonly, ...) [[G1]] +; CHECK: declare noundef i32 @scanf(i8* nocapture noundef readonly, ...) [[G1]] declare i32 @scanf(i8*, ...) ; CHECK: declare void @setbuf(%opaque* nocapture, i8*) [[G1]] @@ -793,10 +793,10 @@ ; CHECK: declare x86_fp80 @sinl(x86_fp80) [[G0]] declare x86_fp80 @sinl(x86_fp80) -; CHECK: declare i32 @snprintf(i8* noalias nocapture, i64, i8* nocapture readonly, ...) [[G1]] +; CHECK: declare noundef i32 @snprintf(i8* noalias nocapture noundef, i64 noundef, i8* nocapture noundef readonly, ...) [[G1]] declare i32 @snprintf(i8*, i64, i8*, ...) -; CHECK: declare i32 @sprintf(i8* noalias nocapture, i8* nocapture readonly, ...) [[G1]] +; CHECK: declare noundef i32 @sprintf(i8* noalias nocapture noundef, i8* nocapture noundef readonly, ...) [[G1]] declare i32 @sprintf(i8*, i8*, ...) ; CHECK: declare double @sqrt(double) [[G0]] @@ -808,7 +808,7 @@ ; CHECK: declare x86_fp80 @sqrtl(x86_fp80) [[G0]] declare x86_fp80 @sqrtl(x86_fp80) -; CHECK: declare i32 @sscanf(i8* nocapture readonly, i8* nocapture readonly, ...) [[G1]] +; CHECK: declare noundef i32 @sscanf(i8* nocapture noundef readonly, i8* nocapture noundef readonly, ...) [[G1]] declare i32 @sscanf(i8*, i8*, ...) ; CHECK: declare i32 @stat(i8* nocapture readonly, %opaque* nocapture) [[G1]] @@ -961,7 +961,7 @@ ; CHECK: declare i32 @uname(%opaque* nocapture) [[G1]] declare i32 @uname(%opaque*) -; CHECK: declare i32 @ungetc(i32, %opaque* nocapture) [[G1]] +; CHECK: declare noundef i32 @ungetc(i32 noundef, %opaque* nocapture noundef) [[G1]] declare i32 @ungetc(i32, %opaque*) ; CHECK: declare i32 @unlink(i8* nocapture readonly) [[G1]] @@ -979,28 +979,28 @@ ; CHECK: declare noalias i8* @valloc(i64) [[G1]] declare i8* @valloc(i64) -; CHECK: declare i32 @vfprintf(%opaque* nocapture, i8* nocapture readonly, %opaque*) [[G1]] +; CHECK: declare noundef i32 @vfprintf(%opaque* nocapture noundef, i8* nocapture noundef readonly, %opaque* noundef) [[G1]] declare i32 @vfprintf(%opaque*, i8*, %opaque*) -; CHECK: declare i32 @vfscanf(%opaque* nocapture, i8* nocapture readonly, %opaque*) [[G1]] +; CHECK: declare noundef i32 @vfscanf(%opaque* nocapture noundef, i8* nocapture noundef readonly, %opaque* noundef) [[G1]] declare i32 @vfscanf(%opaque*, i8*, %opaque*) -; CHECK: declare i32 @vprintf(i8* nocapture readonly, %opaque*) [[G1]] +; CHECK: declare noundef i32 @vprintf(i8* nocapture noundef readonly, %opaque* noundef) [[G1]] declare i32 @vprintf(i8*, %opaque*) -; CHECK: declare i32 @vscanf(i8* nocapture readonly, %opaque*) [[G1]] +; CHECK: declare noundef i32 @vscanf(i8* nocapture noundef readonly, %opaque* noundef) [[G1]] declare i32 @vscanf(i8*, %opaque*) -; CHECK: declare i32 @vsnprintf(i8* nocapture, i64, i8* nocapture readonly, %opaque*) [[G1]] +; CHECK: declare noundef i32 @vsnprintf(i8* nocapture noundef, i64 noundef, i8* nocapture noundef readonly, %opaque* noundef) [[G1]] declare i32 @vsnprintf(i8*, i64, i8*, %opaque*) -; CHECK: declare i32 @vsprintf(i8* nocapture, i8* nocapture readonly, %opaque*) [[G1]] +; CHECK: declare noundef i32 @vsprintf(i8* nocapture noundef, i8* nocapture noundef readonly, %opaque* noundef) [[G1]] declare i32 @vsprintf(i8*, i8*, %opaque*) -; CHECK: declare i32 @vsscanf(i8* nocapture readonly, i8* nocapture readonly, %opaque*) [[G1]] +; CHECK: declare noundef i32 @vsscanf(i8* nocapture noundef readonly, i8* nocapture noundef readonly, %opaque* noundef) [[G1]] declare i32 @vsscanf(i8*, i8*, %opaque*) -; CHECK: declare i64 @write(i32, i8* nocapture readonly, i64) [[G0]] +; CHECK: declare noundef i64 @write(i32 noundef, i8* nocapture noundef readonly, i64 noundef) [[G0]] declare i64 @write(i32, i8*, i64) Index: llvm/test/CodeGen/X86/no-plt-libcalls.ll =================================================================== --- llvm/test/CodeGen/X86/no-plt-libcalls.ll +++ llvm/test/CodeGen/X86/no-plt-libcalls.ll @@ -17,7 +17,7 @@ } ; CHECK: Function Attrs: nofree nounwind nonlazybind -; CHECK-NEXT: declare i32 @puts(i8* nocapture readonly) +; CHECK-NEXT: declare noundef i32 @puts(i8* nocapture noundef readonly) !llvm.module.flags = !{!0} !0 = !{i32 7, !"RtLibUseGOT", i32 1} Index: llvm/lib/Transforms/Utils/BuildLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -37,6 +37,7 @@ STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture"); STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly"); STATISTIC(NumNoAlias, "Number of function returns inferred as noalias"); +STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns"); STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns"); STATISTIC(NumReturnedArg, "Number of arguments inferred as returned"); @@ -104,6 +105,24 @@ return true; } +static bool setRetAndArgsNoUndef(Function &F) { + bool Changed = false; + if (!F.getReturnType()->isVoidTy() && + !F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoUndef)) { + F.addAttribute(AttributeList::ReturnIndex, Attribute::NoUndef); + ++NumNoUndef; + Changed = true; + } + for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) { + if (!F.hasParamAttribute(ArgNo, Attribute::NoUndef)) { + F.addParamAttr(ArgNo, Attribute::NoUndef); + ++NumNoUndef; + Changed = true; + } + } + return Changed; +} + static bool setRetNonNull(Function &F) { assert(F.getReturnType()->isPointerTy() && "nonnull applies only to pointers"); @@ -227,6 +246,7 @@ Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_scanf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); @@ -251,6 +271,7 @@ Changed |= setOnlyReadsMemory(F, 0); return Changed; case LibFunc_sscanf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); @@ -258,6 +279,7 @@ Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_sprintf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotAlias(F, 0); @@ -265,6 +287,7 @@ Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_snprintf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotAlias(F, 0); @@ -347,9 +370,11 @@ return Changed; case LibFunc_read: // May throw; "read" is a valid pthread cancellation point. + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_rewind: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); return Changed; @@ -375,6 +400,7 @@ return Changed; case LibFunc_write: // May throw; "write" is a valid pthread cancellation point. + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); return Changed; @@ -428,6 +454,7 @@ Changed |= setOnlyReadsMemory(F, 0); return Changed; case LibFunc_fopen: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); Changed |= setDoesNotCapture(F, 0); @@ -436,13 +463,21 @@ Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_fdopen: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_feof: + Changed |= setRetAndArgsNoUndef(F); + Changed |= setDoesNotThrow(F); + Changed |= setDoesNotCapture(F, 0); + return Changed; case LibFunc_free: + Changed |= setDoesNotThrow(F); + Changed |= setDoesNotCapture(F, 0); + return Changed; case LibFunc_fseek: case LibFunc_ftell: case LibFunc_fgetc: @@ -456,10 +491,12 @@ case LibFunc_flockfile: case LibFunc_funlockfile: case LibFunc_ftrylockfile: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); return Changed; case LibFunc_ferror: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F); @@ -467,26 +504,37 @@ case LibFunc_fputc: case LibFunc_fputc_unlocked: case LibFunc_fstat: + Changed |= setRetAndArgsNoUndef(F); + Changed |= setDoesNotThrow(F); + Changed |= setDoesNotCapture(F, 1); + return Changed; case LibFunc_frexp: case LibFunc_frexpf: case LibFunc_frexpl: + Changed |= setDoesNotThrow(F); + Changed |= setDoesNotCapture(F, 1); + return Changed; case LibFunc_fstatvfs: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_fgets: case LibFunc_fgets_unlocked: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 2); return Changed; case LibFunc_fread: case LibFunc_fread_unlocked: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 3); return Changed; case LibFunc_fwrite: case LibFunc_fwrite_unlocked: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 3); @@ -494,6 +542,7 @@ return Changed; case LibFunc_fputs: case LibFunc_fputs_unlocked: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); @@ -501,19 +550,29 @@ return Changed; case LibFunc_fscanf: case LibFunc_fprintf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_fgetpos: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_getc: + Changed |= setRetAndArgsNoUndef(F); + Changed |= setDoesNotThrow(F); + Changed |= setDoesNotCapture(F, 0); + return Changed; case LibFunc_getlogin_r: + Changed |= setDoesNotThrow(F); + Changed |= setDoesNotCapture(F, 0); + return Changed; case LibFunc_getc_unlocked: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); return Changed; @@ -525,6 +584,7 @@ case LibFunc_gets: case LibFunc_getchar: case LibFunc_getchar_unlocked: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); return Changed; case LibFunc_getitimer: @@ -537,6 +597,7 @@ Changed |= setOnlyReadsMemory(F, 0); return Changed; case LibFunc_ungetc: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); return Changed; @@ -564,27 +625,32 @@ return Changed; case LibFunc_putc: case LibFunc_putc_unlocked: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_puts: case LibFunc_printf: case LibFunc_perror: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); return Changed; case LibFunc_pread: // May throw; "pread" is a valid pthread cancellation point. + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_pwrite: // May throw; "pwrite" is a valid pthread cancellation point. + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_putchar: case LibFunc_putchar_unlocked: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); return Changed; case LibFunc_popen: @@ -600,11 +666,13 @@ Changed |= setDoesNotCapture(F, 0); return Changed; case LibFunc_vscanf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); return Changed; case LibFunc_vsscanf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); @@ -612,6 +680,7 @@ Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_vfscanf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); @@ -622,18 +691,21 @@ Changed |= setRetDoesNotAlias(F); return Changed; case LibFunc_vprintf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); return Changed; case LibFunc_vfprintf: case LibFunc_vsprintf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_vsnprintf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 2); @@ -641,6 +713,7 @@ return Changed; case LibFunc_open: // May throw; "open" is a valid pthread cancellation point. + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); return Changed; @@ -693,14 +766,17 @@ Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_under_IO_getc: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); return Changed; case LibFunc_under_IO_putc: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_dunder_isoc99_scanf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); @@ -714,6 +790,7 @@ Changed |= setOnlyReadsMemory(F, 0); return Changed; case LibFunc_dunder_isoc99_sscanf: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); @@ -721,6 +798,7 @@ Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_fopen64: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); Changed |= setDoesNotCapture(F, 0); @@ -730,6 +808,7 @@ return Changed; case LibFunc_fseeko64: case LibFunc_ftello64: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); return Changed; @@ -739,11 +818,13 @@ return Changed; case LibFunc_fstat64: case LibFunc_fstatvfs64: + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_open64: // May throw; "open" is a valid pthread cancellation point. + Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); return Changed; Index: clang/test/CodeGen/PR3589-freestanding-libcalls.c =================================================================== --- clang/test/CodeGen/PR3589-freestanding-libcalls.c +++ clang/test/CodeGen/PR3589-freestanding-libcalls.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | grep 'declare i32 @printf' | count 1 -// RUN: %clang_cc1 -triple i386-unknown-unknown -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 1 -// RUN: %clang_cc1 -triple i386-unknown-unknown -ffreestanding -O2 -emit-llvm %s -o - | not grep 'declare i32 @puts' +// RUN: %clang_cc1 -triple i386-unknown-unknown -O2 -emit-llvm %s -o - | grep 'declare noundef i32 @puts' | count 1 +// RUN: %clang_cc1 -triple i386-unknown-unknown -ffreestanding -O2 -emit-llvm %s -o - | not grep 'declare noundef i32 @puts' int printf(const char *, ...);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits