Index: llvm/include/llvm/Transforms/Utils/BuildLibCalls.h =================================================================== --- llvm/include/llvm/Transforms/Utils/BuildLibCalls.h +++ llvm/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -47,54 +47,64 @@ /// pointer. Ptr is required to be some pointer type, and the return value has /// 'intptr_t' type. Value *emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strdup function to the builder, for the specified /// pointer. Ptr is required to be some pointer type, and the return value has /// 'i8*' type. - Value *emitStrDup(Value *Ptr, IRBuilderBase &B, const TargetLibraryInfo *TLI); + Value *emitStrDup(Value *Ptr, IRBuilderBase &B, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strnlen function to the builder, for the specified /// pointer. Ptr is required to be some pointer type, MaxLen must be of size_t /// type, and the return value has 'intptr_t' type. Value *emitStrNLen(Value *Ptr, Value *MaxLen, IRBuilderBase &B, - const DataLayout &DL, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strchr function to the builder, for the specified /// pointer and character. Ptr is required to be some pointer type, and the /// return value has 'i8*' type. Value *emitStrChr(Value *Ptr, char C, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strncmp function to the builder. Value *emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, - const DataLayout &DL, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strcpy function to the builder, for the specified /// pointer arguments. Value *emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the stpcpy function to the builder, for the specified /// pointer arguments. Value *emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strncpy function to the builder, for the specified /// pointer arguments and length. Value *emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the stpncpy function to the builder, for the specified /// pointer arguments and length. Value *emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the __memcpy_chk function to the builder. This expects that /// the Len and ObjSize have type 'intptr_t' and Dst/Src are pointers. Value *emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, IRBuilderBase &B, const DataLayout &DL, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the mempcpy function. Value *emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, @@ -103,52 +113,64 @@ /// Emit a call to the memchr function. This assumes that Ptr is a pointer, /// Val is an i32 value, and Len is an 'intptr_t' value. Value *emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, - const DataLayout &DL, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the memcmp function. Value *emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, - const DataLayout &DL, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the bcmp function. Value *emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, - const DataLayout &DL, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the memccpy function. Value *emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len, - IRBuilderBase &B, const TargetLibraryInfo *TLI); + IRBuilderBase &B, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the snprintf function. Value *emitSNPrintf(Value *Dest, Value *Size, Value *Fmt, ArrayRef Args, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the sprintf function. Value *emitSPrintf(Value *Dest, Value *Fmt, ArrayRef VariadicArgs, - IRBuilderBase &B, const TargetLibraryInfo *TLI); + IRBuilderBase &B, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strcat function. Value *emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strlcpy function. Value *emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strlcat function. Value *emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the strncat function. Value *emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the vsnprintf function. Value *emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList, - IRBuilderBase &B, const TargetLibraryInfo *TLI); + IRBuilderBase &B, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the vsprintf function. Value *emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, IRBuilderBase &B, - const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo = AAMDNodes()); /// Emit a call to the unary function named 'Name' (e.g. 'floor'). This /// function is known to take a single of type matching 'Op' and returns one Index: llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h =================================================================== --- llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -224,7 +224,7 @@ // Helper methods Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, - IRBuilderBase &B); + IRBuilderBase &B, const AAMDNodes &AATags); void classifyArgUse(Value *Val, Function *F, bool IsFloat, SmallVectorImpl &SinCalls, SmallVectorImpl &CosCalls, Index: llvm/lib/Transforms/Utils/BuildLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -1012,8 +1012,8 @@ static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType, ArrayRef ParamTypes, ArrayRef Operands, IRBuilderBase &B, - const TargetLibraryInfo *TLI, - bool IsVaArgs = false) { + const TargetLibraryInfo *TLI, bool IsVaArgs = false, + const AAMDNodes &AAInfo = AAMDNodes()) { if (!TLI->has(TheLibFunc)) return nullptr; @@ -1026,70 +1026,79 @@ if (const Function *F = dyn_cast(Callee.getCallee()->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); + CI->setAAMetadata(AAInfo); return CI; } Value *llvm::emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, const AAMDNodes &AAInfo) { LLVMContext &Context = B.GetInsertBlock()->getContext(); return emitLibCall(LibFunc_strlen, DL.getIntPtrType(Context), - B.getInt8PtrTy(), castToCStr(Ptr, B), B, TLI); + B.getInt8PtrTy(), castToCStr(Ptr, B), B, TLI, false, + AAInfo); } Value *llvm::emitStrDup(Value *Ptr, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, const AAMDNodes &AAInfo) { return emitLibCall(LibFunc_strdup, B.getInt8PtrTy(), B.getInt8PtrTy(), - castToCStr(Ptr, B), B, TLI); + castToCStr(Ptr, B), B, TLI, false, AAInfo); } Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, const AAMDNodes &AAInfo) { Type *I8Ptr = B.getInt8PtrTy(); Type *I32Ty = B.getInt32Ty(); return emitLibCall(LibFunc_strchr, I8Ptr, {I8Ptr, I32Ty}, - {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, B, TLI); + {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, B, TLI, + false, AAInfo); } Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { + const DataLayout &DL, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { LLVMContext &Context = B.GetInsertBlock()->getContext(); return emitLibCall( LibFunc_strncmp, B.getInt32Ty(), {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)}, - {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI); + {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI, false, AAInfo); } Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, const AAMDNodes &AAInfo) { Type *I8Ptr = B.getInt8PtrTy(); return emitLibCall(LibFunc_strcpy, I8Ptr, {I8Ptr, I8Ptr}, - {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI); + {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI, + false, AAInfo); } Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, const AAMDNodes &AAInfo) { Type *I8Ptr = B.getInt8PtrTy(); return emitLibCall(LibFunc_stpcpy, I8Ptr, {I8Ptr, I8Ptr}, - {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI); + {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI, + false, AAInfo); } Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, const AAMDNodes &AAInfo) { Type *I8Ptr = B.getInt8PtrTy(); return emitLibCall(LibFunc_strncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()}, - {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI); + {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI, + false, AAInfo); } Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, const AAMDNodes &AAInfo) { Type *I8Ptr = B.getInt8PtrTy(); return emitLibCall(LibFunc_stpncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()}, - {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI); + {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI, + false, AAInfo); } Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, IRBuilderBase &B, const DataLayout &DL, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { if (!TLI->has(LibFunc_memcpy_chk)) return nullptr; @@ -1108,6 +1117,7 @@ if (const Function *F = dyn_cast(MemCpy.getCallee()->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); + CI->setAAMetadata(AAInfo); return CI; } @@ -1121,101 +1131,118 @@ } Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { + const DataLayout &DL, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { LLVMContext &Context = B.GetInsertBlock()->getContext(); return emitLibCall( LibFunc_memchr, B.getInt8PtrTy(), {B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context)}, - {castToCStr(Ptr, B), Val, Len}, B, TLI); + {castToCStr(Ptr, B), Val, Len}, B, TLI, false, AAInfo); } Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { + const DataLayout &DL, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { LLVMContext &Context = B.GetInsertBlock()->getContext(); return emitLibCall( LibFunc_memcmp, B.getInt32Ty(), {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)}, - {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI); + {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI, false, AAInfo); } Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, - const DataLayout &DL, const TargetLibraryInfo *TLI) { + const DataLayout &DL, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { LLVMContext &Context = B.GetInsertBlock()->getContext(); return emitLibCall( LibFunc_bcmp, B.getInt32Ty(), {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)}, - {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI); + {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI, false, AAInfo); } Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len, - IRBuilderBase &B, const TargetLibraryInfo *TLI) { + IRBuilderBase &B, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { return emitLibCall( LibFunc_memccpy, B.getInt8PtrTy(), {B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), Len->getType()}, - {Ptr1, Ptr2, Val, Len}, B, TLI); + {Ptr1, Ptr2, Val, Len}, B, TLI, false, AAInfo); } Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt, ArrayRef VariadicArgs, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { SmallVector Args{castToCStr(Dest, B), Size, castToCStr(Fmt, B)}; Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end()); return emitLibCall(LibFunc_snprintf, B.getInt32Ty(), {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy()}, - Args, B, TLI, /*IsVaArgs=*/true); + Args, B, TLI, /*IsVaArgs=*/true, AAInfo); } Value *llvm::emitSPrintf(Value *Dest, Value *Fmt, ArrayRef VariadicArgs, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { SmallVector Args{castToCStr(Dest, B), castToCStr(Fmt, B)}; Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end()); return emitLibCall(LibFunc_sprintf, B.getInt32Ty(), {B.getInt8PtrTy(), B.getInt8PtrTy()}, Args, B, TLI, - /*IsVaArgs=*/true); + /*IsVaArgs=*/true, AAInfo); } Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { - return emitLibCall(LibFunc_strcat, B.getInt8PtrTy(), - {B.getInt8PtrTy(), B.getInt8PtrTy()}, - {castToCStr(Dest, B), castToCStr(Src, B)}, B, TLI); + const TargetLibraryInfo *TLI, const AAMDNodes &AAInfo) { + return emitLibCall( + LibFunc_strcat, B.getInt8PtrTy(), + {B.getInt8PtrTy(), B.getInt8PtrTy()}, + {castToCStr(Dest, B), castToCStr(Src, B)}, B, TLI, false, AAInfo); } Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { return emitLibCall(LibFunc_strlcpy, Size->getType(), {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()}, - {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI); + {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI, + false, AAInfo); } Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { return emitLibCall(LibFunc_strlcat, Size->getType(), {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()}, - {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI); + {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI, + false, AAInfo); } Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, - const TargetLibraryInfo *TLI) { + const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { return emitLibCall(LibFunc_strncat, B.getInt8PtrTy(), {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()}, - {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI); + {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI, + false, AAInfo); } Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList, - IRBuilderBase &B, const TargetLibraryInfo *TLI) { + IRBuilderBase &B, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { return emitLibCall( LibFunc_vsnprintf, B.getInt32Ty(), {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy(), VAList->getType()}, - {castToCStr(Dest, B), Size, castToCStr(Fmt, B), VAList}, B, TLI); + {castToCStr(Dest, B), Size, castToCStr(Fmt, B), VAList}, B, TLI, false, + AAInfo); } Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, - IRBuilderBase &B, const TargetLibraryInfo *TLI) { + IRBuilderBase &B, const TargetLibraryInfo *TLI, + const AAMDNodes &AAInfo) { return emitLibCall(LibFunc_vsprintf, B.getInt32Ty(), {B.getInt8PtrTy(), B.getInt8PtrTy(), VAList->getType()}, - {castToCStr(Dest, B), castToCStr(Fmt, B), VAList}, B, TLI); + {castToCStr(Dest, B), castToCStr(Fmt, B), VAList}, B, TLI, + false, AAInfo); } /// Append a suffix to the function name according to the type of 'Op'. Index: llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -246,14 +246,17 @@ if (Len == 0) return Dst; - return emitStrLenMemCpy(Src, Dst, Len, B); + AAMDNodes AATags; + CI->getAAMetadata(AATags); + return emitStrLenMemCpy(Src, Dst, Len, B, AATags); } Value *LibCallSimplifier::emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, - IRBuilderBase &B) { + IRBuilderBase &B, + const AAMDNodes &AATags) { // We need to find the end of the destination string. That's where the // memory is to be moved to. We just generate a call to strlen. - Value *DstLen = emitStrLen(Dst, B, DL, TLI); + Value *DstLen = emitStrLen(Dst, B, DL, TLI, AATags); if (!DstLen) return nullptr; @@ -264,9 +267,9 @@ // We have enough information to now generate the memcpy call to do the // concatenation for us. Make a memcpy to copy the nul byte with align = 1. - B.CreateMemCpy( - CpyDst, Align(1), Src, Align(1), - ConstantInt::get(DL.getIntPtrType(Src->getContext()), Len + 1)); + B.CreateMemCpy(CpyDst, Align(1), Src, Align(1), + ConstantInt::get(DL.getIntPtrType(Src->getContext()), Len + 1), + false, AATags.TBAA, nullptr, AATags.Scope, AATags.NoAlias); return Dst; } @@ -308,9 +311,11 @@ if (Len < SrcLen) return nullptr; + AAMDNodes AATags; + CI->getAAMetadata(AATags); // strncat(x, s, c) -> strcat(x, s) // s is constant so the strcat can be optimized further. - return emitStrLenMemCpy(Src, Dst, SrcLen, B); + return emitStrLenMemCpy(Src, Dst, SrcLen, B, AATags); } Value *LibCallSimplifier::optimizeStrChr(CallInst *CI, IRBuilderBase &B) { @@ -319,6 +324,9 @@ Value *SrcStr = CI->getArgOperand(0); annotateNonNullBasedOnAccess(CI, 0); + AAMDNodes AATags; + CI->getAAMetadata(AATags); + // If the second operand is non-constant, see if we can compute the length // of the input string and turn this into memchr. ConstantInt *CharC = dyn_cast(CI->getArgOperand(1)); @@ -333,7 +341,7 @@ return emitMemChr(SrcStr, CI->getArgOperand(1), // include nul. ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len), - B, DL, TLI); + B, DL, TLI, AATags); } // Otherwise, the character is a constant, see if the first argument is @@ -341,7 +349,7 @@ StringRef Str; if (!getConstantStringInfo(SrcStr, Str)) { if (CharC->isZero()) // strchr(p, 0) -> p + strlen(p) - if (Value *StrLen = emitStrLen(SrcStr, B, DL, TLI)) + if (Value *StrLen = emitStrLen(SrcStr, B, DL, TLI, AATags)) return B.CreateGEP(B.getInt8Ty(), SrcStr, StrLen, "strchr"); return nullptr; } @@ -370,8 +378,11 @@ StringRef Str; if (!getConstantStringInfo(SrcStr, Str)) { // strrchr(s, 0) -> strchr(s, 0) - if (CharC->isZero()) - return emitStrChr(SrcStr, '\0', B, TLI); + if (CharC->isZero()) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); + return emitStrChr(SrcStr, '\0', B, TLI, AATags); + } return nullptr; } @@ -399,13 +410,19 @@ if (HasStr1 && HasStr2) return ConstantInt::get(CI->getType(), Str1.compare(Str2)); - if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x - return B.CreateNeg(B.CreateZExt( - B.CreateLoad(B.getInt8Ty(), Str2P, "strcmpload"), CI->getType())); + AAMDNodes AATags; + CI->getAAMetadata(AATags); + if (HasStr1 && Str1.empty()) { // strcmp("", x) -> -*x + auto load = B.CreateLoad(B.getInt8Ty(), Str2P, "strcmpload"); + load->setAAMetadata(AATags); + return B.CreateNeg(B.CreateZExt(load, CI->getType())); + } - if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x - return B.CreateZExt(B.CreateLoad(B.getInt8Ty(), Str1P, "strcmpload"), - CI->getType()); + if (HasStr2 && Str2.empty()) { // strcmp(x,"") -> *x + auto load = B.CreateLoad(B.getInt8Ty(), Str1P, "strcmpload"); + load->setAAMetadata(AATags); + return B.CreateZExt(load, CI->getType()); + } // strcmp(P, "x") -> memcmp(P, "x", 2) uint64_t Len1 = GetStringLength(Str1P); @@ -419,7 +436,7 @@ return emitMemCmp(Str1P, Str2P, ConstantInt::get(DL.getIntPtrType(CI->getContext()), std::min(Len1, Len2)), - B, DL, TLI); + B, DL, TLI, AATags); } // strcmp to memcmp @@ -428,13 +445,13 @@ return emitMemCmp( Str1P, Str2P, ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len2), B, DL, - TLI); + TLI, AATags); } else if (HasStr1 && !HasStr2) { if (canTransformToMemCmp(CI, Str2P, Len1, DL)) return emitMemCmp( Str1P, Str2P, ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len1), B, DL, - TLI); + TLI, AATags); } annotateNonNullBasedOnAccess(CI, {0, 1}); @@ -460,8 +477,10 @@ if (Length == 0) // strncmp(x,y,0) -> 0 return ConstantInt::get(CI->getType(), 0); + AAMDNodes AATags; + CI->getAAMetadata(AATags); if (Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1) - return emitMemCmp(Str1P, Str2P, Size, B, DL, TLI); + return emitMemCmp(Str1P, Str2P, Size, B, DL, TLI, AATags); StringRef Str1, Str2; bool HasStr1 = getConstantStringInfo(Str1P, Str1); @@ -474,13 +493,17 @@ return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2)); } - if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> -*x - return B.CreateNeg(B.CreateZExt( - B.CreateLoad(B.getInt8Ty(), Str2P, "strcmpload"), CI->getType())); + if (HasStr1 && Str1.empty()) { // strncmp("", x, n) -> -*x + auto load = B.CreateLoad(B.getInt8Ty(), Str2P, "strcmpload"); + load->setAAMetadata(AATags); + return B.CreateNeg(B.CreateZExt(load, CI->getType())); + } - if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x - return B.CreateZExt(B.CreateLoad(B.getInt8Ty(), Str1P, "strcmpload"), - CI->getType()); + if (HasStr2 && Str2.empty()) { // strncmp(x, "", n) -> *x + auto load = B.CreateLoad(B.getInt8Ty(), Str1P, "strcmpload"); + load->setAAMetadata(AATags); + return B.CreateZExt(load, CI->getType()); + } uint64_t Len1 = GetStringLength(Str1P); if (Len1) @@ -496,14 +519,14 @@ return emitMemCmp( Str1P, Str2P, ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len2), B, DL, - TLI); + TLI, AATags); } else if (HasStr1 && !HasStr2) { Len1 = std::min(Len1, Length); if (canTransformToMemCmp(CI, Str2P, Len1, DL)) return emitMemCmp( Str1P, Str2P, ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len1), B, DL, - TLI); + TLI, AATags); } return nullptr; @@ -515,8 +538,11 @@ uint64_t SrcLen = GetStringLength(Src); if (SrcLen && Size) { annotateDereferenceableBytes(CI, 0, SrcLen); - if (SrcLen <= Size->getZExtValue() + 1) - return emitStrDup(Src, B, TLI); + if (SrcLen <= Size->getZExtValue() + 1) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); + return emitStrDup(Src, B, TLI, AATags); + } } return nullptr; @@ -535,11 +561,14 @@ else return nullptr; + AAMDNodes AATags; + CI->getAAMetadata(AATags); // We have enough information to now generate the memcpy call to do the // copy for us. Make a memcpy to copy the nul byte with align = 1. CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1), - ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len)); + ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len), + false, AATags.TBAA, nullptr, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return Dst; } @@ -547,8 +576,10 @@ Value *LibCallSimplifier::optimizeStpCpy(CallInst *CI, IRBuilderBase &B) { Function *Callee = CI->getCalledFunction(); Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); + AAMDNodes AATags; + CI->getAAMetadata(AATags); if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x) - Value *StrLen = emitStrLen(Src, B, DL, TLI); + Value *StrLen = emitStrLen(Src, B, DL, TLI, AATags); return StrLen ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, StrLen) : nullptr; } @@ -566,7 +597,9 @@ // We have enough information to now generate the memcpy call to do the // copy for us. Make a memcpy to copy the nul byte with align = 1. - CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1), LenV); + CallInst *NewCI = + B.CreateMemCpy(Dst, Align(1), Src, Align(1), LenV, false, AATags.TBAA, + nullptr, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return DstEnd; } @@ -599,9 +632,13 @@ return nullptr; } + AAMDNodes AATags; + CI->getAAMetadata(AATags); if (SrcLen == 0) { // strncpy(x, "", y) -> memset(align 1 x, '\0', y) - CallInst *NewCI = B.CreateMemSet(Dst, B.getInt8('\0'), Size, Align(1)); + CallInst *NewCI = + B.CreateMemSet(Dst, B.getInt8('\0'), Size, Align(1), false, AATags.TBAA, + AATags.Scope, AATags.NoAlias); AttrBuilder ArgAttrs(CI->getAttributes().getParamAttributes(0)); NewCI->setAttributes(NewCI->getAttributes().addParamAttributes( CI->getContext(), 0, ArgAttrs)); @@ -624,8 +661,9 @@ Type *PT = Callee->getFunctionType()->getParamType(0); // strncpy(x, s, c) -> memcpy(align 1 x, align 1 s, c) [s and c are constant] - CallInst *NewCI = B.CreateMemCpy(Dst, Align(1), Src, Align(1), - ConstantInt::get(DL.getIntPtrType(PT), Len)); + CallInst *NewCI = B.CreateMemCpy( + Dst, Align(1), Src, Align(1), ConstantInt::get(DL.getIntPtrType(PT), Len), + false, AATags.TBAA, nullptr, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return Dst; } @@ -712,9 +750,13 @@ // strlen(x) != 0 --> *x != 0 // strlen(x) == 0 --> *x == 0 - if (isOnlyUsedInZeroEqualityComparison(CI)) - return B.CreateZExt(B.CreateLoad(B.getIntNTy(CharSize), Src, "strlenfirst"), - CI->getType()); + if (isOnlyUsedInZeroEqualityComparison(CI)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); + auto load = B.CreateLoad(B.getIntNTy(CharSize), Src, "strlenfirst"); + load->setAAMetadata(AATags); + return B.CreateZExt(load, CI->getType()); + } return nullptr; } @@ -757,8 +799,11 @@ } // strpbrk(s, "a") -> strchr(s, 'a') - if (HasS2 && S2.size() == 1) - return emitStrChr(CI->getArgOperand(0), S2[0], B, TLI); + if (HasS2 && S2.size() == 1) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); + return emitStrChr(CI->getArgOperand(0), S2[0], B, TLI, AATags); + } return nullptr; } @@ -813,8 +858,11 @@ } // strcspn(s, "") -> strlen(s) - if (HasS2 && S2.empty()) - return emitStrLen(CI->getArgOperand(0), B, DL, TLI); + if (HasS2 && S2.empty()) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); + return emitStrLen(CI->getArgOperand(0), B, DL, TLI, AATags); + } return nullptr; } @@ -824,13 +872,15 @@ if (CI->getArgOperand(0) == CI->getArgOperand(1)) return B.CreateBitCast(CI->getArgOperand(0), CI->getType()); + AAMDNodes AATags; + CI->getAAMetadata(AATags); // fold strstr(a, b) == a -> strncmp(a, b, strlen(b)) == 0 if (isOnlyUsedInEqualityComparison(CI, CI->getArgOperand(0))) { - Value *StrLen = emitStrLen(CI->getArgOperand(1), B, DL, TLI); + Value *StrLen = emitStrLen(CI->getArgOperand(1), B, DL, TLI, AATags); if (!StrLen) return nullptr; Value *StrNCmp = emitStrNCmp(CI->getArgOperand(0), CI->getArgOperand(1), - StrLen, B, DL, TLI); + StrLen, B, DL, TLI, AATags); if (!StrNCmp) return nullptr; for (auto UI = CI->user_begin(), UE = CI->user_end(); UI != UE;) { @@ -868,7 +918,8 @@ // fold strstr(x, "y") -> strchr(x, 'y'). if (HasStr2 && ToFindStr.size() == 1) { - Value *StrChr = emitStrChr(CI->getArgOperand(0), ToFindStr[0], B, TLI); + Value *StrChr = + emitStrChr(CI->getArgOperand(0), ToFindStr[0], B, TLI, AATags); return StrChr ? B.CreateBitCast(StrChr, CI->getType()) : nullptr; } @@ -976,14 +1027,17 @@ if (Len == 0) // memcmp(s1,s2,0) -> 0 return Constant::getNullValue(CI->getType()); + AAMDNodes AATags; + CI->getAAMetadata(AATags); + // memcmp(S1,S2,1) -> *(unsigned char*)LHS - *(unsigned char*)RHS if (Len == 1) { - Value *LHSV = - B.CreateZExt(B.CreateLoad(B.getInt8Ty(), castToCStr(LHS, B), "lhsc"), - CI->getType(), "lhsv"); - Value *RHSV = - B.CreateZExt(B.CreateLoad(B.getInt8Ty(), castToCStr(RHS, B), "rhsc"), - CI->getType(), "rhsv"); + auto load1 = B.CreateLoad(B.getInt8Ty(), castToCStr(LHS, B), "lhsc"); + load1->setAAMetadata(AATags); + Value *LHSV = B.CreateZExt(load1, CI->getType(), "lhsv"); + auto load2 = B.CreateLoad(B.getInt8Ty(), castToCStr(RHS, B), "rhsc"); + load2->setAAMetadata(AATags); + Value *RHSV = B.CreateZExt(load2, CI->getType(), "rhsv"); return B.CreateSub(LHSV, RHSV, "chardiff"); } @@ -1014,11 +1068,13 @@ Type *LHSPtrTy = IntType->getPointerTo(LHS->getType()->getPointerAddressSpace()); LHSV = B.CreateLoad(IntType, B.CreateBitCast(LHS, LHSPtrTy), "lhsv"); + cast(LHSV)->setAAMetadata(AATags); } if (!RHSV) { Type *RHSPtrTy = IntType->getPointerTo(RHS->getType()->getPointerAddressSpace()); RHSV = B.CreateLoad(IntType, B.CreateBitCast(RHS, RHSPtrTy), "rhsv"); + cast(RHSV)->setAAMetadata(AATags); } return B.CreateZExt(B.CreateICmpNE(LHSV, RHSV), CI->getType(), "memcmp"); } @@ -1082,7 +1138,9 @@ Value *LHS = CI->getArgOperand(0); Value *RHS = CI->getArgOperand(1); Value *Size = CI->getArgOperand(2); - return emitBCmp(LHS, RHS, Size, B, DL, TLI); + AAMDNodes AATags; + CI->getAAMetadata(AATags); + return emitBCmp(LHS, RHS, Size, B, DL, TLI, AATags); } return nullptr; @@ -1098,9 +1156,12 @@ if (isa(CI)) return nullptr; + AAMDNodes AATags; + CI->getAAMetadata(AATags); // memcpy(x, y, n) -> llvm.memcpy(align 1 x, align 1 y, n) - CallInst *NewCI = B.CreateMemCpy(CI->getArgOperand(0), Align(1), - CI->getArgOperand(1), Align(1), Size); + CallInst *NewCI = B.CreateMemCpy( + CI->getArgOperand(0), Align(1), CI->getArgOperand(1), Align(1), Size, + false, AATags.TBAA, AATags.TBAAStruct, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return CI->getArgOperand(0); } @@ -1125,11 +1186,15 @@ return nullptr; } + AAMDNodes AATags; + CI->getAAMetadata(AATags); + // Wrap arg 'c' of type int to char size_t Pos = SrcStr.find(StopChar->getSExtValue() & 0xFF); if (Pos == StringRef::npos) { if (N->getZExtValue() <= SrcStr.size()) { - B.CreateMemCpy(Dst, Align(1), Src, Align(1), CI->getArgOperand(3)); + B.CreateMemCpy(Dst, Align(1), Src, Align(1), CI->getArgOperand(3), false, + AATags.TBAA, nullptr, AATags.Scope, AATags.NoAlias); return Constant::getNullValue(CI->getType()); } return nullptr; @@ -1138,7 +1203,8 @@ Value *NewN = ConstantInt::get(N->getType(), std::min(uint64_t(Pos + 1), N->getZExtValue())); // memccpy -> llvm.memcpy - B.CreateMemCpy(Dst, Align(1), Src, Align(1), NewN); + B.CreateMemCpy(Dst, Align(1), Src, Align(1), NewN, false, AATags.TBAA, + nullptr, AATags.Scope, AATags.NoAlias); return Pos + 1 <= N->getZExtValue() ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, NewN) : Constant::getNullValue(CI->getType()); @@ -1147,9 +1213,12 @@ Value *LibCallSimplifier::optimizeMemPCpy(CallInst *CI, IRBuilderBase &B) { Value *Dst = CI->getArgOperand(0); Value *N = CI->getArgOperand(2); + AAMDNodes AATags; + CI->getAAMetadata(AATags); // mempcpy(x, y, n) -> llvm.memcpy(align 1 x, align 1 y, n), x + n CallInst *NewCI = - B.CreateMemCpy(Dst, Align(1), CI->getArgOperand(1), Align(1), N); + B.CreateMemCpy(Dst, Align(1), CI->getArgOperand(1), Align(1), N, false, + AATags.TBAA, nullptr, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return B.CreateInBoundsGEP(B.getInt8Ty(), Dst, N); } @@ -1160,9 +1229,12 @@ if (isa(CI)) return nullptr; + AAMDNodes AATags; + CI->getAAMetadata(AATags); // memmove(x, y, n) -> llvm.memmove(align 1 x, align 1 y, n) CallInst *NewCI = B.CreateMemMove(CI->getArgOperand(0), Align(1), - CI->getArgOperand(1), Align(1), Size); + CI->getArgOperand(1), Align(1), Size, false, + AATags.TBAA, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return CI->getArgOperand(0); } @@ -1220,9 +1292,13 @@ if (auto *Calloc = foldMallocMemset(CI, B)) return Calloc; + AAMDNodes AATags; + CI->getAAMetadata(AATags); // memset(p, v, n) -> llvm.memset(align 1 p, v, n) Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false); - CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val, Size, Align(1)); + CallInst *NewCI = + B.CreateMemSet(CI->getArgOperand(0), Val, Size, Align(1), false, + AATags.TBAA, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return CI->getArgOperand(0); } @@ -2464,6 +2540,8 @@ if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) return nullptr; + AAMDNodes AATags; + CI->getAAMetadata(AATags); // If we just have a format string (nothing else crazy) transform it. if (CI->getNumArgOperands() == 2) { // Make sure there's no % in the constant array. We could try to handle @@ -2475,7 +2553,8 @@ B.CreateMemCpy( CI->getArgOperand(0), Align(1), CI->getArgOperand(1), Align(1), ConstantInt::get(DL.getIntPtrType(CI->getContext()), - FormatStr.size() + 1)); // Copy the null byte. + FormatStr.size() + 1), // Copy the null byte. + false, AATags.TBAA, nullptr, AATags.Scope, AATags.NoAlias); return ConstantInt::get(CI->getType(), FormatStr.size()); } @@ -2492,9 +2571,9 @@ return nullptr; Value *V = B.CreateTrunc(CI->getArgOperand(2), B.getInt8Ty(), "char"); Value *Ptr = castToCStr(CI->getArgOperand(0), B); - B.CreateStore(V, Ptr); + B.CreateStore(V, Ptr)->setAAMetadata(AATags); Ptr = B.CreateGEP(B.getInt8Ty(), Ptr, B.getInt32(1), "nul"); - B.CreateStore(B.getInt8(0), Ptr); + B.CreateStore(B.getInt8(0), Ptr)->setAAMetadata(AATags); return ConstantInt::get(CI->getType(), 1); } @@ -2507,17 +2586,19 @@ if (CI->use_empty()) // sprintf(dest, "%s", str) -> strcpy(dest, str) - return emitStrCpy(CI->getArgOperand(0), CI->getArgOperand(2), B, TLI); + return emitStrCpy(CI->getArgOperand(0), CI->getArgOperand(2), B, TLI, + AATags); uint64_t SrcLen = GetStringLength(CI->getArgOperand(2)); if (SrcLen) { B.CreateMemCpy( CI->getArgOperand(0), Align(1), CI->getArgOperand(2), Align(1), - ConstantInt::get(DL.getIntPtrType(CI->getContext()), SrcLen)); + ConstantInt::get(DL.getIntPtrType(CI->getContext()), SrcLen), false, + AATags.TBAA, nullptr, AATags.Scope, AATags.NoAlias); // Returns total number of characters written without null-character. return ConstantInt::get(CI->getType(), SrcLen - 1); } else if (Value *V = emitStpCpy(CI->getArgOperand(0), CI->getArgOperand(2), - B, TLI)) { + B, TLI, AATags)) { // sprintf(dest, "%s", str) -> stpcpy(dest, str) - dest Value *PtrDiff = B.CreatePtrDiff(V, CI->getArgOperand(0)); return B.CreateIntCast(PtrDiff, CI->getType(), false); @@ -2529,13 +2610,14 @@ if (OptForSize) return nullptr; - Value *Len = emitStrLen(CI->getArgOperand(2), B, DL, TLI); + Value *Len = emitStrLen(CI->getArgOperand(2), B, DL, TLI, AATags); if (!Len) return nullptr; Value *IncLen = B.CreateAdd(Len, ConstantInt::get(Len->getType(), 1), "leninc"); B.CreateMemCpy(CI->getArgOperand(0), Align(1), CI->getArgOperand(2), - Align(1), IncLen); + Align(1), IncLen, false, AATags.TBAA, nullptr, AATags.Scope, + AATags.NoAlias); // The sprintf result is the unincremented number of bytes in the string. return B.CreateIntCast(Len, CI->getType(), false); @@ -2592,6 +2674,8 @@ if (!getConstantStringInfo(CI->getArgOperand(2), FormatStr)) return nullptr; + AAMDNodes AATags; + CI->getAAMetadata(AATags); // If we just have a format string (nothing else crazy) transform it. if (CI->getNumArgOperands() == 3) { // Make sure there's no % in the constant array. We could try to handle @@ -2606,10 +2690,12 @@ // snprintf(dst, size, fmt) -> llvm.memcpy(align 1 dst, align 1 fmt, // strlen(fmt)+1) - B.CreateMemCpy( - CI->getArgOperand(0), Align(1), CI->getArgOperand(2), Align(1), - ConstantInt::get(DL.getIntPtrType(CI->getContext()), - FormatStr.size() + 1)); // Copy the null byte. + B.CreateMemCpy(CI->getArgOperand(0), Align(1), CI->getArgOperand(2), + Align(1), + ConstantInt::get(DL.getIntPtrType(CI->getContext()), + FormatStr.size() + 1), // Copy the null byte. + false, AATags.TBAA, nullptr, + AATags.Scope, AATags.NoAlias); return ConstantInt::get(CI->getType(), FormatStr.size()); } @@ -2630,9 +2716,9 @@ return nullptr; Value *V = B.CreateTrunc(CI->getArgOperand(3), B.getInt8Ty(), "char"); Value *Ptr = castToCStr(CI->getArgOperand(0), B); - B.CreateStore(V, Ptr); + B.CreateStore(V, Ptr)->setAAMetadata(AATags); Ptr = B.CreateGEP(B.getInt8Ty(), Ptr, B.getInt32(1), "nul"); - B.CreateStore(B.getInt8(0), Ptr); + B.CreateStore(B.getInt8(0), Ptr)->setAAMetadata(AATags); return ConstantInt::get(CI->getType(), 1); } @@ -2649,7 +2735,8 @@ return nullptr; B.CreateMemCpy(CI->getArgOperand(0), Align(1), CI->getArgOperand(3), - Align(1), ConstantInt::get(CI->getType(), Str.size() + 1)); + Align(1), ConstantInt::get(CI->getType(), Str.size() + 1), + false, AATags.TBAA, nullptr, AATags.Scope, AATags.NoAlias); // The snprintf result is the unincremented number of bytes in the string. return ConstantInt::get(CI->getType(), Str.size()); @@ -2822,8 +2909,11 @@ Value *LibCallSimplifier::optimizeBCopy(CallInst *CI, IRBuilderBase &B) { // bcopy(src, dst, n) -> llvm.memmove(dst, src, n) + AAMDNodes AATags; + CI->getAAMetadata(AATags); return B.CreateMemMove(CI->getArgOperand(1), Align(1), CI->getArgOperand(0), - Align(1), CI->getArgOperand(2)); + Align(1), CI->getArgOperand(2), false, AATags.TBAA, + AATags.Scope, AATags.NoAlias); } bool LibCallSimplifier::hasFloatVersion(StringRef FuncName) { @@ -3257,9 +3347,12 @@ Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(CallInst *CI, IRBuilderBase &B) { if (isFortifiedCallFoldable(CI, 3, 2)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); CallInst *NewCI = B.CreateMemCpy(CI->getArgOperand(0), Align(1), CI->getArgOperand(1), - Align(1), CI->getArgOperand(2)); + Align(1), CI->getArgOperand(2), false, AATags.TBAA, + AATags.TBAAStruct, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return CI->getArgOperand(0); } @@ -3269,9 +3362,12 @@ Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(CallInst *CI, IRBuilderBase &B) { if (isFortifiedCallFoldable(CI, 3, 2)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); CallInst *NewCI = - B.CreateMemMove(CI->getArgOperand(0), Align(1), CI->getArgOperand(1), - Align(1), CI->getArgOperand(2)); + B.CreateMemMove( + CI->getArgOperand(0), Align(1), CI->getArgOperand(1), Align(1), + CI->getArgOperand(2), false, AATags.TBAA, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return CI->getArgOperand(0); } @@ -3284,8 +3380,11 @@ if (isFortifiedCallFoldable(CI, 3, 2)) { Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false); + AAMDNodes AATags; + CI->getAAMetadata(AATags); CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val, - CI->getArgOperand(2), Align(1)); + CI->getArgOperand(2), Align(1), false, + AATags.TBAA, AATags.Scope, AATags.NoAlias); NewCI->setAttributes(CI->getAttributes()); return CI->getArgOperand(0); } @@ -3312,9 +3411,11 @@ Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1), *ObjSize = CI->getArgOperand(2); + AAMDNodes AATags; + CI->getAAMetadata(AATags); // __stpcpy_chk(x,x,...) -> x+strlen(x) if (Func == LibFunc_stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src) { - Value *StrLen = emitStrLen(Src, B, DL, TLI); + Value *StrLen = emitStrLen(Src, B, DL, TLI, AATags); return StrLen ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, StrLen) : nullptr; } @@ -3325,9 +3426,9 @@ // string lengths for varying. if (isFortifiedCallFoldable(CI, 2, None, 1)) { if (Func == LibFunc_strcpy_chk) - return emitStrCpy(Dst, Src, B, TLI); + return emitStrCpy(Dst, Src, B, TLI, AATags); else - return emitStpCpy(Dst, Src, B, TLI); + return emitStpCpy(Dst, Src, B, TLI, AATags); } if (OnlyLowerUnknownSize) @@ -3342,7 +3443,7 @@ Type *SizeTTy = DL.getIntPtrType(CI->getContext()); Value *LenV = ConstantInt::get(SizeTTy, Len); - Value *Ret = emitMemCpyChk(Dst, Src, LenV, ObjSize, B, DL, TLI); + Value *Ret = emitMemCpyChk(Dst, Src, LenV, ObjSize, B, DL, TLI, AATags); // If the function was an __stpcpy_chk, and we were able to fold it into // a __memcpy_chk, we still need to return the correct end pointer. if (Ret && Func == LibFunc_stpcpy_chk) @@ -3352,9 +3453,12 @@ Value *FortifiedLibCallSimplifier::optimizeStrLenChk(CallInst *CI, IRBuilderBase &B) { - if (isFortifiedCallFoldable(CI, 1, None, 0)) + if (isFortifiedCallFoldable(CI, 1, None, 0)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); return emitStrLen(CI->getArgOperand(0), B, CI->getModule()->getDataLayout(), - TLI); + TLI, AATags); + } return nullptr; } @@ -3362,12 +3466,14 @@ IRBuilderBase &B, LibFunc Func) { if (isFortifiedCallFoldable(CI, 3, 2)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); if (Func == LibFunc_strncpy_chk) return emitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), B, TLI); + CI->getArgOperand(2), B, TLI, AATags); else return emitStpNCpy(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), B, TLI); + CI->getArgOperand(2), B, TLI, AATags); } return nullptr; @@ -3375,9 +3481,13 @@ Value *FortifiedLibCallSimplifier::optimizeMemCCpyChk(CallInst *CI, IRBuilderBase &B) { - if (isFortifiedCallFoldable(CI, 4, 3)) + if (isFortifiedCallFoldable(CI, 4, 3)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); return emitMemCCpy(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), CI->getArgOperand(3), B, TLI); + CI->getArgOperand(2), CI->getArgOperand(3), B, TLI, + AATags); + } return nullptr; } @@ -3386,8 +3496,10 @@ IRBuilderBase &B) { if (isFortifiedCallFoldable(CI, 3, 1, None, 2)) { SmallVector VariadicArgs(CI->arg_begin() + 5, CI->arg_end()); + AAMDNodes AATags; + CI->getAAMetadata(AATags); return emitSNPrintf(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(4), VariadicArgs, B, TLI); + CI->getArgOperand(4), VariadicArgs, B, TLI, AATags); } return nullptr; @@ -3397,8 +3509,10 @@ IRBuilderBase &B) { if (isFortifiedCallFoldable(CI, 2, None, None, 1)) { SmallVector VariadicArgs(CI->arg_begin() + 4, CI->arg_end()); + AAMDNodes AATags; + CI->getAAMetadata(AATags); return emitSPrintf(CI->getArgOperand(0), CI->getArgOperand(3), VariadicArgs, - B, TLI); + B, TLI, AATags); } return nullptr; @@ -3406,53 +3520,73 @@ Value *FortifiedLibCallSimplifier::optimizeStrCatChk(CallInst *CI, IRBuilderBase &B) { - if (isFortifiedCallFoldable(CI, 2)) - return emitStrCat(CI->getArgOperand(0), CI->getArgOperand(1), B, TLI); + if (isFortifiedCallFoldable(CI, 2)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); + return emitStrCat(CI->getArgOperand(0), CI->getArgOperand(1), B, TLI, + AATags); + } return nullptr; } Value *FortifiedLibCallSimplifier::optimizeStrLCat(CallInst *CI, IRBuilderBase &B) { - if (isFortifiedCallFoldable(CI, 3)) + if (isFortifiedCallFoldable(CI, 3)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); return emitStrLCat(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), B, TLI); + CI->getArgOperand(2), B, TLI, AATags); + } return nullptr; } Value *FortifiedLibCallSimplifier::optimizeStrNCatChk(CallInst *CI, IRBuilderBase &B) { - if (isFortifiedCallFoldable(CI, 3)) + if (isFortifiedCallFoldable(CI, 3)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); return emitStrNCat(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), B, TLI); + CI->getArgOperand(2), B, TLI, AATags); + } return nullptr; } Value *FortifiedLibCallSimplifier::optimizeStrLCpyChk(CallInst *CI, IRBuilderBase &B) { - if (isFortifiedCallFoldable(CI, 3)) + if (isFortifiedCallFoldable(CI, 3)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); return emitStrLCpy(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), B, TLI); + CI->getArgOperand(2), B, TLI, AATags); + } return nullptr; } Value *FortifiedLibCallSimplifier::optimizeVSNPrintfChk(CallInst *CI, IRBuilderBase &B) { - if (isFortifiedCallFoldable(CI, 3, 1, None, 2)) + if (isFortifiedCallFoldable(CI, 3, 1, None, 2)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); return emitVSNPrintf(CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(4), CI->getArgOperand(5), B, TLI); + CI->getArgOperand(4), CI->getArgOperand(5), B, TLI, + AATags); + } return nullptr; } Value *FortifiedLibCallSimplifier::optimizeVSPrintfChk(CallInst *CI, IRBuilderBase &B) { - if (isFortifiedCallFoldable(CI, 2, None, None, 1)) + if (isFortifiedCallFoldable(CI, 2, None, None, 1)) { + AAMDNodes AATags; + CI->getAAMetadata(AATags); return emitVSPrintf(CI->getArgOperand(0), CI->getArgOperand(3), - CI->getArgOperand(4), B, TLI); + CI->getArgOperand(4), B, TLI, AATags); + } return nullptr; } Index: llvm/test/Transforms/InstCombine/bcmp-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/bcmp-1.ll +++ llvm/test/Transforms/InstCombine/bcmp-1.ll @@ -35,14 +35,14 @@ define i32 @test_simplify3(i8* %mem1, i8* %mem2) { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* [[MEM1:%.*]], align 1 +; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* [[MEM1:%.*]], align 1, !tbaa ; CHECK-NEXT: [[LHSV:%.*]] = zext i8 [[LHSC]] to i32 -; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* [[MEM2:%.*]], align 1 +; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* [[MEM2:%.*]], align 1, !tbaa ; CHECK-NEXT: [[RHSV:%.*]] = zext i8 [[RHSC]] to i32 ; CHECK-NEXT: [[CHARDIFF:%.*]] = sub nsw i32 [[LHSV]], [[RHSV]] ; CHECK-NEXT: ret i32 [[CHARDIFF]] ; - %ret = call i32 @bcmp(i8* %mem1, i8* %mem2, i32 1) + %ret = call i32 @bcmp(i8* %mem1, i8* %mem2, i32 1), !tbaa !2 ret i32 %ret } @@ -142,3 +142,7 @@ %cmp = icmp eq i32 %call, 0 ret i1 %cmp } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/bcopy.ll =================================================================== --- llvm/test/Transforms/InstCombine/bcopy.ll +++ llvm/test/Transforms/InstCombine/bcopy.ll @@ -7,19 +7,23 @@ ; CHECK-LABEL: @bcopy_memmove( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[A:%.*]] to i64* ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[B:%.*]] to i64* -; CHECK-NEXT: [[TMP3:%.*]] = load i64, i64* [[TMP1]], align 1 -; CHECK-NEXT: store i64 [[TMP3]], i64* [[TMP2]], align 1 +; CHECK-NEXT: [[TMP3:%.*]] = load i64, i64* [[TMP1]], align 1, !tbaa +; CHECK-NEXT: store i64 [[TMP3]], i64* [[TMP2]], align 1, !tbaa ; CHECK-NEXT: ret void ; - tail call void @bcopy(i8* %a, i8* %b, i32 8) + tail call void @bcopy(i8* %a, i8* %b, i32 8), !tbaa !2 ret void } define void @bcopy_memmove2(i8* nocapture readonly %a, i8* nocapture %b, i32 %len) { ; CHECK-LABEL: @bcopy_memmove2( -; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* align 1 [[B:%.*]], i8* align 1 [[A:%.*]], i32 [[LEN:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* align 1 [[B:%.*]], i8* align 1 [[A:%.*]], i32 [[LEN:%.*]], i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret void ; - tail call void @bcopy(i8* %a, i8* %b, i32 %len) + tail call void @bcopy(i8* %a, i8* %b, i32 %len), !tbaa !2 ret void } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/fortify-folding.ll =================================================================== --- llvm/test/Transforms/InstCombine/fortify-folding.ll +++ llvm/test/Transforms/InstCombine/fortify-folding.ll @@ -11,12 +11,12 @@ define i8* @test_memccpy() { ; CHECK-LABEL: @test_memccpy( -; CHECK-NEXT: [[MEMCCPY:%.*]] = call i8* @memccpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i32 0, i64 60) +; CHECK-NEXT: [[MEMCCPY:%.*]] = call i8* @memccpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i32 0, i64 60), !tbaa ; CHECK-NEXT: ret i8* [[MEMCCPY]] ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__memccpy_chk(i8* %dst, i8* %src, i32 0, i64 60, i64 -1) + %ret = call i8* @__memccpy_chk(i8* %dst, i8* %src, i32 0, i64 60, i64 -1), !tbaa !2 ret i8* %ret } @@ -55,12 +55,12 @@ define i32 @test_snprintf() { ; CHECK-LABEL: @test_snprintf( -; CHECK-NEXT: [[SNPRINTF:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 60, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0)) +; CHECK-NEXT: [[SNPRINTF:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 60, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0)), !tbaa ; CHECK-NEXT: ret i32 [[SNPRINTF]] ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 0, i64 -1, i8* %fmt) + %ret = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* %dst, i64 60, i32 0, i64 -1, i8* %fmt), !tbaa !2 ret i32 %ret } @@ -79,12 +79,12 @@ define i32 @test_sprintf() { ; CHECK-LABEL: @test_sprintf( -; CHECK-NEXT: [[SPRINTF:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0)) +; CHECK-NEXT: [[SPRINTF:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0)), !tbaa ; CHECK-NEXT: ret i32 [[SPRINTF]] ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %fmt = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 0, i64 -1, i8* %fmt) + %ret = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %dst, i32 0, i64 -1, i8* %fmt), !tbaa !2 ret i32 %ret } @@ -103,12 +103,12 @@ define i8* @test_strcat() { ; CHECK-LABEL: @test_strcat( -; CHECK-NEXT: [[STRCAT:%.*]] = call i8* @strcat(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0)) +; CHECK-NEXT: [[STRCAT:%.*]] = call i8* @strcat(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0)), !tbaa ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__strcat_chk(i8* %dst, i8* %src, i64 -1) + %ret = call i8* @__strcat_chk(i8* %dst, i8* %src, i64 -1), !tbaa !2 ret i8* %ret } @@ -125,12 +125,12 @@ define i64 @test_strlcat() { ; CHECK-LABEL: @test_strlcat( -; CHECK-NEXT: [[STRLCAT:%.*]] = call i64 @strlcat(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22) +; CHECK-NEXT: [[STRLCAT:%.*]] = call i64 @strlcat(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22), !tbaa ; CHECK-NEXT: ret i64 [[STRLCAT]] ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i64 @__strlcat_chk(i8* %dst, i8* %src, i64 22, i64 -1) + %ret = call i64 @__strlcat_chk(i8* %dst, i8* %src, i64 22, i64 -1), !tbaa !2 ret i64 %ret } @@ -147,12 +147,12 @@ define i8* @test_strncat() { ; CHECK-LABEL: @test_strncat( -; CHECK-NEXT: [[STRNCAT:%.*]] = call i8* @strncat(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22) +; CHECK-NEXT: [[STRNCAT:%.*]] = call i8* @strncat(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22), !tbaa ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__strncat_chk(i8* %dst, i8* %src, i64 22, i64 -1) + %ret = call i8* @__strncat_chk(i8* %dst, i8* %src, i64 22, i64 -1), !tbaa !2 ret i8* %ret } @@ -169,12 +169,12 @@ define i64 @test_strlcpy() { ; CHECK-LABEL: @test_strlcpy( -; CHECK-NEXT: [[STRLCPY:%.*]] = call i64 @strlcpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22) +; CHECK-NEXT: [[STRLCPY:%.*]] = call i64 @strlcpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), i64 22), !tbaa ; CHECK-NEXT: ret i64 [[STRLCPY]] ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i64 @__strlcpy_chk(i8* %dst, i8* %src, i64 22, i64 -1) + %ret = call i64 @__strlcpy_chk(i8* %dst, i8* %src, i64 22, i64 -1), !tbaa !2 ret i64 %ret } @@ -191,13 +191,13 @@ define i32 @test_vsnprintf() { ; CHECK-LABEL: @test_vsnprintf( -; CHECK-NEXT: [[VSNPRINTF:%.*]] = call i32 @vsnprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null) +; CHECK-NEXT: [[VSNPRINTF:%.*]] = call i32 @vsnprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null), !tbaa ; CHECK-NEXT: ret i32 [[VSNPRINTF]] ; ; ret i32 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null) + %ret = call i32 @__vsnprintf_chk(i8* %dst, i64 4, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null), !tbaa !2 ret i32 %ret } @@ -217,13 +217,13 @@ define i32 @test_vsprintf() { ; CHECK-LABEL: @test_vsprintf( -; CHECK-NEXT: [[VSPRINTF:%.*]] = call i32 @vsprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null) +; CHECK-NEXT: [[VSPRINTF:%.*]] = call i32 @vsprintf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null), !tbaa ; CHECK-NEXT: ret i32 [[VSPRINTF]] ; ; ret i32 %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i32 @__vsprintf_chk(i8* %dst, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null) + %ret = call i32 @__vsprintf_chk(i8* %dst, i32 0, i64 -1, i8* %src, %struct.__va_list_tag* null), !tbaa !2 ret i32 %ret } @@ -251,3 +251,7 @@ declare i64 @__strlcpy_chk(i8*, i8*, i64, i64) declare i32 @__vsnprintf_chk(i8*, i64, i32, i64, i8*, %struct.__va_list_tag*) declare i32 @__vsprintf_chk(i8*, i32, i64, i8*, %struct.__va_list_tag*) + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/memccpy.ll =================================================================== --- llvm/test/Transforms/InstCombine/memccpy.ll +++ llvm/test/Transforms/InstCombine/memccpy.ll @@ -11,116 +11,116 @@ define i8* @memccpy_to_memcpy(i8* %dst) { ; CHECK-LABEL: @memccpy_to_memcpy( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[DST:%.*]] to i64* -; CHECK-NEXT: store i64 8245940763182785896, i64* [[TMP1]], align 1 +; CHECK-NEXT: store i64 8245940763182785896, i64* [[TMP1]], align 1, !tbaa ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 8 ; CHECK-NEXT: ret i8* [[TMP2]] ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 114, i64 12) ; 114 is 'r' + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 114, i64 12), !tbaa !2 ; 114 is 'r' ret i8* %call } define i8* @memccpy_to_memcpy2(i8* %dst) { ; CHECK-LABEL: @memccpy_to_memcpy2( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[DST:%.*]] to i64* -; CHECK-NEXT: store i64 8245940763182785896, i64* [[TMP1]], align 1 +; CHECK-NEXT: store i64 8245940763182785896, i64* [[TMP1]], align 1, !tbaa ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 8 ; CHECK-NEXT: ret i8* [[TMP2]] ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 114, i64 8); ; 114 is 'r' + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 114, i64 8), !tbaa !2 ; 114 is 'r' ret i8* %call } define void @memccpy_to_memcpy3(i8* %dst) { ; CHECK-LABEL: @memccpy_to_memcpy3( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(5) [[DST:%.*]], i8* nonnull align 1 dereferenceable(5) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 5, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(5) [[DST:%.*]], i8* nonnull align 1 dereferenceable(5) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 5, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret void ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 111, i64 10) ; 111 is 'o' + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 111, i64 10), !tbaa !2 ; 111 is 'o' ret void } define void @memccpy_to_memcpy4(i8* %dst) { ; CHECK-LABEL: @memccpy_to_memcpy4( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 11, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 11, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret void ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 0, i64 12) + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 0, i64 12), !tbaa !2 ret void } define i8* @memccpy_to_memcpy5(i8* %dst) { ; CHECK-LABEL: @memccpy_to_memcpy5( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(7) [[DST:%.*]], i8* nonnull align 1 dereferenceable(7) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 7, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(7) [[DST:%.*]], i8* nonnull align 1 dereferenceable(7) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 7, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* null ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 114, i64 7) + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 114, i64 7), !tbaa !2 ret i8* %call } define i8* @memccpy_to_memcpy6(i8* %dst) { ; CHECK-LABEL: @memccpy_to_memcpy6( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(6) [[DST:%.*]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(6) [[DST:%.*]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 6, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* null ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 114, i64 6); + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 114, i64 6), !tbaa !2 ret i8* %call } define i8* @memccpy_to_memcpy7(i8* %dst) { ; CHECK-LABEL: @memccpy_to_memcpy7( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(5) [[DST:%.*]], i8* nonnull align 1 dereferenceable(5) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 5, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(5) [[DST:%.*]], i8* nonnull align 1 dereferenceable(5) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 5, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* null ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 115, i64 5) ; 115 is 's' + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 115, i64 5), !tbaa !2 ; 115 is 's' ret i8* %call } define i8* @memccpy_to_memcpy8(i8* %dst) { ; CHECK-LABEL: @memccpy_to_memcpy8( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 11, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i64 11, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* null ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 115, i64 11) ; 115 is 's' + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @hello, i64 0, i64 0), i32 115, i64 11), !tbaa !2 ; 115 is 's' ret i8* %call } define i8* @memccpy_to_memcpy9(i8* %dst, i64 %n) { ; CHECK-LABEL: @memccpy_to_memcpy9( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(12) [[DST:%.*]], i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @StopCharAfterNulTerminator, i64 0, i64 0), i64 12, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(12) [[DST:%.*]], i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @StopCharAfterNulTerminator, i64 0, i64 0), i64 12, i1 false){{.*}}, !tbaa ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 12 ; CHECK-NEXT: ret i8* [[TMP1]] ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @StopCharAfterNulTerminator, i64 0, i64 0), i32 120, i64 15) ; 120 is 'x' + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @StopCharAfterNulTerminator, i64 0, i64 0), i32 120, i64 15), !tbaa !2 ; 120 is 'x' ret i8* %call } define i8* @memccpy_to_memcpy10(i8* %dst, i64 %n) { ; CHECK-LABEL: @memccpy_to_memcpy10( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i64 11, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i64 11, i1 false){{.*}}, !tbaa ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 11 ; CHECK-NEXT: ret i8* [[TMP1]] ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i32 255, i64 15) + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i32 255, i64 15), !tbaa !2 ret i8* %call } define i8* @memccpy_to_memcpy11(i8* %dst, i64 %n) { ; CHECK-LABEL: @memccpy_to_memcpy11( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i64 11, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i64 11, i1 false){{.*}}, !tbaa ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 11 ; CHECK-NEXT: ret i8* [[TMP1]] ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i32 -1, i64 15) + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i32 -1, i64 15), !tbaa !2 ret i8* %call } define i8* @memccpy_to_memcpy12(i8* %dst, i64 %n) { ; CHECK-LABEL: @memccpy_to_memcpy12( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i64 11, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(11) [[DST:%.*]], i8* nonnull align 1 dereferenceable(11) getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i64 11, i1 false){{.*}}, !tbaa ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 11 ; CHECK-NEXT: ret i8* [[TMP1]] ; - %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i32 1023, i64 15) + %call = call i8* @memccpy(i8* %dst, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @StringWithEOF, i64 0, i64 0), i32 1023, i64 15), !tbaa !2 ret i8* %call } @@ -212,3 +212,7 @@ %call = call i8* @memccpy(i8* %dst, i8* %dst, i32 %c, i64 %n) ret i8* %call } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/memcmp-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memcmp-1.ll +++ llvm/test/Transforms/InstCombine/memcmp-1.ll @@ -35,14 +35,14 @@ define i32 @test_simplify3(i8* %mem1, i8* %mem2) { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* %mem1, align 1 +; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* %mem1, align 1, !tbaa ; CHECK-NEXT: [[LHSV:%.*]] = zext i8 [[LHSC]] to i32 -; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* %mem2, align 1 +; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* %mem2, align 1, !tbaa ; CHECK-NEXT: [[RHSV:%.*]] = zext i8 [[RHSC]] to i32 ; CHECK-NEXT: [[CHARDIFF:%.*]] = sub nsw i32 [[LHSV]], [[RHSV]] ; CHECK-NEXT: ret i32 [[CHARDIFF]] ; - %ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 1) + %ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 1), !tbaa !2 ret i32 %ret } @@ -136,16 +136,20 @@ define i1 @test_simplify10(i8* %mem1, i8* %mem2, i32 %size) { ; NOBCMP-LABEL: @test_simplify10( -; NOBCMP-NEXT: [[CALL:%.*]] = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 %size) +; NOBCMP-NEXT: [[CALL:%.*]] = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 %size), !tbaa ; NOBCMP-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; NOBCMP-NEXT: ret i1 [[CMP]] ; ; BCMP-LABEL: @test_simplify10( -; BCMP-NEXT: [[CALL:%.*]] = call i32 @bcmp(i8* %mem1, i8* %mem2, i32 %size) +; BCMP-NEXT: [[CALL:%.*]] = call i32 @bcmp(i8* %mem1, i8* %mem2, i32 %size), !tbaa ; BCMP-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; BCMP-NEXT: ret i1 [[CMP]] ; - %call = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 %size) + %call = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 %size), !tbaa !2 %cmp = icmp eq i32 %call, 0 ret i1 %cmp } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/memcmp-constant-fold.ll =================================================================== --- llvm/test/Transforms/InstCombine/memcmp-constant-fold.ll +++ llvm/test/Transforms/InstCombine/memcmp-constant-fold.ll @@ -11,17 +11,17 @@ define i1 @memcmp_4bytes_unaligned_constant_i8(i8* align 4 %x) { ; LE-LABEL: @memcmp_4bytes_unaligned_constant_i8( ; LE-NEXT: [[TMP1:%.*]] = bitcast i8* [[X:%.*]] to i32* -; LE-NEXT: [[LHSV:%.*]] = load i32, i32* [[TMP1]], align 4 +; LE-NEXT: [[LHSV:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa ; LE-NEXT: [[TMP2:%.*]] = icmp eq i32 [[LHSV]], 16777216 ; LE-NEXT: ret i1 [[TMP2]] ; ; BE-LABEL: @memcmp_4bytes_unaligned_constant_i8( ; BE-NEXT: [[TMP1:%.*]] = bitcast i8* [[X:%.*]] to i32* -; BE-NEXT: [[LHSV:%.*]] = load i32, i32* [[TMP1]], align 4 +; BE-NEXT: [[LHSV:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa ; BE-NEXT: [[TMP2:%.*]] = icmp eq i32 [[LHSV]], 1 ; BE-NEXT: ret i1 [[TMP2]] ; - %call = tail call i32 @memcmp(i8* %x, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @charbuf, i64 0, i64 0), i64 4) + %call = tail call i32 @memcmp(i8* %x, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @charbuf, i64 0, i64 0), i64 4), !tbaa !2 %cmpeq0 = icmp eq i32 %call, 0 ret i1 %cmpeq0 } @@ -34,17 +34,17 @@ define i1 @memcmp_4bytes_unaligned_constant_i16(i8* align 4 %x) { ; LE-LABEL: @memcmp_4bytes_unaligned_constant_i16( ; LE-NEXT: [[TMP1:%.*]] = bitcast i8* [[X:%.*]] to i32* -; LE-NEXT: [[RHSV:%.*]] = load i32, i32* [[TMP1]], align 4 +; LE-NEXT: [[RHSV:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa ; LE-NEXT: [[TMP2:%.*]] = icmp eq i32 [[RHSV]], 131073 ; LE-NEXT: ret i1 [[TMP2]] ; ; BE-LABEL: @memcmp_4bytes_unaligned_constant_i16( ; BE-NEXT: [[TMP1:%.*]] = bitcast i8* [[X:%.*]] to i32* -; BE-NEXT: [[RHSV:%.*]] = load i32, i32* [[TMP1]], align 4 +; BE-NEXT: [[RHSV:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa ; BE-NEXT: [[TMP2:%.*]] = icmp eq i32 [[RHSV]], 65538 ; BE-NEXT: ret i1 [[TMP2]] ; - %call = tail call i32 @memcmp(i8* bitcast (i16* getelementptr inbounds ([4 x i16], [4 x i16]* @intbuf_unaligned, i64 0, i64 0) to i8*), i8* %x, i64 4) + %call = tail call i32 @memcmp(i8* bitcast (i16* getelementptr inbounds ([4 x i16], [4 x i16]* @intbuf_unaligned, i64 0, i64 0) to i8*), i8* %x, i64 4), !tbaa !2 %cmpeq0 = icmp eq i32 %call, 0 ret i1 %cmpeq0 } @@ -79,3 +79,6 @@ ret i1 %cmpeq0 } +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/memcpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memcpy-1.ll +++ llvm/test/Transforms/InstCombine/memcpy-1.ll @@ -11,10 +11,10 @@ define i8* @test_simplify1(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[MEM1:%.*]], i8* align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[MEM1:%.*]], i8* align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[MEM1]] ; - %ret = call i8* @memcpy(i8* %mem1, i8* %mem2, i32 %size) + %ret = call i8* @memcpy(i8* %mem1, i8* %mem2, i32 %size), !tbaa !2 ret i8* %ret } @@ -22,9 +22,13 @@ define i8* @test_simplify2(i8* %mem1, i8* %mem2, i32 %size) strictfp { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[MEM1:%.*]], i8* align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[MEM1:%.*]], i8* align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[MEM1]] ; - %ret = call i8* @memcpy(i8* %mem1, i8* %mem2, i32 %size) strictfp + %ret = call i8* @memcpy(i8* %mem1, i8* %mem2, i32 %size) strictfp, !tbaa !2 ret i8* %ret } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/memcpy_chk-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memcpy_chk-1.ll +++ llvm/test/Transforms/InstCombine/memcpy_chk-1.ll @@ -18,23 +18,23 @@ define i8* @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*) ; %dst = bitcast %struct.T1* @t1 to i8* %src = bitcast %struct.T2* @t2 to i8* - %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824) + %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824), !tbaa !2 ret i8* %ret } define i8* @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T3* @t3 to i8*), i64 1824, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T3* @t3 to i8*), i64 1824, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*) ; %dst = bitcast %struct.T1* @t1 to i8* %src = bitcast %struct.T3* @t3 to i8* - %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 2848) + %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 2848), !tbaa !2 ret i8* %ret } @@ -65,13 +65,17 @@ define i8* @test_simplify_return_indcall(i8* ()* %alloc) { ; CHECK-LABEL: @test_simplify_return_indcall( ; CHECK-NEXT: [[DST:%.*]] = call i8* [[ALLOC:%.*]]() -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(1824) [[DST]], i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(1824) [[DST]], i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[DST]] ; %src = bitcast %struct.T2* @t2 to i8* %dst = call i8* %alloc() - %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824) + %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824), !tbaa !2 ret i8* %ret } declare i8* @__memcpy_chk(i8*, i8*, i64, i64) + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/memmove-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memmove-1.ll +++ llvm/test/Transforms/InstCombine/memmove-1.ll @@ -10,8 +10,12 @@ define i8* @test_simplify1(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_simplify1( - %ret = call i8* @memmove(i8* %mem1, i8* %mem2, i32 %size) -; CHECK: call void @llvm.memmove + %ret = call i8* @memmove(i8* %mem1, i8* %mem2, i32 %size), !tbaa !2 +; CHECK: call void @llvm.memmove{{.*}}, !tbaa ret i8* %ret ; CHECK: ret i8* %mem1 } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/memmove_chk-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memmove_chk-1.ll +++ llvm/test/Transforms/InstCombine/memmove_chk-1.ll @@ -18,25 +18,25 @@ define i8* @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false) +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*) ; %dst = bitcast %struct.T1* @t1 to i8* %src = bitcast %struct.T2* @t2 to i8* - %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 1824) + %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 1824), !tbaa !2 ret i8* %ret } define i8* @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T3* @t3 to i8*), i64 1824, i1 false) +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T3* @t3 to i8*), i64 1824, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*) ; %dst = bitcast %struct.T1* @t1 to i8* %src = bitcast %struct.T3* @t3 to i8* - %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 2848) + %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 2848), !tbaa !2 ret i8* %ret } @@ -67,3 +67,7 @@ } declare i8* @__memmove_chk(i8*, i8*, i64, i64) + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/memset-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memset-1.ll +++ llvm/test/Transforms/InstCombine/memset-1.ll @@ -14,10 +14,10 @@ define i8* @test_simplify1(i8* %mem, i32 %val, i32 %size) { ; CHECK-LABEL: @test_simplify1( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[VAL:%.*]] to i8 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[MEM:%.*]], i8 [[TMP1]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[MEM:%.*]], i8 [[TMP1]], i32 [[SIZE:%.*]], i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[MEM]] ; - %ret = call i8* @memset(i8* %mem, i32 %val, i32 %size) + %ret = call i8* @memset(i8* %mem, i32 %val, i32 %size), !tbaa !2 ret i8* %ret } @@ -49,11 +49,11 @@ define i8* @notmalloc_memset(i32 %size, i8*(i32)* %notmalloc) { ; CHECK-LABEL: @notmalloc_memset( ; CHECK-NEXT: [[CALL1:%.*]] = call i8* [[NOTMALLOC:%.*]](i32 [[SIZE:%.*]]) #0 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[CALL1]], i8 0, i32 [[SIZE]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[CALL1]], i8 0, i32 [[SIZE]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[CALL1]] ; %call1 = call i8* %notmalloc(i32 %size) #1 - %call2 = call i8* @memset(i8* %call1, i32 0, i32 %size) #1 + %call2 = call i8* @memset(i8* %call1, i32 0, i32 %size) #1, !tbaa !2 ret i8* %call2 } @@ -68,7 +68,7 @@ ; CHECK-NEXT: br i1 [[CMP]], label [[CLEANUP:%.*]], label [[IF_END:%.*]] ; CHECK: if.end: ; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[CALL]] to float* -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[CALL]], i8 0, i32 [[SIZE]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[CALL]], i8 0, i32 [[SIZE]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: br label [[CLEANUP]] ; CHECK: cleanup: ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi float* [ [[BC]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ] @@ -80,7 +80,7 @@ br i1 %cmp, label %cleanup, label %if.end if.end: %bc = bitcast i8* %call to float* - %call2 = tail call i8* @memset(i8* nonnull %call, i32 0, i32 %size) #1 + %call2 = tail call i8* @memset(i8* nonnull %call, i32 0, i32 %size) #1, !tbaa !2 br label %cleanup cleanup: %retval.0 = phi float* [ %bc, %if.end ], [ null, %entry ] @@ -93,23 +93,23 @@ ; CHECK-LABEL: @buffer_is_modified_then_memset( ; CHECK-NEXT: [[PTR:%.*]] = tail call i8* @malloc(i32 [[SIZE:%.*]]) #0 ; CHECK-NEXT: store i8 1, i8* [[PTR]], align 1 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[PTR]], i8 0, i32 [[SIZE]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[PTR]], i8 0, i32 [[SIZE]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; %ptr = tail call i8* @malloc(i32 %size) #1 store i8 1, i8* %ptr ;; fdata[0] = 1; - %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1 + %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1, !tbaa !2 ret i8* %memset } define i8* @memset_size_select(i1 %b, i8* %ptr) { ; CHECK-LABEL: @memset_size_select( ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[B:%.*]], i32 10, i32 50 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(10) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(10) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; %size = select i1 %b, i32 10, i32 50 - %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1 + %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1, !tbaa !2 ret i8* %memset } @@ -117,53 +117,53 @@ define i8* @memset_size_select2(i1 %b, i8* %ptr) { ; CHECK-LABEL: @memset_size_select2( ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[B:%.*]], i32 10, i32 50 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(80) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(80) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; %size = select i1 %b, i32 10, i32 50 - %memset = tail call i8* @memset(i8* nonnull dereferenceable(80) %ptr, i32 0, i32 %size) #1 + %memset = tail call i8* @memset(i8* nonnull dereferenceable(80) %ptr, i32 0, i32 %size) #1, !tbaa !2 ret i8* %memset } define i8* @memset_size_select3(i1 %b, i8* %ptr) { ; CHECK-LABEL: @memset_size_select3( ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[B:%.*]], i32 10, i32 50 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; %size = select i1 %b, i32 10, i32 50 - %memset = tail call i8* @memset(i8* dereferenceable_or_null(40) %ptr, i32 0, i32 %size) + %memset = tail call i8* @memset(i8* dereferenceable_or_null(40) %ptr, i32 0, i32 %size), !tbaa !2 ret i8* %memset } define i8* @memset_size_select4(i1 %b, i8* %ptr) { ; CHECK-LABEL: @memset_size_select4( ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[B:%.*]], i32 10, i32 50 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; %size = select i1 %b, i32 10, i32 50 - %memset = tail call i8* @memset(i8* nonnull dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1 + %memset = tail call i8* @memset(i8* nonnull dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1, !tbaa !2 ret i8* %memset } define i8* @memset_size_ashr(i1 %b, i8* %ptr, i32 %v) { ; CHECK-LABEL: @memset_size_ashr( ; CHECK-NEXT: [[SIZE:%.*]] = ashr i32 -2, [[V:%.*]] -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; %size = ashr i32 -2, %v - %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1 + %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1, !tbaa !2 ret i8* %memset } define i8* @memset_attrs1(i1 %b, i8* %ptr, i32 %size) { ; CHECK-LABEL: @memset_attrs1( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 dereferenceable_or_null(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 dereferenceable_or_null(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; - %memset = tail call i8* @memset(i8* dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1 + %memset = tail call i8* @memset(i8* dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1, !tbaa !2 ret i8* %memset } @@ -171,30 +171,30 @@ ; do not change dereferenceable attribute define i8* @memset_attrs2(i1 %b, i8* %ptr, i32 %size) { ; CHECK-LABEL: @memset_attrs2( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; - %memset = tail call i8* @memset(i8* nonnull dereferenceable(40) %ptr, i32 0, i32 %size) #1 + %memset = tail call i8* @memset(i8* nonnull dereferenceable(40) %ptr, i32 0, i32 %size) #1, !tbaa !2 ret i8* %memset } ; size is unknown, just copy attrs, no changes in attrs define i8* @memset_attrs3(i1 %b, i8* %ptr, i32 %size) { ; CHECK-LABEL: @memset_attrs3( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable_or_null(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable_or_null(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; - %memset = tail call i8* @memset(i8* nonnull dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1 + %memset = tail call i8* @memset(i8* nonnull dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1, !tbaa !2 ret i8* %memset } ; be sure to drop nonnull since size is unknown and can be 0 define i8* @memset_attrs4(i1 %b, i8* %ptr, i32 %size) { ; CHECK-LABEL: @memset_attrs4( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #0 +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #0{{.*}}, !tbaa ; CHECK-NEXT: ret i8* [[PTR]] ; - %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1 + %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1, !tbaa !2, !tbaa !2 ret i8* %memset } @@ -203,3 +203,6 @@ attributes #1 = { nounwind } attributes #2 = { nounwind readnone } +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/memset_chk-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memset_chk-1.ll +++ llvm/test/Transforms/InstCombine/memset_chk-1.ll @@ -14,34 +14,34 @@ define i8* @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*) ; %dst = bitcast %struct.T* @t to i8* - %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824) + %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824), !tbaa !2 ret i8* %ret } define i8* @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*) ; %dst = bitcast %struct.T* @t to i8* - %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 3648) + %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 3648), !tbaa !2 ret i8* %ret } define i8* @test_simplify3() { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 4 dereferenceable(1824) bitcast (%struct.T* @t to i8*), i8 0, i64 1824, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*) ; %dst = bitcast %struct.T* @t to i8* - %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 -1) + %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 -1), !tbaa !2 ret i8* %ret } @@ -77,14 +77,14 @@ ; CHECK-NEXT: [[ADD180:%.*]] = add i64 [[CALL49]], 1 ; CHECK-NEXT: [[YO107:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[B:%.*]], i1 false, i1 false, i1 false) ; CHECK-NEXT: [[CALL50:%.*]] = call i8* @__memmove_chk(i8* [[B]], i8* [[A]], i64 [[ADD180]], i64 [[YO107]]) -; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(i8* nonnull dereferenceable(1) [[B]]) +; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(i8* nonnull dereferenceable(1) [[B]]), !tbaa ; CHECK-NEXT: [[STRCHR1:%.*]] = getelementptr i8, i8* [[B]], i64 [[STRLEN]] ; CHECK-NEXT: [[D:%.*]] = load i8*, i8** [[C:%.*]], align 8 ; CHECK-NEXT: [[SUB182:%.*]] = ptrtoint i8* [[D]] to i64 ; CHECK-NEXT: [[SUB183:%.*]] = ptrtoint i8* [[B]] to i64 ; CHECK-NEXT: [[SUB184:%.*]] = sub i64 [[SUB182]], [[SUB183]] ; CHECK-NEXT: [[ADD52_I_I:%.*]] = add nsw i64 [[SUB184]], 1 -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[STRCHR1]], i8 0, i64 [[ADD52_I_I]], i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[STRCHR1]], i8 0, i64 [[ADD52_I_I]], i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i32 4 ; entry: @@ -92,13 +92,13 @@ %add180 = add i64 %call49, 1 %yo107 = call i64 @llvm.objectsize.i64.p0i8(i8* %b, i1 false, i1 false, i1 false) %call50 = call i8* @__memmove_chk(i8* %b, i8* %a, i64 %add180, i64 %yo107) - %call51i = call i8* @strrchr(i8* %b, i32 0) + %call51i = call i8* @strrchr(i8* %b, i32 0), !tbaa !2 %d = load i8*, i8** %c, align 8 %sub182 = ptrtoint i8* %d to i64 %sub183 = ptrtoint i8* %b to i64 %sub184 = sub i64 %sub182, %sub183 %add52.i.i = add nsw i64 %sub184, 1 - %call185 = call i8* @__memset_chk(i8* %call51i, i32 0, i64 %add52.i.i, i64 -1) + %call185 = call i8* @__memset_chk(i8* %call51i, i32 0, i64 %add52.i.i, i64 -1), !tbaa !2 ret i32 4 } @@ -147,3 +147,6 @@ attributes #1 = { nounwind } attributes #2 = { nounwind readnone } +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/snprintf.ll =================================================================== --- llvm/test/Transforms/InstCombine/snprintf.ll +++ llvm/test/Transforms/InstCombine/snprintf.ll @@ -75,10 +75,10 @@ define void @test_correct_copy(i8* %buf) #0 { ; CHECK-LABEL: @test_correct_copy( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[BUF:%.*]] to i32* -; CHECK-NEXT: store i32 7500915, i32* [[TMP1]], align 1 +; CHECK-NEXT: store i32 7500915, i32* [[TMP1]], align 1, !tbaa ; CHECK-NEXT: ret void ; - %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2 + %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2, !tbaa !2 ret void } @@ -101,12 +101,12 @@ define i32 @test_char_ok_size(i8* %buf) #0 { ; CHECK-LABEL: @test_char_ok_size( -; CHECK-NEXT: store i8 65, i8* [[BUF:%.*]], align 1 +; CHECK-NEXT: store i8 65, i8* [[BUF:%.*]], align 1, !tbaa ; CHECK-NEXT: [[NUL:%.*]] = getelementptr i8, i8* [[BUF]], i64 1 -; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1 +; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1, !tbaa ; CHECK-NEXT: ret i32 1 ; - %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65) #2 + %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65) #2, !tbaa !2 ret i32 %call } @@ -130,9 +130,13 @@ define i32 @test_str_ok_size(i8* %buf) #0 { ; CHECK-LABEL: @test_str_ok_size( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[BUF:%.*]] to i32* -; CHECK-NEXT: store i32 7500915, i32* [[TMP1]], align 1 +; CHECK-NEXT: store i32 7500915, i32* [[TMP1]], align 1, !tbaa ; CHECK-NEXT: ret i32 3 ; - %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2 + %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2, !tbaa !2 ret i32 %call } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/sprintf-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/sprintf-1.ll +++ llvm/test/Transforms/InstCombine/sprintf-1.ll @@ -22,31 +22,31 @@ define void @test_simplify1(i8* %dst) { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(13) [[DST:%.*]], i8* nonnull align 1 dereferenceable(13) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0), i32 13, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(13) [[DST:%.*]], i8* nonnull align 1 dereferenceable(13) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0), i32 13, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret void ; %fmt = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0 - call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt) + call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt), !tbaa !2 ret void } define void @test_simplify2(i8* %dst) { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: store i8 0, i8* [[DST:%.*]], align 1 +; CHECK-NEXT: store i8 0, i8* [[DST:%.*]], align 1, !tbaa ; CHECK-NEXT: ret void ; %fmt = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt) + call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt), !tbaa !2 ret void } define void @test_simplify3(i8* %dst) { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: store i8 0, i8* [[DST:%.*]], align 1 +; CHECK-NEXT: store i8 0, i8* [[DST:%.*]], align 1, !tbaa ; CHECK-NEXT: ret void ; %fmt = getelementptr [7 x i8], [7 x i8]* @null_hello, i32 0, i32 0 - call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt) + call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt), !tbaa !2 ret void } @@ -54,13 +54,13 @@ define void @test_simplify4(i8* %dst) { ; CHECK-LABEL: @test_simplify4( -; CHECK-NEXT: store i8 104, i8* [[DST:%.*]], align 1 +; CHECK-NEXT: store i8 104, i8* [[DST:%.*]], align 1, !tbaa ; CHECK-NEXT: [[NUL:%.*]] = getelementptr i8, i8* [[DST]], i32 1 -; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1 +; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1, !tbaa ; CHECK-NEXT: ret void ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_c, i32 0, i32 0 - call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8 104) + call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8 104), !tbaa !2 ret void } @@ -68,11 +68,11 @@ define void @test_simplify5(i8* %dst, i8* %str) { ; CHECK-LABEL: @test_simplify5( -; CHECK-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) [[STR:%.*]]) +; CHECK-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) [[STR:%.*]]), !tbaa ; CHECK-NEXT: ret void ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_s, i32 0, i32 0 - call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str) + call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str), !tbaa !2 ret void } @@ -80,15 +80,15 @@ define void @test_simplify6(i8* %dst) { ; CHECK-IPRINTF-LABEL: @test_simplify6( -; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @siprintf(i8* [[DST:%.*]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187) +; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @siprintf(i8* [[DST:%.*]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187), !tbaa ; CHECK-IPRINTF-NEXT: ret void ; ; WIN-LABEL: @test_simplify6( -; WIN-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187) +; WIN-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187), !tbaa ; WIN-NEXT: ret void ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_d, i32 0, i32 0 - call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i32 187) + call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i32 187), !tbaa !2 ret void } @@ -96,32 +96,32 @@ define i32 @test_simplify7(i8* %dst, i8* %str) { ; CHECK-IPRINTF-LABEL: @test_simplify7( -; CHECK-IPRINTF-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* [[DST:%.*]], i8* [[STR:%.*]]) +; CHECK-IPRINTF-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* [[DST:%.*]], i8* [[STR:%.*]]), !tbaa ; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = ptrtoint i8* [[STPCPY]] to i32 ; CHECK-IPRINTF-NEXT: [[TMP2:%.*]] = ptrtoint i8* [[DST]] to i32 ; CHECK-IPRINTF-NEXT: [[TMP3:%.*]] = sub i32 [[TMP1]], [[TMP2]] ; CHECK-IPRINTF-NEXT: ret i32 [[TMP3]] ; ; WIN-LABEL: @test_simplify7( -; WIN-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]]) +; WIN-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]]), !tbaa ; WIN-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1 -; WIN-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false) +; WIN-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false){{.*}}, !tbaa ; WIN-NEXT: ret i32 [[STRLEN]] ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_s, i32 0, i32 0 - %r = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str) + %r = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str), !tbaa !2 ret i32 %r } ; Check sprintf(dst, "%s", str) -> llvm.memcpy(dest, str, strlen(str) + 1, 1). define i32 @test_simplify8(i8* %dst) { ; CHECK-LABEL: @test_simplify8( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(13) [[DST:%.*]], i8* nonnull align 1 dereferenceable(13) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0), i32 13, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(13) [[DST:%.*]], i8* nonnull align 1 dereferenceable(13) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0), i32 13, i1 false){{.*}}, !tbaa ; CHECK-NEXT: ret i32 12 ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_s, i32 0, i32 0 %str = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0 - %r = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str) + %r = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str), !tbaa !2 ret i32 %r } @@ -129,20 +129,20 @@ define i32 @test_simplify9(i8* %dst, i8* %str) { ; CHECK-IPRINTF-LABEL: @test_simplify9( -; CHECK-IPRINTF-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* [[DST:%.*]], i8* [[STR:%.*]]) +; CHECK-IPRINTF-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* [[DST:%.*]], i8* [[STR:%.*]]), !tbaa ; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = ptrtoint i8* [[STPCPY]] to i32 ; CHECK-IPRINTF-NEXT: [[TMP2:%.*]] = ptrtoint i8* [[DST]] to i32 ; CHECK-IPRINTF-NEXT: [[TMP3:%.*]] = sub i32 [[TMP1]], [[TMP2]] ; CHECK-IPRINTF-NEXT: ret i32 [[TMP3]] ; ; WIN-LABEL: @test_simplify9( -; WIN-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]]) +; WIN-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]]), !tbaa ; WIN-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1 -; WIN-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false) +; WIN-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false){{.*}}, !tbaa ; WIN-NEXT: ret i32 [[STRLEN]] ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_s, i32 0, i32 0 - %r = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str) + %r = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str), !tbaa !2 ret i32 %r } @@ -152,7 +152,7 @@ ; CHECK-NEXT: ret void ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_f, i32 0, i32 0 - call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, double 1.87) + call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, double 1.87), !tbaa !2 ret void } @@ -161,13 +161,13 @@ ; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]]) ; CHECK-NEXT: ret void ; - call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, double %d) + call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, double %d), !tbaa !2 ret void } define i32 @test_no_simplify3(i8* %dst, i8* %str) minsize { ; CHECK-IPRINTF-LABEL: @test_no_simplify3( -; CHECK-IPRINTF-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* [[DST:%.*]], i8* [[STR:%.*]]) +; CHECK-IPRINTF-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* [[DST:%.*]], i8* [[STR:%.*]]), !tbaa ; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = ptrtoint i8* [[STPCPY]] to i32 ; CHECK-IPRINTF-NEXT: [[TMP2:%.*]] = ptrtoint i8* [[DST]] to i32 ; CHECK-IPRINTF-NEXT: [[TMP3:%.*]] = sub i32 [[TMP1]], [[TMP2]] @@ -178,6 +178,10 @@ ; WIN-NEXT: ret i32 [[R]] ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_s, i32 0, i32 0 - %r = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str) + %r = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str), !tbaa !2 ret i32 %r } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strcat-2.ll =================================================================== --- llvm/test/Transforms/InstCombine/strcat-2.ll +++ llvm/test/Transforms/InstCombine/strcat-2.ll @@ -12,12 +12,14 @@ define void @test_simplify1() { ; CHECK-LABEL: @test_simplify1( +; CHECK: call i32 @strlen({{.*}}), !tbaa +; CHECK: call void @llvm.memcpy{{.*}}({{.*}}), !tbaa ; CHECK-NOT: call i8* @strcat ; CHECK: ret void %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strcat(i8* %dst, i8* %src) + call i8* @strcat(i8* %dst, i8* %src), !tbaa !2 ret void } @@ -30,3 +32,7 @@ call i8* @strcat(i8* %dst, i8* %src) ret void } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strchr-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strchr-1.ll +++ llvm/test/Transforms/InstCombine/strchr-1.ll @@ -49,13 +49,13 @@ define void @test_simplify4(i32 %chr) { ; CHECK-LABEL: @test_simplify4( -; CHECK-NEXT: [[MEMCHR:%.*]] = call i8* @memchr(i8* nonnull dereferenceable(14) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]], i32 14) +; CHECK-NEXT: [[MEMCHR:%.*]] = call i8* @memchr(i8* nonnull dereferenceable(14) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]], i32 14), !tbaa ; CHECK-NEXT: store i8* [[MEMCHR]], i8** @chp, align 4 ; CHECK-NEXT: ret void ; %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @strchr(i8* %src, i32 %chr) + %dst = call i8* @strchr(i8* %src, i32 %chr), !tbaa !2 store i8* %dst, i8** @chp ret void } @@ -75,13 +75,13 @@ ; Check transformation strchr(p, 0) -> p + strlen(p) define void @test_simplify6(i8* %str) { ; CHECK-LABEL: @test_simplify6( -; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]]) +; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]]), !tbaa ; CHECK-NEXT: [[STRCHR:%.*]] = getelementptr i8, i8* [[STR]], i32 [[STRLEN]] ; CHECK-NEXT: store i8* [[STRCHR]], i8** @chp, align 4 ; CHECK-NEXT: ret void ; - %dst = call i8* @strchr(i8* %str, i32 0) + %dst = call i8* @strchr(i8* %str, i32 0), !tbaa !2 store i8* %dst, i8** @chp ret void } @@ -123,3 +123,7 @@ %ret = call i8* @strchr(i8* %str, i32 %c) ret i8* %ret } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strcmp-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strcmp-1.ll +++ llvm/test/Transforms/InstCombine/strcmp-1.ll @@ -15,24 +15,24 @@ ; strcmp("", x) -> -*x define i32 @test1(i8* %str2) { ; CHECK-LABEL: @test1( -; CHECK: %strcmpload = load i8, i8* %str +; CHECK: %strcmpload = load i8, i8* %str {{.*}}, !tbaa ; CHECK: %1 = zext i8 %strcmpload to i32 ; CHECK: %2 = sub nsw i32 0, %1 ; CHECK: ret i32 %2 ; NOBCMP-LABEL: @test1( -; NOBCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR2:%.*]], align 1 +; NOBCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR2:%.*]], align 1, !tbaa ; NOBCMP-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32 ; NOBCMP-NEXT: [[TMP2:%.*]] = sub nsw i32 0, [[TMP1]] ; NOBCMP-NEXT: ret i32 [[TMP2]] ; ; BCMP-LABEL: @test1( -; BCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR2:%.*]], align 1 +; BCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR2:%.*]], align 1, !tbaa ; BCMP-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32 ; BCMP-NEXT: [[TMP2:%.*]] = sub nsw i32 0, [[TMP1]] ; BCMP-NEXT: ret i32 [[TMP2]] ; %str1 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %temp1 = call i32 @strcmp(i8* %str1, i8* %str2) + %temp1 = call i32 @strcmp(i8* %str1, i8* %str2), !tbaa !2 ret i32 %temp1 } @@ -40,21 +40,21 @@ ; strcmp(x, "") -> *x define i32 @test2(i8* %str1) { ; CHECK-LABEL: @test2( -; CHECK: %strcmpload = load i8, i8* %str +; CHECK: %strcmpload = load i8, i8* %str {{.*}}, !tbaa ; CHECK: %1 = zext i8 %strcmpload to i32 ; CHECK: ret i32 %1 ; NOBCMP-LABEL: @test2( -; NOBCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR1:%.*]], align 1 +; NOBCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR1:%.*]], align 1, !tbaa ; NOBCMP-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32 ; NOBCMP-NEXT: ret i32 [[TMP1]] ; ; BCMP-LABEL: @test2( -; BCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR1:%.*]], align 1 +; BCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR1:%.*]], align 1, !tbaa ; BCMP-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32 ; BCMP-NEXT: ret i32 [[TMP1]] ; %str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %temp1 = call i32 @strcmp(i8* %str1, i8* %str2) + %temp1 = call i32 @strcmp(i8* %str1, i8* %str2), !tbaa !2 ret i32 %temp1 } @@ -93,23 +93,23 @@ ; (This transform is rather difficult to trigger in a useful manner) define i32 @test5(i1 %b) { ; CHECK-LABEL: @test5( -; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5) +; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5), !tbaa ; CHECK: ret i32 %memcmp ; NOBCMP-LABEL: @test5( ; NOBCMP-NEXT: [[STR2:%.*]] = select i1 [[B:%.*]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @bell, i32 0, i32 0) -; NOBCMP-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* nonnull dereferenceable(5) [[STR2]], i32 5) +; NOBCMP-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* nonnull dereferenceable(5) [[STR2]], i32 5), !tbaa ; NOBCMP-NEXT: ret i32 [[MEMCMP]] ; ; BCMP-LABEL: @test5( ; BCMP-NEXT: [[STR2:%.*]] = select i1 [[B:%.*]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @bell, i32 0, i32 0) -; BCMP-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* nonnull dereferenceable(5) [[STR2]], i32 5) +; BCMP-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* nonnull dereferenceable(5) [[STR2]], i32 5), !tbaa ; BCMP-NEXT: ret i32 [[MEMCMP]] ; %str1 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0 %temp1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0 %temp2 = getelementptr inbounds [5 x i8], [5 x i8]* @bell, i32 0, i32 0 %str2 = select i1 %b, i8* %temp1, i8* %temp2 - %temp3 = call i32 @strcmp(i8* %str1, i8* %str2) + %temp3 = call i32 @strcmp(i8* %str1, i8* %str2), !tbaa !2 ret i32 %temp3 } @@ -131,13 +131,13 @@ define i1 @test7(i1 %b) { ; NOBCMP-LABEL: @test7( ; NOBCMP-NEXT: [[STR2:%.*]] = select i1 [[B:%.*]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @bell, i32 0, i32 0) -; NOBCMP-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* nonnull dereferenceable(5) [[STR2]], i32 5) +; NOBCMP-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* nonnull dereferenceable(5) [[STR2]], i32 5), !tbaa ; NOBCMP-NEXT: [[RES:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; NOBCMP-NEXT: ret i1 [[RES]] ; ; BCMP-LABEL: @test7( ; BCMP-NEXT: [[STR2:%.*]] = select i1 [[B:%.*]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @bell, i32 0, i32 0) -; BCMP-NEXT: [[BCMP:%.*]] = call i32 @bcmp(i8* nonnull dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* nonnull dereferenceable(5) [[STR2]], i32 5) +; BCMP-NEXT: [[BCMP:%.*]] = call i32 @bcmp(i8* nonnull dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* nonnull dereferenceable(5) [[STR2]], i32 5), !tbaa ; BCMP-NEXT: [[RES:%.*]] = icmp eq i32 [[BCMP]], 0 ; BCMP-NEXT: ret i1 [[RES]] ; @@ -147,7 +147,11 @@ %temp1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0 %temp2 = getelementptr inbounds [5 x i8], [5 x i8]* @bell, i32 0, i32 0 %str2 = select i1 %b, i8* %temp1, i8* %temp2 - %temp3 = call i32 @strcmp(i8* %str1, i8* %str2) + %temp3 = call i32 @strcmp(i8* %str1, i8* %str2), !tbaa !2 %res = icmp eq i32 %temp3, 0 ret i1 %res } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strcmp-memcmp.ll =================================================================== --- llvm/test/Transforms/InstCombine/strcmp-memcmp.ll +++ llvm/test/Transforms/InstCombine/strcmp-memcmp.ll @@ -11,13 +11,13 @@ define i32 @strcmp_memcmp([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strcmp_memcmp( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -28,13 +28,13 @@ define i32 @strcmp_memcmp2([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strcmp_memcmp2( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string) + %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -43,13 +43,13 @@ define i32 @strcmp_memcmp3([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strcmp_memcmp3( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)), !tbaa !2 %cmp = icmp ne i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -58,13 +58,13 @@ define i32 @strcmp_memcmp4([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strcmp_memcmp4( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string) + %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string), !tbaa !2 %cmp = icmp ne i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -73,13 +73,13 @@ define i32 @strcmp_memcmp5([5 x i8]* dereferenceable (5) %buf) { ; CHECK-LABEL: @strcmp_memcmp5( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [5 x i8], [5 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [5 x i8], [5 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull align 1 %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(i8* nonnull align 1 %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -88,13 +88,13 @@ define i32 @strcmp_memcmp6([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strcmp_memcmp6( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)), !tbaa !2 %cmp = icmp sgt i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -103,12 +103,12 @@ define i32 @strcmp_memcmp7([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strcmp_memcmp7( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31 ; CHECK-NEXT: ret i32 [[MEMCMP_LOBIT]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string) + %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string), !tbaa !2 %cmp = icmp slt i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -117,13 +117,13 @@ define i32 @strcmp_memcmp8([4 x i8]* dereferenceable (4) %buf) { ; CHECK-LABEL: @strcmp_memcmp8( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -132,13 +132,13 @@ define i32 @strcmp_memcmp9([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strcmp_memcmp9( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0)) + %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0)), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -148,13 +148,13 @@ define i32 @strncmp_memcmp([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(2) [[STRING]], i8* nonnull dereferenceable(2) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(2) [[STRING]], i8* nonnull dereferenceable(2) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2) + %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -165,13 +165,13 @@ define i32 @strncmp_memcmp2([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp2( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 11) + %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 11), !tbaa !2 %cmp = icmp ne i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -180,13 +180,13 @@ define i32 @strncmp_memcmp3([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp3( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 11) + %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 11), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -195,13 +195,13 @@ define i32 @strncmp_memcmp4([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp4( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 5) + %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 5), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -210,13 +210,13 @@ define i32 @strncmp_memcmp5([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp5( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -226,13 +226,13 @@ define i32 @strncmp_memcmp6([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp6( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5), !tbaa !2 %cmp = icmp ne i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -241,13 +241,13 @@ define i32 @strncmp_memcmp7([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp7( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) + %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -256,13 +256,13 @@ define i32 @strncmp_memcmp8([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp8( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(3) [[STRING]], i8* nonnull dereferenceable(3) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(3) [[STRING]], i8* nonnull dereferenceable(3) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3) + %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -271,13 +271,13 @@ define i32 @strncmp_memcmp9([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp9( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5), !tbaa !2 %cmp = icmp sgt i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -286,12 +286,12 @@ define i32 @strncmp_memcmp10([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp10( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31 ; CHECK-NEXT: ret i32 [[MEMCMP_LOBIT]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5), !tbaa !2 %cmp = icmp slt i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -300,13 +300,13 @@ define i32 @strncmp_memcmp11([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp11( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 12) + %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 12), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -315,13 +315,13 @@ define i32 @strncmp_memcmp12([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp12( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(4) [[STRING]], i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 12) + %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 12), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -330,13 +330,13 @@ define i32 @strncmp_memcmp13([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp13( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(2) [[STRING]], i8* nonnull dereferenceable(2) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(2) [[STRING]], i8* nonnull dereferenceable(2) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2) + %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -345,13 +345,13 @@ define i32 @strncmp_memcmp14([12 x i8]* dereferenceable (12) %buf) { ; CHECK-LABEL: @strncmp_memcmp14( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(4) [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4), !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 12) + %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 12), !tbaa !2 %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -367,7 +367,7 @@ ; CHECK-NEXT: ret i32 [[CONV]] ; %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)), !tbaa !2 %cmp = icmp sgt i32 %call, 3 %conv = zext i1 %cmp to i32 ret i32 %conv @@ -558,3 +558,7 @@ } declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strcpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strcpy-1.ll +++ llvm/test/Transforms/InstCombine/strcpy-1.ll @@ -15,14 +15,14 @@ define void @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false), !tbaa ; CHECK-NEXT: ret void ; %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strcpy(i8* %dst, i8* %src) + call i8* @strcpy(i8* %dst, i8* %src), !tbaa !2 ret void } @@ -40,13 +40,13 @@ define void @test_simplify3(i8* %dst) { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(80) [[DST:%.*]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(80) [[DST:%.*]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false), !tbaa ; CHECK-NEXT: ret void ; %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strcpy(i8* dereferenceable(80) %dst, i8* %src) + call i8* @strcpy(i8* dereferenceable(80) %dst, i8* %src), !tbaa !2 ret void } @@ -62,3 +62,7 @@ %ret = call i8* @strcpy(i8* %dst, i8* %src) ret i8* %ret } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strcpy_chk-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strcpy_chk-1.ll +++ llvm/test/Transforms/InstCombine/strcpy_chk-1.ll @@ -14,37 +14,37 @@ define i8* @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false), !tbaa ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60) + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60), !tbaa !2 ret i8* %ret } define i8* @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false), !tbaa ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 12) + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 12), !tbaa !2 ret i8* %ret } define i8* @test_simplify3() { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false), !tbaa ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1) + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1), !tbaa !2 ret i8* %ret } @@ -52,13 +52,13 @@ define i8* @test_simplify4() { ; CHECK-LABEL: @test_simplify4( -; CHECK-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0)) +; CHECK-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0)), !tbaa ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1) + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1), !tbaa !2 ret i8* %ret } @@ -67,14 +67,14 @@ define i8* @test_simplify5() { ; CHECK-LABEL: @test_simplify5( ; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false) -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i32 [[LEN]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i32 [[LEN]]), !tbaa ; CHECK-NEXT: ret i8* [[TMP1]] ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false) - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len) + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len), !tbaa !2 ret i8* %ret } @@ -83,13 +83,13 @@ define i8* @test_simplify6() { ; CHECK-LABEL: @test_simplify6( ; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false) -; CHECK-NEXT: [[RET:%.*]] = call i8* @__strcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i32 [[LEN]]) +; CHECK-NEXT: [[RET:%.*]] = call i8* @__strcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i32 [[LEN]]), !tbaa ; CHECK-NEXT: ret i8* [[RET]] ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false) - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %dst, i32 %len) + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %dst, i32 %len), !tbaa !2 ret i8* %ret } @@ -109,3 +109,7 @@ declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strcspn-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strcspn-1.ll +++ llvm/test/Transforms/InstCombine/strcspn-1.ll @@ -20,7 +20,7 @@ ; %pat = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %ret = call i64 @strcspn(i8* %str, i8* %pat) + %ret = call i64 @strcspn(i8* %str, i8* %pat), !tbaa !2 ret i64 %ret } @@ -60,3 +60,7 @@ %ret = call i64 @strcspn(i8* %str, i8* %pat) ret i64 %ret } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strlen-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strlen-1.ll +++ llvm/test/Transforms/InstCombine/strlen-1.ll @@ -66,11 +66,11 @@ define i1 @test_simplify6(i8* %str_p) { ; CHECK-LABEL: @test_simplify6( -; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* [[STR_P:%.*]], align 1 +; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* [[STR_P:%.*]], align 1, !tbaa ; CHECK-NEXT: [[EQ_NULL:%.*]] = icmp eq i8 [[STRLENFIRST]], 0 ; CHECK-NEXT: ret i1 [[EQ_NULL]] ; - %str_l = call i32 @strlen(i8* %str_p) + %str_l = call i32 @strlen(i8* %str_p), !tbaa !2 %eq_null = icmp eq i32 %str_l, 0 ret i1 %eq_null } @@ -89,11 +89,11 @@ define i1 @test_simplify8(i8* %str_p) { ; CHECK-LABEL: @test_simplify8( -; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* [[STR_P:%.*]], align 1 +; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* [[STR_P:%.*]], align 1, !tbaa ; CHECK-NEXT: [[NE_NULL:%.*]] = icmp ne i8 [[STRLENFIRST]], 0 ; CHECK-NEXT: ret i1 [[NE_NULL]] ; - %str_l = call i32 @strlen(i8* %str_p) + %str_l = call i32 @strlen(i8* %str_p), !tbaa !2 %ne_null = icmp ne i32 %str_l, 0 ret i1 %ne_null } @@ -234,12 +234,12 @@ define i1 @strlen0_after_write_to_second_byte_global() { ; CHECK-LABEL: @strlen0_after_write_to_second_byte_global( ; CHECK-NEXT: store i8 49, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 1), align 16 -; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), align 1 +; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), align 1, !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[STRLENFIRST]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; store i8 49, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 1), align 16 - %len = tail call i32 @strlen(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0)) + %len = tail call i32 @strlen(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0)), !tbaa !2 %cmp = icmp eq i32 %len, 0 ret i1 %cmp } @@ -259,15 +259,19 @@ ; CHECK-LABEL: @strlen0_after_write_to_second_byte( ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i32 1 ; CHECK-NEXT: store i8 49, i8* [[GEP]], align 1 -; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* [[PTR]], align 1 +; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* [[PTR]], align 1, !tbaa ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[STRLENFIRST]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %gep = getelementptr i8, i8* %ptr, i64 1 store i8 49, i8* %gep - %len = tail call i32 @strlen(i8* nonnull dereferenceable(1) %ptr) + %len = tail call i32 @strlen(i8* nonnull dereferenceable(1) %ptr), !tbaa !2 %cmp = icmp eq i32 %len, 0 ret i1 %cmp } attributes #0 = { null_pointer_is_valid } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strncat-2.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncat-2.ll +++ llvm/test/Transforms/InstCombine/strncat-2.ll @@ -12,15 +12,15 @@ define void @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0)) +; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0)), !tbaa ; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 [[STRLEN]] -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) [[ENDPTR]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) [[ENDPTR]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false), !tbaa ; CHECK-NEXT: ret void ; %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncat(i8* %dst, i8* %src, i32 13) + call i8* @strncat(i8* %dst, i8* %src, i32 13), !tbaa !2 ret void } @@ -102,12 +102,16 @@ define i8* @test5(i8* %str, i32 %n) { ; CHECK-LABEL: @test5( -; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]]) +; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]]), !tbaa ; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr i8, i8* [[STR]], i32 [[STRLEN]] -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) [[ENDPTR]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) [[ENDPTR]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false), !tbaa ; CHECK-NEXT: ret i8* [[STR]] ; %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %temp1 = call i8* @strncat(i8* %str, i8* %src, i32 10) + %temp1 = call i8* @strncat(i8* %str, i8* %src, i32 10), !tbaa !2 ret i8* %temp1 } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strncmp-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncmp-1.ll +++ llvm/test/Transforms/InstCombine/strncmp-1.ll @@ -14,27 +14,27 @@ ; strncmp("", x, n) -> -*x define i32 @test1(i8* %str2) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR2:%.*]], align 1 +; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR2:%.*]], align 1, !tbaa ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32 ; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i32 0, [[TMP1]] ; CHECK-NEXT: ret i32 [[TMP2]] ; %str1 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10) + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10), !tbaa !2 ret i32 %temp1 } ; strncmp(x, "", n) -> *x define i32 @test2(i8* %str1) { ; CHECK-LABEL: @test2( -; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR1:%.*]], align 1 +; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR1:%.*]], align 1, !tbaa ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32 ; CHECK-NEXT: ret i32 [[TMP1]] ; %str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10) + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10), !tbaa !2 ret i32 %temp1 } @@ -75,15 +75,15 @@ ; strncmp(x,y,1) -> memcmp(x,y,1) define i32 @test6(i8* %str1, i8* %str2) { ; CHECK-LABEL: @test6( -; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* [[STR1:%.*]], align 1 +; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* [[STR1:%.*]], align 1, !tbaa ; CHECK-NEXT: [[LHSV:%.*]] = zext i8 [[LHSC]] to i32 -; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* [[STR2:%.*]], align 1 +; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* [[STR2:%.*]], align 1, !tbaa ; CHECK-NEXT: [[RHSV:%.*]] = zext i8 [[RHSC]] to i32 ; CHECK-NEXT: [[CHARDIFF:%.*]] = sub nsw i32 [[LHSV]], [[RHSV]] ; CHECK-NEXT: ret i32 [[CHARDIFF]] ; - %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 1) + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 1), !tbaa !2 ret i32 %temp1 } @@ -148,3 +148,7 @@ %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 %n) ret i32 %temp1 } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strncpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncpy-1.ll +++ llvm/test/Transforms/InstCombine/strncpy-1.ll @@ -21,9 +21,9 @@ ; CHECK-NEXT: [[TARGET:%.*]] = alloca [1024 x i8], align 1 ; CHECK-NEXT: [[ARG1:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[TARGET]], i32 0, i32 0 ; CHECK-NEXT: store i8 0, i8* [[ARG1]], align 1 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) [[ARG1]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(42) [[ARG1]], i8 0, i32 42, i1 false) -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(42) [[ARG1]], i8 0, i32 42, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) [[ARG1]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false), !tbaa +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(42) [[ARG1]], i8 0, i32 42, i1 false), !tbaa +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(42) [[ARG1]], i8 0, i32 42, i1 false), !tbaa ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @puts(i8* nonnull [[ARG1]]) ; CHECK-NEXT: ret i32 0 ; @@ -32,13 +32,13 @@ store i8 0, i8* %arg1 %arg2 = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %rslt1 = call i8* @strncpy(i8* %arg1, i8* %arg2, i32 6) + %rslt1 = call i8* @strncpy(i8* %arg1, i8* %arg2, i32 6), !tbaa !2 %arg3 = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %rslt2 = call i8* @strncpy(i8* %rslt1, i8* %arg3, i32 42) + %rslt2 = call i8* @strncpy(i8* %rslt1, i8* %arg3, i32 42), !tbaa !2 %arg4 = getelementptr [7 x i8], [7 x i8]* @null_hello, i32 0, i32 0 - %rslt3 = call i8* @strncpy(i8* %rslt2, i8* %arg4, i32 42) + %rslt3 = call i8* @strncpy(i8* %rslt2, i8* %arg4, i32 42), !tbaa !2 call i32 @puts( i8* %rslt3 ) ret i32 0 @@ -48,13 +48,13 @@ define void @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(32) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8 0, i32 32, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(32) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8 0, i32 32, i1 false), !tbaa ; CHECK-NEXT: ret void ; %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - call i8* @strncpy(i8* %dst, i8* %src, i32 32) + call i8* @strncpy(i8* %dst, i8* %src, i32 32), !tbaa !2 ret void } @@ -75,33 +75,33 @@ define void @test_simplify4() { ; CHECK-LABEL: @test_simplify4( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false), !tbaa ; CHECK-NEXT: ret void ; %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncpy(i8* %dst, i8* %src, i32 6) + call i8* @strncpy(i8* %dst, i8* %src, i32 6), !tbaa !2 ret void } define void @test_simplify5(i8* %dst) { ; CHECK-LABEL: @test_simplify5( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(32) [[DST:%.*]], i8* nonnull align 1 dereferenceable(32) getelementptr inbounds ([33 x i8], [33 x i8]* @str, i32 0, i32 0), i32 32, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(32) [[DST:%.*]], i8* nonnull align 1 dereferenceable(32) getelementptr inbounds ([33 x i8], [33 x i8]* @str, i32 0, i32 0), i32 32, i1 false), !tbaa ; CHECK-NEXT: ret void ; %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncpy(i8* dereferenceable(8) %dst, i8* %src, i32 32) + call i8* @strncpy(i8* dereferenceable(8) %dst, i8* %src, i32 32), !tbaa !2 ret void } define void @test_simplify6(i8* %dst) { ; CHECK-LABEL: @test_simplify6( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(80) [[DST:%.*]], i8* nonnull align 1 dereferenceable(32) getelementptr inbounds ([33 x i8], [33 x i8]* @str.1, i32 0, i32 0), i32 32, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(80) [[DST:%.*]], i8* nonnull align 1 dereferenceable(32) getelementptr inbounds ([33 x i8], [33 x i8]* @str.1, i32 0, i32 0), i32 32, i1 false), !tbaa ; CHECK-NEXT: ret void ; %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncpy(i8* dereferenceable(80) %dst, i8* %src, i32 32) + call i8* @strncpy(i8* dereferenceable(80) %dst, i8* %src, i32 32), !tbaa !2 ret void } @@ -130,17 +130,17 @@ ; CHECK-NEXT: ret i8* [[DST]] ; %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strncpy(i8* nonnull %dst, i8* nonnull %src, i32 5) + %ret = call i8* @strncpy(i8* nonnull %dst, i8* nonnull %src, i32 5), !tbaa !2 ret i8* %ret } define i8* @test3(i8* %dst, i32 %n) { ; CHECK-LABEL: @test3( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noalias nonnull align 1 dereferenceable(5) [[DST:%.*]], i8 0, i32 5, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noalias nonnull align 1 dereferenceable(5) [[DST:%.*]], i8 0, i32 5, i1 false), !tbaa ; CHECK-NEXT: ret i8* [[DST]] ; %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %ret = call i8* @strncpy(i8* noalias nonnull %dst, i8* nonnull %src, i32 5); + %ret = call i8* @strncpy(i8* noalias nonnull %dst, i8* nonnull %src, i32 5), !tbaa !2 ret i8* %ret } @@ -169,3 +169,7 @@ call i8* @strncpy(i8* %dst, i8* %src, i32 8) ret void } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strncpy-3.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncpy-3.ll +++ llvm/test/Transforms/InstCombine/strncpy-3.ll @@ -12,39 +12,39 @@ define void @fill_with_zeros(i8* %dst) { ; CHECK-LABEL: @fill_with_zeros( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[DST:%.*]] to i32* -; CHECK-NEXT: store i32 97, i32* [[TMP1]], align 1 +; CHECK-NEXT: store i32 97, i32* [[TMP1]], align 1, !tbaa ; CHECK-NEXT: ret void ; - tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @str, i64 0, i64 0), i64 4) + tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @str, i64 0, i64 0), i64 4), !tbaa !2 ret void } define void @fill_with_zeros2(i8* %dst) { ; CHECK-LABEL: @fill_with_zeros2( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[DST:%.*]] to i32* -; CHECK-NEXT: store i32 6513249, i32* [[TMP1]], align 1 +; CHECK-NEXT: store i32 6513249, i32* [[TMP1]], align 1, !tbaa ; CHECK-NEXT: ret void ; - tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @str2, i64 0, i64 0), i64 4) + tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @str2, i64 0, i64 0), i64 4), !tbaa !2 ret void } define void @fill_with_zeros3(i8* %dst) { ; CHECK-LABEL: @fill_with_zeros3( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[DST:%.*]] to i32* -; CHECK-NEXT: store i32 1684234849, i32* [[TMP1]], align 1 +; CHECK-NEXT: store i32 1684234849, i32* [[TMP1]], align 1, !tbaa ; CHECK-NEXT: ret void ; - tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str3, i64 0, i64 0), i64 4) + tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str3, i64 0, i64 0), i64 4), !tbaa !2 ret void } define void @fill_with_zeros4(i8* %dst) { ; CHECK-LABEL: @fill_with_zeros4( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(128) [[DST:%.*]], i8* nonnull align 1 dereferenceable(128) getelementptr inbounds ([129 x i8], [129 x i8]* @str.2, i64 0, i64 0), i64 128, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(128) [[DST:%.*]], i8* nonnull align 1 dereferenceable(128) getelementptr inbounds ([129 x i8], [129 x i8]* @str.2, i64 0, i64 0), i64 128, i1 false), !tbaa ; CHECK-NEXT: ret void ; - tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str3, i64 0, i64 0), i64 128) + tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str3, i64 0, i64 0), i64 128), !tbaa !2 ret void } @@ -56,3 +56,7 @@ tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str3, i64 0, i64 0), i64 129) ret void } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strncpy_chk-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncpy_chk-1.ll +++ llvm/test/Transforms/InstCombine/strncpy_chk-1.ll @@ -14,37 +14,37 @@ define i8* @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false), !tbaa ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60) + %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60), !tbaa !2 ret i8* %ret } define i8* @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false), !tbaa ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 12) + %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 12), !tbaa !2 ret i8* %ret } define i8* @test_simplify3() { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: [[STRNCPY:%.*]] = call i8* @strncpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 12) +; CHECK-NEXT: [[STRNCPY:%.*]] = call i8* @strncpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 12), !tbaa ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60) + %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60), !tbaa !2 ret i8* %ret } @@ -75,3 +75,7 @@ } declare i8* @__strncpy_chk(i8*, i8*, i32, i32) + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strndup.ll =================================================================== --- llvm/test/Transforms/InstCombine/strndup.ll +++ llvm/test/Transforms/InstCombine/strndup.ll @@ -8,51 +8,51 @@ define i8* @test1() { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(1) i8* @strdup(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @null, i64 0, i64 0)) +; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(1) i8* @strdup(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @null, i64 0, i64 0)), !tbaa ; CHECK-NEXT: ret i8* [[STRDUP]] ; %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i32 0) + %ret = call i8* @strndup(i8* %src, i32 0), !tbaa !2 ret i8* %ret } define i8* @test2() { ; CHECK-LABEL: @test2( -; CHECK-NEXT: [[RET:%.*]] = call dereferenceable_or_null(5) i8* @strndup(i8* dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0), i32 4) +; CHECK-NEXT: [[RET:%.*]] = call dereferenceable_or_null(5) i8* @strndup(i8* dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0), i32 4), !tbaa ; CHECK-NEXT: ret i8* [[RET]] ; %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i32 4) + %ret = call i8* @strndup(i8* %src, i32 4), !tbaa !2 ret i8* %ret } define i8* @test3() { ; CHECK-LABEL: @test3( -; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0)) +; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0)), !tbaa ; CHECK-NEXT: ret i8* [[STRDUP]] ; %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i32 5) + %ret = call i8* @strndup(i8* %src, i32 5), !tbaa !2 ret i8* %ret } define i8* @test4() { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0)) +; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0)), !tbaa ; CHECK-NEXT: ret i8* [[STRDUP]] ; %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i32 6) + %ret = call i8* @strndup(i8* %src, i32 6), !tbaa !2 ret i8* %ret } define i8* @test5() { ; CHECK-LABEL: @test5( -; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0)) +; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0)), !tbaa ; CHECK-NEXT: ret i8* [[STRDUP]] ; %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i32 7) + %ret = call i8* @strndup(i8* %src, i32 7), !tbaa !2 ret i8* %ret } @@ -65,3 +65,7 @@ %ret = call i8* @strndup(i8* %src, i32 %n) ret i8* %ret } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strpbrk-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strpbrk-1.ll +++ llvm/test/Transforms/InstCombine/strpbrk-1.ll @@ -52,12 +52,12 @@ define i8* @test_simplify4(i8* %str) { ; CHECK-LABEL: @test_simplify4( -; CHECK-NEXT: [[STRCHR:%.*]] = call i8* @strchr(i8* nonnull dereferenceable(1) [[STR:%.*]], i32 119) +; CHECK-NEXT: [[STRCHR:%.*]] = call i8* @strchr(i8* nonnull dereferenceable(1) [[STR:%.*]], i32 119), !tbaa ; CHECK-NEXT: ret i8* [[STRCHR]] ; %pat = getelementptr [2 x i8], [2 x i8]* @w, i32 0, i32 0 - %ret = call i8* @strpbrk(i8* %str, i8* %pat) + %ret = call i8* @strpbrk(i8* %str, i8* %pat), !tbaa !2 ret i8* %ret } @@ -72,3 +72,7 @@ %ret = call i8* @strpbrk(i8* %str, i8* %pat) ret i8* %ret } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0} Index: llvm/test/Transforms/InstCombine/strstr-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strstr-1.ll +++ llvm/test/Transforms/InstCombine/strstr-1.ll @@ -27,11 +27,11 @@ define i8* @test_simplify2(i8* %str) { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: [[STRCHR:%.*]] = call i8* @strchr(i8* nonnull dereferenceable(1) [[STR:%.*]], i32 97) +; CHECK-NEXT: [[STRCHR:%.*]] = call i8* @strchr(i8* nonnull dereferenceable(1) [[STR:%.*]], i32 97), !tbaa ; CHECK-NEXT: ret i8* [[STRCHR]] ; %pat = getelementptr inbounds [2 x i8], [2 x i8]* @.str1, i32 0, i32 0 - %ret = call i8* @strstr(i8* %str, i8* %pat) + %ret = call i8* @strstr(i8* %str, i8* %pat), !tbaa !2 ret i8* %ret } @@ -61,12 +61,12 @@ define i1 @test_simplify5(i8* %str, i8* %pat) { ; CHECK-LABEL: @test_simplify5( -; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(i8* nonnull dereferenceable(1) [[PAT:%.*]]) -; CHECK-NEXT: [[STRNCMP:%.*]] = call i32 @strncmp(i8* [[STR:%.*]], i8* [[PAT]], i64 [[STRLEN]]) +; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(i8* nonnull dereferenceable(1) [[PAT:%.*]]), !tbaa +; CHECK-NEXT: [[STRNCMP:%.*]] = call i32 @strncmp(i8* [[STR:%.*]], i8* [[PAT]], i64 [[STRLEN]]), !tbaa ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[STRNCMP]], 0 ; CHECK-NEXT: ret i1 [[CMP1]] ; - %ret = call i8* @strstr(i8* %str, i8* %pat) + %ret = call i8* @strstr(i8* %str, i8* %pat), !tbaa !2 %cmp = icmp eq i8* %ret, %str ret i1 %cmp } @@ -88,3 +88,7 @@ %ret = call i8* @strstr(i8* %str1, i8* %str2) ret i8* %ret } + +!0 = !{!"tbaa_root"} +!1 = !{!"tbaa_scalar", !0, i64 0} +!2 = !{!1, !1, i64 0}