diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.def b/llvm/include/llvm/Analysis/TargetLibraryInfo.def --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.def +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.def @@ -715,18 +715,12 @@ /// int fgetc(FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fgetc) TLI_DEFINE_STRING_INTERNAL("fgetc") -/// int fgetc_unlocked(FILE *stream); -TLI_DEFINE_ENUM_INTERNAL(fgetc_unlocked) -TLI_DEFINE_STRING_INTERNAL("fgetc_unlocked") /// int fgetpos(FILE *stream, fpos_t *pos); TLI_DEFINE_ENUM_INTERNAL(fgetpos) TLI_DEFINE_STRING_INTERNAL("fgetpos") /// char *fgets(char *s, int n, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fgets) TLI_DEFINE_STRING_INTERNAL("fgets") -/// char *fgets_unlocked(char *s, int n, FILE *stream); -TLI_DEFINE_ENUM_INTERNAL(fgets_unlocked) -TLI_DEFINE_STRING_INTERNAL("fgets_unlocked") /// int fileno(FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fileno) TLI_DEFINE_STRING_INTERNAL("fileno") @@ -796,21 +790,12 @@ /// int fputc(int c, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fputc) TLI_DEFINE_STRING_INTERNAL("fputc") -/// int fputc_unlocked(int c, FILE *stream); -TLI_DEFINE_ENUM_INTERNAL(fputc_unlocked) -TLI_DEFINE_STRING_INTERNAL("fputc_unlocked") /// int fputs(const char *s, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fputs) TLI_DEFINE_STRING_INTERNAL("fputs") -/// int fputs_unlocked(const char *s, FILE *stream); -TLI_DEFINE_ENUM_INTERNAL(fputs_unlocked) -TLI_DEFINE_STRING_INTERNAL("fputs_unlocked") /// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fread) TLI_DEFINE_STRING_INTERNAL("fread") -/// size_t fread_unlocked(void *ptr, size_t size, size_t nitems, FILE *stream); -TLI_DEFINE_ENUM_INTERNAL(fread_unlocked) -TLI_DEFINE_STRING_INTERNAL("fread_unlocked") /// void free(void *ptr); TLI_DEFINE_ENUM_INTERNAL(free) TLI_DEFINE_STRING_INTERNAL("free") @@ -868,21 +853,12 @@ /// size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fwrite) TLI_DEFINE_STRING_INTERNAL("fwrite") -/// size_t fwrite_unlocked(const void *ptr, size_t size, size_t nitems, FILE *stream); -TLI_DEFINE_ENUM_INTERNAL(fwrite_unlocked) -TLI_DEFINE_STRING_INTERNAL("fwrite_unlocked") /// int getc(FILE *stream); TLI_DEFINE_ENUM_INTERNAL(getc) TLI_DEFINE_STRING_INTERNAL("getc") -/// int getc_unlocked(FILE *stream); -TLI_DEFINE_ENUM_INTERNAL(getc_unlocked) -TLI_DEFINE_STRING_INTERNAL("getc_unlocked") /// int getchar(void); TLI_DEFINE_ENUM_INTERNAL(getchar) TLI_DEFINE_STRING_INTERNAL("getchar") -/// int getchar_unlocked(void); -TLI_DEFINE_ENUM_INTERNAL(getchar_unlocked) -TLI_DEFINE_STRING_INTERNAL("getchar_unlocked") /// char *getenv(const char *name); TLI_DEFINE_ENUM_INTERNAL(getenv) TLI_DEFINE_STRING_INTERNAL("getenv") @@ -1088,15 +1064,9 @@ /// int putc(int c, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(putc) TLI_DEFINE_STRING_INTERNAL("putc") -/// int putc_unlocked(int c, FILE *stream); -TLI_DEFINE_ENUM_INTERNAL(putc_unlocked) -TLI_DEFINE_STRING_INTERNAL("putc_unlocked") /// int putchar(int c); TLI_DEFINE_ENUM_INTERNAL(putchar) TLI_DEFINE_STRING_INTERNAL("putchar") -/// int putchar_unlocked(int c); -TLI_DEFINE_ENUM_INTERNAL(putchar_unlocked) -TLI_DEFINE_STRING_INTERNAL("putchar_unlocked") /// int puts(const char *s); TLI_DEFINE_ENUM_INTERNAL(puts) TLI_DEFINE_STRING_INTERNAL("puts") diff --git a/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h b/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h --- a/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h +++ b/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -187,21 +187,11 @@ Value *emitFPutC(Value *Char, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI); - /// Emit a call to the fputc_unlocked function. This assumes that Char is an - /// i32, and File is a pointer to FILE. - Value *emitFPutCUnlocked(Value *Char, Value *File, IRBuilderBase &B, - const TargetLibraryInfo *TLI); - /// Emit a call to the fputs function. Str is required to be a pointer and /// File is a pointer to FILE. Value *emitFPutS(Value *Str, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI); - /// Emit a call to the fputs_unlocked function. Str is required to be a - /// pointer and File is a pointer to FILE. - Value *emitFPutSUnlocked(Value *Str, Value *File, IRBuilderBase &B, - const TargetLibraryInfo *TLI); - /// Emit a call to the fwrite function. This assumes that Ptr is a pointer, /// Size is an 'intptr_t', and File is a pointer to FILE. Value *emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B, @@ -214,27 +204,6 @@ /// Emit a call to the calloc function. Value *emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs, IRBuilderBase &B, const TargetLibraryInfo &TLI); - - /// Emit a call to the fwrite_unlocked function. This assumes that Ptr is a - /// pointer, Size is an 'intptr_t', N is nmemb and File is a pointer to FILE. - Value *emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File, - IRBuilderBase &B, const DataLayout &DL, - const TargetLibraryInfo *TLI); - - /// Emit a call to the fgetc_unlocked function. File is a pointer to FILE. - Value *emitFGetCUnlocked(Value *File, IRBuilderBase &B, - const TargetLibraryInfo *TLI); - - /// Emit a call to the fgets_unlocked function. Str is required to be a - /// pointer, Size is an i32 and File is a pointer to FILE. - Value *emitFGetSUnlocked(Value *Str, Value *Size, Value *File, - IRBuilderBase &B, const TargetLibraryInfo *TLI); - - /// Emit a call to the fread_unlocked function. This assumes that Ptr is a - /// pointer, Size is an 'intptr_t', N is nmemb and File is a pointer to FILE. - Value *emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File, - IRBuilderBase &B, const DataLayout &DL, - const TargetLibraryInfo *TLI); } #endif diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -75,18 +75,6 @@ }) && "TargetLibraryInfoImpl function names must be sorted"); - // Set IO unlocked variants as unavailable - // Set them as available per system below - TLI.setUnavailable(LibFunc_getchar_unlocked); - TLI.setUnavailable(LibFunc_putc_unlocked); - TLI.setUnavailable(LibFunc_putchar_unlocked); - TLI.setUnavailable(LibFunc_fputc_unlocked); - TLI.setUnavailable(LibFunc_fgetc_unlocked); - TLI.setUnavailable(LibFunc_fread_unlocked); - TLI.setUnavailable(LibFunc_fwrite_unlocked); - TLI.setUnavailable(LibFunc_fputs_unlocked); - TLI.setUnavailable(LibFunc_fgets_unlocked); - bool ShouldExtI32Param = false, ShouldExtI32Return = false, ShouldSignExtI32Param = false; // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and @@ -122,12 +110,6 @@ // memset_pattern16 is only available on iOS 3.0 and Mac OS X 10.5 and later. // All versions of watchOS support it. if (T.isMacOSX()) { - // available IO unlocked variants on Mac OS X - TLI.setAvailable(LibFunc_getc_unlocked); - TLI.setAvailable(LibFunc_getchar_unlocked); - TLI.setAvailable(LibFunc_putc_unlocked); - TLI.setAvailable(LibFunc_putchar_unlocked); - if (T.isMacOSXVersionLT(10, 5)) TLI.setUnavailable(LibFunc_memset_pattern16); } else if (T.isiOS()) { @@ -519,21 +501,6 @@ TLI.setUnavailable(LibFunc_sinhl_finite); } - if ((T.isOSLinux() && T.isGNUEnvironment()) || - (T.isAndroid() && !T.isAndroidVersionLT(28))) { - // available IO unlocked variants on GNU/Linux and Android P or later - TLI.setAvailable(LibFunc_getc_unlocked); - TLI.setAvailable(LibFunc_getchar_unlocked); - TLI.setAvailable(LibFunc_putc_unlocked); - TLI.setAvailable(LibFunc_putchar_unlocked); - TLI.setAvailable(LibFunc_fputc_unlocked); - TLI.setAvailable(LibFunc_fgetc_unlocked); - TLI.setAvailable(LibFunc_fread_unlocked); - TLI.setAvailable(LibFunc_fwrite_unlocked); - TLI.setAvailable(LibFunc_fputs_unlocked); - TLI.setAvailable(LibFunc_fgets_unlocked); - } - // As currently implemented in clang, NVPTX code has no standard library to // speak of. Headers provide a standard-ish library implementation, but many // of the signatures are wrong -- for example, many libm functions are not @@ -941,7 +908,6 @@ case LibFunc_feof: case LibFunc_fflush: case LibFunc_fgetc: - case LibFunc_fgetc_unlocked: case LibFunc_fileno: case LibFunc_flockfile: case LibFunc_free: @@ -955,7 +921,6 @@ case LibFunc_ftrylockfile: case LibFunc_funlockfile: case LibFunc_getc: - case LibFunc_getc_unlocked: case LibFunc_getlogin_r: case LibFunc_mkdir: case LibFunc_mktime: @@ -972,7 +937,6 @@ return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && FTy.getParamType(1)->isPointerTy()); case LibFunc_fputc: - case LibFunc_fputc_unlocked: case LibFunc_fstat: case LibFunc_frexp: case LibFunc_frexpf: @@ -980,22 +944,18 @@ case LibFunc_fstatvfs: return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); case LibFunc_fgets: - case LibFunc_fgets_unlocked: return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(2)->isPointerTy()); case LibFunc_fread: - case LibFunc_fread_unlocked: return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(3)->isPointerTy()); case LibFunc_fwrite: - case LibFunc_fwrite_unlocked: return (NumParams == 4 && FTy.getReturnType()->isIntegerTy() && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isIntegerTy() && FTy.getParamType(2)->isIntegerTy() && FTy.getParamType(3)->isPointerTy()); case LibFunc_fputs: - case LibFunc_fputs_unlocked: return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isPointerTy()); case LibFunc_fscanf: @@ -1009,7 +969,6 @@ return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isPointerTy()); case LibFunc_getchar: - case LibFunc_getchar_unlocked: return (NumParams == 0 && FTy.getReturnType()->isIntegerTy()); case LibFunc_gets: return (NumParams == 1 && FTy.getParamType(0) == PCharTy); @@ -1022,7 +981,6 @@ return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isPointerTy()); case LibFunc_putc: - case LibFunc_putc_unlocked: return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); case LibFunc_pread: case LibFunc_pwrite: @@ -1420,7 +1378,6 @@ case LibFunc_isascii: case LibFunc_toascii: case LibFunc_putchar: - case LibFunc_putchar_unlocked: return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && FTy.getReturnType() == FTy.getParamType(0)); diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp --- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -442,7 +442,6 @@ case LibFunc_fseek: case LibFunc_ftell: case LibFunc_fgetc: - case LibFunc_fgetc_unlocked: case LibFunc_fseeko: case LibFunc_ftello: case LibFunc_fileno: @@ -461,7 +460,6 @@ Changed |= setOnlyReadsMemory(F); return Changed; case LibFunc_fputc: - case LibFunc_fputc_unlocked: case LibFunc_fstat: case LibFunc_frexp: case LibFunc_frexpf: @@ -471,25 +469,21 @@ Changed |= setDoesNotCapture(F, 1); return Changed; case LibFunc_fgets: - case LibFunc_fgets_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 2); return Changed; case LibFunc_fread: - case LibFunc_fread_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 3); return Changed; case LibFunc_fwrite: - case LibFunc_fwrite_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 3); // FIXME: readonly #1? return Changed; case LibFunc_fputs: - case LibFunc_fputs_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); @@ -509,7 +503,6 @@ return Changed; case LibFunc_getc: case LibFunc_getlogin_r: - case LibFunc_getc_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); return Changed; @@ -520,7 +513,6 @@ return Changed; case LibFunc_gets: case LibFunc_getchar: - case LibFunc_getchar_unlocked: Changed |= setDoesNotThrow(F); return Changed; case LibFunc_getitimer: @@ -559,7 +551,6 @@ Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_putc: - case LibFunc_putc_unlocked: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); return Changed; @@ -580,7 +571,6 @@ Changed |= setOnlyReadsMemory(F, 1); return Changed; case LibFunc_putchar: - case LibFunc_putchar_unlocked: Changed |= setDoesNotThrow(F); return Changed; case LibFunc_popen: @@ -1188,26 +1178,6 @@ return CI; } -Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_fputc_unlocked)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked); - FunctionCallee F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(), - B.getInt32Ty(), File->getType()); - if (File->getType()->isPointerTy()) - inferLibFuncAttributes(M, FPutcUnlockedName, *TLI); - Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari"); - CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName); - - if (const Function *Fn = - dyn_cast(F.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); - return CI; -} - Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilderBase &B, const TargetLibraryInfo *TLI) { if (!TLI->has(LibFunc_fputs)) @@ -1227,25 +1197,6 @@ return CI; } -Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_fputs_unlocked)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked); - FunctionCallee F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(), - B.getInt8PtrTy(), File->getType()); - if (File->getType()->isPointerTy()) - inferLibFuncAttributes(M, FPutsUnlockedName, *TLI); - CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName); - - if (const Function *Fn = - dyn_cast(F.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); - return CI; -} - Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI) { if (!TLI->has(LibFunc_fwrite)) @@ -1310,88 +1261,3 @@ return CI; } - -Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File, - IRBuilderBase &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_fwrite_unlocked)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - LLVMContext &Context = B.GetInsertBlock()->getContext(); - StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked); - FunctionCallee F = M->getOrInsertFunction( - FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(), - DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); - - if (File->getType()->isPointerTy()) - inferLibFuncAttributes(M, FWriteUnlockedName, *TLI); - CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File}); - - if (const Function *Fn = - dyn_cast(F.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); - return CI; -} - -Value *llvm::emitFGetCUnlocked(Value *File, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_fgetc_unlocked)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked); - FunctionCallee F = M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(), - File->getType()); - if (File->getType()->isPointerTy()) - inferLibFuncAttributes(M, FGetCUnlockedName, *TLI); - CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName); - - if (const Function *Fn = - dyn_cast(F.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); - return CI; -} - -Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File, - IRBuilderBase &B, const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_fgets_unlocked)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked); - FunctionCallee F = - M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(), - B.getInt8PtrTy(), B.getInt32Ty(), File->getType()); - inferLibFuncAttributes(M, FGetSUnlockedName, *TLI); - CallInst *CI = - B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName); - - if (const Function *Fn = - dyn_cast(F.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); - return CI; -} - -Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File, - IRBuilderBase &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { - if (!TLI->has(LibFunc_fread_unlocked)) - return nullptr; - - Module *M = B.GetInsertBlock()->getModule(); - LLVMContext &Context = B.GetInsertBlock()->getContext(); - StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked); - FunctionCallee F = M->getOrInsertFunction( - FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(), - DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); - - if (File->getType()->isPointerTy()) - inferLibFuncAttributes(M, FReadUnlockedName, *TLI); - CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File}); - - if (const Function *Fn = - dyn_cast(F.getCallee()->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); - return CI; -} diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -138,28 +138,6 @@ return ConstantInt::get(CI->getType(), Result); } -static bool isLocallyOpenedFile(Value *File, CallInst *CI, - const TargetLibraryInfo *TLI) { - CallInst *FOpen = dyn_cast(File); - if (!FOpen) - return false; - - Function *InnerCallee = FOpen->getCalledFunction(); - if (!InnerCallee) - return false; - - LibFunc Func; - if (!TLI->getLibFunc(*InnerCallee, Func) || !TLI->has(Func) || - Func != LibFunc_fopen) - return false; - - inferLibFuncAttributes(*CI->getCalledFunction(), *TLI); - if (PointerMayBeCaptured(File, true, true)) - return false; - - return true; -} - static bool isOnlyUsedInComparisonWithZero(Value *V) { for (User *U : V->users()) { if (ICmpInst *IC = dyn_cast(U)) @@ -2754,11 +2732,6 @@ } } - if (isLocallyOpenedFile(CI->getArgOperand(3), CI, TLI)) - return emitFWriteUnlocked(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), CI->getArgOperand(3), B, DL, - TLI); - return nullptr; } @@ -2773,15 +2746,9 @@ if (OptForSize) return nullptr; - // Check if has any use - if (!CI->use_empty()) { - if (isLocallyOpenedFile(CI->getArgOperand(1), CI, TLI)) - return emitFPutSUnlocked(CI->getArgOperand(0), CI->getArgOperand(1), B, - TLI); - else - // We can't optimize if return value is used. - return nullptr; - } + // We can't optimize if return value is used. + if (!CI->use_empty()) + return nullptr; // fputs(s,F) --> fwrite(s,strlen(s),1,F) uint64_t Len = GetStringLength(CI->getArgOperand(0)); @@ -2795,40 +2762,6 @@ CI->getArgOperand(1), B, DL, TLI); } -Value *LibCallSimplifier::optimizeFPutc(CallInst *CI, IRBuilderBase &B) { - optimizeErrorReporting(CI, B, 1); - - if (isLocallyOpenedFile(CI->getArgOperand(1), CI, TLI)) - return emitFPutCUnlocked(CI->getArgOperand(0), CI->getArgOperand(1), B, - TLI); - - return nullptr; -} - -Value *LibCallSimplifier::optimizeFGetc(CallInst *CI, IRBuilderBase &B) { - if (isLocallyOpenedFile(CI->getArgOperand(0), CI, TLI)) - return emitFGetCUnlocked(CI->getArgOperand(0), B, TLI); - - return nullptr; -} - -Value *LibCallSimplifier::optimizeFGets(CallInst *CI, IRBuilderBase &B) { - if (isLocallyOpenedFile(CI->getArgOperand(2), CI, TLI)) - return emitFGetSUnlocked(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), B, TLI); - - return nullptr; -} - -Value *LibCallSimplifier::optimizeFRead(CallInst *CI, IRBuilderBase &B) { - if (isLocallyOpenedFile(CI->getArgOperand(3), CI, TLI)) - return emitFReadUnlocked(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), CI->getArgOperand(3), B, DL, - TLI); - - return nullptr; -} - Value *LibCallSimplifier::optimizePuts(CallInst *CI, IRBuilderBase &B) { annotateNonNullBasedOnAccess(CI, 0); if (!CI->use_empty()) @@ -3162,16 +3095,8 @@ return optimizeFPrintF(CI, Builder); case LibFunc_fwrite: return optimizeFWrite(CI, Builder); - case LibFunc_fread: - return optimizeFRead(CI, Builder); case LibFunc_fputs: return optimizeFPuts(CI, Builder); - case LibFunc_fgets: - return optimizeFGets(CI, Builder); - case LibFunc_fputc: - return optimizeFPutc(CI, Builder); - case LibFunc_fgetc: - return optimizeFGetc(CI, Builder); case LibFunc_puts: return optimizePuts(CI, Builder); case LibFunc_perror: diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll --- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll +++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll @@ -511,13 +511,13 @@ ; CHECK: declare i32 @getc(%opaque* nocapture) [[G1]] declare i32 @getc(%opaque*) -; CHECK: declare i32 @getc_unlocked(%opaque* nocapture) [[G1]] +; CHECK: declare i32 @getc_unlocked(%opaque*){{$}} declare i32 @getc_unlocked(%opaque*) ; CHECK: declare i32 @getchar() [[G1]] declare i32 @getchar() -; CHECK: declare i32 @getchar_unlocked() [[G1]] +; CHECK: declare i32 @getchar_unlocked(){{$}} declare i32 @getchar_unlocked() ; CHECK: declare i8* @getenv(i8* nocapture) [[G2]] @@ -706,7 +706,7 @@ ; CHECK: declare i32 @putchar(i32) [[G1]] declare i32 @putchar(i32) -; CHECK: declare i32 @putchar_unlocked(i32) [[G1]] +; CHECK: declare i32 @putchar_unlocked(i32){{$}} declare i32 @putchar_unlocked(i32) ; CHECK: declare i32 @puts(i8* nocapture readonly) [[G1]] diff --git a/llvm/test/Transforms/InstCombine/unlocked-stdio.ll b/llvm/test/Transforms/InstCombine/unlocked-stdio.ll deleted file mode 100644 --- a/llvm/test/Transforms/InstCombine/unlocked-stdio.ll +++ /dev/null @@ -1,224 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -instcombine -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s - -%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] } -%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 } - -@.str = private unnamed_addr constant [5 x i8] c"file\00", align 1 -@.str.1 = private unnamed_addr constant [2 x i8] c"w\00", align 1 -@.str.2 = private unnamed_addr constant [4 x i8] c"str\00", align 1 -@stdout = external global %struct._IO_FILE*, align 8 -@global_file = common global %struct._IO_FILE* null, align 8 - -define void @external_fgetc_test(%struct._IO_FILE* %f) { -; CHECK-LABEL: @external_fgetc_test( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @fgetc(%struct._IO_FILE* [[F:%.*]]) -; CHECK-NEXT: ret void -; - %call = call i32 @fgetc(%struct._IO_FILE* %f) - ret void -} - -declare i32 @fgetc(%struct._IO_FILE* nocapture) #0 - -define void @external_fgetc_test2() { -; CHECK-LABEL: @external_fgetc_test2( -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[FPUTC_UNLOCKED:%.*]] = call i32 @fputc_unlocked(i32 99, %struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) - %call1 = call i32 @fputc(i32 99, %struct._IO_FILE* %call) - ret void -} - -declare %struct._IO_FILE* @fopen(i8*, i8*) -declare i32 @fputc(i32, %struct._IO_FILE* nocapture) #0 - -define internal void @fgetc_test() { -; CHECK-LABEL: @fgetc_test( -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[FGETC_UNLOCKED:%.*]] = call i32 @fgetc_unlocked(%struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) - %call1 = call i32 @fgetc(%struct._IO_FILE* %call) - ret void -} - -define void @external_fgetc_internal_test() { -; CHECK-LABEL: @external_fgetc_internal_test( -; CHECK-NEXT: call void @fgetc_test() -; CHECK-NEXT: ret void -; - call void @fgetc_test() - ret void -} - -define internal void @fwrite_test() { -; CHECK-LABEL: @fwrite_test( -; CHECK-NEXT: [[S:%.*]] = alloca [10 x i8], align 1 -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* [[S]], i64 0, i64 0 -; CHECK-NEXT: [[TMP1:%.*]] = call i64 @fwrite_unlocked(i8* nonnull [[ARRAYDECAY]], i64 10, i64 10, %struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %s = alloca [10 x i8], align 1 - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) - %arraydecay = getelementptr inbounds [10 x i8], [10 x i8]* %s, i64 0, i64 0 - %call1 = call i64 @fwrite(i8* nonnull %arraydecay, i64 10, i64 10, %struct._IO_FILE* %call) - ret void -} - -define internal void @fread_test() { -; CHECK-LABEL: @fread_test( -; CHECK-NEXT: [[S:%.*]] = alloca [10 x i8], align 1 -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* [[S]], i64 0, i64 0 -; CHECK-NEXT: [[TMP1:%.*]] = call i64 @fread_unlocked(i8* nonnull [[ARRAYDECAY]], i64 10, i64 10, %struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %s = alloca [10 x i8], align 1 - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) - %arraydecay = getelementptr inbounds [10 x i8], [10 x i8]* %s, i64 0, i64 0 - %call1 = call i64 @fread(i8* nonnull %arraydecay, i64 10, i64 10, %struct._IO_FILE* %call) - ret void -} - -define internal void @fputs_test() { -; CHECK-LABEL: @fputs_test( -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[TMP1:%.*]] = call i64 @fwrite_unlocked(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i64 3, i64 1, %struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) - %call1 = call i32 @fputs(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), %struct._IO_FILE* %call) - ret void -} - -define internal void @fgets_test() { -; CHECK-LABEL: @fgets_test( -; CHECK-NEXT: [[BUF:%.*]] = alloca [10 x i8], align 1 -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* [[BUF]], i64 0, i64 0 -; CHECK-NEXT: [[FGETS_UNLOCKED:%.*]] = call i8* @fgets_unlocked(i8* nonnull [[ARRAYDECAY]], i32 10, %struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %buf = alloca [10 x i8], align 1 - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) - %arraydecay = getelementptr inbounds [10 x i8], [10 x i8]* %buf, i64 0, i64 0 - %call1 = call i8* @fgets(i8* nonnull %arraydecay, i32 10, %struct._IO_FILE* %call) - ret void -} - -define internal void @fputc_test() { -; CHECK-LABEL: @fputc_test( -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[FPUTC_UNLOCKED:%.*]] = call i32 @fputc_unlocked(i32 99, %struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) - %call1 = call i32 @fputc(i32 99, %struct._IO_FILE* %call) - ret void -} - -define i32 @main() { -; CHECK-LABEL: @main( -; CHECK-NEXT: call void @fwrite_test() -; CHECK-NEXT: call void @fread_test() -; CHECK-NEXT: call void @fputs_test() -; CHECK-NEXT: call void @fgets_test() -; CHECK-NEXT: call void @fputc_test() -; CHECK-NEXT: call void @fgetc_test() -; CHECK-NEXT: ret i32 0 -; - call void @fwrite_test() - call void @fread_test() - call void @fputs_test() - call void @fgets_test() - call void @fputc_test() - call void @fgetc_test() - ret i32 0 -} - -declare i32 @fclose(%struct._IO_FILE* nocapture) - -define void @test_with_fclose() { -; CHECK-LABEL: @test_with_fclose( -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[TMP1:%.*]] = call i64 @fwrite_unlocked(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i64 3, i64 1, %struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: [[CALL2:%.*]] = call i32 @fclose(%struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) #2 - %call1 = call i64 @fwrite(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i64 3, i64 1, %struct._IO_FILE* %call) - %call2 = call i32 @fclose(%struct._IO_FILE* %call) #2 - ret void -} - -declare void @modify_file(%struct._IO_FILE*) - -define void @test_captured_by_function(){ -; CHECK-LABEL: @test_captured_by_function( -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: call void @modify_file(%struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: [[CALL1:%.*]] = call i64 @fwrite(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i64 3, i64 1, %struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: [[CALL2:%.*]] = call i32 @fclose(%struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) #2 - call void @modify_file(%struct._IO_FILE* %call) #2 - %call1 = call i64 @fwrite(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i64 3, i64 1, %struct._IO_FILE* %call) - %call2 = call i32 @fclose(%struct._IO_FILE* %call) #2 - ret void -} - -define void @test_captured_by_global_value() { -; CHECK-LABEL: @test_captured_by_global_value( -; CHECK-NEXT: [[CALL:%.*]] = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[DOTCAST:%.*]] = ptrtoint %struct._IO_FILE* [[CALL]] to i64 -; CHECK-NEXT: store i64 [[DOTCAST]], i64* bitcast (%struct._IO_FILE** @global_file to i64*), align 8 -; CHECK-NEXT: [[CALL1:%.*]] = call i64 @fwrite(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i64 3, i64 1, %struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: [[CALL2:%.*]] = call i32 @fclose(%struct._IO_FILE* [[CALL]]) -; CHECK-NEXT: ret void -; - %call = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) #2 - %.cast = ptrtoint %struct._IO_FILE* %call to i64 - store i64 %.cast, i64* bitcast (%struct._IO_FILE** @global_file to i64*), align 8 - %call1 = call i64 @fwrite(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i64 3, i64 1, %struct._IO_FILE* %call) - %call2 = call i32 @fclose(%struct._IO_FILE* %call) #2 - ret void -} - -define void @test_captured_by_standard_stream(i8* nocapture readonly %s) { -; CHECK-LABEL: @test_captured_by_standard_stream( -; CHECK-NEXT: [[CALL:%.*]] = tail call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[TMP:%.*]] = load %struct._IO_FILE*, %struct._IO_FILE** @stdout, align 8 -; CHECK-NEXT: [[CALL1:%.*]] = tail call i32 @fputs(i8* [[S:%.*]], %struct._IO_FILE* [[TMP]]) -; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @fclose(%struct._IO_FILE* [[TMP]]) -; CHECK-NEXT: ret void -; - %call = tail call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) - %tmp = load %struct._IO_FILE*, %struct._IO_FILE** @stdout, align 8 - %call1 = tail call i32 @fputs(i8* %s, %struct._IO_FILE* %tmp) - %call2 = tail call i32 @fclose(%struct._IO_FILE* %tmp) - ret void -} - -define void @test_captured_by_arg(i8* nocapture readonly %s, %struct._IO_FILE* nocapture %file) { -; CHECK-LABEL: @test_captured_by_arg( -; CHECK-NEXT: [[CALL:%.*]] = tail call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) -; CHECK-NEXT: [[CALL1:%.*]] = tail call i32 @fputs(i8* [[S:%.*]], %struct._IO_FILE* [[FILE:%.*]]) -; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @fclose(%struct._IO_FILE* [[FILE]]) -; CHECK-NEXT: ret void -; - %call = tail call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0)) - %call1 = tail call i32 @fputs(i8* %s, %struct._IO_FILE* %file) - %call2 = tail call i32 @fclose(%struct._IO_FILE* %file) - ret void -} - -declare i64 @fwrite(i8* nocapture, i64, i64, %struct._IO_FILE* nocapture) -declare i64 @fread(i8* nocapture, i64, i64, %struct._IO_FILE* nocapture) -declare i32 @fputs(i8* nocapture readonly, %struct._IO_FILE* nocapture) -declare i8* @fgets(i8*, i32, %struct._IO_FILE* nocapture)