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 @@ -37,6 +37,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" @@ -100,6 +101,21 @@ llvm_unreachable("missing an alloc family"); } +AllocFnKind allocKindFromAllocType(AllocType AT) { + AllocFnKind K = AllocFnKind::Unknown; + if (AT & OpNewLike) + K |= AllocFnKind::Alloc | AllocFnKind::Uninitialized; + if (AT & MallocLike) + K |= AllocFnKind::Alloc | AllocFnKind::Uninitialized; + if (AT & CallocLike) + K |= AllocFnKind::Alloc | AllocFnKind::Zeroed; + if (AT & AlignedAllocLike) + K |= AllocFnKind::Alloc | AllocFnKind::Aligned | AllocFnKind::Uninitialized; + if (AT & ReallocLike) + K |= AllocFnKind::Resize; + return K; +} + struct AllocFnsTy { AllocType AllocTy; unsigned NumParams; @@ -115,9 +131,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) @@ -142,13 +156,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::Alloc) || + 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::Alloc) || + 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::Alloc); } /// 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::Alloc) || + 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 @@ -277,9 +277,6 @@ bool Changed = false; - if(!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F, &TLI)) - Changed |= setDoesNotFreeMemory(F); - if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT()) Changed |= setNonLazyBind(F); @@ -292,14 +289,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: @@ -311,7 +308,7 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 1); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_strcat: case LibFunc_strncat: Changed |= setOnlyAccessesArgMemory(F); @@ -322,7 +319,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); @@ -337,14 +334,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 @@ -355,7 +352,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: // @@ -366,7 +363,7 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setDoesNotCapture(F, 1); - return Changed; + break; case LibFunc_strstr: case LibFunc_strpbrk: Changed |= setOnlyAccessesArgMemory(F); @@ -374,26 +371,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 |= setArgNoUndef(F, 1); LLVM_FALLTHROUGH; @@ -405,7 +402,7 @@ Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_stat: case LibFunc_statvfs: Changed |= setRetAndArgsNoUndef(F); @@ -413,7 +410,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); @@ -421,7 +418,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); @@ -430,7 +427,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); @@ -439,7 +436,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); @@ -447,13 +444,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); @@ -471,7 +468,7 @@ Changed |= setDoesNotThrow(F); Changed |= setRetDoesNotAlias(F); Changed |= setWillReturn(F); - return Changed; + break; case LibFunc_memcmp: Changed |= setOnlyAccessesArgMemory(F); Changed |= setOnlyReadsMemory(F); @@ -479,21 +476,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); @@ -504,7 +501,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); @@ -513,7 +510,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); @@ -526,7 +523,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::Alloc | AllocFnKind::Aligned | @@ -538,19 +535,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"); @@ -567,17 +564,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: @@ -585,7 +582,7 @@ Changed |= setDoesNotThrow(F); Changed |= setDoesNotCapture(F, 0); Changed |= setOnlyReadsMemory(F, 0); - return Changed; + break; case LibFunc_rename: Changed |= setRetAndArgsNoUndef(F); Changed |= setDoesNotThrow(F); @@ -593,20 +590,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); @@ -615,7 +612,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); @@ -623,14 +620,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; @@ -643,21 +640,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: @@ -666,13 +663,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); @@ -681,19 +678,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; @@ -706,7 +703,7 @@ Changed |= setDoesNotThrow(F); Changed |= setWillReturn(F); Changed |= setDoesNotCapture(F, 0); - return Changed; + break; case LibFunc_fseek: case LibFunc_ftell: case LibFunc_fgetc: @@ -723,45 +720,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); @@ -769,7 +766,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); @@ -777,7 +774,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); @@ -785,73 +782,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); @@ -860,13 +857,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: @@ -874,24 +871,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); @@ -900,18 +897,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); @@ -919,20 +916,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); @@ -940,63 +937,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; @@ -1006,28 +1003,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: @@ -1036,7 +1033,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); @@ -1044,7 +1041,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); @@ -1053,30 +1050,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 @@ -1085,7 +1082,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: @@ -1100,19 +1097,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: @@ -1239,12 +1236,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("alloc,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("alloc,uninitialized") allocsize(1) "alloc-family"="malloc" } +; IS________OPM: attributes #[[ATTR9]] = { nounwind willreturn } +; IS________OPM: attributes #[[ATTR10:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,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("alloc,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("alloc,uninitialized") allocsize(1) "alloc-family"="malloc" } +; IS________NPM: attributes #[[ATTR9]] = { nounwind willreturn } +; IS________NPM: attributes #[[ATTR10:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,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,10 +21,19 @@ ; 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-NEXT: store i8* [[TMP1]], i8** @G, align 8 -; CHECK-NEXT: ret i8* [[TMP1]] +; NOT_CGSCC_NPM: Function Attrs: nofree nounwind willreturn +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo +; NOT_CGSCC_NPM-SAME: () #[[ATTR0:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14:[0-9]+]] +; NOT_CGSCC_NPM-NEXT: store i8* [[TMP1]], i8** @G, align 8 +; NOT_CGSCC_NPM-NEXT: ret i8* [[TMP1]] +; +; IS__CGSCC____: Function Attrs: nofree nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo +; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR15:[0-9]+]] +; IS__CGSCC____-NEXT: store i8* [[TMP1]], i8** @G, align 8 +; IS__CGSCC____-NEXT: ret i8* [[TMP1]] ; %1 = tail call noalias i8* @malloc(i64 4) store i8* %1, i8** @G, align 8 @@ -37,9 +46,17 @@ ; 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-NEXT: ret i8* [[TMP1]] +; NOT_CGSCC_NPM: Function Attrs: inaccessiblememonly nofree nounwind willreturn +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@return_noalias +; NOT_CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_CGSCC_NPM-NEXT: ret i8* [[TMP1]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@return_noalias +; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: ret i8* [[TMP1]] ; %1 = tail call noalias i8* @malloc(i64 4) ret i8* %1 @@ -48,16 +65,24 @@ 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-NEXT: ret i8* [[TMP1]] +; NOT_CGSCC_NPM: Function Attrs: inaccessiblememonly nofree nounwind willreturn +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@return_noalias_looks_like_capture +; NOT_CGSCC_NPM-SAME: () #[[ATTR2]] { +; NOT_CGSCC_NPM-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_CGSCC_NPM-NEXT: ret i8* [[TMP1]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@return_noalias_looks_like_capture +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: ret i8* [[TMP1]] ; %1 = tail call noalias i8* @malloc(i64 4) call void @nocapture(i8* %1) @@ -65,10 +90,19 @@ } define i16* @return_noalias_casted(){ -; CHECK-LABEL: define {{[^@]+}}@return_noalias_casted() { -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; CHECK-NEXT: [[C:%.*]] = bitcast i8* [[TMP1]] to i16* -; CHECK-NEXT: ret i16* [[C]] +; NOT_CGSCC_NPM: Function Attrs: inaccessiblememonly nofree nounwind willreturn +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@return_noalias_casted +; NOT_CGSCC_NPM-SAME: () #[[ATTR2]] { +; NOT_CGSCC_NPM-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_CGSCC_NPM-NEXT: [[C:%.*]] = bitcast i8* [[TMP1]] to i16* +; NOT_CGSCC_NPM-NEXT: ret i16* [[C]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@return_noalias_casted +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: [[C:%.*]] = bitcast i8* [[TMP1]] to i16* +; IS__CGSCC____-NEXT: ret i16* [[C]] ; %1 = tail call noalias i8* @malloc(i64 4) %c = bitcast i8* %1 to i16* @@ -105,14 +139,14 @@ define i8* @bar() nounwind uwtable { ; NOT_CGSCC_NPM: Function Attrs: nounwind uwtable ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@bar -; NOT_CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] { -; NOT_CGSCC_NPM-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR2:[0-9]+]] +; NOT_CGSCC_NPM-SAME: () #[[ATTR4:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR15:[0-9]+]] ; NOT_CGSCC_NPM-NEXT: ret i8* [[TMP1]] ; ; IS__CGSCC____: Function Attrs: nounwind uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@bar -; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR3:[0-9]+]] +; IS__CGSCC____-SAME: () #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR16:[0-9]+]] ; IS__CGSCC____-NEXT: ret i8* [[TMP1]] ; %1 = tail call i8* (...) @baz() @@ -122,26 +156,26 @@ define i8* @foo1(i32 %0) nounwind uwtable { ; NOT_CGSCC_NPM: Function Attrs: nounwind uwtable ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo1 -; NOT_CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; NOT_CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR4]] { ; NOT_CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 ; NOT_CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] ; NOT_CGSCC_NPM: 3: -; NOT_CGSCC_NPM-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR2]] +; NOT_CGSCC_NPM-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR15]] ; NOT_CGSCC_NPM-NEXT: br label [[TMP5]] ; NOT_CGSCC_NPM: 5: -; NOT_CGSCC_NPM-NEXT: [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; NOT_CGSCC_NPM-NEXT: [[TMP6:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) ; NOT_CGSCC_NPM-NEXT: ret i8* [[TMP6]] ; ; IS__CGSCC____: Function Attrs: nounwind uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1 -; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR4]] { ; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 ; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] ; IS__CGSCC____: 3: -; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR3]] +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR16]] ; IS__CGSCC____-NEXT: br label [[TMP5]] ; IS__CGSCC____: 5: -; IS__CGSCC____-NEXT: [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; IS__CGSCC____-NEXT: [[TMP6:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) ; IS__CGSCC____-NEXT: ret i8* [[TMP6]] ; %2 = icmp eq i32 %0, 0 @@ -164,7 +198,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 @@ -174,13 +208,13 @@ define i8** @calle1(){ ; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@calle1 -; NOT_CGSCC_NPM-SAME: () #[[ATTR0]] { +; NOT_CGSCC_NPM-SAME: () #[[ATTR3]] { ; NOT_CGSCC_NPM-NEXT: ret i8** @G ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@calle1 -; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call noundef nonnull align 8 dereferenceable(8) i8** @getter() #[[ATTR11:[0-9]+]] +; IS__CGSCC____-SAME: () #[[ATTR5:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call noundef nonnull align 8 dereferenceable(8) i8** @getter() #[[ATTR17:[0-9]+]] ; IS__CGSCC____-NEXT: ret i8** [[TMP1]] ; %1 = call i8** @getter() @@ -191,26 +225,26 @@ declare noalias i8* @strdup(i8* nocapture) nounwind define i8* @test6() nounwind uwtable ssp { -; NOT_CGSCC_NPM: Function Attrs: nounwind ssp uwtable +; NOT_CGSCC_NPM: Function Attrs: inaccessiblememonly nofree nounwind ssp willreturn uwtable ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6 -; NOT_CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] { +; NOT_CGSCC_NPM-SAME: () #[[ATTR6:[0-9]+]] { ; NOT_CGSCC_NPM-NEXT: [[X:%.*]] = alloca [2 x i8], align 1 ; NOT_CGSCC_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0 ; NOT_CGSCC_NPM-NEXT: store i8 97, i8* [[ARRAYIDX]], align 1 ; NOT_CGSCC_NPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1 ; NOT_CGSCC_NPM-NEXT: store i8 0, i8* [[ARRAYIDX1]], align 1 -; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture noundef nonnull dereferenceable(2) [[ARRAYIDX]]) #[[ATTR2]] +; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture nofree noundef nonnull readonly dereferenceable(2) [[ARRAYIDX]]) #[[ATTR16:[0-9]+]] ; NOT_CGSCC_NPM-NEXT: ret i8* [[CALL]] ; -; IS__CGSCC____: Function Attrs: nounwind ssp uwtable +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree nounwind ssp willreturn uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@test6 -; IS__CGSCC____-SAME: () #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-SAME: () #[[ATTR7:[0-9]+]] { ; IS__CGSCC____-NEXT: [[X:%.*]] = alloca [2 x i8], align 1 ; IS__CGSCC____-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0 ; IS__CGSCC____-NEXT: store i8 97, i8* [[ARRAYIDX]], align 1 ; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1 ; IS__CGSCC____-NEXT: store i8 0, i8* [[ARRAYIDX1]], align 1 -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture noundef nonnull dereferenceable(2) [[ARRAYIDX]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture nofree noundef nonnull readonly dereferenceable(2) [[ARRAYIDX]]) #[[ATTR18:[0-9]+]] ; IS__CGSCC____-NEXT: ret i8* [[CALL]] ; %x = alloca [2 x i8], align 1 @@ -225,11 +259,11 @@ ; TEST 7 define i8* @test7() nounwind { -; NOT_CGSCC_NPM: Function Attrs: nounwind +; NOT_CGSCC_NPM: Function Attrs: nofree nounwind willreturn ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test7 -; NOT_CGSCC_NPM-SAME: () #[[ATTR2]] { +; NOT_CGSCC_NPM-SAME: () #[[ATTR0]] { ; NOT_CGSCC_NPM-NEXT: entry: -; NOT_CGSCC_NPM-NEXT: [[A:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR2]] +; NOT_CGSCC_NPM-NEXT: [[A:%.*]] = call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR16]] ; NOT_CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[A]], null ; NOT_CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]] ; NOT_CGSCC_NPM: if.end: @@ -239,11 +273,11 @@ ; NOT_CGSCC_NPM-NEXT: [[RETVAL_0:%.*]] = phi i8* [ [[A]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ] ; NOT_CGSCC_NPM-NEXT: ret i8* [[RETVAL_0]] ; -; IS__CGSCC____: Function Attrs: nounwind +; IS__CGSCC____: Function Attrs: nofree nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test7 -; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-SAME: () #[[ATTR0]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[A:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[A:%.*]] = call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR18]] ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[A]], null ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]] ; IS__CGSCC____: if.end: @@ -270,17 +304,29 @@ ; TEST 8 define i8* @test8(i32* %0) nounwind uwtable { -; CHECK: Function Attrs: nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@test8 -; CHECK-SAME: (i32* [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32* [[TMP0]], null -; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] -; CHECK: 4: -; CHECK-NEXT: store i8 10, i8* [[TMP2]], align 1 -; CHECK-NEXT: br label [[TMP5]] -; CHECK: 5: -; CHECK-NEXT: ret i8* [[TMP2]] +; NOT_CGSCC_NPM: Function Attrs: nofree nounwind willreturn uwtable +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test8 +; NOT_CGSCC_NPM-SAME: (i32* nofree [[TMP0:%.*]]) #[[ATTR7:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: [[TMP2:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_CGSCC_NPM-NEXT: [[TMP3:%.*]] = icmp ne i32* [[TMP0]], null +; NOT_CGSCC_NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] +; NOT_CGSCC_NPM: 4: +; NOT_CGSCC_NPM-NEXT: store i8 10, i8* [[TMP2]], align 1 +; NOT_CGSCC_NPM-NEXT: br label [[TMP5]] +; NOT_CGSCC_NPM: 5: +; NOT_CGSCC_NPM-NEXT: ret i8* [[TMP2]] +; +; IS__CGSCC____: Function Attrs: nofree nounwind willreturn uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@test8 +; IS__CGSCC____-SAME: (i32* nofree [[TMP0:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = tail call noalias noundef i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp ne i32* [[TMP0]], null +; IS__CGSCC____-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] +; IS__CGSCC____: 4: +; IS__CGSCC____-NEXT: store i8 10, i8* [[TMP2]], align 1 +; IS__CGSCC____-NEXT: br label [[TMP5]] +; IS__CGSCC____: 5: +; IS__CGSCC____-NEXT: ret i8* [[TMP2]] ; %2 = tail call noalias i8* @malloc(i64 4) %3 = icmp ne i32* %0, null @@ -398,14 +444,23 @@ declare void @use_nocapture(i8* nocapture) declare void @use(i8*) 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: 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: ret void +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test12_1() { +; NOT_CGSCC_NPM-NEXT: [[A:%.*]] = alloca i8, align 4 +; NOT_CGSCC_NPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_CGSCC_NPM-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]]) +; NOT_CGSCC_NPM-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]]) +; NOT_CGSCC_NPM-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef [[B]]) +; NOT_CGSCC_NPM-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef [[B]]) +; NOT_CGSCC_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12_1() { +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i8, align 4 +; IS__CGSCC____-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]]) +; IS__CGSCC____-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]]) +; IS__CGSCC____-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef [[B]]) +; IS__CGSCC____-NEXT: tail call void @use_nocapture(i8* noalias nocapture noundef [[B]]) +; IS__CGSCC____-NEXT: ret void ; %A = alloca i8, align 4 %B = tail call noalias i8* @malloc(i64 4) @@ -417,13 +472,21 @@ } 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: ret void +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test12_2() { +; NOT_CGSCC_NPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_CGSCC_NPM-NEXT: tail call void @use_nocapture(i8* nocapture noundef [[A]]) +; NOT_CGSCC_NPM-NEXT: tail call void @use_nocapture(i8* nocapture noundef [[A]]) +; NOT_CGSCC_NPM-NEXT: tail call void @use(i8* noundef [[A]]) +; NOT_CGSCC_NPM-NEXT: tail call void @use_nocapture(i8* nocapture noundef [[A]]) +; NOT_CGSCC_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12_2() { +; IS__CGSCC____-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: tail call void @use_nocapture(i8* nocapture noundef [[A]]) +; IS__CGSCC____-NEXT: tail call void @use_nocapture(i8* nocapture noundef [[A]]) +; IS__CGSCC____-NEXT: tail call void @use(i8* noundef [[A]]) +; IS__CGSCC____-NEXT: tail call void @use_nocapture(i8* nocapture noundef [[A]]) +; IS__CGSCC____-NEXT: ret void ; ; FIXME: This should be @use_nocapture(i8* noalias [[A]]) ; FIXME: This should be @use_nocapture(i8* noalias nocapture [[A]]) @@ -437,10 +500,15 @@ 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: ret void +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test12_3() { +; NOT_CGSCC_NPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_CGSCC_NPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A]]) +; NOT_CGSCC_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12_3() { +; IS__CGSCC____-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A]]) +; IS__CGSCC____-NEXT: ret void ; %A = tail call noalias i8* @malloc(i64 4) tail call void @two_args(i8* %A, i8* %A) @@ -449,26 +517,34 @@ 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_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: ret void +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test12_4() { +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; IS__TUNIT_NPM-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1 +; IS__TUNIT_NPM-NEXT: tail call void @two_args(i8* noalias nocapture noundef [[A]], i8* noalias nocapture noundef [[B]]) +; IS__TUNIT_NPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A]]) +; IS__TUNIT_NPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A_1]]) +; IS__TUNIT_NPM-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[B]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12_4() { +; IS__CGSCC____-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1 +; IS__CGSCC____-NEXT: tail call void @two_args(i8* noalias nocapture noundef [[A]], i8* noalias nocapture noundef [[B]]) +; IS__CGSCC____-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A]]) +; IS__CGSCC____-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[A_1]]) +; IS__CGSCC____-NEXT: tail call void @two_args(i8* nocapture noundef [[A]], i8* nocapture noundef [[B]]) +; IS__CGSCC____-NEXT: ret void ; %A = tail call noalias i8* @malloc(i64 4) %B = tail call noalias i8* @malloc(i64 4) @@ -499,17 +575,15 @@ } 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_CGSCC_NPM-LABEL: define {{[^@]+}}@test13_use_noalias() { +; NOT_CGSCC_NPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_CGSCC_NPM-NEXT: call void @use_i8_internal(i8* noalias nocapture noundef [[M1]]) +; NOT_CGSCC_NPM-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 +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13_use_noalias() { +; IS__CGSCC____-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: call void @use_i8_internal(i8* noalias nocapture noundef [[M1]]) +; IS__CGSCC____-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias() ; IS__CGSCC_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 4) @@ -525,20 +599,17 @@ } 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_CGSCC_NPM-LABEL: define {{[^@]+}}@test13_use_alias() { +; NOT_CGSCC_NPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR14]] +; NOT_CGSCC_NPM-NEXT: call void @use_i8_internal(i8* nocapture noundef [[M1]]) +; NOT_CGSCC_NPM-NEXT: call void @use_i8_internal(i8* nocapture noundef [[M1]]) +; NOT_CGSCC_NPM-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 +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13_use_alias() { +; IS__CGSCC____-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) #[[ATTR15]] +; IS__CGSCC____-NEXT: call void @use_i8_internal(i8* nocapture noundef [[M1]]) +; IS__CGSCC____-NEXT: call void @use_i8_internal(i8* nocapture noundef [[M1]]) +; IS__CGSCC____-NEXT: ret void ; %m1 = tail call noalias i8* @malloc(i64 4) %c1 = bitcast i8* %m1 to i16* @@ -553,7 +624,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]] ; @@ -564,20 +635,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 nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@i2p -; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR11]] +; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR17]] ; 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]]) #[[ATTR12:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[BC]]) #[[ATTR19:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 [[CALL]] ; %c = call i32 @p2i(i32* %arg) @@ -589,13 +660,13 @@ define internal i32 @ret(i32* %arg) { ; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@ret -; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { +; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR9:[0-9]+]] { ; NOT_CGSCC_NPM-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4 ; NOT_CGSCC_NPM-NEXT: ret i32 [[L]] ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ret -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__CGSCC____-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4 ; IS__CGSCC____-NEXT: ret i32 [[L]] ; @@ -618,7 +689,7 @@ ; 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 void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR14]] ; 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) @@ -630,7 +701,7 @@ ; 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]]) #[[ATTR13:[0-9]+]] +; IS__CGSCC____-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR15]] ; 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) @@ -685,13 +756,13 @@ define void @make_alias(i32* %p) { ; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@make_alias -; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] { +; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR11:[0-9]+]] { ; NOT_CGSCC_NPM-NEXT: store i32* [[P]], i32** @alias_of_p, align 8 ; NOT_CGSCC_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@make_alias -; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR12:[0-9]+]] { ; IS__CGSCC____-NEXT: store i32* [[P]], i32** @alias_of_p, align 8 ; IS__CGSCC____-NEXT: ret void ; @@ -702,13 +773,13 @@ define void @only_store(i32* %p) { ; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@only_store -; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] { +; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR12:[0-9]+]] { ; NOT_CGSCC_NPM-NEXT: store i32 0, i32* [[P]], align 4 ; NOT_CGSCC_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@only_store -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR13:[0-9]+]] { ; IS__CGSCC____-NEXT: store i32 0, i32* [[P]], align 4 ; IS__CGSCC____-NEXT: ret void ; @@ -719,26 +790,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 nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test15_caller -; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR14:[0-9]+]] { ; 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* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14:[0-9]+]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR20:[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]]) #[[ATTR14]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR20]] ; IS__CGSCC____-NEXT: ret void ; %tobool = icmp eq i32 %c, 0 @@ -776,36 +847,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 nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_sub -; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR14]] { ; 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* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR20]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR20]] ; 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]]) #[[ATTR14]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR20]] ; IS__CGSCC____-NEXT: br label [[IF_END3]] ; IS__CGSCC____: if.end3: ; IS__CGSCC____-NEXT: ret void @@ -833,14 +904,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 nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_caller -; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] { -; IS__CGSCC____-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR14]] +; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR14]] { +; IS__CGSCC____-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR20]] ; IS__CGSCC____-NEXT: ret void ; tail call void @test16_sub(i32* %p, i32 %c, i32 %c) @@ -869,30 +940,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 nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test17_caller -; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR14]] { ; 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]]) #[[ATTR14]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR20]] ; 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]]) #[[ATTR14]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR20]] ; IS__CGSCC____-NEXT: br label [[L3]] ; IS__CGSCC____: l3: ; IS__CGSCC____-NEXT: ret void @@ -927,12 +998,12 @@ define void @noreturn() { ; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@noreturn -; NOT_CGSCC_NPM-SAME: () #[[ATTR9]] { +; NOT_CGSCC_NPM-SAME: () #[[ATTR13]] { ; NOT_CGSCC_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@noreturn -; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-SAME: () #[[ATTR5]] { ; IS__CGSCC____-NEXT: ret void ; call void @noreturn() @@ -942,28 +1013,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 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:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-SAME: (i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[C:%.*]]) #[[ATTR14]] { ; 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]]) #[[ATTR14]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR20]] ; 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]]) #[[ATTR14]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR20]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -980,33 +1051,45 @@ 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("alloc,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]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind } -; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind ssp uwtable } -; IS__CGSCC____: attributes #[[ATTR5]] = { nofree nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR7:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR11]] = { readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR12]] = { readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR13]] = { willreturn } -; IS__CGSCC____: attributes #[[ATTR14]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,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]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nofree nounwind willreturn "alloc-family"="malloc" } +; IS__CGSCC____: attributes #[[ATTR7]] = { inaccessiblememonly nofree nounwind ssp willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR8]] = { nofree nounwind willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR9]] = { nofree nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR10]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR11:[0-9]+]] = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR12]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR13]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR15]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR16]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR17]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR18]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR19]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR20]] = { 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 nosync nounwind willreturn @@ -181,7 +181,7 @@ ; 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]]) #[[ATTR15:[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]]) #[[ATTR22:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7:![0-9]+]] ; IS__CGSCC_OPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 @@ -189,11 +189,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:![0-9]+]] ; 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) #[[ATTR16:[0-9]+]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR23:[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) #[[ATTR16]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR23]] ; 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) #[[ATTR16]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR23]] ; IS__CGSCC_OPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_OPM-NEXT: [[I4:%.*]] = 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 @@ -227,7 +227,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]] ; 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]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR22]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn @@ -236,7 +236,7 @@ ; 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]]) #[[ATTR14:[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]]) #[[ATTR20:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7:![0-9]+]] ; IS__CGSCC_NPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 @@ -244,11 +244,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:![0-9]+]] ; 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) #[[ATTR15:[0-9]+]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR21:[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) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]] ; 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) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]] ; IS__CGSCC_NPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_NPM-NEXT: [[I4:%.*]] = 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 @@ -282,7 +282,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]] ; 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]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: ret void ; entry: @@ -421,7 +421,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]] ] @@ -449,7 +449,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:%.*]] ] @@ -506,7 +506,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]] ] @@ -525,7 +525,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() { @@ -589,7 +589,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) #[[ATTR17:[0-9]+]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR24:[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]] ] @@ -615,7 +615,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]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1024, i8* nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[I]]) #[[ATTR20]] ; 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:%.*]] ] @@ -672,7 +672,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) #[[ATTR16:[0-9]+]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR22:[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]] ] @@ -869,7 +869,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: @@ -878,7 +878,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 @@ -887,7 +887,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: @@ -896,7 +896,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 @@ -905,7 +905,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]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR22]] ; 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: @@ -914,7 +914,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]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR22]] ; IS__CGSCC_OPM-NEXT: ret i32 5 ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -923,7 +923,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]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR20]] ; 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: @@ -932,7 +932,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]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: ret i32 5 ; entry: @@ -973,7 +973,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: @@ -982,7 +982,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 @@ -991,7 +991,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: @@ -1000,7 +1000,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 @@ -1009,7 +1009,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]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR22]] ; 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: @@ -1018,7 +1018,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]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR22]] ; IS__CGSCC_OPM-NEXT: ret i32 5 ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -1027,7 +1027,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]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR20]] ; 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: @@ -1036,7 +1036,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]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: ret i32 5 ; entry: @@ -1084,9 +1084,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 @@ -1109,9 +1109,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 @@ -1137,9 +1137,9 @@ ; IS__CGSCC_OPM-NEXT: store float 0x3FF19999A0000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] ; IS__CGSCC_OPM-NEXT: store float 0x40019999A0000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]] ; IS__CGSCC_OPM-NEXT: store float 0x400A666660000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]] -; 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) #[[ATTR16]] -; 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) #[[ATTR16]] -; 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) #[[ATTR16]] +; 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) #[[ATTR23]] +; 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) #[[ATTR23]] +; 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) #[[ATTR23]] ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] ; IS__CGSCC_OPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__CGSCC_OPM-NEXT: store float [[I]], float* [[F1]], align 4, !tbaa [[TBAA7]] @@ -1173,9 +1173,9 @@ ; IS__CGSCC_NPM-NEXT: store float 0x3FF19999A0000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] ; IS__CGSCC_NPM-NEXT: store float 0x40019999A0000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]] ; IS__CGSCC_NPM-NEXT: store float 0x400A666660000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]] -; 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) #[[ATTR15]] -; 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) #[[ATTR15]] -; 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) #[[ATTR15]] +; 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) #[[ATTR21]] +; 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) #[[ATTR21]] +; 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) #[[ATTR21]] ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] ; IS__CGSCC_NPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 ; IS__CGSCC_NPM-NEXT: store float [[I]], float* [[F1]], align 4, !tbaa [[TBAA7]] @@ -1307,7 +1307,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]] ] @@ -1382,7 +1382,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]] ] @@ -1455,7 +1455,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) #[[ATTR17]] +; 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) #[[ATTR24]] ; 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]] ] @@ -1528,7 +1528,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) #[[ATTR16]] +; 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) #[[ATTR22]] ; 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]] ] @@ -1702,11 +1702,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 @@ -1752,11 +1752,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 @@ -1802,11 +1802,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) #[[ATTR16]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR23]] ; 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) #[[ATTR16]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR23]] ; 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) #[[ATTR16]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR23]] ; 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 @@ -1852,11 +1852,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) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR21]] ; 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) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]] ; 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) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]] ; 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 @@ -2014,7 +2014,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]] ] @@ -2094,7 +2094,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]] ] @@ -2173,7 +2173,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) #[[ATTR17]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR24]] ; 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]] ] @@ -2252,7 +2252,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) #[[ATTR16]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR22]] ; 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]] ] @@ -2385,9 +2385,9 @@ ; IS__TUNIT_OPM-NEXT: [[X:%.*]] = alloca i32, align 4 ; IS__TUNIT_OPM-NEXT: [[Y:%.*]] = alloca i32, align 4 ; IS__TUNIT_OPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] 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: [[I1:%.*]] = bitcast i32* [[Y]] to i8* -; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR13]] +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR20]] ; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] ; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] ; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* @@ -2410,9 +2410,9 @@ ; IS__TUNIT_NPM-NEXT: [[X:%.*]] = alloca i32, align 4 ; IS__TUNIT_NPM-NEXT: [[Y:%.*]] = alloca i32, align 4 ; IS__TUNIT_NPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] 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: [[I1:%.*]] = bitcast i32* [[Y]] to i8* -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] ; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] ; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* @@ -2435,9 +2435,9 @@ ; IS__CGSCC_OPM-NEXT: [[X:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: [[Y:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] 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]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR22]] ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR22]] ; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] ; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* @@ -2460,9 +2460,9 @@ ; IS__CGSCC_NPM-NEXT: [[X:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: [[Y:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] 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]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] ; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] ; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* @@ -3420,34 +3420,46 @@ } define dso_local i32 @round_trip_malloc(i32 %x) { +; IS__TUNIT_OPM: Function Attrs: nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_malloc -; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16:[0-9]+]] +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @malloc(i64 noundef 4) #[[ATTR23:[0-9]+]] ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 ; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__TUNIT_OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; -; IS________NPM-LABEL: define {{[^@]+}}@round_trip_malloc -; IS________NPM-SAME: (i32 returned [[X:%.*]]) { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* -; IS________NPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 -; IS________NPM-NEXT: ret i32 [[X]] +; IS__TUNIT_NPM: Function Attrs: nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@round_trip_malloc +; IS__TUNIT_NPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__TUNIT_NPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 +; IS__TUNIT_NPM-NEXT: ret i32 [[X]] ; +; IS__CGSCC_OPM: Function Attrs: nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_malloc -; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR11:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR18:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @malloc(i64 noundef 4) #[[ATTR25:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 ; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__CGSCC_OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR26:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] ; +; IS__CGSCC_NPM: Function Attrs: nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@round_trip_malloc +; IS__CGSCC_NPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 [[X]] +; entry: %call = call noalias i8* @malloc(i64 4) norecurse %0 = bitcast i8* %call to i32* @@ -3459,28 +3471,40 @@ } define dso_local i32 @round_trip_malloc_constant() { -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { +; IS__TUNIT_OPM: Function Attrs: nounwind willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant +; IS__TUNIT_OPM-SAME: () #[[ATTR10]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @malloc(i64 noundef 4) #[[ATTR23]] ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__TUNIT_OPM-NEXT: store i32 7, i32* [[TMP0]], align 4 ; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__TUNIT_OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24]] ; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; -; IS________NPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: ret i32 7 +; IS__TUNIT_NPM: Function Attrs: nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant +; IS__TUNIT_NPM-SAME: () #[[ATTR8]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: ret i32 7 ; -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { +; IS__CGSCC_OPM: Function Attrs: nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant +; IS__CGSCC_OPM-SAME: () #[[ATTR11]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @malloc(i64 noundef 4) #[[ATTR25]] ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__CGSCC_OPM-NEXT: store i32 7, i32* [[TMP0]], align 4 ; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__CGSCC_OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR26]] ; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] ; +; IS__CGSCC_NPM: Function Attrs: nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant +; IS__CGSCC_NPM-SAME: () #[[ATTR9]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: ret i32 7 +; entry: %call = call noalias i8* @malloc(i64 4) norecurse %0 = bitcast i8* %call to i32* @@ -3496,46 +3520,61 @@ declare void @free(i8*) define dso_local i32 @conditional_malloc(i32 %x) { +; IS__TUNIT_OPM: Function Attrs: nofree nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@conditional_malloc -; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR13:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16]] -; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* ; IS__TUNIT_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 ; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; IS__TUNIT_OPM: if.then: -; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 ; IS__TUNIT_OPM-NEXT: br label [[IF_END]] ; IS__TUNIT_OPM: if.end: -; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-NEXT: ret i32 [[X]] ; -; IS________NPM-LABEL: define {{[^@]+}}@conditional_malloc -; IS________NPM-SAME: (i32 returned [[X:%.*]]) { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 -; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* -; IS________NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 -; IS________NPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; IS________NPM: if.then: -; IS________NPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 -; IS________NPM-NEXT: br label [[IF_END]] -; IS________NPM: if.end: -; IS________NPM-NEXT: ret i32 [[X]] +; IS__TUNIT_NPM: Function Attrs: nofree nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@conditional_malloc +; IS__TUNIT_NPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__TUNIT_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__TUNIT_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT_NPM: if.then: +; IS__TUNIT_NPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 +; IS__TUNIT_NPM-NEXT: br label [[IF_END]] +; IS__TUNIT_NPM: if.end: +; IS__TUNIT_NPM-NEXT: ret i32 [[X]] ; +; IS__CGSCC_OPM: Function Attrs: nofree nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@conditional_malloc -; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR14:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR18]] -; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* ; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 ; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; IS__CGSCC_OPM: if.then: -; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 ; IS__CGSCC_OPM-NEXT: br label [[IF_END]] ; IS__CGSCC_OPM: if.end: -; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; IS__CGSCC_OPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@conditional_malloc +; IS__CGSCC_NPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__CGSCC_NPM: if.then: +; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 +; IS__CGSCC_NPM-NEXT: br label [[IF_END]] +; IS__CGSCC_NPM: if.end: +; IS__CGSCC_NPM-NEXT: ret i32 [[X]] ; entry: %call = call noalias i8* @malloc(i64 4) norecurse @@ -3553,33 +3592,49 @@ } define dso_local i32 @round_trip_calloc(i32 %x) { +; IS__TUNIT_OPM: Function Attrs: nofree nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_calloc -; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR13]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR16]] -; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 -; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] -; -; IS________NPM-LABEL: define {{[^@]+}}@round_trip_calloc -; IS________NPM-SAME: (i32 [[X:%.*]]) { -; 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: store i32 [[X]], i32* [[TMP1]], align 4 -; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 -; IS________NPM-NEXT: ret i32 [[TMP2]] -; +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP2]] +; +; IS__TUNIT_NPM: Function Attrs: nofree nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@round_trip_calloc +; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) #[[ATTR11]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__TUNIT_NPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_calloc -; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR14]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR18]] -; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 -; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@round_trip_calloc +; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) #[[ATTR12]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP2]] ; entry: %call = call noalias i8* @calloc(i64 4, i64 1) norecurse @@ -3590,30 +3645,49 @@ } define dso_local i32 @round_trip_calloc_constant() { -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { +; IS__TUNIT_OPM: Function Attrs: nofree nounwind willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant +; IS__TUNIT_OPM-SAME: () #[[ATTR13]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR16]] -; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS__TUNIT_OPM-NEXT: store i32 11, i32* [[TMP0]], align 4 -; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] -; -; IS________NPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { -; 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: store i32 11, i32* [[TMP1]], align 4 -; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 -; IS________NPM-NEXT: ret i32 [[TMP2]] -; -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__TUNIT_OPM-NEXT: store i32 11, i32* [[TMP1]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP2]] +; +; IS__TUNIT_NPM: Function Attrs: nofree nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant +; IS__TUNIT_NPM-SAME: () #[[ATTR11]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__TUNIT_NPM-NEXT: store i32 11, i32* [[TMP1]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant +; IS__CGSCC_OPM-SAME: () #[[ATTR14]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR18]] -; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS__CGSCC_OPM-NEXT: store i32 11, i32* [[TMP0]], align 4 -; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__CGSCC_OPM-NEXT: store i32 11, i32* [[TMP1]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant +; IS__CGSCC_NPM-SAME: () #[[ATTR12]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; IS__CGSCC_NPM-NEXT: store i32 11, i32* [[TMP1]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP2]] ; entry: %call = call noalias i8* @calloc(i64 4, i64 1) norecurse @@ -3626,10 +3700,11 @@ declare noalias i8* @calloc(i64, i64) define dso_local i32 @conditional_calloc(i32 %x) { +; IS__TUNIT_OPM: Function Attrs: nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@conditional_calloc -; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR10]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR23]] ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__TUNIT_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 ; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] @@ -3639,29 +3714,30 @@ ; IS__TUNIT_OPM: if.end: ; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 ; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* -; IS__TUNIT_OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP2]]) #[[ATTR24]] ; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; -; IS________NPM-LABEL: define {{[^@]+}}@conditional_calloc -; IS________NPM-SAME: (i32 [[X:%.*]]) { -; 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: [[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* [[TMP1]], align 4 -; 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]] +; IS__TUNIT_NPM: Function Attrs: nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@conditional_calloc +; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) #[[ATTR8]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; 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* [[TMP1]], align 4 +; IS__TUNIT_NPM-NEXT: br label [[IF_END]] +; IS__TUNIT_NPM: if.end: +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP2]] ; +; IS__CGSCC_OPM: Function Attrs: nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@conditional_calloc -; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR11]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR25]] ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 ; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] @@ -3671,9 +3747,25 @@ ; IS__CGSCC_OPM: if.end: ; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 ; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* -; IS__CGSCC_OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP2]]) #[[ATTR26]] ; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] ; +; IS__CGSCC_NPM: Function Attrs: nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@conditional_calloc +; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) #[[ATTR9]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i32* +; 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* [[TMP1]], align 4 +; IS__CGSCC_NPM-NEXT: br label [[IF_END]] +; IS__CGSCC_NPM: if.end: +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP2]] +; entry: %call = call noalias i8* @calloc(i64 1, i64 4) norecurse %0 = bitcast i8* %call to i32* @@ -3692,10 +3784,11 @@ } define dso_local i32 @conditional_calloc_zero(i1 %c) { +; IS__TUNIT_OPM: Function Attrs: nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@conditional_calloc_zero -; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) { +; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR10]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR23]] ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS__TUNIT_OPM: if.then: @@ -3704,26 +3797,26 @@ ; IS__TUNIT_OPM: if.end: ; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 ; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* -; IS__TUNIT_OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP2]]) #[[ATTR24]] ; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; -; IS________NPM-LABEL: define {{[^@]+}}@conditional_calloc_zero -; IS________NPM-SAME: (i1 [[C:%.*]]) { -; 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 +; IS__TUNIT_NPM: Function Attrs: nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@conditional_calloc_zero +; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR8]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__TUNIT_NPM: if.then: +; IS__TUNIT_NPM-NEXT: br label [[IF_END]] +; IS__TUNIT_NPM: if.end: +; IS__TUNIT_NPM-NEXT: ret i32 0 ; +; IS__CGSCC_OPM: Function Attrs: nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@conditional_calloc_zero -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) { +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR11]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR25]] ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS__CGSCC_OPM: if.then: @@ -3732,9 +3825,21 @@ ; IS__CGSCC_OPM: if.end: ; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 ; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* -; IS__CGSCC_OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP2]]) #[[ATTR26]] ; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] ; +; IS__CGSCC_NPM: Function Attrs: nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@conditional_calloc_zero +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR9]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1 +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[TMP0]], i8 0, i64 4, i1 false) +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__CGSCC_NPM: if.then: +; IS__CGSCC_NPM-NEXT: br label [[IF_END]] +; IS__CGSCC_NPM: if.end: +; IS__CGSCC_NPM-NEXT: ret i32 0 +; entry: %call = call noalias i8* @calloc(i64 1, i64 4) norecurse %0 = bitcast i8* %call to i32* @@ -3752,35 +3857,39 @@ } define dso_local i32* @malloc_like(i32 %s) { +; IS__TUNIT_OPM: Function Attrs: inaccessiblememonly nofree nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@malloc_like -; IS__TUNIT_OPM-SAME: (i32 [[S:%.*]]) { +; IS__TUNIT_OPM-SAME: (i32 [[S:%.*]]) #[[ATTR15:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias noundef i8* @malloc(i64 noundef [[CONV]]) #[[ATTR23]] ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__TUNIT_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_OPM: Function Attrs: inaccessiblememonly nofree nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@malloc_like -; IS__CGSCC_OPM-SAME: (i32 [[S:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32 [[S:%.*]]) #[[ATTR16:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias noundef i8* @malloc(i64 noundef [[CONV]]) #[[ATTR25]] ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__CGSCC_OPM-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:%.*]]) #[[ATTR14:[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]]) #[[ATTR17:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias noundef i8* @malloc(i64 noundef [[CONV]]) #[[ATTR23:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__CGSCC_NPM-NEXT: ret i32* [[TMP0]] ; @@ -3792,44 +3901,48 @@ } define dso_local i32 @round_trip_malloc_like(i32 %x) { +; IS__TUNIT_OPM: Function Attrs: nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_like -; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR10]] { ; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR16]] +; 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* noundef [[TMP1]]) #[[ATTR16]] +; 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:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR11]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i32* @malloc_like(i32 noundef 4) #[[ATTR26]] ; 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* noundef [[TMP1]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR26]] ; 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:%.*]]) #[[ATTR9]] { ; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR17]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias nonnull align 4 dereferenceable(4) i32* @malloc_like(i32 noundef 4) #[[ATTR24:[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]]) #[[ATTR17]] +; IS__CGSCC_NPM-NEXT: call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR24]] ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] ; entry: @@ -3845,41 +3958,41 @@ ; 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) #[[ATTR16]] +; 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* noundef [[TMP1]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR27:[0-9]+]] ; IS__TUNIT_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: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR23:[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]]) #[[ATTR24:[0-9]+]] ; IS__TUNIT_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) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR27:[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* noundef [[TMP1]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR28:[0-9]+]] ; IS__CGSCC_OPM-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) #[[ATTR17]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR25:[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]]) #[[ATTR17]] +; IS__CGSCC_NPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR26:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] ; entry: @@ -3897,7 +4010,7 @@ ; 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) #[[ATTR16]] +; 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: @@ -3906,13 +4019,13 @@ ; 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* [[TMP1]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR27]] ; IS__TUNIT_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: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR23]] ; 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: @@ -3921,13 +4034,13 @@ ; 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: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR24]] ; IS__TUNIT_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) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR27]] ; 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: @@ -3936,13 +4049,13 @@ ; 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* [[TMP1]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR28]] ; IS__CGSCC_OPM-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) #[[ATTR17]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR25]] ; 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: @@ -3951,7 +4064,7 @@ ; 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]]) #[[ATTR17]] +; IS__CGSCC_NPM-NEXT: call void @free(i8* nocapture noundef [[TMP1]]) #[[ATTR26]] ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] ; entry: @@ -3976,24 +4089,26 @@ ; 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: Function Attrs: nofree nounwind willreturn ; 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-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) #[[ATTR13]] { ; 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: [[TMP1:%.*]] = alloca i8, i64 24, align 1 +; IS__TUNIT_OPM-NEXT: [[DST1:%.*]] = bitcast i8* [[TMP1]] 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: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 8 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[SRC2]] to double** +; IS__TUNIT_OPM-NEXT: store double* [[SRC]], double** [[TMP2]], align 8 +; IS__TUNIT_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__TUNIT_OPM-NEXT: call fastcc void @nested_memory_callee() #[[ATTR10]] ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: nofree nounwind willreturn ; 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-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) #[[ATTR11]] { ; 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* @@ -4005,40 +4120,42 @@ ; 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: call fastcc void @nested_memory_callee() #[[ATTR8]] ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: nofree nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_nested_memory -; IS__CGSCC_OPM-SAME: (float* nofree [[DST:%.*]], double* nofree [[SRC:%.*]]) { +; IS__CGSCC_OPM-SAME: (float* nofree [[DST:%.*]], double* nofree [[SRC:%.*]]) #[[ATTR14]] { ; 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: store %struct.STy* @global, %struct.STy** [[INNER]], align 8 -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias dereferenceable_or_null(24) i8* @malloc(i64 noundef 24) +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias align 8 dereferenceable_or_null(24) i8* @malloc(i64 noundef 24) #[[ATTR22]] ; 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(%struct.STy* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(24) [[LOCAL]]) #[[ATTR17]] +; IS__CGSCC_OPM-NEXT: call fastcc void @nested_memory_callee(%struct.STy* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(24) [[LOCAL]]) #[[ATTR11]] ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: nofree nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_nested_memory -; IS__CGSCC_NPM-SAME: (float* nofree [[DST:%.*]], double* nofree [[SRC:%.*]]) { +; IS__CGSCC_NPM-SAME: (float* nofree [[DST:%.*]], double* nofree [[SRC:%.*]]) #[[ATTR12]] { ; 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: [[CALL:%.*]] = call noalias dereferenceable_or_null(24) i8* @malloc(i64 noundef 24) +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias align 8 dereferenceable_or_null(24) i8* @malloc(i64 noundef 24) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: [[DST1:%.*]] = bitcast i8* [[CALL]] to float** ; IS__CGSCC_NPM-NEXT: store float* [[DST]], float** [[DST1]], align 8 ; IS__CGSCC_NPM-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 8 ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[SRC2]] to double** ; IS__CGSCC_NPM-NEXT: store double* [[SRC]], double** [[TMP1]], align 8 ; IS__CGSCC_NPM-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_NPM-NEXT: call fastcc void @nested_memory_callee(float* nofree nonnull align 4294967296 undef, double* nofree nonnull align 4294967296 undef, %struct.STy* nofree noundef nonnull align 8 dereferenceable(24) @global) #[[ATTR16]] +; IS__CGSCC_NPM-NEXT: call fastcc void @nested_memory_callee(float* nofree nonnull align 4294967296 undef, double* nofree nonnull align 4294967296 undef, %struct.STy* nofree noundef nonnull align 8 dereferenceable(24) @global) #[[ATTR9]] ; IS__CGSCC_NPM-NEXT: ret void ; entry: @@ -4060,7 +4177,7 @@ define internal fastcc void @nested_memory_callee(%struct.STy* nocapture readonly %S) nofree norecurse nounwind uwtable { ; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nested_memory_callee -; IS__TUNIT_OPM-SAME: () #[[ATTR10:[0-9]+]] { +; IS__TUNIT_OPM-SAME: () #[[ATTR16:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** getelementptr inbounds ([[STRUCT_STY:%.*]], %struct.STy* @global, i64 0, i32 2), align 8 ; IS__TUNIT_OPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 1 @@ -4074,7 +4191,7 @@ ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@nested_memory_callee -; IS__TUNIT_NPM-SAME: () #[[ATTR8:[0-9]+]] { +; IS__TUNIT_NPM-SAME: () #[[ATTR14:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** getelementptr inbounds ([[STRUCT_STY:%.*]], %struct.STy* @global, i64 0, i32 2), align 8 ; IS__TUNIT_NPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 1 @@ -4088,7 +4205,7 @@ ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nested_memory_callee -; IS__CGSCC_OPM-SAME: (%struct.STy* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__CGSCC_OPM-SAME: (%struct.STy* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR17:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY:%.*]], %struct.STy* [[S]], i64 0, i32 2 ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** [[INNER]], align 8 @@ -4105,7 +4222,7 @@ ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@nested_memory_callee -; IS__CGSCC_NPM-SAME: (float* [[TMP0:%.*]], double* [[TMP1:%.*]], %struct.STy* [[TMP2:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC_NPM-SAME: (float* [[TMP0:%.*]], double* [[TMP1:%.*]], %struct.STy* [[TMP2:%.*]]) #[[ATTR15:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[S_PRIV:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[S_PRIV_CAST:%.*]] = bitcast %struct.STy* [[S_PRIV]] to float** @@ -4147,7 +4264,7 @@ define hidden void @no_propagation_of_unknown_index_access(i32* %in, i32* %out, i32 %idx) #0 { ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access -; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR17:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* @@ -4194,7 +4311,7 @@ ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]] ; IS__TUNIT_NPM: for.cond: ; IS__TUNIT_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] @@ -4215,7 +4332,7 @@ ; IS__TUNIT_NPM-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 ; IS__TUNIT_NPM-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] ; IS__TUNIT_NPM: for.cond.cleanup6: -; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR18]] ; IS__TUNIT_NPM-NEXT: ret void ; IS__TUNIT_NPM: for.body7: ; IS__TUNIT_NPM-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 @@ -4233,7 +4350,7 @@ ; ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR18:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* @@ -4276,11 +4393,11 @@ ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR16:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND:%.*]] ; IS__CGSCC_NPM: for.cond: ; IS__CGSCC_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] @@ -4301,7 +4418,7 @@ ; IS__CGSCC_NPM-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 ; IS__CGSCC_NPM-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] ; IS__CGSCC_NPM: for.cond.cleanup6: -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR20]] ; IS__CGSCC_NPM-NEXT: ret void ; IS__CGSCC_NPM: for.body7: ; IS__CGSCC_NPM-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 @@ -4368,12 +4485,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 @@ -4382,12 +4499,12 @@ ; ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@alloca_non_unique -; IS__TUNIT_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR15:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__TUNIT_NPM-NEXT: store i32 [[IN]], i32* [[A]], align 4 ; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT_NPM: t: -; IS__TUNIT_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__TUNIT_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__TUNIT_NPM-NEXT: ret i1 [[R]] ; IS__TUNIT_NPM: f: ; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 @@ -4396,12 +4513,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:%.*]]) #[[ATTR13:[0-9]+]] { +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR19:[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) #[[ATTR19:[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) #[[ATTR29:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; IS__CGSCC_OPM: f: ; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 @@ -4410,12 +4527,12 @@ ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@alloca_non_unique -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR17:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: store i32 [[IN]], i32* [[A]], align 4 ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_NPM: t: -; IS__CGSCC_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) #[[ATTR18:[0-9]+]] +; IS__CGSCC_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) #[[ATTR27:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret i1 [[R]] ; IS__CGSCC_NPM: f: ; IS__CGSCC_NPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 @@ -4439,25 +4556,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 nosync nounwind readnone ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@alloca_non_unique_caller -; IS__CGSCC_OPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR14:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR17]] +; IS__CGSCC_OPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR20:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR24]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@alloca_non_unique_caller -; IS__CGSCC_NPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR12:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR16]] +; IS__CGSCC_NPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR18:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR22]] ; IS__CGSCC_NPM-NEXT: ret i1 [[R]] ; %r = call i1 @alloca_non_unique(i32* undef, i32 %in, i1 %c) @@ -4502,7 +4619,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 } @@ -4510,37 +4627,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("alloc,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("alloc,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("alloc,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("alloc,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 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 nosync nounwind willreturn } @@ -4549,35 +4685,54 @@ ; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind readnone } ; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind willreturn uwtable } -; IS__CGSCC_OPM: attributes #[[ATTR12]] = { argmemonly nofree norecurse nosync nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR13]] = { argmemonly nofree nosync nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree nosync nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR15]] = { willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nounwind willreturn writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR17]] = { nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR18]] = { norecurse } -; IS__CGSCC_OPM: attributes #[[ATTR19]] = { nofree nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR12:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" } +; IS__CGSCC_OPM: attributes #[[ATTR13:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" } +; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR15:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" } +; IS__CGSCC_OPM: attributes #[[ATTR16]] = { inaccessiblememonly nofree nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind willreturn uwtable } +; IS__CGSCC_OPM: attributes #[[ATTR18]] = { argmemonly nofree norecurse nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR19]] = { argmemonly nofree nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR20]] = { nofree nosync nounwind readnone } +; IS__CGSCC_OPM: attributes #[[ATTR21:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR22]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR23]] = { nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR24]] = { nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR25]] = { norecurse willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR26]] = { norecurse nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR27]] = { norecurse } +; IS__CGSCC_OPM: attributes #[[ATTR28]] = { norecurse nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR29]] = { nofree nosync nounwind } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree 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 nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn uwtable } -; IS__CGSCC_NPM: attributes #[[ATTR10]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR11]] = { argmemonly nofree nosync nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nofree nosync nounwind readnone } -; IS__CGSCC_NPM: attributes #[[ATTR13:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR14]] = { willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR16]] = { nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR17]] = { norecurse } -; IS__CGSCC_NPM: attributes #[[ATTR18]] = { nofree nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR10:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" } +; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { inaccessiblemem_or_argmemonly mustprogress nounwind willreturn allockind("free") "alloc-family"="malloc" } +; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nofree nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR13:[0-9]+]] = { inaccessiblememonly mustprogress nofree nounwind willreturn allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" } +; IS__CGSCC_NPM: attributes #[[ATTR14]] = { inaccessiblememonly nofree nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind willreturn uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR16]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR17]] = { argmemonly nofree nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR18]] = { nofree nosync nounwind readnone } +; IS__CGSCC_NPM: attributes #[[ATTR19:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR20]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR21]] = { nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR22]] = { nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR23]] = { norecurse willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR24]] = { norecurse nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR25]] = { norecurse } +; IS__CGSCC_NPM: attributes #[[ATTR26]] = { norecurse nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR27]] = { 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("alloc,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("alloc,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("alloc,uninitialized,aligned") allocsize(1) "alloc-family"="malloc" define noalias i8* @test3() nounwind uwtable ssp { entry: