diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp --- a/llvm/lib/Analysis/MemoryBuiltins.cpp +++ b/llvm/lib/Analysis/MemoryBuiltins.cpp @@ -36,6 +36,7 @@ #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" @@ -99,6 +100,21 @@ llvm_unreachable("missing an alloc family"); } +AllocFnKind allocKindFromAllocType(AllocType AT) { + AllocFnKind K = AllocFnKind::Unknown; + if (AT & OpNewLike) + K |= AllocFnKind::New | AllocFnKind::Uninitialized; + if (AT & MallocLike) + K |= AllocFnKind::New | AllocFnKind::Uninitialized; + if (AT & CallocLike) + K |= AllocFnKind::New | AllocFnKind::Zeroed; + if (AT & AlignedAllocLike) + K |= AllocFnKind::New | AllocFnKind::Aligned | AllocFnKind::Uninitialized; + if (AT & ReallocLike) + K |= AllocFnKind::Resize; + return K; +} + struct AllocFnsTy { AllocType AllocTy; unsigned NumParams; @@ -114,9 +130,7 @@ // FIXME: certain users need more information. E.g., SimplifyLibCalls needs to // know which functions are nounwind, noalias, nocapture parameters, etc. static const std::pair AllocationFnData[] = { - {LibFunc_malloc, {MallocLike, 1, 0, -1, -1, MallocFamily::Malloc}}, {LibFunc_vec_malloc, {MallocLike, 1, 0, -1, -1, MallocFamily::VecMalloc}}, - {LibFunc_valloc, {MallocLike, 1, 0, -1, -1, MallocFamily::Malloc}}, {LibFunc_Znwj, {OpNewLike, 1, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned int) {LibFunc_ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1, MallocFamily::CPPNew}}, // new(unsigned int, nothrow) {LibFunc_ZnwjSt11align_val_t, {OpNewLike, 2, 0, -1, 1, MallocFamily::CPPNewAligned}}, // new(unsigned int, align_val_t) @@ -141,13 +155,9 @@ {LibFunc_msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned int, nothrow) {LibFunc_msvc_new_array_longlong, {OpNewLike, 1, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned long long) {LibFunc_msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1, -1, MallocFamily::MSVCArrayNew}}, // new[](unsigned long long, nothrow) - {LibFunc_aligned_alloc, {AlignedAllocLike, 2, 1, -1, 0, MallocFamily::Malloc}}, {LibFunc_memalign, {AlignedAllocLike, 2, 1, -1, 0, MallocFamily::Malloc}}, - {LibFunc_calloc, {CallocLike, 2, 0, 1, -1, MallocFamily::Malloc}}, {LibFunc_vec_calloc, {CallocLike, 2, 0, 1, -1, MallocFamily::VecMalloc}}, - {LibFunc_realloc, {ReallocLike, 2, 1, -1, -1, MallocFamily::Malloc}}, {LibFunc_vec_realloc, {ReallocLike, 2, 1, -1, -1, MallocFamily::VecMalloc}}, - {LibFunc_reallocf, {ReallocLike, 2, 1, -1, -1, MallocFamily::Malloc}}, {LibFunc_strdup, {StrDupLike, 1, -1, -1, -1, MallocFamily::Malloc}}, {LibFunc_dunder_strdup, {StrDupLike, 1, -1, -1, -1, MallocFamily::Malloc}}, {LibFunc_strndup, {StrDupLike, 2, 1, -1, -1, MallocFamily::Malloc}}, @@ -266,34 +276,56 @@ return Result; } +static bool checkFnAllocKind(const Value *V, llvm::AllocFnKind Wanted) { + const auto *CB = dyn_cast(V); + const Function *F = dyn_cast(V); + if (CB) { + F = CB->getCalledFunction(); + if (!F) + return false; + if (CB->hasFnAttr(Attribute::AllocKind)) { + return (AllocFnKind(CB->getFnAttr(Attribute::AllocKind).getValueAsInt()) & + Wanted) == Wanted; + } + } + if (!F) + return false; + assert(F && "Function has to be non-null by the time we get here!"); + if (F->hasFnAttribute(Attribute::AllocKind)) + return (AllocFnKind( + F->getFnAttribute(Attribute::AllocKind).getValueAsInt()) & + Wanted) == Wanted; + return false; +} + +static Optional getAllocationFamilyAttribute(const Value *V) { + const auto *CB = dyn_cast(V); + const Function *F = dyn_cast(V); + if (CB) { + F = CB->getCalledFunction(); + if (!F) + return None; + if (CB->getAttributes().hasFnAttr("alloc-family")) { + return CB->getFnAttr("alloc-family").getValueAsString(); + } + } + if (!F || !F->getAttributes().hasFnAttr("alloc-family")) + return None; + return F->getAttributes().getFnAttr("alloc-family").getValueAsString(); +} /// Tests if a value is a call or invoke to a library function that /// allocates or reallocates memory (either malloc, calloc, realloc, or strdup /// like). bool llvm::isAllocationFn(const Value *V, const TargetLibraryInfo *TLI) { - return getAllocationData(V, AnyAlloc, TLI).hasValue(); + return getAllocationData(V, AnyAlloc, TLI).hasValue() || + checkFnAllocKind(V, AllocFnKind::New) || + checkFnAllocKind(V, AllocFnKind::Resize); } bool llvm::isAllocationFn( const Value *V, function_ref GetTLI) { - return getAllocationData(V, AnyAlloc, GetTLI).hasValue(); -} - -/// Tests if a value is a call or invoke to a library function that -/// allocates uninitialized memory (such as malloc). -static bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI) { - return getAllocationData(V, MallocOrOpNewLike, TLI).hasValue(); -} - -/// Tests if a value is a call or invoke to a library function that -/// allocates uninitialized memory with alignment (such as aligned_alloc). -static bool isAlignedAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI) { - return getAllocationData(V, AlignedAllocLike, TLI) - .hasValue(); -} - -/// Tests if a value is a call or invoke to a library function that -/// allocates zero-filled memory (such as calloc). -static bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI) { - return getAllocationData(V, CallocLike, TLI).hasValue(); + return getAllocationData(V, AnyAlloc, GetTLI).hasValue() || + checkFnAllocKind(V, AllocFnKind::New) || + checkFnAllocKind(V, AllocFnKind::Resize); } /// Tests if a value is a call or invoke to a library function that @@ -305,19 +337,22 @@ /// Tests if a value is a call or invoke to a library function that /// allocates memory (either malloc, calloc, or strdup like). bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI) { - return getAllocationData(V, AllocLike, TLI).hasValue(); + return getAllocationData(V, AllocLike, TLI).hasValue() || + checkFnAllocKind(V, AllocFnKind::New); } /// Tests if a value is a call or invoke to a library function that /// reallocates memory (e.g., realloc). bool llvm::isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI) { - return getAllocationData(V, ReallocLike, TLI).hasValue(); + return getAllocationData(V, ReallocLike, TLI).hasValue() || + checkFnAllocKind(V, AllocFnKind::Resize); } /// Tests if a functions is a call or invoke to a library function that /// reallocates memory (e.g., realloc). bool llvm::isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI) { - return getAllocationDataForFunction(F, ReallocLike, TLI).hasValue(); + return getAllocationDataForFunction(F, ReallocLike, TLI).hasValue() || + checkFnAllocKind(F, AllocFnKind::Resize); } bool llvm::isAllocRemovable(const CallBase *CB, const TargetLibraryInfo *TLI) { @@ -424,15 +459,11 @@ const TargetLibraryInfo *TLI, Type *Ty) { assert(isAllocationFn(Alloc, TLI)); - - // malloc and aligned_alloc are uninitialized (undef) - if (isMallocLikeFn(Alloc, TLI) || isAlignedAllocLikeFn(Alloc, TLI)) + AllocFnKind AK = getAllocKind(Alloc, TLI); + if ((AK & AllocFnKind::Uninitialized) != AllocFnKind::Unknown) return UndefValue::get(Ty); - - // calloc zero initializes - if (isCallocLikeFn(Alloc, TLI)) + if ((AK & AllocFnKind::Zeroed) != AllocFnKind::Unknown) return Constant::getNullValue(Ty); - return nullptr; } @@ -444,7 +475,6 @@ // clang-format off static const std::pair FreeFnData[] = { - {LibFunc_free, {1, MallocFamily::Malloc}}, {LibFunc_ZdlPv, {1, MallocFamily::CPPNew}}, // operator delete(void*) {LibFunc_ZdaPv, {1, MallocFamily::CPPNewArray}}, // operator delete[](void*) {LibFunc_msvc_delete_ptr32, {1, MallocFamily::MSVCNew}}, // operator delete(void*) @@ -503,14 +533,19 @@ const auto FreeData = getFreeFunctionDataForFunction(Callee, TLIFn); if (FreeData.hasValue()) return mangledNameForMallocFamily(FreeData.getValue().Family); + if (checkFnAllocKind(I, AllocFnKind::Free) || + checkFnAllocKind(I, AllocFnKind::New) || + checkFnAllocKind(I, AllocFnKind::Resize)) + return getAllocationFamilyAttribute(I); return None; } /// isLibFreeFunction - Returns true if the function is a builtin free() bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) { Optional FnData = getFreeFunctionDataForFunction(F, TLIFn); - if (!FnData.hasValue()) - return false; + if (!FnData.hasValue()) { + return checkFnAllocKind(F, AllocFnKind::Free); + } // Check free prototype. // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin @@ -540,6 +575,22 @@ return isLibFreeFunction(Callee, TLIFn) ? dyn_cast(I) : nullptr; } +AllocFnKind llvm::getAllocKind(const CallBase *CB, + const TargetLibraryInfo *TLI) { + const Function *F = CB->getCalledFunction(); + if (!F) + return AllocFnKind::Unknown; + Optional A = getAllocationDataForFunction(F, AnyAlloc, TLI); + if (A.hasValue()) + return allocKindFromAllocType(A->AllocTy); + if (isFreeCall(CB, TLI)) + return AllocFnKind::Free; + if (CB->hasFnAttr(Attribute::AllocKind)) + return AllocFnKind(CB->getFnAttr(Attribute::AllocKind).getValueAsInt()); + if (F->hasFnAttribute(Attribute::AllocKind)) + return AllocFnKind(F->getFnAttribute(Attribute::AllocKind).getValueAsInt()); + return AllocFnKind::Unknown; +} //===----------------------------------------------------------------------===// // Utility functions to compute size of objects. 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 @@ -278,9 +278,6 @@ bool Changed = false; - if(!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F, &TLI)) - Changed |= setDoesNotFreeMemory(F); - if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT()) Changed |= setNonLazyBind(F); @@ -293,14 +290,14 @@ Changed |= setOnlyAccessesArgMemory(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_strchr: case LibFunc_strrchr: Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyReadsMemory(F); Changed |= setDoesNotThrow(F); Changed |= setWillReturn(F); - return Changed; + break; case LibFunc_strtol: case LibFunc_strtod: case LibFunc_strtof: @@ -312,7 +309,7 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_strcat: case LibFunc_strncat: Changed |= setOnlyAccessesArgMemory(F); @@ -323,7 +320,7 @@ Changed |= setOnlyReadsMemory(F, 1); Changed |= setDoesNotAlias(F, 0); Changed |= setDoesNotAlias(F, 1); - return Changed; + break; case LibFunc_strcpy: case LibFunc_strncpy: Changed |= setReturnedArg(F, 0); @@ -338,14 +335,14 @@ Changed |= setOnlyReadsMemory(F, 1); Changed |= setDoesNotAlias(F, 0); Changed |= setDoesNotAlias(F, 1); - return Changed; + break; case LibFunc_strxfrm: Changed |= setDoesNotThrow(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_strcmp: // 0,1 case LibFunc_strspn: // 0,1 case LibFunc_strncmp: // 0,1 @@ -356,7 +353,7 @@ Changed |= setOnlyReadsMemory(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_strcoll: case LibFunc_strcasecmp: // 0,1 case LibFunc_strncasecmp: // @@ -367,7 +364,7 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_strstr: case LibFunc_strpbrk: Changed |= setOnlyAccessesArgMemory(F); @@ -375,26 +372,26 @@ Changed |= setDoesNotThrow(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_strtok: case LibFunc_strtok_r: Changed |= setDoesNotThrow(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_scanf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_setbuf: case LibFunc_setvbuf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_strndup: Changed |= setAllocSize(F, 1, None); Changed |= setArgNoUndef(F, 1); @@ -407,7 +404,7 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_stat: case LibFunc_statvfs: Changed |= setRetAndArgsNoUndef(F); @@ -415,7 +412,7 @@ Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_sscanf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -423,7 +420,7 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_sprintf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -432,7 +429,7 @@ Changed |= setOnlyWritesMemory(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_snprintf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -441,7 +438,7 @@ Changed |= setOnlyWritesMemory(F, 0); Changed |= setDoesNotCapture(F, 2); Changed |= setOnlyReadsMemory(F, 2); - return Changed; + break; case LibFunc_setitimer: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -449,13 +446,13 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setDoesNotCapture(F, 2); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_system: // May throw; "system" is a valid pthread cancellation point. Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_aligned_alloc: Changed |= setAlignedAllocParam(F, 0); Changed |= setAllocSize(F, 1, None); @@ -473,7 +470,7 @@ Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); Changed |= setWillReturn(F); - return Changed; + break; case LibFunc_memcmp: Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyReadsMemory(F); @@ -481,21 +478,21 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_memchr: case LibFunc_memrchr: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyReadsMemory(F); Changed |= setWillReturn(F); - return Changed; + break; case LibFunc_modf: case LibFunc_modff: case LibFunc_modfl: Changed |= setDoesNotThrow(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_memcpy: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); @@ -506,7 +503,7 @@ Changed |= setDoesNotAlias(F, 1); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_memmove: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); @@ -515,7 +512,7 @@ Changed |= setOnlyWritesMemory(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_mempcpy: case LibFunc_memccpy: Changed |= setWillReturn(F); @@ -528,7 +525,7 @@ Changed |= setDoesNotAlias(F, 1); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_memalign: Changed |= setAllocFamily(F, "malloc"); Changed |= setAllocKind(F, AllocFnKind::New | AllocFnKind::Aligned | @@ -540,19 +537,19 @@ Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); Changed |= setWillReturn(F); - return Changed; + break; case LibFunc_mkdir: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_mktime: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_realloc: case LibFunc_reallocf: Changed |= setAllocFamily(F, "malloc"); @@ -569,17 +566,17 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setArgNoUndef(F, 1); - return Changed; + break; case LibFunc_read: // May throw; "read" is a valid pthread cancellation point. Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_rewind: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_rmdir: case LibFunc_remove: case LibFunc_realpath: @@ -587,7 +584,7 @@ Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_rename: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -595,20 +592,20 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_readlink: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; 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; + break; case LibFunc_bcopy: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); @@ -617,7 +614,7 @@ Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyWritesMemory(F, 1); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_bcmp: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); @@ -625,14 +622,14 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_bzero: Changed |= setDoesNotThrow(F); Changed |= setOnlyAccessesArgMemory(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyWritesMemory(F, 0); - return Changed; + break; case LibFunc_calloc: Changed |= setAllocFamily(F, "malloc"); LLVM_FALLTHROUGH; @@ -645,21 +642,21 @@ Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); Changed |= setWillReturn(F); - return Changed; + break; case LibFunc_chmod: case LibFunc_chown: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_ctermid: case LibFunc_clearerr: case LibFunc_closedir: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_atoi: case LibFunc_atol: case LibFunc_atof: @@ -668,13 +665,13 @@ Changed |= setOnlyReadsMemory(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_access: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_fopen: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -683,19 +680,19 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_fdopen: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_feof: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_free: Changed |= setAllocFamily(F, "malloc"); LLVM_FALLTHROUGH; @@ -708,7 +705,7 @@ Changed |= setDoesNotThrow(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_fseek: case LibFunc_ftell: case LibFunc_fgetc: @@ -725,45 +722,45 @@ Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_ferror: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F); - return Changed; + break; case LibFunc_fputc: case LibFunc_fputc_unlocked: case LibFunc_fstat: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_frexp: case LibFunc_frexpf: case LibFunc_frexpl: Changed |= setDoesNotThrow(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_fstatvfs: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_fgets: case LibFunc_fgets_unlocked: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 2); - return Changed; + break; case LibFunc_fread: case LibFunc_fread_unlocked: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 3); - return Changed; + break; case LibFunc_fwrite: case LibFunc_fwrite_unlocked: Changed |= setRetAndArgsNoUndef(F); @@ -771,7 +768,7 @@ Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 3); // FIXME: readonly #1? - return Changed; + break; case LibFunc_fputs: case LibFunc_fputs_unlocked: Changed |= setRetAndArgsNoUndef(F); @@ -779,7 +776,7 @@ Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_fscanf: case LibFunc_fprintf: Changed |= setRetAndArgsNoUndef(F); @@ -787,73 +784,73 @@ Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_fgetpos: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_getc: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_getlogin_r: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_getc_unlocked: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_getenv: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setOnlyReadsMemory(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_gets: case LibFunc_getchar: case LibFunc_getchar_unlocked: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); - return Changed; + break; case LibFunc_getitimer: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_getpwnam: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_ungetc: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_uname: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_unlink: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_unsetenv: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_utime: case LibFunc_utimes: Changed |= setRetAndArgsNoUndef(F); @@ -862,13 +859,13 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_putc: case LibFunc_putc_unlocked: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_puts: case LibFunc_printf: case LibFunc_perror: @@ -876,24 +873,24 @@ Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_pread: // May throw; "pread" is a valid pthread cancellation point. Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; 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; + break; case LibFunc_putchar: case LibFunc_putchar_unlocked: Changed |= setRetAndArgsNoUndef(F); Changed |= setArgExtAttr(F, 0, TLI); Changed |= setDoesNotThrow(F); - return Changed; + break; case LibFunc_popen: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -902,18 +899,18 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_pclose: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_vscanf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_vsscanf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -921,20 +918,20 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_vfscanf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_vprintf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_vfprintf: case LibFunc_vsprintf: Changed |= setRetAndArgsNoUndef(F); @@ -942,63 +939,63 @@ Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_vsnprintf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 2); Changed |= setOnlyReadsMemory(F, 2); - return Changed; + break; 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; + break; case LibFunc_opendir: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_tmpfile: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); - return Changed; + break; case LibFunc_times: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_htonl: case LibFunc_htons: case LibFunc_ntohl: case LibFunc_ntohs: Changed |= setDoesNotThrow(F); Changed |= setDoesNotAccessMemory(F); - return Changed; + break; case LibFunc_lstat: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_lchown: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_qsort: // May throw; places call through function pointer. // Cannot give undef pointer/size Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotCapture(F, 3); - return Changed; + break; case LibFunc_dunder_strndup: Changed |= setArgNoUndef(F, 1); LLVM_FALLTHROUGH; @@ -1008,28 +1005,28 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_dunder_strtok_r: Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_under_IO_getc: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_under_IO_putc: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_dunder_isoc99_scanf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_stat64: case LibFunc_lstat64: case LibFunc_statvfs64: @@ -1038,7 +1035,7 @@ Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_dunder_isoc99_sscanf: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -1046,7 +1043,7 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_fopen64: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -1055,30 +1052,30 @@ Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); Changed |= setOnlyReadsMemory(F, 1); - return Changed; + break; case LibFunc_fseeko64: case LibFunc_ftello64: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_tmpfile64: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); - return Changed; + break; case LibFunc_fstat64: case LibFunc_fstatvfs64: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; 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; + break; case LibFunc_gettimeofday: // Currently some platforms have the restrict keyword on the arguments to // gettimeofday. To be conservative, do not add noalias to gettimeofday's @@ -1087,7 +1084,7 @@ Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_memset_pattern4: case LibFunc_memset_pattern8: case LibFunc_memset_pattern16: @@ -1102,19 +1099,19 @@ Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyWritesMemory(F, 0); Changed |= setDoesNotThrow(F); - return Changed; + break; // int __nvvm_reflect(const char *) case LibFunc_nvvm_reflect: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotAccessMemory(F); Changed |= setDoesNotThrow(F); - return Changed; + break; case LibFunc_ldexp: case LibFunc_ldexpf: case LibFunc_ldexpl: Changed |= setArgExtAttr(F, 1, TLI); Changed |= setWillReturn(F); - return Changed; + break; case LibFunc_abs: case LibFunc_acos: case LibFunc_acosf: @@ -1241,12 +1238,15 @@ Changed |= setDoesNotFreeMemory(F); Changed |= setOnlyWritesMemory(F); Changed |= setWillReturn(F); - return Changed; + break; default: // FIXME: It'd be really nice to cover all the library functions we're // aware of here. - return false; + break; } + if (!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F, &TLI)) + Changed |= setDoesNotFreeMemory(F); + return Changed; } bool llvm::hasFloatFn(const TargetLibraryInfo *TLI, Type *Ty, diff --git a/llvm/test/Transforms/Attributor/assumes_info.ll b/llvm/test/Transforms/Attributor/assumes_info.ll --- a/llvm/test/Transforms/Attributor/assumes_info.ll +++ b/llvm/test/Transforms/Attributor/assumes_info.ll @@ -1,8 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM -; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM +; RUN: opt -inferattrs -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=inferattrs,attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM +; RUN: opt -inferattrs -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=inferattrs,attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM define dso_local void @entry(i1 %cond) #0 { ; CHECK-LABEL: define {{[^@]+}}@entry diff --git a/llvm/test/Transforms/Attributor/heap_to_stack.ll b/llvm/test/Transforms/Attributor/heap_to_stack.ll --- a/llvm/test/Transforms/Attributor/heap_to_stack.ll +++ b/llvm/test/Transforms/Attributor/heap_to_stack.ll @@ -1,8 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM -; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM +; RUN: opt -inferattrs -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=inferattrs,attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM +; RUN: opt -inferattrs -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=inferattrs,attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM declare noalias i8* @malloc(i64) @@ -34,24 +34,24 @@ ; IS________OPM-LABEL: define {{[^@]+}}@h2s_value_simplify_interaction ; IS________OPM-SAME: (i1 [[C:%.*]], i8* nocapture nofree readnone [[A:%.*]]) { ; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[M:%.*]] = tail call noalias align 16 i8* @malloc(i64 noundef 4) +; IS________OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 16 ; IS________OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS________OPM: t: ; IS________OPM-NEXT: br i1 false, label [[DEAD:%.*]], label [[F2:%.*]] ; IS________OPM: f: ; IS________OPM-NEXT: br label [[J:%.*]] ; IS________OPM: f2: -; IS________OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M]] to i32* +; IS________OPM-NEXT: [[C1:%.*]] = bitcast i8* [[TMP0]] to i32* ; IS________OPM-NEXT: [[C2:%.*]] = bitcast i32* [[C1]] to i8* ; IS________OPM-NEXT: [[L:%.*]] = load i8, i8* [[C2]], align 16 ; IS________OPM-NEXT: call void @usei8(i8 [[L]]) -; IS________OPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef align 16 [[C2]]) #[[ATTR5:[0-9]+]] +; IS________OPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef align 16 [[C2]]) #[[ATTR12:[0-9]+]] ; IS________OPM-NEXT: br label [[J]] ; IS________OPM: dead: ; IS________OPM-NEXT: unreachable ; IS________OPM: j: -; IS________OPM-NEXT: [[PHI:%.*]] = phi i8* [ [[M]], [[F]] ], [ null, [[F2]] ] -; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef align 16 [[PHI]]) #[[ATTR5]] +; IS________OPM-NEXT: [[PHI:%.*]] = phi i8* [ [[TMP0]], [[F]] ], [ null, [[F2]] ] +; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef align 16 [[PHI]]) #[[ATTR12]] ; IS________OPM-NEXT: ret void ; ; IS________NPM-LABEL: define {{[^@]+}}@h2s_value_simplify_interaction @@ -66,13 +66,13 @@ ; IS________NPM: f2: ; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[TMP0]], align 16 ; IS________NPM-NEXT: call void @usei8(i8 [[L]]) -; IS________NPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef align 16 [[TMP0]]) #[[ATTR6:[0-9]+]] +; IS________NPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef align 16 [[TMP0]]) #[[ATTR12:[0-9]+]] ; IS________NPM-NEXT: br label [[J]] ; IS________NPM: dead: ; IS________NPM-NEXT: unreachable ; IS________NPM: j: ; IS________NPM-NEXT: [[PHI:%.*]] = phi i8* [ [[TMP0]], [[F]] ], [ null, [[F2]] ] -; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef align 16 [[PHI]]) #[[ATTR6]] +; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef align 16 [[PHI]]) #[[ATTR12]] ; IS________NPM-NEXT: ret void ; entry: @@ -100,10 +100,11 @@ } define void @nofree_arg_only(i8* %p1, i8* %p2) { +; CHECK: Function Attrs: willreturn ; CHECK-LABEL: define {{[^@]+}}@nofree_arg_only -; CHECK-SAME: (i8* nocapture nofree [[P1:%.*]], i8* nocapture [[P2:%.*]]) { -; CHECK-NEXT: tail call void @free(i8* nocapture [[P2]]) -; CHECK-NEXT: tail call void @nofree_func(i8* nocapture nofree [[P1]]) +; CHECK-SAME: (i8* nocapture nofree [[P1:%.*]], i8* nocapture noundef [[P2:%.*]]) #[[ATTR7:[0-9]+]] { +; CHECK-NEXT: tail call void @free(i8* nocapture noundef [[P2]]) #[[ATTR9:[0-9]+]] +; CHECK-NEXT: tail call void @nofree_func(i8* nocapture nofree [[P1]]) #[[ATTR7]] ; CHECK-NEXT: ret void ; tail call void @free(i8* %p2) @@ -115,10 +116,10 @@ define void @test1() { ; CHECK-LABEL: define {{[^@]+}}@test1() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; CHECK-NEXT: tail call void @nocapture_func_frees_pointer(i8* noalias nocapture [[TMP1]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; CHECK-NEXT: tail call void @nocapture_func_frees_pointer(i8* noalias nocapture noundef [[TMP1]]) ; CHECK-NEXT: tail call void (...) @func_throws() -; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) +; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR12:[0-9]+]] ; CHECK-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) @@ -132,9 +133,9 @@ define void @test2() { ; CHECK-LABEL: define {{[^@]+}}@test2() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; CHECK-NEXT: tail call void @sync_func(i8* [[TMP1]]) -; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP1]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; CHECK-NEXT: tail call void @sync_func(i8* noundef [[TMP1]]) +; CHECK-NEXT: tail call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR12]] ; CHECK-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) @@ -146,15 +147,19 @@ ; TEST 3 - 1 malloc, 1 free define void @test3() { -; IS________OPM-LABEL: define {{[^@]+}}@test3() { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) +; IS________OPM: Function Attrs: willreturn +; IS________OPM-LABEL: define {{[^@]+}}@test3 +; IS________OPM-SAME: () #[[ATTR7]] { +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] +; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] ; IS________OPM-NEXT: ret void ; -; IS________NPM-LABEL: define {{[^@]+}}@test3() { +; IS________NPM: Function Attrs: willreturn +; IS________NPM-LABEL: define {{[^@]+}}@test3 +; IS________NPM-SAME: () #[[ATTR7]] { ; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] ; IS________NPM-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) @@ -164,18 +169,35 @@ } define void @test3a(i8* %p) { -; IS________OPM-LABEL: define {{[^@]+}}@test3a -; IS________OPM-SAME: (i8* nocapture [[P:%.*]]) { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]]) -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) -; IS________OPM-NEXT: ret void -; -; IS________NPM-LABEL: define {{[^@]+}}@test3a -; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) { -; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]]) -; IS________NPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test3a +; IS__TUNIT_OPM-SAME: (i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree noundef [[TMP1]], i8* nocapture [[P]]) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test3a +; IS__TUNIT_NPM-SAME: (i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree noundef [[TMP1]], i8* nocapture [[P]]) #[[ATTR7]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3a +; IS__CGSCC_OPM-SAME: (i8* nocapture noundef [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree noundef [[TMP1]], i8* nocapture noundef [[P]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test3a +; IS__CGSCC_NPM-SAME: (i8* nocapture noundef [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree noundef [[TMP1]], i8* nocapture noundef [[P]]) #[[ATTR7]] +; IS__CGSCC_NPM-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) tail call void @nofree_arg_only(i8* %1, i8* %p) @@ -186,18 +208,35 @@ declare noalias i8* @aligned_alloc(i64, i64) define void @test3b(i8* %p) { -; IS________OPM-LABEL: define {{[^@]+}}@test3b -; IS________OPM-SAME: (i8* nocapture [[P:%.*]]) { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 32, i64 noundef 128) -; IS________OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]]) -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) -; IS________OPM-NEXT: ret void -; -; IS________NPM-LABEL: define {{[^@]+}}@test3b -; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) { -; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 128, align 32 -; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]]) -; IS________NPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test3b +; IS__TUNIT_OPM-SAME: (i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 32, i64 noundef 128) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree noundef [[TMP1]], i8* nocapture [[P]]) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test3b +; IS__TUNIT_NPM-SAME: (i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 128, align 32 +; IS__TUNIT_NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree noundef [[TMP1]], i8* nocapture [[P]]) #[[ATTR7]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3b +; IS__CGSCC_OPM-SAME: (i8* nocapture noundef [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 32, i64 noundef 128) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree noundef [[TMP1]], i8* nocapture noundef [[P]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test3b +; IS__CGSCC_NPM-SAME: (i8* nocapture noundef [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 128, align 32 +; IS__CGSCC_NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree noundef [[TMP1]], i8* nocapture noundef [[P]]) #[[ATTR7]] +; IS__CGSCC_NPM-NEXT: ret void ; %1 = tail call noalias i8* @aligned_alloc(i64 32, i64 128) tail call void @nofree_arg_only(i8* %1, i8* %p) @@ -207,10 +246,11 @@ ; leave alone non-constant alignments. define void @test3c(i64 %alignment) { +; CHECK: Function Attrs: nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@test3c -; CHECK-SAME: (i64 [[ALIGNMENT:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 [[ALIGNMENT]], i64 noundef 128) -; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) +; CHECK-SAME: (i64 noundef [[ALIGNMENT:%.*]]) #[[ATTR9]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef [[ALIGNMENT]], i64 noundef 128) #[[ATTR7]] +; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] ; CHECK-NEXT: ret void ; %1 = tail call noalias i8* @aligned_alloc(i64 %alignment, i64 128) @@ -220,19 +260,37 @@ ; leave alone a constant-but-invalid alignment define void @test3d(i8* %p) { -; IS________OPM-LABEL: define {{[^@]+}}@test3d -; IS________OPM-SAME: (i8* nocapture [[P:%.*]]) { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 33, i64 noundef 128) -; IS________OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]]) -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) -; IS________OPM-NEXT: ret void -; -; IS________NPM-LABEL: define {{[^@]+}}@test3d -; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) { -; IS________NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 33, i64 noundef 128) -; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]]) -; IS________NPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) -; IS________NPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test3d +; IS__TUNIT_OPM-SAME: (i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 33, i64 noundef 128) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree noundef [[TMP1]], i8* nocapture [[P]]) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test3d +; IS__TUNIT_NPM-SAME: (i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 33, i64 noundef 128) #[[ATTR7]] +; IS__TUNIT_NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree noundef [[TMP1]], i8* nocapture [[P]]) #[[ATTR7]] +; IS__TUNIT_NPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3d +; IS__CGSCC_OPM-SAME: (i8* nocapture noundef [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 33, i64 noundef 128) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree noundef [[TMP1]], i8* nocapture noundef [[P]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test3d +; IS__CGSCC_NPM-SAME: (i8* nocapture noundef [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 33, i64 noundef 128) #[[ATTR7]] +; IS__CGSCC_NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree noundef [[TMP1]], i8* nocapture noundef [[P]]) #[[ATTR7]] +; IS__CGSCC_NPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] +; IS__CGSCC_NPM-NEXT: ret void ; ; CHECK-SAME; (i8* nocapture [[P:%.*]]) { %1 = tail call noalias i8* @aligned_alloc(i64 33, i64 128) @@ -244,16 +302,20 @@ declare noalias i8* @calloc(i64, i64) define void @test0() { -; IS________OPM-LABEL: define {{[^@]+}}@test0() { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 2, i64 noundef 4) -; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) +; IS________OPM: Function Attrs: willreturn +; IS________OPM-LABEL: define {{[^@]+}}@test0 +; IS________OPM-SAME: () #[[ATTR7]] { +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 2, i64 noundef 4) #[[ATTR7]] +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] +; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] ; IS________OPM-NEXT: ret void ; -; IS________NPM-LABEL: define {{[^@]+}}@test0() { +; IS________NPM: Function Attrs: willreturn +; IS________NPM-LABEL: define {{[^@]+}}@test0 +; IS________NPM-SAME: () #[[ATTR7]] { ; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 8, align 1 ; IS________NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP1]], i8 0, i64 8, i1 false) -; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] ; IS________NPM-NEXT: ret void ; %1 = tail call noalias i8* @calloc(i64 2, i64 4) @@ -264,15 +326,12 @@ ; TEST 4 define void @test4() { -; IS________OPM-LABEL: define {{[^@]+}}@test4() { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP1]]) -; IS________OPM-NEXT: ret void -; -; IS________NPM-LABEL: define {{[^@]+}}@test4() { -; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP1]]) -; IS________NPM-NEXT: ret void +; CHECK: Function Attrs: nofree willreturn +; CHECK-LABEL: define {{[^@]+}}@test4 +; CHECK-SAME: () #[[ATTR11:[0-9]+]] { +; CHECK-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 +; CHECK-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] +; CHECK-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) tail call void @nofree_func(i8* %1) @@ -283,34 +342,67 @@ ; are in nofree functions and are not captured define void @test5(i32, i8* %p) { -; IS________OPM-LABEL: define {{[^@]+}}@test5 -; IS________OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) { -; IS________OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 -; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] -; IS________OPM: 4: -; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) -; IS________OPM-NEXT: br label [[TMP6:%.*]] -; IS________OPM: 5: -; IS________OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP2]], i8* nocapture [[P]]) -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP2]]) -; IS________OPM-NEXT: br label [[TMP6]] -; IS________OPM: 6: -; IS________OPM-NEXT: ret void -; -; IS________NPM-LABEL: define {{[^@]+}}@test5 -; IS________NPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) { -; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 -; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] -; IS________NPM: 4: -; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) -; IS________NPM-NEXT: br label [[TMP6:%.*]] -; IS________NPM: 5: -; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP2]], i8* nocapture [[P]]) -; IS________NPM-NEXT: br label [[TMP6]] -; IS________NPM: 6: -; IS________NPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test5 +; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS__TUNIT_OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; IS__TUNIT_OPM: 4: +; IS__TUNIT_OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree noundef [[TMP2]]) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: br label [[TMP6:%.*]] +; IS__TUNIT_OPM: 5: +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree noundef [[TMP2]], i8* nocapture [[P]]) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP2]]) #[[ATTR9]] +; IS__TUNIT_OPM-NEXT: br label [[TMP6]] +; IS__TUNIT_OPM: 6: +; IS__TUNIT_OPM-NEXT: ret void +; +; IS__TUNIT_NPM: Function Attrs: willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test5 +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS__TUNIT_NPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; IS__TUNIT_NPM: 4: +; IS__TUNIT_NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree noundef [[TMP2]]) #[[ATTR7]] +; IS__TUNIT_NPM-NEXT: br label [[TMP6:%.*]] +; IS__TUNIT_NPM: 5: +; IS__TUNIT_NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree noundef [[TMP2]], i8* nocapture [[P]]) #[[ATTR7]] +; IS__TUNIT_NPM-NEXT: br label [[TMP6]] +; IS__TUNIT_NPM: 6: +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test5 +; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; IS__CGSCC_OPM: 4: +; IS__CGSCC_OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree noundef [[TMP2]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: br label [[TMP6:%.*]] +; IS__CGSCC_OPM: 5: +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree noundef [[TMP2]], i8* nocapture noundef [[P]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP2]]) #[[ATTR9]] +; IS__CGSCC_OPM-NEXT: br label [[TMP6]] +; IS__CGSCC_OPM: 6: +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test5 +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS__CGSCC_NPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; IS__CGSCC_NPM: 4: +; IS__CGSCC_NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree noundef [[TMP2]]) #[[ATTR7]] +; IS__CGSCC_NPM-NEXT: br label [[TMP6:%.*]] +; IS__CGSCC_NPM: 5: +; IS__CGSCC_NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree noundef [[TMP2]], i8* nocapture noundef [[P]]) #[[ATTR7]] +; IS__CGSCC_NPM-NEXT: br label [[TMP6]] +; IS__CGSCC_NPM: 6: +; IS__CGSCC_NPM-NEXT: ret void ; %2 = tail call noalias i8* @malloc(i64 4) %3 = icmp eq i32 %0, 0 @@ -332,28 +424,30 @@ ; TEST 6 - all exit paths have a call to free define void @test6(i32) { +; IS________OPM: Function Attrs: willreturn ; IS________OPM-LABEL: define {{[^@]+}}@test6 -; IS________OPM-SAME: (i32 [[TMP0:%.*]]) { -; IS________OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; IS________OPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR7]] { +; IS________OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] ; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 ; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] ; IS________OPM: 4: -; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP2]]) +; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree noundef [[TMP2]]) #[[ATTR7]] +; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP2]]) #[[ATTR9]] ; IS________OPM-NEXT: br label [[TMP6:%.*]] ; IS________OPM: 5: -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP2]]) +; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP2]]) #[[ATTR9]] ; IS________OPM-NEXT: br label [[TMP6]] ; IS________OPM: 6: ; IS________OPM-NEXT: ret void ; +; IS________NPM: Function Attrs: willreturn ; IS________NPM-LABEL: define {{[^@]+}}@test6 -; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { +; IS________NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR7]] { ; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 ; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] ; IS________NPM: 4: -; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) +; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree noundef [[TMP2]]) #[[ATTR7]] ; IS________NPM-NEXT: br label [[TMP6:%.*]] ; IS________NPM: 5: ; IS________NPM-NEXT: br label [[TMP6]] @@ -381,13 +475,13 @@ define void @test7() { ; IS________OPM-LABEL: define {{[^@]+}}@test7() { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call() #[[ATTR3:[0-9]+]] +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; IS________OPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call() #[[ATTR4:[0-9]+]] ; IS________OPM-NEXT: unreachable ; ; IS________NPM-LABEL: define {{[^@]+}}@test7() { ; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call() #[[ATTR3:[0-9]+]] +; IS________NPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call() #[[ATTR4:[0-9]+]] ; IS________NPM-NEXT: unreachable ; %1 = tail call noalias i8* @malloc(i64 4) @@ -400,12 +494,12 @@ define void @test8() { ; CHECK-LABEL: define {{[^@]+}}@test8() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; CHECK-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; CHECK-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef [[TMP1]]) #[[ATTR7]] ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* ; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 ; CHECK-NEXT: tail call void @foo(i32* noundef align 4 [[TMP2]]) -; CHECK-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; CHECK-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR12]] ; CHECK-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) @@ -420,23 +514,14 @@ ; TEST 9 - FIXME: malloc should be converted. define void @test9() { -; IS________OPM-LABEL: define {{[^@]+}}@test9() { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) -; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* -; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 -; IS________OPM-NEXT: tail call void @foo_nounw(i32* nofree noundef align 4 [[TMP2]]) #[[ATTR5]] -; IS________OPM-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________OPM-NEXT: ret void -; -; IS________NPM-LABEL: define {{[^@]+}}@test9() { -; IS________NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) -; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* -; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 -; IS________NPM-NEXT: tail call void @foo_nounw(i32* nofree noundef align 4 [[TMP2]]) #[[ATTR6]] -; IS________NPM-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________NPM-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@test9() { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; CHECK-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef [[TMP1]]) #[[ATTR7]] +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 +; CHECK-NEXT: tail call void @foo_nounw(i32* nofree noundef align 4 [[TMP2]]) #[[ATTR12]] +; CHECK-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR12]] +; CHECK-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) tail call void @no_sync_func(i8* %1) @@ -451,18 +536,22 @@ ; TEST 10 - 1 malloc, 1 free define i32 @test10() { -; IS________OPM-LABEL: define {{[^@]+}}@test10() { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS________OPM: Function Attrs: willreturn +; IS________OPM-LABEL: define {{[^@]+}}@test10 +; IS________OPM-SAME: () #[[ATTR7]] { +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] ; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* ; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 ; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR9]] ; IS________OPM-NEXT: ret i32 [[TMP3]] ; -; IS________NPM-LABEL: define {{[^@]+}}@test10() { +; IS________NPM: Function Attrs: willreturn +; IS________NPM-LABEL: define {{[^@]+}}@test10 +; IS________NPM-SAME: () #[[ATTR7]] { ; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] ; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* ; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 ; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 @@ -478,20 +567,24 @@ } define i32 @test_lifetime() { -; IS________OPM-LABEL: define {{[^@]+}}@test_lifetime() { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS________OPM: Function Attrs: willreturn +; IS________OPM-LABEL: define {{[^@]+}}@test_lifetime +; IS________OPM-SAME: () #[[ATTR7]] { +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] +; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR7]] ; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* ; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 ; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR9]] ; IS________OPM-NEXT: ret i32 [[TMP3]] ; -; IS________NPM-LABEL: define {{[^@]+}}@test_lifetime() { +; IS________NPM: Function Attrs: willreturn +; IS________NPM-LABEL: define {{[^@]+}}@test_lifetime +; IS________NPM-SAME: () #[[ATTR7]] { ; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] +; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR7]] ; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* ; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 ; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 @@ -510,15 +603,19 @@ ; TEST 11 define void @test11() { -; IS________OPM-LABEL: define {{[^@]+}}@test11() { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: tail call void @sync_will_return(i8* [[TMP1]]) #[[ATTR5]] -; IS________OPM-NEXT: tail call void @free(i8* nocapture [[TMP1]]) +; IS________OPM: Function Attrs: nounwind willreturn +; IS________OPM-LABEL: define {{[^@]+}}@test11 +; IS________OPM-SAME: () #[[ATTR9]] { +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] +; IS________OPM-NEXT: tail call void @sync_will_return(i8* noundef [[TMP1]]) #[[ATTR9]] +; IS________OPM-NEXT: tail call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR9]] ; IS________OPM-NEXT: ret void ; -; IS________NPM-LABEL: define {{[^@]+}}@test11() { +; IS________NPM: Function Attrs: nounwind willreturn +; IS________NPM-LABEL: define {{[^@]+}}@test11 +; IS________NPM-SAME: () #[[ATTR9]] { ; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: tail call void @sync_will_return(i8* [[TMP1]]) #[[ATTR6]] +; IS________NPM-NEXT: tail call void @sync_will_return(i8* noundef [[TMP1]]) #[[ATTR9]] ; IS________NPM-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) @@ -529,9 +626,10 @@ ; TEST 12 define i32 @irreducible_cfg(i32 %0) { +; IS________OPM: Function Attrs: nounwind ; IS________OPM-LABEL: define {{[^@]+}}@irreducible_cfg -; IS________OPM-SAME: (i32 [[TMP0:%.*]]) { -; IS________OPM-NEXT: [[TMP2:%.*]] = call noalias i8* @malloc(i64 noundef 4) +; IS________OPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR12]] { +; IS________OPM-NEXT: [[TMP2:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @malloc(i64 noundef 4) ; IS________OPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32* ; IS________OPM-NEXT: store i32 10, i32* [[TMP3]], align 4 ; IS________OPM-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1 @@ -555,14 +653,14 @@ ; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1 ; IS________OPM-NEXT: br label [[TMP8]] ; IS________OPM: 15: -; IS________OPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4 -; IS________OPM-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP3]] to i8* -; IS________OPM-NEXT: call void @free(i8* nocapture noundef [[TMP17]]) -; IS________OPM-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP3]], align 4 -; IS________OPM-NEXT: ret i32 [[TMP18]] +; IS________OPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8* +; IS________OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP16]]) #[[ATTR12]] +; IS________OPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4 +; IS________OPM-NEXT: ret i32 [[TMP17]] ; +; IS________NPM: Function Attrs: nounwind ; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg -; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { +; IS________NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR12]] { ; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32* ; IS________NPM-NEXT: store i32 10, i32* [[TMP3]], align 4 @@ -630,44 +728,25 @@ define i32 @malloc_in_loop(i32 %0) { -; IS________OPM-LABEL: define {{[^@]+}}@malloc_in_loop -; IS________OPM-SAME: (i32 [[TMP0:%.*]]) { -; IS________OPM-NEXT: [[TMP2:%.*]] = alloca i32, align 4 -; IS________OPM-NEXT: [[TMP3:%.*]] = alloca i32*, align 8 -; IS________OPM-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4 -; IS________OPM-NEXT: br label [[TMP4:%.*]] -; IS________OPM: 4: -; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4 -; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1 -; IS________OPM-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4 -; IS________OPM-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0 -; IS________OPM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP11:%.*]] -; IS________OPM: 8: -; IS________OPM-NEXT: [[TMP9:%.*]] = call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32* -; IS________OPM-NEXT: store i32 1, i32* [[TMP10]], align 8 -; IS________OPM-NEXT: br label [[TMP4]] -; IS________OPM: 11: -; IS________OPM-NEXT: ret i32 5 -; -; IS________NPM-LABEL: define {{[^@]+}}@malloc_in_loop -; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { -; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i32, align 4 -; IS________NPM-NEXT: [[TMP3:%.*]] = alloca i32*, align 8 -; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4 -; IS________NPM-NEXT: br label [[TMP4:%.*]] -; IS________NPM: 4: -; IS________NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4 -; IS________NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1 -; IS________NPM-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4 -; IS________NPM-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0 -; IS________NPM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP11:%.*]] -; IS________NPM: 8: -; IS________NPM-NEXT: [[TMP9:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32* -; IS________NPM-NEXT: br label [[TMP4]] -; IS________NPM: 11: -; IS________NPM-NEXT: ret i32 5 +; CHECK: Function Attrs: nofree nounwind +; CHECK-LABEL: define {{[^@]+}}@malloc_in_loop +; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR3:[0-9]+]] { +; CHECK-NEXT: [[TMP2:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[TMP3:%.*]] = alloca i32*, align 8 +; CHECK-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4 +; CHECK-NEXT: br label [[TMP4:%.*]] +; CHECK: 4: +; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4 +; CHECK-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1 +; CHECK-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4 +; CHECK-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0 +; CHECK-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP11:%.*]] +; CHECK: 8: +; CHECK-NEXT: [[TMP9:%.*]] = alloca i8, i64 4, align 1 +; CHECK-NEXT: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32* +; CHECK-NEXT: br label [[TMP4]] +; CHECK: 11: +; CHECK-NEXT: ret i32 5 ; %2 = alloca i32, align 4 %3 = alloca i32*, align 8 @@ -693,13 +772,15 @@ ; Malloc/Calloc too large define i32 @test13() { -; CHECK-LABEL: define {{[^@]+}}@test13() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 256) -; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; CHECK: Function Attrs: willreturn +; CHECK-LABEL: define {{[^@]+}}@test13 +; CHECK-SAME: () #[[ATTR7]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 256) #[[ATTR7]] +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* ; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR9]] ; CHECK-NEXT: ret i32 [[TMP3]] ; %1 = tail call noalias i8* @malloc(i64 256) @@ -712,13 +793,15 @@ } define i32 @test_sle() { -; CHECK-LABEL: define {{[^@]+}}@test_sle() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef -1) -; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; CHECK: Function Attrs: willreturn +; CHECK-LABEL: define {{[^@]+}}@test_sle +; CHECK-SAME: () #[[ATTR7]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef -1) #[[ATTR7]] +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* ; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR9]] ; CHECK-NEXT: ret i32 [[TMP3]] ; %1 = tail call noalias i8* @malloc(i64 -1) @@ -731,13 +814,15 @@ } define i32 @test_overflow() { -; CHECK-LABEL: define {{[^@]+}}@test_overflow() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 65537, i64 noundef 65537) -; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; CHECK: Function Attrs: willreturn +; CHECK-LABEL: define {{[^@]+}}@test_overflow +; CHECK-SAME: () #[[ATTR7]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 65537, i64 noundef 65537) #[[ATTR7]] +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* ; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR9]] ; CHECK-NEXT: ret i32 [[TMP3]] ; %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) @@ -750,10 +835,12 @@ } define void @test14() { -; CHECK-LABEL: define {{[^@]+}}@test14() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 64, i64 noundef 4) -; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) -; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) +; CHECK: Function Attrs: willreturn +; CHECK-LABEL: define {{[^@]+}}@test14 +; CHECK-SAME: () #[[ATTR7]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 64, i64 noundef 4) #[[ATTR7]] +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] ; CHECK-NEXT: ret void ; %1 = tail call noalias i8* @calloc(i64 64, i64 4) @@ -763,11 +850,12 @@ } define void @test15(i64 %S) { +; CHECK: Function Attrs: willreturn ; CHECK-LABEL: define {{[^@]+}}@test15 -; CHECK-SAME: (i64 [[S:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 [[S]]) -; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) -; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) +; CHECK-SAME: (i64 noundef [[S:%.*]]) #[[ATTR7]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef [[S]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef [[TMP1]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef [[TMP1]]) #[[ATTR9]] ; CHECK-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 %S) @@ -777,19 +865,21 @@ } define void @test16a(i8 %v, i8** %P) { +; IS________OPM: Function Attrs: willreturn ; IS________OPM-LABEL: define {{[^@]+}}@test16a -; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) #[[ATTR7]] { +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias nonnull dereferenceable(1) i8* @malloc(i64 noundef 4) #[[ATTR7]] ; IS________OPM-NEXT: store i8 [[V]], i8* [[TMP1]], align 1 -; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[TMP1]]) -; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull dereferenceable(1) [[TMP1]]) +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[TMP1]]) #[[ATTR7]] +; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull dereferenceable(1) [[TMP1]]) #[[ATTR9]] ; IS________OPM-NEXT: ret void ; +; IS________NPM: Function Attrs: willreturn ; IS________NPM-LABEL: define {{[^@]+}}@test16a -; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) { +; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) #[[ATTR7]] { ; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: store i8 [[V]], i8* [[TMP1]], align 1 -; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[TMP1]]) +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[TMP1]]) #[[ATTR7]] ; IS________NPM-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) @@ -800,12 +890,13 @@ } define void @test16b(i8 %v, i8** %P) { +; CHECK: Function Attrs: willreturn ; CHECK-LABEL: define {{[^@]+}}@test16b -; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR7]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] ; CHECK-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 -; CHECK-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) -; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP1]]) +; CHECK-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef [[TMP1]]) #[[ATTR7]] +; CHECK-NEXT: tail call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR9]] ; CHECK-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) @@ -816,19 +907,21 @@ } define void @test16c(i8 %v, i8** %P) { +; IS________OPM: Function Attrs: nounwind willreturn ; IS________OPM-LABEL: define {{[^@]+}}@test16c -; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR9]] { +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] ; IS________OPM-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 -; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) #[[ATTR5]] -; IS________OPM-NEXT: tail call void @free(i8* nocapture [[TMP1]]) +; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef [[TMP1]]) #[[ATTR9]] +; IS________OPM-NEXT: tail call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR9]] ; IS________OPM-NEXT: ret void ; +; IS________NPM: Function Attrs: nounwind willreturn ; IS________NPM-LABEL: define {{[^@]+}}@test16c -; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { +; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR9]] { ; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 -; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) #[[ATTR6]] +; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef [[TMP1]]) #[[ATTR9]] ; IS________NPM-NEXT: ret void ; %1 = tail call noalias i8* @malloc(i64 4) @@ -839,9 +932,10 @@ } define void @test16d(i8 %v, i8** %P) { +; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@test16d -; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR13:[0-9]+]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR7]] ; CHECK-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 ; CHECK-NEXT: ret void ; @@ -850,18 +944,34 @@ ret void } ;. -; IS________OPM: attributes #[[ATTR0:[0-9]+]] = { nounwind willreturn } -; IS________OPM: attributes #[[ATTR1:[0-9]+]] = { nofree nosync willreturn } -; IS________OPM: attributes #[[ATTR2:[0-9]+]] = { nofree nounwind } -; IS________OPM: attributes #[[ATTR3]] = { noreturn } -; IS________OPM: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; IS________OPM: attributes #[[ATTR5]] = { nounwind } +; IS________OPM: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(0) "alloc-family"="malloc" } +; IS________OPM: attributes #[[ATTR1:[0-9]+]] = { mustprogress nounwind willreturn } +; IS________OPM: attributes #[[ATTR2:[0-9]+]] = { mustprogress nofree nosync willreturn } +; IS________OPM: attributes #[[ATTR3]] = { nofree nounwind } +; IS________OPM: attributes #[[ATTR4]] = { noreturn } +; IS________OPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" } +; IS________OPM: attributes #[[ATTR6:[0-9]+]] = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn } +; IS________OPM: attributes #[[ATTR7]] = { willreturn } +; IS________OPM: attributes #[[ATTR8:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(1) "alloc-family"="malloc" } +; IS________OPM: attributes #[[ATTR9]] = { nounwind willreturn } +; IS________OPM: attributes #[[ATTR10:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,zeroed") allocsize(0,1) "alloc-family"="malloc" } +; IS________OPM: attributes #[[ATTR11]] = { nofree willreturn } +; IS________OPM: attributes #[[ATTR12]] = { nounwind } +; IS________OPM: attributes #[[ATTR13]] = { inaccessiblemem_or_argmemonly nofree nounwind willreturn } ;. -; IS________NPM: attributes #[[ATTR0:[0-9]+]] = { nounwind willreturn } -; IS________NPM: attributes #[[ATTR1:[0-9]+]] = { nofree nosync willreturn } -; IS________NPM: attributes #[[ATTR2:[0-9]+]] = { nofree nounwind } -; IS________NPM: attributes #[[ATTR3]] = { noreturn } -; IS________NPM: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; IS________NPM: attributes #[[ATTR5:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } -; IS________NPM: attributes #[[ATTR6]] = { nounwind } +; IS________NPM: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(0) "alloc-family"="malloc" } +; IS________NPM: attributes #[[ATTR1:[0-9]+]] = { mustprogress nounwind willreturn } +; IS________NPM: attributes #[[ATTR2:[0-9]+]] = { mustprogress nofree nosync willreturn } +; IS________NPM: attributes #[[ATTR3]] = { nofree nounwind } +; IS________NPM: attributes #[[ATTR4]] = { noreturn } +; IS________NPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" } +; IS________NPM: attributes #[[ATTR6:[0-9]+]] = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn } +; IS________NPM: attributes #[[ATTR7]] = { willreturn } +; IS________NPM: attributes #[[ATTR8:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(1) "alloc-family"="malloc" } +; IS________NPM: attributes #[[ATTR9]] = { nounwind willreturn } +; IS________NPM: attributes #[[ATTR10:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,zeroed") allocsize(0,1) "alloc-family"="malloc" } +; IS________NPM: attributes #[[ATTR11]] = { nofree willreturn } +; IS________NPM: attributes #[[ATTR12]] = { nounwind } +; IS________NPM: attributes #[[ATTR13]] = { inaccessiblemem_or_argmemonly nofree nounwind willreturn } +; IS________NPM: attributes #[[ATTR14:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll --- a/llvm/test/Transforms/Attributor/noalias.ll +++ b/llvm/test/Transforms/Attributor/noalias.ll @@ -1,9 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM +; RUN: opt -inferattrs -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=inferattrs,attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; TODO: The old pass manager cgscc run is disabled as it causes a crash on windows which is under investigation: http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/25479/steps/test-check-all/logs/FAIL%3A%20LLVM%3A%3Anoalias.ll ; opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM +; RUN: opt -aa-pipeline=basic-aa -passes=inferattrs,attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM ; TEST 1 - negative. @@ -21,8 +21,10 @@ ; CHECK: @[[ALIAS_OF_P:[a-zA-Z0-9_$"\\.-]+]] = external global i32* ;. define i8* @foo() { -; CHECK-LABEL: define {{[^@]+}}@foo() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; CHECK: Function Attrs: nofree nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@foo +; CHECK-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14:[0-9]+]] ; CHECK-NEXT: store i8* [[TMP1]], i8** @G, align 8 ; CHECK-NEXT: ret i8* [[TMP1]] ; @@ -37,8 +39,10 @@ ; call noalias function in return instruction. define i8* @return_noalias(){ -; CHECK-LABEL: define {{[^@]+}}@return_noalias() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; CHECK: Function Attrs: inaccessiblememonly nofree nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@return_noalias +; CHECK-SAME: () #[[ATTR2:[0-9]+]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14]] ; CHECK-NEXT: ret i8* [[TMP1]] ; %1 = tail call noalias i8* @malloc(i64 4) @@ -48,15 +52,17 @@ define void @nocapture(i8* %a){ ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@nocapture -; CHECK-SAME: (i8* nocapture nofree readnone [[A:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-SAME: (i8* nocapture nofree readnone [[A:%.*]]) #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: ret void ; ret void } define i8* @return_noalias_looks_like_capture(){ -; CHECK-LABEL: define {{[^@]+}}@return_noalias_looks_like_capture() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; CHECK: Function Attrs: inaccessiblememonly nofree nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@return_noalias_looks_like_capture +; CHECK-SAME: () #[[ATTR2]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14]] ; CHECK-NEXT: ret i8* [[TMP1]] ; %1 = tail call noalias i8* @malloc(i64 4) @@ -65,8 +71,10 @@ } define i16* @return_noalias_casted(){ -; CHECK-LABEL: define {{[^@]+}}@return_noalias_casted() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; CHECK: Function Attrs: inaccessiblememonly nofree nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@return_noalias_casted +; CHECK-SAME: () #[[ATTR2]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14]] ; CHECK-NEXT: [[C:%.*]] = bitcast i8* [[TMP1]] to i16* ; CHECK-NEXT: ret i16* [[C]] ; @@ -105,8 +113,8 @@ define i8* @bar() nounwind uwtable { ; CHECK: Function Attrs: nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@bar -; CHECK-SAME: () #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR2:[0-9]+]] +; CHECK-SAME: () #[[ATTR4:[0-9]+]] { +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR15:[0-9]+]] ; CHECK-NEXT: ret i8* [[TMP1]] ; %1 = tail call i8* (...) @baz() @@ -116,14 +124,14 @@ define i8* @foo1(i32 %0) nounwind uwtable { ; CHECK: Function Attrs: nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@foo1 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR4]] { ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] ; CHECK: 3: -; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR2]] +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR15]] ; CHECK-NEXT: br label [[TMP5]] ; CHECK: 5: -; CHECK-NEXT: [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; CHECK-NEXT: [[TMP6:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) ; CHECK-NEXT: ret i8* [[TMP6]] ; %2 = icmp eq i32 %0, 0 @@ -146,7 +154,7 @@ define i8** @getter() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@getter -; CHECK-SAME: () #[[ATTR0]] { +; CHECK-SAME: () #[[ATTR3]] { ; CHECK-NEXT: ret i8** @G ; ret i8** @G @@ -156,7 +164,7 @@ define i8** @calle1(){ ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@calle1 -; CHECK-SAME: () #[[ATTR0]] { +; CHECK-SAME: () #[[ATTR3]] { ; CHECK-NEXT: ret i8** @G ; %1 = call i8** @getter() @@ -167,15 +175,15 @@ declare noalias i8* @strdup(i8* nocapture) nounwind define i8* @test6() nounwind uwtable ssp { -; CHECK: Function Attrs: nounwind ssp uwtable +; CHECK: Function Attrs: inaccessiblememonly nofree nounwind ssp willreturn uwtable ; CHECK-LABEL: define {{[^@]+}}@test6 -; CHECK-SAME: () #[[ATTR3:[0-9]+]] { +; CHECK-SAME: () #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: [[X:%.*]] = alloca [2 x i8], align 1 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0 ; CHECK-NEXT: store i8 97, i8* [[ARRAYIDX]], align 1 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1 ; CHECK-NEXT: store i8 0, i8* [[ARRAYIDX1]], align 1 -; CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture noundef nonnull dereferenceable(2) [[ARRAYIDX]]) #[[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture nofree noundef nonnull readonly dereferenceable(2) [[ARRAYIDX]]) #[[ATTR16:[0-9]+]] ; CHECK-NEXT: ret i8* [[CALL]] ; %x = alloca [2 x i8], align 1 @@ -190,11 +198,11 @@ ; TEST 7 define i8* @test7() nounwind { -; CHECK: Function Attrs: nounwind +; CHECK: Function Attrs: nofree nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@test7 -; CHECK-SAME: () #[[ATTR2]] { +; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[A:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR2]] +; CHECK-NEXT: [[A:%.*]] = call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR16]] ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[A]], null ; CHECK-NEXT: br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]] ; CHECK: if.end: @@ -221,10 +229,10 @@ ; TEST 8 define i8* @test8(i32* %0) nounwind uwtable { -; CHECK: Function Attrs: nounwind uwtable +; CHECK: Function Attrs: nofree nounwind willreturn uwtable ; CHECK-LABEL: define {{[^@]+}}@test8 -; CHECK-SAME: (i32* [[TMP0:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; CHECK-SAME: (i32* nofree [[TMP0:%.*]]) #[[ATTR7:[0-9]+]] { +; CHECK-NEXT: [[TMP2:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14]] ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32* [[TMP0]], null ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] ; CHECK: 4: @@ -351,11 +359,11 @@ define void @test12_1() { ; CHECK-LABEL: define {{[^@]+}}@test12_1() { ; CHECK-NEXT: [[A:%.*]] = alloca i8, align 4 -; CHECK-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; CHECK-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] ; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]]) ; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]]) -; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture [[B]]) -; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture [[B]]) +; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef [[B]]) +; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef [[B]]) ; CHECK-NEXT: ret void ; %A = alloca i8, align 4 @@ -369,11 +377,11 @@ define void @test12_2(){ ; CHECK-LABEL: define {{[^@]+}}@test12_2() { -; CHECK-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture [[A]]) -; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture [[A]]) -; CHECK-NEXT: tail call void @use(i8* [[A]]) -; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture [[A]]) +; CHECK-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture noundef [[A]]) +; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture noundef [[A]]) +; CHECK-NEXT: tail call void @use(i8* noundef [[A]]) +; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture noundef [[A]]) ; CHECK-NEXT: ret void ; ; FIXME: This should be @use_nocapture(i8* noalias [[A]]) @@ -389,8 +397,8 @@ declare void @two_args(i8* nocapture , i8* nocapture) define void @test12_3(){ ; CHECK-LABEL: define {{[^@]+}}@test12_3() { -; CHECK-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; CHECK-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]]) +; CHECK-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; CHECK-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A]]) ; CHECK-NEXT: ret void ; %A = tail call noalias i8* @malloc(i64 4) @@ -400,25 +408,23 @@ define void @test12_4(){ ; IS________OPM-LABEL: define {{[^@]+}}@test12_4() { -; IS________OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; IS________OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; IS________OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] ; IS________OPM-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1 -; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]]) -; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]]) -; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]]) -; IS________OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]]) +; IS________OPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[B]]) +; IS________OPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A]]) +; IS________OPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A_1]]) +; IS________OPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[B]]) ; IS________OPM-NEXT: ret void ; ; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test12_4() { -; NOT_TUNIT_OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; NOT_TUNIT_OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; NOT_TUNIT_OPM-NEXT: [[A_0:%.*]] = getelementptr i8, i8* [[A]], i64 0 +; NOT_TUNIT_OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_TUNIT_OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] ; NOT_TUNIT_OPM-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1 -; NOT_TUNIT_OPM-NEXT: [[B_0:%.*]] = getelementptr i8, i8* [[B]], i64 0 -; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* noalias nocapture [[A]], i8* noalias nocapture [[B]]) -; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_0]]) -; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]]) -; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A_0]], i8* nocapture [[B_0]]) +; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* noalias nocapture noundef [[A]], i8* noalias nocapture noundef [[B]]) +; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A]]) +; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A_1]]) +; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[B]]) ; NOT_TUNIT_OPM-NEXT: ret void ; %A = tail call noalias i8* @malloc(i64 4) @@ -450,17 +456,10 @@ } define void @test13_use_noalias(){ -; IS________OPM-LABEL: define {{[^@]+}}@test13_use_noalias() { -; IS________OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: call void @use_i8_internal(i8* noalias nocapture [[M1]]) -; IS________OPM-NEXT: ret void -; -; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test13_use_noalias() { -; NOT_TUNIT_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; NOT_TUNIT_OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16* -; NOT_TUNIT_OPM-NEXT: [[C2:%.*]] = bitcast i16* [[C1]] to i8* -; NOT_TUNIT_OPM-NEXT: call void @use_i8_internal(i8* noalias nocapture [[C2]]) -; NOT_TUNIT_OPM-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@test13_use_noalias() { +; CHECK-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; CHECK-NEXT: call void @use_i8_internal(i8* noalias nocapture noundef [[M1]]) +; CHECK-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias() ; IS__CGSCC_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 4) @@ -476,20 +475,11 @@ } define void @test13_use_alias(){ -; IS________OPM-LABEL: define {{[^@]+}}@test13_use_alias() { -; IS________OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; IS________OPM-NEXT: call void @use_i8_internal(i8* nocapture [[M1]]) -; IS________OPM-NEXT: call void @use_i8_internal(i8* nocapture [[M1]]) -; IS________OPM-NEXT: ret void -; -; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test13_use_alias() { -; NOT_TUNIT_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; NOT_TUNIT_OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16* -; NOT_TUNIT_OPM-NEXT: [[C2A:%.*]] = bitcast i16* [[C1]] to i8* -; NOT_TUNIT_OPM-NEXT: [[C2B:%.*]] = bitcast i16* [[C1]] to i8* -; NOT_TUNIT_OPM-NEXT: call void @use_i8_internal(i8* nocapture [[C2A]]) -; NOT_TUNIT_OPM-NEXT: call void @use_i8_internal(i8* nocapture [[C2B]]) -; NOT_TUNIT_OPM-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@test13_use_alias() { +; CHECK-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; CHECK-NEXT: call void @use_i8_internal(i8* nocapture noundef [[M1]]) +; CHECK-NEXT: call void @use_i8_internal(i8* nocapture noundef [[M1]]) +; CHECK-NEXT: ret void ; %m1 = tail call noalias i8* @malloc(i64 4) %c1 = bitcast i8* %m1 to i16* @@ -504,7 +494,7 @@ define internal i32 @p2i(i32* %arg) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@p2i -; CHECK-SAME: (i32* noalias nofree readnone [[ARG:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nofree readnone [[ARG:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32 ; CHECK-NEXT: ret i32 [[P2I]] ; @@ -515,20 +505,20 @@ define i32 @i2p(i32* %arg) { ; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@i2p -; NOT_CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { -; NOT_CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR9:[0-9]+]] +; NOT_CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR8:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR13:[0-9]+]] ; NOT_CGSCC_NPM-NEXT: [[I2P:%.*]] = inttoptr i32 [[C]] to i8* ; NOT_CGSCC_NPM-NEXT: [[BC:%.*]] = bitcast i8* [[I2P]] to i32* -; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree readonly align 4 [[BC]]) #[[ATTR10:[0-9]+]] +; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree readonly align 4 [[BC]]) #[[ATTR17:[0-9]+]] ; NOT_CGSCC_NPM-NEXT: ret i32 [[CALL]] ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@i2p -; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR10:[0-9]+]] +; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR17:[0-9]+]] ; IS__CGSCC____-NEXT: [[I2P:%.*]] = inttoptr i32 [[C]] to i8* ; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* [[I2P]] to i32* -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[BC]]) #[[ATTR11:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[BC]]) #[[ATTR18:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 [[CALL]] ; %c = call i32 @p2i(i32* %arg) @@ -540,7 +530,7 @@ define internal i32 @ret(i32* %arg) { ; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; CHECK-LABEL: define {{[^@]+}}@ret -; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { +; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR9:[0-9]+]] { ; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4 ; CHECK-NEXT: ret i32 [[L]] ; @@ -558,29 +548,17 @@ ; Function Attrs: nounwind optsize define internal fastcc double @strtox(i8* %s, i8** %p, i32 %prec) unnamed_addr { -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@strtox -; NOT_CGSCC_NPM-SAME: (i8* [[S:%.*]]) unnamed_addr { -; NOT_CGSCC_NPM-NEXT: entry: -; NOT_CGSCC_NPM-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 -; NOT_CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* -; NOT_CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR11:[0-9]+]] -; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) -; NOT_CGSCC_NPM-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) -; NOT_CGSCC_NPM-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) -; NOT_CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) -; NOT_CGSCC_NPM-NEXT: ret double [[CALL1]] -; -; IS__CGSCC____-LABEL: define {{[^@]+}}@strtox -; IS__CGSCC____-SAME: (i8* [[S:%.*]]) unnamed_addr { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 -; IS__CGSCC____-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* -; IS__CGSCC____-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR12:[0-9]+]] -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) -; IS__CGSCC____-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) -; IS__CGSCC____-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) -; IS__CGSCC____-NEXT: ret double [[CALL1]] +; CHECK-LABEL: define {{[^@]+}}@strtox +; CHECK-SAME: (i8* [[S:%.*]]) unnamed_addr { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 +; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* +; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR14]] +; CHECK-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) +; CHECK-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) +; CHECK-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) +; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) +; CHECK-NEXT: ret double [[CALL1]] ; entry: %f = alloca %struct._IO_FILE, align 8 @@ -630,7 +608,7 @@ define void @make_alias(i32* %p) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; CHECK-LABEL: define {{[^@]+}}@make_alias -; CHECK-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] { +; CHECK-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR11:[0-9]+]] { ; CHECK-NEXT: store i32* [[P]], i32** @alias_of_p, align 8 ; CHECK-NEXT: ret void ; @@ -641,7 +619,7 @@ define void @only_store(i32* %p) { ; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; CHECK-LABEL: define {{[^@]+}}@only_store -; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] { +; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR12:[0-9]+]] { ; CHECK-NEXT: store i32 0, i32* [[P]], align 4 ; CHECK-NEXT: ret void ; @@ -652,26 +630,26 @@ define void @test15_caller(i32* noalias %p, i32 %c) { ; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test15_caller -; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { +; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] { ; NOT_CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; NOT_CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; NOT_CGSCC_NPM: if.then: -; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR12:[0-9]+]] +; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR18:[0-9]+]] ; NOT_CGSCC_NPM-NEXT: br label [[IF_END]] ; NOT_CGSCC_NPM: if.end: -; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]] +; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR18]] ; NOT_CGSCC_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test15_caller -; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] { ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13:[0-9]+]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR19:[0-9]+]] ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: ret void ; %tobool = icmp eq i32 %c, 0 @@ -709,36 +687,36 @@ define internal void @test16_sub(i32* noalias %p, i32 %c1, i32 %c2) { ; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test16_sub -; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR7]] { +; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR11]] { ; NOT_CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0 ; NOT_CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; NOT_CGSCC_NPM: if.then: -; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]] -; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly align 4 [[P]]) #[[ATTR12]] +; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* noalias nocapture nofree writeonly align 4 [[P]]) #[[ATTR18]] +; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly align 4 [[P]]) #[[ATTR18]] ; NOT_CGSCC_NPM-NEXT: br label [[IF_END]] ; NOT_CGSCC_NPM: if.end: ; NOT_CGSCC_NPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0 ; NOT_CGSCC_NPM-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] ; NOT_CGSCC_NPM: if.then2: -; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]] +; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR18]] ; NOT_CGSCC_NPM-NEXT: br label [[IF_END3]] ; NOT_CGSCC_NPM: if.end3: ; NOT_CGSCC_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_sub -; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR11]] { ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR19]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: ; IS__CGSCC____-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] ; IS__CGSCC____: if.then2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: br label [[IF_END3]] ; IS__CGSCC____: if.end3: ; IS__CGSCC____-NEXT: ret void @@ -766,14 +744,14 @@ define void @test16_caller(i32* %p, i32 %c) { ; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test16_caller -; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { -; NOT_CGSCC_NPM-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR12]] +; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] { +; NOT_CGSCC_NPM-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR18]] ; NOT_CGSCC_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_caller -; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { -; IS__CGSCC____-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR13]] +; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] { +; IS__CGSCC____-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: ret void ; tail call void @test16_sub(i32* %p, i32 %c, i32 %c) @@ -802,30 +780,30 @@ define void @test17_caller(i32* noalias %p, i32 %c) { ; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test17_caller -; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { +; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] { ; NOT_CGSCC_NPM-NEXT: entry: ; NOT_CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; NOT_CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; NOT_CGSCC_NPM: l1: -; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]] +; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR18]] ; NOT_CGSCC_NPM-NEXT: br label [[L3:%.*]] ; NOT_CGSCC_NPM: l2: -; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]] +; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR18]] ; NOT_CGSCC_NPM-NEXT: br label [[L3]] ; NOT_CGSCC_NPM: l3: ; NOT_CGSCC_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test17_caller -; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; IS__CGSCC____: l1: -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: br label [[L3:%.*]] ; IS__CGSCC____: l2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: br label [[L3]] ; IS__CGSCC____: l3: ; IS__CGSCC____-NEXT: ret void @@ -860,7 +838,7 @@ define void @noreturn() { ; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@noreturn -; CHECK-SAME: () #[[ATTR9:[0-9]+]] { +; CHECK-SAME: () #[[ATTR13:[0-9]+]] { ; CHECK-NEXT: ret void ; call void @noreturn() @@ -870,28 +848,28 @@ define void @test18_caller(i32* noalias %p, i32 %c) { ; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test18_caller -; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { +; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] { ; NOT_CGSCC_NPM-NEXT: entry: ; NOT_CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; NOT_CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; NOT_CGSCC_NPM: l1: -; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]] +; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR18]] ; NOT_CGSCC_NPM-NEXT: br label [[L2]] ; NOT_CGSCC_NPM: l2: -; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]] +; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR18]] ; NOT_CGSCC_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test18_caller -; IS__CGSCC____-SAME: (i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-SAME: (i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[C:%.*]]) #[[ATTR11]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; IS__CGSCC____: l1: -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: br label [[L2]] ; IS__CGSCC____: l2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -908,32 +886,44 @@ ret void } ;. -; NOT_CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR1]] = { nounwind uwtable } -; NOT_CGSCC_NPM: attributes #[[ATTR2]] = { nounwind } -; NOT_CGSCC_NPM: attributes #[[ATTR3]] = { nounwind ssp uwtable } -; NOT_CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readonly willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR6:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly } -; NOT_CGSCC_NPM: attributes #[[ATTR8]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; NOT_CGSCC_NPM: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR10]] = { nofree nosync nounwind readonly willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR11]] = { willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn writeonly } +; NOT_CGSCC_NPM: attributes #[[ATTR0]] = { nofree nounwind willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR1:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(0) "alloc-family"="malloc" } +; NOT_CGSCC_NPM: attributes #[[ATTR2]] = { inaccessiblememonly nofree nounwind willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR4]] = { nounwind uwtable } +; NOT_CGSCC_NPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nofree nounwind willreturn "alloc-family"="malloc" } +; NOT_CGSCC_NPM: attributes #[[ATTR6]] = { inaccessiblememonly nofree nounwind ssp willreturn uwtable } +; NOT_CGSCC_NPM: attributes #[[ATTR7]] = { nofree nounwind willreturn uwtable } +; NOT_CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind readonly willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR10:[0-9]+]] = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind willreturn writeonly } +; NOT_CGSCC_NPM: attributes #[[ATTR12]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; NOT_CGSCC_NPM: attributes #[[ATTR13]] = { nofree nosync nounwind readnone willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR14]] = { willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR15]] = { nounwind } +; NOT_CGSCC_NPM: attributes #[[ATTR16]] = { nounwind willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR17]] = { nofree nosync nounwind readonly willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR18]] = { nofree nosync nounwind willreturn writeonly } ;. -; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { nounwind uwtable } -; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind } -; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind ssp uwtable } -; IS__CGSCC____: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR10]] = { readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR11]] = { readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR12]] = { willreturn } -; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(0) "alloc-family"="malloc" } +; IS__CGSCC____: attributes #[[ATTR2]] = { inaccessiblememonly nofree nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind uwtable } +; IS__CGSCC____: attributes #[[ATTR5:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nofree nounwind willreturn "alloc-family"="malloc" } +; IS__CGSCC____: attributes #[[ATTR6]] = { inaccessiblememonly nofree nounwind ssp willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nounwind willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR10:[0-9]+]] = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR12]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR13]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR14]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR15]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR16]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR17]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR18]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR19]] = { nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll --- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll @@ -1,8 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=50 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=50 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM -; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM +; RUN: opt -inferattrs -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=50 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=inferattrs,attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=50 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM +; RUN: opt -inferattrs -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=inferattrs,attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM ; %struct.S = type { i32, i32, i32, float, float, float } @@ -109,16 +109,16 @@ ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4 ; IS__TUNIT_OPM-NEXT: [[I:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR13:[0-9]+]] +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR20:[0-9]+]] ; IS__TUNIT_OPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__TUNIT_OPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 ; IS__TUNIT_OPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR14:[0-9]+]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR21:[0-9]+]] ; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR14]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]] ; IS__TUNIT_OPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR14]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]] ; IS__TUNIT_OPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__TUNIT_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]] ; IS__TUNIT_OPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 @@ -136,7 +136,7 @@ ; IS__TUNIT_OPM-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2 ; IS__TUNIT_OPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]] ; IS__TUNIT_OPM-NEXT: [[I12:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR13]] +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR20]] ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn @@ -145,16 +145,16 @@ ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4 ; IS__TUNIT_NPM-NEXT: [[I:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR12:[0-9]+]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR18:[0-9]+]] ; IS__TUNIT_NPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__TUNIT_NPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 ; IS__TUNIT_NPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR13:[0-9]+]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR19:[0-9]+]] ; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR13]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR19]] ; IS__TUNIT_NPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR13]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR19]] ; IS__TUNIT_NPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__TUNIT_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]] ; IS__TUNIT_NPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 @@ -172,7 +172,7 @@ ; IS__TUNIT_NPM-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2 ; IS__TUNIT_NPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]] ; IS__TUNIT_NPM-NEXT: [[I12:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn @@ -181,16 +181,16 @@ ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4 ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR13:[0-9]+]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR20:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_OPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 ; IS__CGSCC_OPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR14:[0-9]+]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR21:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]] ; IS__CGSCC_OPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]] ; IS__CGSCC_OPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__CGSCC_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]] ; IS__CGSCC_OPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 @@ -208,7 +208,7 @@ ; IS__CGSCC_OPM-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2 ; IS__CGSCC_OPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]] ; IS__CGSCC_OPM-NEXT: [[I12:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR20]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn @@ -217,16 +217,16 @@ ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR12:[0-9]+]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR18:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_NPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 ; IS__CGSCC_NPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR13:[0-9]+]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR19:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR19]] ; IS__CGSCC_NPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR19]] ; IS__CGSCC_NPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__CGSCC_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]] ; IS__CGSCC_NPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 @@ -244,7 +244,7 @@ ; IS__CGSCC_NPM-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2 ; IS__CGSCC_NPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]] ; IS__CGSCC_NPM-NEXT: [[I12:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR18]] ; IS__CGSCC_NPM-NEXT: ret void ; entry: @@ -383,7 +383,7 @@ ; IS__TUNIT_OPM-NEXT: store i8 0, i8* [[ARRAYIDX25]], align 1, !tbaa [[TBAA15]] ; IS__TUNIT_OPM-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 500 ; IS__TUNIT_OPM-NEXT: [[I22:%.*]] = bitcast i8* [[ARRAYIDX26]] to i32* -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(524) [[I22]], i32 noundef 0) #[[ATTR15:[0-9]+]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(524) [[I22]], i32 noundef 0) #[[ATTR22:[0-9]+]] ; IS__TUNIT_OPM-NEXT: br label [[FOR_COND28:%.*]] ; IS__TUNIT_OPM: for.cond28: ; IS__TUNIT_OPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ] @@ -411,7 +411,7 @@ ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 ; IS__TUNIT_NPM-NEXT: [[I:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 0 -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1024, i8* nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[I]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1024, i8* nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[I]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]] ; IS__TUNIT_NPM: for.cond: ; IS__TUNIT_NPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] @@ -468,7 +468,7 @@ ; IS__TUNIT_NPM-NEXT: store i8 0, i8* [[ARRAYIDX25]], align 1, !tbaa [[TBAA15]] ; IS__TUNIT_NPM-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 500 ; IS__TUNIT_NPM-NEXT: [[I22:%.*]] = bitcast i8* [[ARRAYIDX26]] to i32* -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(524) [[I22]], i32 noundef 0) #[[ATTR13]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(524) [[I22]], i32 noundef 0) #[[ATTR19]] ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND28:%.*]] ; IS__TUNIT_NPM: for.cond28: ; IS__TUNIT_NPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ] @@ -487,7 +487,7 @@ ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND28]], !llvm.loop [[LOOP23:![0-9]+]] ; IS__TUNIT_NPM: for.end38: ; IS__TUNIT_NPM-NEXT: [[I24:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 0 -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 1024, i8* nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[I24]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 1024, i8* nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[I24]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@local_alloca_simplifiable_2() { @@ -551,7 +551,7 @@ ; IS__CGSCC_OPM-NEXT: store i8 0, i8* [[ARRAYIDX25]], align 1, !tbaa [[TBAA15]] ; IS__CGSCC_OPM-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 500 ; IS__CGSCC_OPM-NEXT: [[I22:%.*]] = bitcast i8* [[ARRAYIDX26]] to i32* -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR15:[0-9]+]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR22:[0-9]+]] ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND28:%.*]] ; IS__CGSCC_OPM: for.cond28: ; IS__CGSCC_OPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ] @@ -577,7 +577,7 @@ ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 0 -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1024, i8* nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[I]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1024, i8* nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[I]]) #[[ATTR18]] ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND:%.*]] ; IS__CGSCC_NPM: for.cond: ; IS__CGSCC_NPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] @@ -634,7 +634,7 @@ ; IS__CGSCC_NPM-NEXT: store i8 0, i8* [[ARRAYIDX25]], align 1, !tbaa [[TBAA15]] ; IS__CGSCC_NPM-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 500 ; IS__CGSCC_NPM-NEXT: [[I22:%.*]] = bitcast i8* [[ARRAYIDX26]] to i32* -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR14:[0-9]+]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR20:[0-9]+]] ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND28:%.*]] ; IS__CGSCC_NPM: for.cond28: ; IS__CGSCC_NPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ] @@ -831,7 +831,7 @@ ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__TUNIT_OPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR13]] +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR20]] ; IS__TUNIT_OPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__TUNIT_OPM: cond.true: @@ -840,7 +840,7 @@ ; IS__TUNIT_OPM-NEXT: br label [[COND_END]] ; IS__TUNIT_OPM: cond.end: ; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = bitcast i32* [[L]] to i8* -; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR13]] +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR20]] ; IS__TUNIT_OPM-NEXT: ret i32 5 ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -849,7 +849,7 @@ ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__TUNIT_NPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__TUNIT_NPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__TUNIT_NPM: cond.true: @@ -858,7 +858,7 @@ ; IS__TUNIT_NPM-NEXT: br label [[COND_END]] ; IS__TUNIT_NPM: cond.end: ; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = bitcast i32* [[L]] to i8* -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: ret i32 5 ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -867,7 +867,7 @@ ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR20]] ; IS__CGSCC_OPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__CGSCC_OPM: cond.true: @@ -876,7 +876,7 @@ ; IS__CGSCC_OPM-NEXT: br label [[COND_END]] ; IS__CGSCC_OPM: cond.end: ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR20]] ; IS__CGSCC_OPM-NEXT: ret i32 5 ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -885,7 +885,7 @@ ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR18]] ; IS__CGSCC_NPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__CGSCC_NPM: cond.true: @@ -894,7 +894,7 @@ ; IS__CGSCC_NPM-NEXT: br label [[COND_END]] ; IS__CGSCC_NPM: cond.end: ; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR18]] ; IS__CGSCC_NPM-NEXT: ret i32 5 ; entry: @@ -935,7 +935,7 @@ ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__TUNIT_OPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR13]] +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR20]] ; IS__TUNIT_OPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__TUNIT_OPM: cond.true: @@ -944,7 +944,7 @@ ; IS__TUNIT_OPM-NEXT: br label [[COND_END]] ; IS__TUNIT_OPM: cond.end: ; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = bitcast i32* [[L]] to i8* -; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR13]] +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR20]] ; IS__TUNIT_OPM-NEXT: ret i32 5 ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -953,7 +953,7 @@ ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__TUNIT_NPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__TUNIT_NPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__TUNIT_NPM: cond.true: @@ -962,7 +962,7 @@ ; IS__TUNIT_NPM-NEXT: br label [[COND_END]] ; IS__TUNIT_NPM: cond.end: ; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = bitcast i32* [[L]] to i8* -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: ret i32 5 ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -971,7 +971,7 @@ ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR20]] ; IS__CGSCC_OPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__CGSCC_OPM: cond.true: @@ -980,7 +980,7 @@ ; IS__CGSCC_OPM-NEXT: br label [[COND_END]] ; IS__CGSCC_OPM: cond.end: ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR20]] ; IS__CGSCC_OPM-NEXT: ret i32 5 ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -989,7 +989,7 @@ ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR18]] ; IS__CGSCC_NPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__CGSCC_NPM: cond.true: @@ -998,7 +998,7 @@ ; IS__CGSCC_NPM-NEXT: br label [[COND_END]] ; IS__CGSCC_NPM: cond.end: ; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR18]] ; IS__CGSCC_NPM-NEXT: ret i32 5 ; entry: @@ -1046,9 +1046,9 @@ ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@static_global_simplifiable_1 ; IS__TUNIT_OPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR6:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR14]] -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR14]] -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR14]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR21]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR21]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR21]] ; IS__TUNIT_OPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__TUNIT_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7]] ; IS__TUNIT_OPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 @@ -1071,9 +1071,9 @@ ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@static_global_simplifiable_1 ; IS__TUNIT_NPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR13]] -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR13]] -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR13]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR19]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR19]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR19]] ; IS__TUNIT_NPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__TUNIT_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7]] ; IS__TUNIT_NPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 @@ -1096,9 +1096,9 @@ ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@static_global_simplifiable_1 ; IS__CGSCC_OPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR14]] -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR14]] -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR21]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR21]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR21]] ; IS__CGSCC_OPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__CGSCC_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7]] ; IS__CGSCC_OPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 @@ -1121,9 +1121,9 @@ ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@static_global_simplifiable_1 ; IS__CGSCC_NPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR13]] -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR13]] -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR19]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR19]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR19]] ; IS__CGSCC_NPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__CGSCC_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7]] ; IS__CGSCC_NPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 @@ -1247,7 +1247,7 @@ ; IS__TUNIT_OPM-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP26:![0-9]+]] ; IS__TUNIT_OPM: for.end23: ; IS__TUNIT_OPM-NEXT: store i8 0, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 1023), align 1, !tbaa [[TBAA15]] -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(524) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR15]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(524) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR22]] ; IS__TUNIT_OPM-NEXT: br label [[FOR_COND25:%.*]] ; IS__TUNIT_OPM: for.cond25: ; IS__TUNIT_OPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ] @@ -1322,7 +1322,7 @@ ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP26:![0-9]+]] ; IS__TUNIT_NPM: for.end23: ; IS__TUNIT_NPM-NEXT: store i8 0, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 1023), align 1, !tbaa [[TBAA15]] -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(524) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR13]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree writeonly align 4 dereferenceable_or_null(524) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR19]] ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND25:%.*]] ; IS__TUNIT_NPM: for.cond25: ; IS__TUNIT_NPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ] @@ -1395,7 +1395,7 @@ ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP26:![0-9]+]] ; IS__CGSCC_OPM: for.end23: ; IS__CGSCC_OPM-NEXT: store i8 0, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 1023), align 1, !tbaa [[TBAA15]] -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR22]] ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND25:%.*]] ; IS__CGSCC_OPM: for.cond25: ; IS__CGSCC_OPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ] @@ -1468,7 +1468,7 @@ ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP26:![0-9]+]] ; IS__CGSCC_NPM: for.end23: ; IS__CGSCC_NPM-NEXT: store i8 0, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 1023), align 1, !tbaa [[TBAA15]] -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND25:%.*]] ; IS__CGSCC_NPM: for.cond25: ; IS__CGSCC_NPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ] @@ -1642,11 +1642,11 @@ ; IS__TUNIT_OPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__TUNIT_OPM-NEXT: store float 0x400A666660000000, float* [[F3]], align 4, !tbaa [[TBAA11]] ; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR14]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR21]] ; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR14]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]] ; IS__TUNIT_OPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR14]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]] ; IS__TUNIT_OPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__TUNIT_OPM-NEXT: [[I:%.*]] = load float, float* [[F11]], align 4, !tbaa [[TBAA7]] ; IS__TUNIT_OPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 @@ -1692,11 +1692,11 @@ ; IS__TUNIT_NPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__TUNIT_NPM-NEXT: store float 0x400A666660000000, float* [[F3]], align 4, !tbaa [[TBAA11]] ; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR13]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR19]] ; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR13]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR19]] ; IS__TUNIT_NPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR13]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR19]] ; IS__TUNIT_NPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__TUNIT_NPM-NEXT: [[I:%.*]] = load float, float* [[F11]], align 4, !tbaa [[TBAA7]] ; IS__TUNIT_NPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 @@ -1742,11 +1742,11 @@ ; IS__CGSCC_OPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__CGSCC_OPM-NEXT: store float 0x400A666660000000, float* [[F3]], align 4, !tbaa [[TBAA11]] ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR21]] ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]] ; IS__CGSCC_OPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]] ; IS__CGSCC_OPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = load float, float* [[F11]], align 4, !tbaa [[TBAA7]] ; IS__CGSCC_OPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 @@ -1792,11 +1792,11 @@ ; IS__CGSCC_NPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__CGSCC_NPM-NEXT: store float 0x400A666660000000, float* [[F3]], align 4, !tbaa [[TBAA11]] ; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR19]] ; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR19]] ; IS__CGSCC_NPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR19]] ; IS__CGSCC_NPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = load float, float* [[F11]], align 4, !tbaa [[TBAA7]] ; IS__CGSCC_NPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 @@ -1954,7 +1954,7 @@ ; IS__TUNIT_OPM-NEXT: store i8 0, i8* [[ARRAYIDX24]], align 1, !tbaa [[TBAA15]] ; IS__TUNIT_OPM-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i64 500 ; IS__TUNIT_OPM-NEXT: [[I21:%.*]] = bitcast i8* [[ARRAYIDX25]] to i32* -; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 [[I21]], i32 noundef 0) #[[ATTR15]] +; IS__TUNIT_OPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 [[I21]], i32 noundef 0) #[[ATTR22]] ; IS__TUNIT_OPM-NEXT: br label [[FOR_COND27:%.*]] ; IS__TUNIT_OPM: for.cond27: ; IS__TUNIT_OPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ] @@ -2034,7 +2034,7 @@ ; IS__TUNIT_NPM-NEXT: store i8 0, i8* [[ARRAYIDX24]], align 1, !tbaa [[TBAA15]] ; IS__TUNIT_NPM-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i64 500 ; IS__TUNIT_NPM-NEXT: [[I21:%.*]] = bitcast i8* [[ARRAYIDX25]] to i32* -; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 [[I21]], i32 noundef 0) #[[ATTR13]] +; IS__TUNIT_NPM-NEXT: call void @write_arg(i32* nocapture nofree nonnull writeonly align 4 [[I21]], i32 noundef 0) #[[ATTR19]] ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND27:%.*]] ; IS__TUNIT_NPM: for.cond27: ; IS__TUNIT_NPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ] @@ -2113,7 +2113,7 @@ ; IS__CGSCC_OPM-NEXT: store i8 0, i8* [[ARRAYIDX24]], align 1, !tbaa [[TBAA15]] ; IS__CGSCC_OPM-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i64 500 ; IS__CGSCC_OPM-NEXT: [[I21:%.*]] = bitcast i8* [[ARRAYIDX25]] to i32* -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR22]] ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND27:%.*]] ; IS__CGSCC_OPM: for.cond27: ; IS__CGSCC_OPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ] @@ -2192,7 +2192,7 @@ ; IS__CGSCC_NPM-NEXT: store i8 0, i8* [[ARRAYIDX24]], align 1, !tbaa [[TBAA15]] ; IS__CGSCC_NPM-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i64 500 ; IS__CGSCC_NPM-NEXT: [[I21:%.*]] = bitcast i8* [[ARRAYIDX25]] to i32* -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND27:%.*]] ; IS__CGSCC_NPM: for.cond27: ; IS__CGSCC_NPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ] @@ -2325,9 +2325,9 @@ ; IS________OPM-NEXT: [[X:%.*]] = alloca i32, align 4 ; IS________OPM-NEXT: [[Y:%.*]] = alloca i32, align 4 ; IS________OPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR13:[0-9]+]] +; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR20:[0-9]+]] ; IS________OPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR13]] +; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR20]] ; IS________OPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] ; IS________OPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] ; IS________OPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* @@ -2350,9 +2350,9 @@ ; IS________NPM-NEXT: [[X:%.*]] = alloca i32, align 4 ; IS________NPM-NEXT: [[Y:%.*]] = alloca i32, align 4 ; IS________NPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR12:[0-9]+]] +; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR18:[0-9]+]] ; IS________NPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR12]] +; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR18]] ; IS________NPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] ; IS________NPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] ; IS________NPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* @@ -3254,18 +3254,20 @@ } define dso_local i32 @round_trip_malloc(i32 %x) { +; IS________OPM: Function Attrs: nounwind willreturn ; IS________OPM-LABEL: define {{[^@]+}}@round_trip_malloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { +; IS________OPM-SAME: (i32 [[X:%.*]]) #[[ATTR10:[0-9]+]] { ; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16:[0-9]+]] +; IS________OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @malloc(i64 noundef 4) #[[ATTR23:[0-9]+]] ; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS________OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 ; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR16]] +; IS________OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24:[0-9]+]] ; IS________OPM-NEXT: ret i32 [[TMP1]] ; +; IS________NPM: Function Attrs: nounwind willreturn ; IS________NPM-LABEL: define {{[^@]+}}@round_trip_malloc -; IS________NPM-SAME: (i32 returned [[X:%.*]]) { +; IS________NPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR8:[0-9]+]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* @@ -3283,16 +3285,20 @@ } define dso_local i32 @round_trip_malloc_constant() { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { +; IS________OPM: Function Attrs: nounwind willreturn +; IS________OPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant +; IS________OPM-SAME: () #[[ATTR10]] { ; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16]] +; IS________OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @malloc(i64 noundef 4) #[[ATTR23]] ; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS________OPM-NEXT: store i32 7, i32* [[TMP0]], align 4 ; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR16]] +; IS________OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24]] ; IS________OPM-NEXT: ret i32 [[TMP1]] ; -; IS________NPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { +; IS________NPM: Function Attrs: nounwind willreturn +; IS________NPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant +; IS________NPM-SAME: () #[[ATTR8]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: ret i32 7 ; @@ -3311,22 +3317,23 @@ declare void @free(i8*) define dso_local i32 @conditional_malloc(i32 %x) { +; IS________OPM: Function Attrs: nofree nounwind willreturn ; IS________OPM-LABEL: define {{[^@]+}}@conditional_malloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { +; IS________OPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR13:[0-9]+]] { ; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS________OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* ; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 ; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; IS________OPM: if.then: -; IS________OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS________OPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 ; IS________OPM-NEXT: br label [[IF_END]] ; IS________OPM: if.end: -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS________OPM-NEXT: ret i32 [[X]] ; +; IS________NPM: Function Attrs: nofree nounwind willreturn ; IS________NPM-LABEL: define {{[^@]+}}@conditional_malloc -; IS________NPM-SAME: (i32 returned [[X:%.*]]) { +; IS________NPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR11:[0-9]+]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* @@ -3354,17 +3361,20 @@ } define dso_local i32 @round_trip_calloc(i32 %x) { +; IS________OPM: Function Attrs: nofree nounwind willreturn ; IS________OPM-LABEL: define {{[^@]+}}@round_trip_calloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { +; IS________OPM-SAME: (i32 [[X:%.*]]) #[[ATTR13]] { ; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: ret i32 [[TMP1]] -; +; IS________OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS________OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS________OPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 +; IS________OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS________OPM-NEXT: ret i32 [[TMP2]] +; +; IS________NPM: Function Attrs: nofree nounwind willreturn ; IS________NPM-LABEL: define {{[^@]+}}@round_trip_calloc -; IS________NPM-SAME: (i32 [[X:%.*]]) { +; IS________NPM-SAME: (i32 [[X:%.*]]) #[[ATTR11]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) @@ -3382,15 +3392,20 @@ } define dso_local i32 @round_trip_calloc_constant() { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { +; IS________OPM: Function Attrs: nofree nounwind willreturn +; IS________OPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant +; IS________OPM-SAME: () #[[ATTR13]] { ; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: store i32 11, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: ret i32 [[TMP1]] -; -; IS________NPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { +; IS________OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS________OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS________OPM-NEXT: store i32 11, i32* [[TMP1]], align 4 +; IS________OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS________OPM-NEXT: ret i32 [[TMP2]] +; +; IS________NPM: Function Attrs: nofree nounwind willreturn +; IS________NPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant +; IS________NPM-SAME: () #[[ATTR11]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) @@ -3410,10 +3425,11 @@ declare noalias i8* @calloc(i64, i64) define dso_local i32 @conditional_calloc(i32 %x) { +; IS________OPM: Function Attrs: nounwind willreturn ; IS________OPM-LABEL: define {{[^@]+}}@conditional_calloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { +; IS________OPM-SAME: (i32 [[X:%.*]]) #[[ATTR10]] { ; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR16]] +; IS________OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR23]] ; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 ; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] @@ -3423,11 +3439,12 @@ ; IS________OPM: if.end: ; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 ; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* -; IS________OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR16]] +; IS________OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP2]]) #[[ATTR24]] ; IS________OPM-NEXT: ret i32 [[TMP1]] ; +; IS________NPM: Function Attrs: nounwind willreturn ; IS________NPM-LABEL: define {{[^@]+}}@conditional_calloc -; IS________NPM-SAME: (i32 [[X:%.*]]) { +; IS________NPM-SAME: (i32 [[X:%.*]]) #[[ATTR8]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) @@ -3439,7 +3456,6 @@ ; IS________NPM-NEXT: br label [[IF_END]] ; IS________NPM: if.end: ; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 -; IS________NPM-NEXT: [[TMP3:%.*]] = bitcast i32* [[TMP1]] to i8* ; IS________NPM-NEXT: ret i32 [[TMP2]] ; entry: @@ -3460,10 +3476,11 @@ } define dso_local i32 @conditional_calloc_zero(i1 %c) { +; IS________OPM: Function Attrs: nounwind willreturn ; IS________OPM-LABEL: define {{[^@]+}}@conditional_calloc_zero -; IS________OPM-SAME: (i1 [[C:%.*]]) { +; IS________OPM-SAME: (i1 [[C:%.*]]) #[[ATTR10]] { ; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR16]] +; IS________OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR23]] ; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS________OPM-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS________OPM: if.then: @@ -3472,20 +3489,19 @@ ; IS________OPM: if.end: ; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 ; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* -; IS________OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR16]] +; IS________OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP2]]) #[[ATTR24]] ; IS________OPM-NEXT: ret i32 [[TMP1]] ; +; IS________NPM: Function Attrs: nounwind willreturn ; IS________NPM-LABEL: define {{[^@]+}}@conditional_calloc_zero -; IS________NPM-SAME: (i1 [[C:%.*]]) { +; IS________NPM-SAME: (i1 [[C:%.*]]) #[[ATTR8]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 ; IS________NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) -; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* ; IS________NPM-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS________NPM: if.then: ; IS________NPM-NEXT: br label [[IF_END]] ; IS________NPM: if.end: -; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP1]] to i8* ; IS________NPM-NEXT: ret i32 0 ; entry: @@ -3505,27 +3521,30 @@ } define dso_local i32* @malloc_like(i32 %s) { +; IS________OPM: Function Attrs: inaccessiblememonly nofree nounwind willreturn ; IS________OPM-LABEL: define {{[^@]+}}@malloc_like -; IS________OPM-SAME: (i32 [[S:%.*]]) { +; IS________OPM-SAME: (i32 [[S:%.*]]) #[[ATTR15:[0-9]+]] { ; IS________OPM-NEXT: entry: ; IS________OPM-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR16]] +; IS________OPM-NEXT: [[CALL:%.*]] = call noalias noundef i8* @malloc(i64 noundef [[CONV]]) #[[ATTR23]] ; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS________OPM-NEXT: ret i32* [[TMP0]] ; +; IS__TUNIT_NPM: Function Attrs: inaccessiblememonly nofree nounwind willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@malloc_like -; IS__TUNIT_NPM-SAME: (i32 [[S:%.*]]) { +; IS__TUNIT_NPM-SAME: (i32 [[S:%.*]]) #[[ATTR13:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 -; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR14:[0-9]+]] +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noalias noundef i8* @malloc(i64 noundef [[CONV]]) #[[ATTR20:[0-9]+]] ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__TUNIT_NPM-NEXT: ret i32* [[TMP0]] ; +; IS__CGSCC_NPM: Function Attrs: inaccessiblememonly nofree nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@malloc_like -; IS__CGSCC_NPM-SAME: (i32 [[S:%.*]]) { +; IS__CGSCC_NPM-SAME: (i32 [[S:%.*]]) #[[ATTR13:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR15:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias noundef i8* @malloc(i64 noundef [[CONV]]) #[[ATTR21:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__CGSCC_NPM-NEXT: ret i32* [[TMP0]] ; @@ -3537,34 +3556,48 @@ } define dso_local i32 @round_trip_malloc_like(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_malloc_like -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS________OPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP0]] -; +; IS__TUNIT_OPM: Function Attrs: nounwind willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_like +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR10]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i32* @malloc_like(i32 noundef 4) #[[ATTR25:[0-9]+]] +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__TUNIT_OPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR24]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP0]] +; +; IS__TUNIT_NPM: Function Attrs: nounwind willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@round_trip_malloc_like -; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) #[[ATTR8]] { ; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR14]] +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noalias i32* @malloc_like(i32 noundef 4) #[[ATTR21:[0-9]+]] ; IS__TUNIT_NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 ; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS__TUNIT_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR14]] +; IS__TUNIT_NPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR22:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP0]] ; +; IS__CGSCC_OPM: Function Attrs: nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_like +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR10]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i32* @malloc_like(i32 noundef 4) #[[ATTR24]] +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR24]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP0]] +; +; IS__CGSCC_NPM: Function Attrs: nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@round_trip_malloc_like -; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) #[[ATTR8]] { ; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i32* @malloc_like(i32 noundef 4) #[[ATTR22:[0-9]+]] ; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS__CGSCC_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR22]] ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] ; entry: @@ -3577,35 +3610,35 @@ } define dso_local i32 @round_trip_unknown_alloc(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS________OPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP0]] -; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc -; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR14]] -; IS__TUNIT_NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS__TUNIT_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR14]] -; IS__TUNIT_NPM-NEXT: ret i32 [[TMP0]] -; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc -; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR15]] -; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS__CGSCC_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR15]] -; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR26:[0-9]+]] +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__TUNIT_OPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR27:[0-9]+]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP0]] +; +; IS________NPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc +; IS________NPM-SAME: (i32 [[X:%.*]]) { +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR23:[0-9]+]] +; IS________NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS________NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS________NPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR24:[0-9]+]] +; IS________NPM-NEXT: ret i32 [[TMP0]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR25:[0-9]+]] +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR26:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP0]] ; entry: %call = call i32* @unknown_alloc(i32 4) norecurse @@ -3619,50 +3652,50 @@ declare noalias i32* @unknown_alloc(i32) define dso_local i32 @conditional_unknown_alloc(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 -; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; IS________OPM: if.then: -; IS________OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS________OPM-NEXT: br label [[IF_END]] -; IS________OPM: if.end: -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS________OPM-NEXT: call void @free(i8* [[TMP1]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP0]] -; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc -; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR14]] -; IS__TUNIT_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 -; IS__TUNIT_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; IS__TUNIT_NPM: if.then: -; IS__TUNIT_NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS__TUNIT_NPM-NEXT: br label [[IF_END]] -; IS__TUNIT_NPM: if.end: -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS__TUNIT_NPM-NEXT: call void @free(i8* [[TMP1]]) #[[ATTR14]] -; IS__TUNIT_NPM-NEXT: ret i32 [[TMP0]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR26]] +; IS__TUNIT_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__TUNIT_OPM: if.then: +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: br label [[IF_END]] +; IS__TUNIT_OPM: if.end: +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__TUNIT_OPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR27]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP0]] +; +; IS________NPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc +; IS________NPM-SAME: (i32 [[X:%.*]]) { +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR23]] +; IS________NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS________NPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS________NPM: if.then: +; IS________NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS________NPM-NEXT: br label [[IF_END]] +; IS________NPM: if.end: +; IS________NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS________NPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR24]] +; IS________NPM-NEXT: ret i32 [[TMP0]] ; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc -; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR15]] -; IS__CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 -; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; IS__CGSCC_NPM: if.then: -; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS__CGSCC_NPM-NEXT: br label [[IF_END]] -; IS__CGSCC_NPM: if.end: -; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS__CGSCC_NPM-NEXT: call void @free(i8* [[TMP1]]) #[[ATTR15]] -; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR25]] +; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__CGSCC_OPM: if.then: +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: br label [[IF_END]] +; IS__CGSCC_OPM: if.end: +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR26]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP0]] ; entry: %call = call noalias i32* @unknown_alloc(i32 4) norecurse @@ -3686,69 +3719,39 @@ ; We mark %dst as writeonly and %src as readonly, that is (for now) all we can expect. define dso_local void @test_nested_memory(float* %dst, double* %src) { -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test_nested_memory -; IS__TUNIT_OPM-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) { -; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 -; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast %struct.STy* [[LOCAL]] to i8* -; IS__TUNIT_OPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[LOCAL]], i64 0, i32 2 -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias dereferenceable_or_null(24) i8* @malloc(i64 noundef 24) -; IS__TUNIT_OPM-NEXT: [[DST1:%.*]] = bitcast i8* [[CALL]] to float** -; IS__TUNIT_OPM-NEXT: store float* [[DST]], float** [[DST1]], align 8 -; IS__TUNIT_OPM-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 8 -; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[SRC2]] to double** -; IS__TUNIT_OPM-NEXT: store double* [[SRC]], double** [[TMP1]], align 8 -; IS__TUNIT_OPM-NEXT: store i8* [[CALL]], i8** bitcast (%struct.STy** getelementptr inbounds ([[STRUCT_STY]], %struct.STy* @global, i64 0, i32 2) to i8**), align 8 -; IS__TUNIT_OPM-NEXT: call fastcc void @nested_memory_callee() #[[ATTR17:[0-9]+]] -; IS__TUNIT_OPM-NEXT: ret void -; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test_nested_memory -; IS__TUNIT_NPM-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast %struct.STy* [[LOCAL]] to i8* -; IS__TUNIT_NPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[LOCAL]], i64 0, i32 2 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 24, align 1 -; IS__TUNIT_NPM-NEXT: [[DST1:%.*]] = bitcast i8* [[TMP1]] to float** -; IS__TUNIT_NPM-NEXT: store float* [[DST]], float** [[DST1]], align 8 -; IS__TUNIT_NPM-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 8 -; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[SRC2]] to double** -; IS__TUNIT_NPM-NEXT: store double* [[SRC]], double** [[TMP2]], align 8 -; IS__TUNIT_NPM-NEXT: store i8* [[TMP1]], i8** bitcast (%struct.STy** getelementptr inbounds ([[STRUCT_STY]], %struct.STy* @global, i64 0, i32 2) to i8**), align 8 -; IS__TUNIT_NPM-NEXT: call fastcc void @nested_memory_callee() #[[ATTR15:[0-9]+]] -; IS__TUNIT_NPM-NEXT: ret void -; -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_nested_memory -; IS__CGSCC_OPM-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 -; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast %struct.STy* [[LOCAL]] to i8* -; IS__CGSCC_OPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[LOCAL]], i64 0, i32 2 -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias dereferenceable_or_null(24) i8* @malloc(i64 noundef 24) -; IS__CGSCC_OPM-NEXT: [[DST1:%.*]] = bitcast i8* [[CALL]] to float** -; IS__CGSCC_OPM-NEXT: store float* [[DST]], float** [[DST1]], align 8 -; IS__CGSCC_OPM-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 8 -; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[SRC2]] to double** -; IS__CGSCC_OPM-NEXT: store double* [[SRC]], double** [[TMP1]], align 8 -; IS__CGSCC_OPM-NEXT: store i8* [[CALL]], i8** bitcast (%struct.STy** getelementptr inbounds ([[STRUCT_STY]], %struct.STy* @global, i64 0, i32 2) to i8**), align 8 -; IS__CGSCC_OPM-NEXT: call fastcc void @nested_memory_callee() #[[ATTR15]] -; IS__CGSCC_OPM-NEXT: ret void +; IS________OPM: Function Attrs: nofree nounwind willreturn +; IS________OPM-LABEL: define {{[^@]+}}@test_nested_memory +; IS________OPM-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) #[[ATTR13]] { +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 +; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast %struct.STy* [[LOCAL]] to i8* +; IS________OPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[LOCAL]], i64 0, i32 2 +; IS________OPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 24, align 1 +; IS________OPM-NEXT: [[DST1:%.*]] = bitcast i8* [[TMP1]] to float** +; IS________OPM-NEXT: store float* [[DST]], float** [[DST1]], align 8 +; IS________OPM-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 8 +; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[SRC2]] to double** +; IS________OPM-NEXT: store double* [[SRC]], double** [[TMP2]], align 8 +; IS________OPM-NEXT: store i8* [[TMP1]], i8** bitcast (%struct.STy** getelementptr inbounds ([[STRUCT_STY]], %struct.STy* @global, i64 0, i32 2) to i8**), align 8 +; IS________OPM-NEXT: call fastcc void @nested_memory_callee() #[[ATTR10]] +; IS________OPM-NEXT: ret void ; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_nested_memory -; IS__CGSCC_NPM-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 -; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast %struct.STy* [[LOCAL]] to i8* -; IS__CGSCC_NPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[LOCAL]], i64 0, i32 2 -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 24, align 1 -; IS__CGSCC_NPM-NEXT: [[DST1:%.*]] = bitcast i8* [[TMP1]] to float** -; IS__CGSCC_NPM-NEXT: store float* [[DST]], float** [[DST1]], align 8 -; IS__CGSCC_NPM-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 8 -; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[SRC2]] to double** -; IS__CGSCC_NPM-NEXT: store double* [[SRC]], double** [[TMP2]], align 8 -; IS__CGSCC_NPM-NEXT: store i8* [[TMP1]], i8** bitcast (%struct.STy** getelementptr inbounds ([[STRUCT_STY]], %struct.STy* @global, i64 0, i32 2) to i8**), align 8 -; IS__CGSCC_NPM-NEXT: call fastcc void @nested_memory_callee() #[[ATTR14]] -; IS__CGSCC_NPM-NEXT: ret void +; IS________NPM: Function Attrs: nofree nounwind willreturn +; IS________NPM-LABEL: define {{[^@]+}}@test_nested_memory +; IS________NPM-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) #[[ATTR11]] { +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 +; IS________NPM-NEXT: [[TMP0:%.*]] = bitcast %struct.STy* [[LOCAL]] to i8* +; IS________NPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[LOCAL]], i64 0, i32 2 +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 24, align 1 +; IS________NPM-NEXT: [[DST1:%.*]] = bitcast i8* [[TMP1]] to float** +; IS________NPM-NEXT: store float* [[DST]], float** [[DST1]], align 8 +; IS________NPM-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 8 +; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[SRC2]] to double** +; IS________NPM-NEXT: store double* [[SRC]], double** [[TMP2]], align 8 +; IS________NPM-NEXT: store i8* [[TMP1]], i8** bitcast (%struct.STy** getelementptr inbounds ([[STRUCT_STY]], %struct.STy* @global, i64 0, i32 2) to i8**), align 8 +; IS________NPM-NEXT: call fastcc void @nested_memory_callee() #[[ATTR8]] +; IS________NPM-NEXT: ret void ; entry: %local = alloca %struct.STy, align 8 @@ -3769,7 +3772,7 @@ define internal fastcc void @nested_memory_callee(%struct.STy* nocapture readonly %S) nofree norecurse nounwind uwtable { ; IS________OPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable ; IS________OPM-LABEL: define {{[^@]+}}@nested_memory_callee -; IS________OPM-SAME: () #[[ATTR10:[0-9]+]] { +; IS________OPM-SAME: () #[[ATTR16:[0-9]+]] { ; IS________OPM-NEXT: entry: ; IS________OPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** getelementptr inbounds ([[STRUCT_STY:%.*]], %struct.STy* @global, i64 0, i32 2), align 8 ; IS________OPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 1 @@ -3783,7 +3786,7 @@ ; ; IS________NPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable ; IS________NPM-LABEL: define {{[^@]+}}@nested_memory_callee -; IS________NPM-SAME: () #[[ATTR8:[0-9]+]] { +; IS________NPM-SAME: () #[[ATTR14:[0-9]+]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** getelementptr inbounds ([[STRUCT_STY:%.*]], %struct.STy* @global, i64 0, i32 2), align 8 ; IS________NPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 1 @@ -3815,7 +3818,7 @@ define hidden void @no_propagation_of_unknown_index_access(i32* %in, i32* %out, i32 %idx) #0 { ; IS________OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind ; IS________OPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access -; IS________OPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR11:[0-9]+]] { +; IS________OPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR17:[0-9]+]] { ; IS________OPM-NEXT: entry: ; IS________OPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 ; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* @@ -3862,7 +3865,7 @@ ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 ; IS________NPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR12]] +; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR18]] ; IS________NPM-NEXT: br label [[FOR_COND:%.*]] ; IS________NPM: for.cond: ; IS________NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] @@ -3883,7 +3886,7 @@ ; IS________NPM-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 ; IS________NPM-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] ; IS________NPM: for.cond.cleanup6: -; IS________NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR12]] +; IS________NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR18]] ; IS________NPM-NEXT: ret void ; IS________NPM: for.body7: ; IS________NPM-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 @@ -3950,12 +3953,12 @@ define internal i1 @alloca_non_unique(i32* %p, i32 %in, i1 %c) { ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@alloca_non_unique -; IS__TUNIT_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR18:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__TUNIT_OPM-NEXT: store i32 [[IN]], i32* [[A]], align 4 ; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT_OPM: t: -; IS__TUNIT_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR18:[0-9]+]] +; IS__TUNIT_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR28:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret i1 [[R]] ; IS__TUNIT_OPM: f: ; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 @@ -3964,12 +3967,12 @@ ; ; IS________NPM: Function Attrs: argmemonly nofree nosync nounwind ; IS________NPM-LABEL: define {{[^@]+}}@alloca_non_unique -; IS________NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] { +; IS________NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR15:[0-9]+]] { ; IS________NPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS________NPM-NEXT: store i32 [[IN]], i32* [[A]], align 4 ; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS________NPM: t: -; IS________NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR16:[0-9]+]] +; IS________NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR25:[0-9]+]] ; IS________NPM-NEXT: ret i1 [[R]] ; IS________NPM: f: ; IS________NPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 @@ -3978,12 +3981,12 @@ ; ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@alloca_non_unique -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR18:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: store i32 [[IN]], i32* [[A]], align 4 ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_OPM: t: -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR17:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR27:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; IS__CGSCC_OPM: f: ; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 @@ -4007,25 +4010,25 @@ ; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@alloca_non_unique_caller ; IS__TUNIT_OPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { -; IS__TUNIT_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR18]] +; IS__TUNIT_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR28]] ; IS__TUNIT_OPM-NEXT: ret i1 [[R]] ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@alloca_non_unique_caller -; IS__TUNIT_NPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR10:[0-9]+]] { -; IS__TUNIT_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR16]] +; IS__TUNIT_NPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR16:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR25]] ; IS__TUNIT_NPM-NEXT: ret i1 [[R]] ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@alloca_non_unique_caller ; IS__CGSCC_OPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR22]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@alloca_non_unique_caller -; IS__CGSCC_NPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR10:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR14]] +; IS__CGSCC_NPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR16:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: ret i1 [[R]] ; %r = call i1 @alloca_non_unique(i32* undef, i32 %in, i1 %c) @@ -4070,7 +4073,7 @@ ;. ; IS__TUNIT_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__TUNIT_OPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__TUNIT_OPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind } ; IS__TUNIT_OPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn } @@ -4078,37 +4081,56 @@ ; IS__TUNIT_OPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind readonly willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind readnone } ; IS__TUNIT_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind writeonly } -; IS__TUNIT_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind willreturn uwtable } -; IS__TUNIT_OPM: attributes #[[ATTR11]] = { argmemonly nofree norecurse nosync nounwind } -; IS__TUNIT_OPM: attributes #[[ATTR12]] = { argmemonly nofree nosync nounwind } -; IS__TUNIT_OPM: attributes #[[ATTR13]] = { willreturn } -; IS__TUNIT_OPM: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn writeonly } -; IS__TUNIT_OPM: attributes #[[ATTR15]] = { nofree nosync nounwind writeonly } -; IS__TUNIT_OPM: attributes #[[ATTR16]] = { norecurse } -; IS__TUNIT_OPM: attributes #[[ATTR17]] = { nounwind } -; IS__TUNIT_OPM: attributes #[[ATTR18]] = { nofree nosync nounwind } +; IS__TUNIT_OPM: attributes #[[ATTR10]] = { nounwind willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR11:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(0) "alloc-family"="malloc" } +; IS__TUNIT_OPM: attributes #[[ATTR12:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" } +; IS__TUNIT_OPM: attributes #[[ATTR13]] = { nofree nounwind willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR14:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,zeroed") allocsize(0,1) "alloc-family"="malloc" } +; IS__TUNIT_OPM: attributes #[[ATTR15]] = { inaccessiblememonly nofree nounwind willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind willreturn uwtable } +; IS__TUNIT_OPM: attributes #[[ATTR17]] = { argmemonly nofree norecurse nosync nounwind } +; IS__TUNIT_OPM: attributes #[[ATTR18]] = { argmemonly nofree nosync nounwind } +; IS__TUNIT_OPM: attributes #[[ATTR19:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } +; IS__TUNIT_OPM: attributes #[[ATTR20]] = { willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR21]] = { nofree nosync nounwind willreturn writeonly } +; IS__TUNIT_OPM: attributes #[[ATTR22]] = { nofree nosync nounwind writeonly } +; IS__TUNIT_OPM: attributes #[[ATTR23]] = { norecurse willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR24]] = { norecurse nounwind willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR25]] = { nofree norecurse nounwind willreturn } +; IS__TUNIT_OPM: attributes #[[ATTR26]] = { norecurse } +; IS__TUNIT_OPM: attributes #[[ATTR27]] = { norecurse nounwind } +; IS__TUNIT_OPM: attributes #[[ATTR28]] = { nofree nosync nounwind } ;. ; IS__TUNIT_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__TUNIT_NPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__TUNIT_NPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly } ; IS__TUNIT_NPM: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readonly willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind writeonly } -; IS__TUNIT_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn uwtable } -; IS__TUNIT_NPM: attributes #[[ATTR9]] = { argmemonly nofree nosync nounwind } -; IS__TUNIT_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone } -; IS__TUNIT_NPM: attributes #[[ATTR11:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } -; IS__TUNIT_NPM: attributes #[[ATTR12]] = { willreturn } -; IS__TUNIT_NPM: attributes #[[ATTR13]] = { nofree nosync nounwind willreturn writeonly } -; IS__TUNIT_NPM: attributes #[[ATTR14]] = { norecurse } -; IS__TUNIT_NPM: attributes #[[ATTR15]] = { nounwind } -; IS__TUNIT_NPM: attributes #[[ATTR16]] = { nofree nosync nounwind } +; IS__TUNIT_NPM: attributes #[[ATTR8]] = { nounwind willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR9:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(0) "alloc-family"="malloc" } +; IS__TUNIT_NPM: attributes #[[ATTR10:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" } +; IS__TUNIT_NPM: attributes #[[ATTR11]] = { nofree nounwind willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR12:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,zeroed") allocsize(0,1) "alloc-family"="malloc" } +; IS__TUNIT_NPM: attributes #[[ATTR13]] = { inaccessiblememonly nofree nounwind willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR14]] = { nofree norecurse nosync nounwind willreturn uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR15]] = { argmemonly nofree nosync nounwind } +; IS__TUNIT_NPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind readnone } +; IS__TUNIT_NPM: attributes #[[ATTR17:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } +; IS__TUNIT_NPM: attributes #[[ATTR18]] = { willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR19]] = { nofree nosync nounwind willreturn writeonly } +; IS__TUNIT_NPM: attributes #[[ATTR20]] = { norecurse willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR21]] = { nofree norecurse nounwind willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR22]] = { norecurse nounwind willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR23]] = { norecurse } +; IS__TUNIT_NPM: attributes #[[ATTR24]] = { norecurse nounwind } +; IS__TUNIT_NPM: attributes #[[ATTR25]] = { nofree nosync nounwind } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly } @@ -4116,32 +4138,51 @@ ; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind readnone } ; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind willreturn uwtable } -; IS__CGSCC_OPM: attributes #[[ATTR11]] = { argmemonly nofree norecurse nosync nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR12]] = { argmemonly nofree nosync nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR13]] = { willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nounwind willreturn writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR15]] = { nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR16]] = { norecurse } -; IS__CGSCC_OPM: attributes #[[ATTR17]] = { nofree nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR11:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(0) "alloc-family"="malloc" } +; IS__CGSCC_OPM: attributes #[[ATTR12:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" } +; IS__CGSCC_OPM: attributes #[[ATTR13]] = { nofree nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR14:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,zeroed") allocsize(0,1) "alloc-family"="malloc" } +; IS__CGSCC_OPM: attributes #[[ATTR15]] = { inaccessiblememonly nofree nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind willreturn uwtable } +; IS__CGSCC_OPM: attributes #[[ATTR17]] = { argmemonly nofree norecurse nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR18]] = { argmemonly nofree nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR19:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR20]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR21]] = { nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR22]] = { nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR23]] = { norecurse willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR24]] = { norecurse nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR25]] = { norecurse } +; IS__CGSCC_OPM: attributes #[[ATTR26]] = { norecurse nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR27]] = { nofree nosync nounwind } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn uwtable } -; IS__CGSCC_NPM: attributes #[[ATTR9]] = { argmemonly nofree nosync nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR12]] = { willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR13]] = { nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR14]] = { nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR15]] = { norecurse } -; IS__CGSCC_NPM: attributes #[[ATTR16]] = { nofree nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR9:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,uninitialized") allocsize(0) "alloc-family"="malloc" } +; IS__CGSCC_NPM: attributes #[[ATTR10:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" } +; IS__CGSCC_NPM: attributes #[[ATTR11]] = { nofree nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR12:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("new,zeroed") allocsize(0,1) "alloc-family"="malloc" } +; IS__CGSCC_NPM: attributes #[[ATTR13]] = { inaccessiblememonly nofree nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR14]] = { nofree norecurse nosync nounwind willreturn uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR15]] = { argmemonly nofree nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind readnone } +; IS__CGSCC_NPM: attributes #[[ATTR17:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR18]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR19]] = { nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR20]] = { nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR21]] = { norecurse willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR22]] = { norecurse nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR23]] = { norecurse } +; IS__CGSCC_NPM: attributes #[[ATTR24]] = { norecurse nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR25]] = { nofree nosync nounwind } ;. ; CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} ; CHECK: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1} diff --git a/llvm/test/Transforms/NewGVN/calloc-load-removal.ll b/llvm/test/Transforms/NewGVN/calloc-load-removal.ll --- a/llvm/test/Transforms/NewGVN/calloc-load-removal.ll +++ b/llvm/test/Transforms/NewGVN/calloc-load-removal.ll @@ -1,5 +1,4 @@ ; RUN: opt -S -passes=newgvn < %s | FileCheck %s -; RUN: opt -S -passes=newgvn -disable-simplify-libcalls < %s | FileCheck %s -check-prefix=CHECK_NO_LIBCALLS ; Check that loads from calloc are recognized as being zero. target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" @@ -22,4 +21,4 @@ } -declare noalias i8* @calloc(i64, i64) +declare noalias i8* @calloc(i64, i64) mustprogress nofree nounwind willreturn allockind("new,zeroed") allocsize(0,1) "alloc-family"="malloc" diff --git a/llvm/test/Transforms/NewGVN/malloc-load-removal.ll b/llvm/test/Transforms/NewGVN/malloc-load-removal.ll --- a/llvm/test/Transforms/NewGVN/malloc-load-removal.ll +++ b/llvm/test/Transforms/NewGVN/malloc-load-removal.ll @@ -1,11 +1,10 @@ ; RUN: opt -S -passes=newgvn < %s | FileCheck %s -; RUN: opt -S -passes=newgvn -disable-simplify-libcalls < %s | FileCheck %s -check-prefix=CHECK_NO_LIBCALLS ; PR13694 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.8.0" -declare i8* @malloc(i64) nounwind +declare i8* @malloc(i64) nounwind allockind("new,uninitialized") allocsize(0) "alloc-family"="malloc" define noalias i8* @test1() nounwind uwtable ssp { entry: @@ -55,7 +54,7 @@ ; CHECK_NO_LIBCALLS: icmp } -declare i8* @aligned_alloc(i64, i64) nounwind +declare i8* @aligned_alloc(i64 allocalign, i64) nounwind allockind("new,uninitialized,aligned") allocsize(1) "alloc-family"="malloc" define noalias i8* @test3() nounwind uwtable ssp { entry: