[llvm] r372091 - [SimplifyLibCalls] Mark known arguments with nonnull
David Bolvansky via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 17 02:32:52 PDT 2019
Author: xbolva00
Date: Tue Sep 17 02:32:52 2019
New Revision: 372091
URL: http://llvm.org/viewvc/llvm-project?rev=372091&view=rev
Log:
[SimplifyLibCalls] Mark known arguments with nonnull
Reviewers: efriedma, jdoerfert
Reviewed By: jdoerfert
Subscribers: ychen, rsmith, joerg, aaron.ballman, lebedev.ri, uenoku, jdoerfert, hfinkel, javed.absar, spatel, dmgreen, llvm-commits
Differential Revision: https://reviews.llvm.org/D53342
Added:
llvm/trunk/test/Transforms/InstCombine/memrchr.ll
Modified:
llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
llvm/trunk/test/Analysis/BasicAA/gep-alias.ll
llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll
llvm/trunk/test/CodeGen/X86/no-plt-libcalls.ll
llvm/trunk/test/Other/cgscc-libcall-update.ll
llvm/trunk/test/Transforms/InstCombine/ARM/strcmp.ll
llvm/trunk/test/Transforms/InstCombine/align-addr.ll
llvm/trunk/test/Transforms/InstCombine/fortify-folding.ll
llvm/trunk/test/Transforms/InstCombine/getelementptr.ll
llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll
llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes-addrspaces.ll
llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes.ll
llvm/trunk/test/Transforms/InstCombine/memchr.ll
llvm/trunk/test/Transforms/InstCombine/memcmp-constant-fold.ll
llvm/trunk/test/Transforms/InstCombine/memcpy-from-global.ll
llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll
llvm/trunk/test/Transforms/InstCombine/memcpy.ll
llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll
llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll
llvm/trunk/test/Transforms/InstCombine/mempcpy.ll
llvm/trunk/test/Transforms/InstCombine/memset-1.ll
llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll
llvm/trunk/test/Transforms/InstCombine/objsize.ll
llvm/trunk/test/Transforms/InstCombine/printf-1.ll
llvm/trunk/test/Transforms/InstCombine/printf-2.ll
llvm/trunk/test/Transforms/InstCombine/puts-1.ll
llvm/trunk/test/Transforms/InstCombine/snprintf.ll
llvm/trunk/test/Transforms/InstCombine/sprintf-1.ll
llvm/trunk/test/Transforms/InstCombine/stpcpy-1.ll
llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll
llvm/trunk/test/Transforms/InstCombine/strchr-1.ll
llvm/trunk/test/Transforms/InstCombine/strcmp-1.ll
llvm/trunk/test/Transforms/InstCombine/strcmp-memcmp.ll
llvm/trunk/test/Transforms/InstCombine/strcpy-1.ll
llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll
llvm/trunk/test/Transforms/InstCombine/strcspn-1.ll
llvm/trunk/test/Transforms/InstCombine/strlen-1.ll
llvm/trunk/test/Transforms/InstCombine/strncat-2.ll
llvm/trunk/test/Transforms/InstCombine/strncat-3.ll
llvm/trunk/test/Transforms/InstCombine/strncmp-1.ll
llvm/trunk/test/Transforms/InstCombine/strncmp-2.ll
llvm/trunk/test/Transforms/InstCombine/strncpy-1.ll
llvm/trunk/test/Transforms/InstCombine/strncpy-2.ll
llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll
llvm/trunk/test/Transforms/InstCombine/strpbrk-1.ll
llvm/trunk/test/Transforms/InstCombine/strrchr-1.ll
llvm/trunk/test/Transforms/InstCombine/strstr-1.ll
Modified: llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h Tue Sep 17 02:32:52 2019
@@ -170,13 +170,14 @@ private:
Value *optimizeStrCSpn(CallInst *CI, IRBuilder<> &B);
Value *optimizeStrStr(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemChr(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemRChr(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemCmp(CallInst *CI, IRBuilder<> &B);
Value *optimizeBCmp(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemCmpBCmpCommon(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemPCpy(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B, bool isIntrinsic = false);
- Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B, bool isIntrinsic = false);
- Value *optimizeMemSet(CallInst *CI, IRBuilder<> &B, bool isIntrinsic = false);
+ Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemSet(CallInst *CI, IRBuilder<> &B);
Value *optimizeRealloc(CallInst *CI, IRBuilder<> &B);
Value *optimizeWcslen(CallInst *CI, IRBuilder<> &B);
// Wrapper for all String/Memory Library Call Optimizations
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Tue Sep 17 02:32:52 2019
@@ -189,21 +189,23 @@ static bool canTransformToMemCmp(CallIns
static void annotateDereferenceableBytes(CallInst *CI,
ArrayRef<unsigned> ArgNos,
uint64_t DereferenceableBytes) {
- const Function *F = CI->getFunction();
+ const Function *F = CI->getCaller();
if (!F)
return;
for (unsigned ArgNo : ArgNos) {
uint64_t DerefBytes = DereferenceableBytes;
unsigned AS = CI->getArgOperand(ArgNo)->getType()->getPointerAddressSpace();
- if (!llvm::NullPointerIsDefined(F, AS))
+ if (!llvm::NullPointerIsDefined(F, AS) ||
+ CI->paramHasAttr(ArgNo, Attribute::NonNull))
DerefBytes = std::max(CI->getDereferenceableOrNullBytes(
ArgNo + AttributeList::FirstArgIndex),
DereferenceableBytes);
-
+
if (CI->getDereferenceableBytes(ArgNo + AttributeList::FirstArgIndex) <
DerefBytes) {
CI->removeParamAttr(ArgNo, Attribute::Dereferenceable);
- if (!llvm::NullPointerIsDefined(F, AS))
+ if (!llvm::NullPointerIsDefined(F, AS) ||
+ CI->paramHasAttr(ArgNo, Attribute::NonNull))
CI->removeParamAttr(ArgNo, Attribute::DereferenceableOrNull);
CI->addParamAttr(ArgNo, Attribute::getWithDereferenceableBytes(
CI->getContext(), DerefBytes));
@@ -211,6 +213,40 @@ static void annotateDereferenceableBytes
}
}
+static void annotateNonNullBasedOnAccess(CallInst *CI,
+ ArrayRef<unsigned> ArgNos) {
+ Function *F = CI->getCaller();
+ if (!F)
+ return;
+
+ for (unsigned ArgNo : ArgNos) {
+ if (CI->paramHasAttr(ArgNo, Attribute::NonNull))
+ continue;
+ unsigned AS = CI->getArgOperand(ArgNo)->getType()->getPointerAddressSpace();
+ if (llvm::NullPointerIsDefined(F, AS))
+ continue;
+
+ CI->addParamAttr(ArgNo, Attribute::NonNull);
+ annotateDereferenceableBytes(CI, ArgNo, 1);
+ }
+}
+
+static void annotateNonNullAndDereferenceable(CallInst *CI, ArrayRef<unsigned> ArgNos,
+ Value *Size, const DataLayout &DL) {
+ if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size)) {
+ annotateNonNullBasedOnAccess(CI, ArgNos);
+ annotateDereferenceableBytes(CI, ArgNos, LenC->getZExtValue());
+ } else if (isKnownNonZero(Size, DL)) {
+ annotateNonNullBasedOnAccess(CI, ArgNos);
+ const APInt *X, *Y;
+ uint64_t DerefMin = 1;
+ if (match(Size, m_Select(m_Value(), m_APInt(X), m_APInt(Y)))) {
+ DerefMin = std::min(X->getZExtValue(), Y->getZExtValue());
+ annotateDereferenceableBytes(CI, ArgNos, DerefMin);
+ }
+ }
+}
+
//===----------------------------------------------------------------------===//
// String and Memory Library Call Optimizations
//===----------------------------------------------------------------------===//
@@ -219,10 +255,13 @@ Value *LibCallSimplifier::optimizeStrCat
// Extract some information from the instruction
Value *Dst = CI->getArgOperand(0);
Value *Src = CI->getArgOperand(1);
+ annotateNonNullBasedOnAccess(CI, {0, 1});
// See if we can get the length of the input string.
uint64_t Len = GetStringLength(Src);
- if (Len == 0)
+ if (Len)
+ annotateDereferenceableBytes(CI, 1, Len);
+ else
return nullptr;
--Len; // Unbias length.
@@ -257,24 +296,34 @@ Value *LibCallSimplifier::optimizeStrNCa
// Extract some information from the instruction.
Value *Dst = CI->getArgOperand(0);
Value *Src = CI->getArgOperand(1);
+ Value *Size = CI->getArgOperand(2);
uint64_t Len;
+ annotateNonNullBasedOnAccess(CI, 0);
+ if (isKnownNonZero(Size, DL))
+ annotateNonNullBasedOnAccess(CI, 1);
// We don't do anything if length is not constant.
- if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
+ ConstantInt *LengthArg = dyn_cast<ConstantInt>(Size);
+ if (LengthArg) {
Len = LengthArg->getZExtValue();
- else
+ // strncat(x, c, 0) -> x
+ if (!Len)
+ return Dst;
+ } else {
return nullptr;
+ }
// See if we can get the length of the input string.
uint64_t SrcLen = GetStringLength(Src);
- if (SrcLen == 0)
+ if (SrcLen) {
+ annotateDereferenceableBytes(CI, 1, SrcLen);
+ --SrcLen; // Unbias length.
+ } else {
return nullptr;
- --SrcLen; // Unbias length.
+ }
- // Handle the simple, do-nothing cases:
// strncat(x, "", c) -> x
- // strncat(x, c, 0) -> x
- if (SrcLen == 0 || Len == 0)
+ if (SrcLen == 0)
return Dst;
// We don't optimize this case.
@@ -290,13 +339,18 @@ Value *LibCallSimplifier::optimizeStrChr
Function *Callee = CI->getCalledFunction();
FunctionType *FT = Callee->getFunctionType();
Value *SrcStr = CI->getArgOperand(0);
+ annotateNonNullBasedOnAccess(CI, 0);
// 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<ConstantInt>(CI->getArgOperand(1));
if (!CharC) {
uint64_t Len = GetStringLength(SrcStr);
- if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32)) // memchr needs i32.
+ if (Len)
+ annotateDereferenceableBytes(CI, 0, Len);
+ else
+ return nullptr;
+ if (!FT->getParamType(1)->isIntegerTy(32)) // memchr needs i32.
return nullptr;
return emitMemChr(SrcStr, CI->getArgOperand(1), // include nul.
@@ -329,6 +383,7 @@ Value *LibCallSimplifier::optimizeStrChr
Value *LibCallSimplifier::optimizeStrRChr(CallInst *CI, IRBuilder<> &B) {
Value *SrcStr = CI->getArgOperand(0);
ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
+ annotateNonNullBasedOnAccess(CI, 0);
// Cannot fold anything if we're not looking for a constant.
if (!CharC)
@@ -376,7 +431,12 @@ Value *LibCallSimplifier::optimizeStrCmp
// strcmp(P, "x") -> memcmp(P, "x", 2)
uint64_t Len1 = GetStringLength(Str1P);
+ if (Len1)
+ annotateDereferenceableBytes(CI, 0, Len1);
uint64_t Len2 = GetStringLength(Str2P);
+ if (Len2)
+ annotateDereferenceableBytes(CI, 1, Len2);
+
if (Len1 && Len2) {
return emitMemCmp(Str1P, Str2P,
ConstantInt::get(DL.getIntPtrType(CI->getContext()),
@@ -399,17 +459,22 @@ Value *LibCallSimplifier::optimizeStrCmp
TLI);
}
+ annotateNonNullBasedOnAccess(CI, {0, 1});
return nullptr;
}
Value *LibCallSimplifier::optimizeStrNCmp(CallInst *CI, IRBuilder<> &B) {
- Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
+ Value *Str1P = CI->getArgOperand(0);
+ Value *Str2P = CI->getArgOperand(1);
+ Value *Size = CI->getArgOperand(2);
if (Str1P == Str2P) // strncmp(x,x,n) -> 0
return ConstantInt::get(CI->getType(), 0);
+ if (isKnownNonZero(Size, DL))
+ annotateNonNullBasedOnAccess(CI, {0, 1});
// Get the length argument if it is constant.
uint64_t Length;
- if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
+ if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(Size))
Length = LengthArg->getZExtValue();
else
return nullptr;
@@ -418,7 +483,7 @@ Value *LibCallSimplifier::optimizeStrNCm
return ConstantInt::get(CI->getType(), 0);
if (Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1)
- return emitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, DL, TLI);
+ return emitMemCmp(Str1P, Str2P, Size, B, DL, TLI);
StringRef Str1, Str2;
bool HasStr1 = getConstantStringInfo(Str1P, Str1);
@@ -440,7 +505,11 @@ Value *LibCallSimplifier::optimizeStrNCm
CI->getType());
uint64_t Len1 = GetStringLength(Str1P);
+ if (Len1)
+ annotateDereferenceableBytes(CI, 0, Len1);
uint64_t Len2 = GetStringLength(Str2P);
+ if (Len2)
+ annotateDereferenceableBytes(CI, 1, Len2);
// strncmp to memcmp
if (!HasStr1 && HasStr2) {
@@ -466,16 +535,21 @@ Value *LibCallSimplifier::optimizeStrCpy
Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
if (Dst == Src) // strcpy(x,x) -> x
return Src;
-
+
+ annotateNonNullBasedOnAccess(CI, {0, 1});
// See if we can get the length of the input string.
uint64_t Len = GetStringLength(Src);
- if (Len == 0)
+ if (Len)
+ annotateDereferenceableBytes(CI, 1, Len);
+ else
return nullptr;
// 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.
- B.CreateMemCpy(Dst, 1, Src, 1,
- ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len));
+ CallInst *NewCI =
+ B.CreateMemCpy(Dst, 1, Src, 1,
+ ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len));
+ NewCI->setAttributes(CI->getAttributes());
return Dst;
}
@@ -489,7 +563,9 @@ Value *LibCallSimplifier::optimizeStpCpy
// See if we can get the length of the input string.
uint64_t Len = GetStringLength(Src);
- if (Len == 0)
+ if (Len)
+ annotateDereferenceableBytes(CI, 1, Len);
+ else
return nullptr;
Type *PT = Callee->getFunctionType()->getParamType(0);
@@ -499,7 +575,8 @@ Value *LibCallSimplifier::optimizeStpCpy
// 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.
- B.CreateMemCpy(Dst, 1, Src, 1, LenV);
+ CallInst *NewCI = B.CreateMemCpy(Dst, 1, Src, 1, LenV);
+ NewCI->setAttributes(CI->getAttributes());
return DstEnd;
}
@@ -507,37 +584,48 @@ Value *LibCallSimplifier::optimizeStrNCp
Function *Callee = CI->getCalledFunction();
Value *Dst = CI->getArgOperand(0);
Value *Src = CI->getArgOperand(1);
- Value *LenOp = CI->getArgOperand(2);
+ Value *Size = CI->getArgOperand(2);
+ annotateNonNullBasedOnAccess(CI, 0);
+ if (isKnownNonZero(Size, DL))
+ annotateNonNullBasedOnAccess(CI, 1);
+
+ uint64_t Len;
+ if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(Size))
+ Len = LengthArg->getZExtValue();
+ else
+ return nullptr;
+
+ // strncpy(x, y, 0) -> x
+ if (Len == 0)
+ return Dst;
// See if we can get the length of the input string.
uint64_t SrcLen = GetStringLength(Src);
- if (SrcLen == 0)
+ if (SrcLen) {
+ annotateDereferenceableBytes(CI, 1, SrcLen);
+ --SrcLen; // Unbias length.
+ } else {
return nullptr;
- --SrcLen;
+ }
if (SrcLen == 0) {
// strncpy(x, "", y) -> memset(align 1 x, '\0', y)
- B.CreateMemSet(Dst, B.getInt8('\0'), LenOp, 1);
+ CallInst *NewCI = B.CreateMemSet(Dst, B.getInt8('\0'), Size, 1);
+ AttrBuilder ArgAttrs(CI->getAttributes().getParamAttributes(0));
+ NewCI->getAttributes().addParamAttributes(CI->getContext(), 0, ArgAttrs);
return Dst;
}
- uint64_t Len;
- if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(LenOp))
- Len = LengthArg->getZExtValue();
- else
- return nullptr;
-
- if (Len == 0)
- return Dst; // strncpy(x, y, 0) -> x
-
// Let strncpy handle the zero padding
if (Len > SrcLen + 1)
return nullptr;
Type *PT = Callee->getFunctionType()->getParamType(0);
// strncpy(x, s, c) -> memcpy(align 1 x, align 1 s, c) [s and c are constant]
- B.CreateMemCpy(Dst, 1, Src, 1, ConstantInt::get(DL.getIntPtrType(PT), Len));
-
+ CallInst *NewCI = B.CreateMemCpy(Dst, 1, Src, 1, ConstantInt::get(DL.getIntPtrType(PT), Len));
+ // AttrBuilder ArgAttrs(CI->getAttributes().getParamAttributes(0));
+// NewCI->getAttributes().addParamAttributes(CI->getContext(), 0, ArgAttrs);
+ NewCI->setAttributes(CI->getAttributes());
return Dst;
}
@@ -633,7 +721,10 @@ Value *LibCallSimplifier::optimizeString
}
Value *LibCallSimplifier::optimizeStrLen(CallInst *CI, IRBuilder<> &B) {
- return optimizeStringLength(CI, B, 8);
+ if (Value *V = optimizeStringLength(CI, B, 8))
+ return V;
+ annotateNonNullBasedOnAccess(CI, 0);
+ return nullptr;
}
Value *LibCallSimplifier::optimizeWcslen(CallInst *CI, IRBuilder<> &B) {
@@ -781,23 +872,35 @@ Value *LibCallSimplifier::optimizeStrStr
Value *StrChr = emitStrChr(CI->getArgOperand(0), ToFindStr[0], B, TLI);
return StrChr ? B.CreateBitCast(StrChr, CI->getType()) : nullptr;
}
+
+ annotateNonNullBasedOnAccess(CI, {0, 1});
+ return nullptr;
+}
+
+Value *LibCallSimplifier::optimizeMemRChr(CallInst *CI, IRBuilder<> &B) {
+ if (isKnownNonZero(CI->getOperand(2), DL))
+ annotateNonNullBasedOnAccess(CI, 0);
return nullptr;
}
Value *LibCallSimplifier::optimizeMemChr(CallInst *CI, IRBuilder<> &B) {
Value *SrcStr = CI->getArgOperand(0);
+ Value *Size = CI->getArgOperand(2);
+ annotateNonNullAndDereferenceable(CI, 0, Size, DL);
ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
- ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
+ ConstantInt *LenC = dyn_cast<ConstantInt>(Size);
// memchr(x, y, 0) -> null
if (LenC) {
if (LenC->isZero())
return Constant::getNullValue(CI->getType());
- annotateDereferenceableBytes(CI, {0}, LenC->getZExtValue());
+ } else {
+ // From now on we need at least constant length and string.
+ return nullptr;
}
- // From now on we need at least constant length and string.
+
StringRef Str;
- if (!LenC || !getConstantStringInfo(SrcStr, Str, 0, /*TrimAtNul=*/false))
+ if (!getConstantStringInfo(SrcStr, Str, 0, /*TrimAtNul=*/false))
return nullptr;
// Truncate the string to LenC. If Str is smaller than LenC we will still only
@@ -940,6 +1043,7 @@ static Value *optimizeMemCmpConstantSize
Ret = 1;
return ConstantInt::get(CI->getType(), Ret);
}
+
return nullptr;
}
@@ -952,14 +1056,19 @@ Value *LibCallSimplifier::optimizeMemCmp
if (LHS == RHS) // memcmp(s,s,x) -> 0
return Constant::getNullValue(CI->getType());
+ annotateNonNullAndDereferenceable(CI, {0, 1}, Size, DL);
// Handle constant lengths.
- if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size)) {
- if (Value *Res = optimizeMemCmpConstantSize(CI, LHS, RHS,
- LenC->getZExtValue(), B, DL))
- return Res;
- annotateDereferenceableBytes(CI, {0, 1}, LenC->getZExtValue());
- }
+ ConstantInt *LenC = dyn_cast<ConstantInt>(Size);
+ if (!LenC)
+ return nullptr;
+ // memcmp(d,s,0) -> 0
+ if (LenC->getZExtValue() == 0)
+ return Constant::getNullValue(CI->getType());
+
+ if (Value *Res =
+ optimizeMemCmpConstantSize(CI, LHS, RHS, LenC->getZExtValue(), B, DL))
+ return Res;
return nullptr;
}
@@ -984,17 +1093,16 @@ Value *LibCallSimplifier::optimizeBCmp(C
return optimizeMemCmpBCmpCommon(CI, B);
}
-Value *LibCallSimplifier::optimizeMemCpy(CallInst *CI, IRBuilder<> &B,
- bool isIntrinsic) {
+Value *LibCallSimplifier::optimizeMemCpy(CallInst *CI, IRBuilder<> &B) {
Value *Size = CI->getArgOperand(2);
- if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size))
- annotateDereferenceableBytes(CI, {0, 1}, LenC->getZExtValue());
-
- if (isIntrinsic)
+ annotateNonNullAndDereferenceable(CI, {0, 1}, Size, DL);
+ if (isa<IntrinsicInst>(CI))
return nullptr;
// memcpy(x, y, n) -> llvm.memcpy(align 1 x, align 1 y, n)
- B.CreateMemCpy(CI->getArgOperand(0), 1, CI->getArgOperand(1), 1, Size);
+ CallInst *NewCI =
+ B.CreateMemCpy(CI->getArgOperand(0), 1, CI->getArgOperand(1), 1, Size);
+ NewCI->setAttributes(CI->getAttributes());
return CI->getArgOperand(0);
}
@@ -1007,17 +1115,17 @@ Value *LibCallSimplifier::optimizeMemPCp
return B.CreateInBoundsGEP(B.getInt8Ty(), Dst, N);
}
-Value *LibCallSimplifier::optimizeMemMove(CallInst *CI, IRBuilder<> &B, bool isIntrinsic) {
+Value *LibCallSimplifier::optimizeMemMove(CallInst *CI, IRBuilder<> &B) {
Value *Size = CI->getArgOperand(2);
- if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size))
- annotateDereferenceableBytes(CI, {0, 1}, LenC->getZExtValue());
-
- if (isIntrinsic)
+ annotateNonNullAndDereferenceable(CI, {0, 1}, Size, DL);
+ if (isa<IntrinsicInst>(CI))
return nullptr;
// memmove(x, y, n) -> llvm.memmove(align 1 x, align 1 y, n)
- B.CreateMemMove( CI->getArgOperand(0), 1, CI->getArgOperand(1), 1, Size);
- return CI->getArgOperand(0);
+ CallInst *NewCI =
+ B.CreateMemMove(CI->getArgOperand(0), 1, CI->getArgOperand(1), 1, Size);
+ NewCI->setAttributes(CI->getAttributes());
+ return CI->getArgOperand(0);
}
/// Fold memset[_chk](malloc(n), 0, n) --> calloc(1, n).
@@ -1064,13 +1172,10 @@ Value *LibCallSimplifier::foldMallocMems
return nullptr;
}
-Value *LibCallSimplifier::optimizeMemSet(CallInst *CI, IRBuilder<> &B,
- bool isIntrinsic) {
+Value *LibCallSimplifier::optimizeMemSet(CallInst *CI, IRBuilder<> &B) {
Value *Size = CI->getArgOperand(2);
- if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size))
- annotateDereferenceableBytes(CI, {0}, LenC->getZExtValue());
-
- if (isIntrinsic)
+ annotateNonNullAndDereferenceable(CI, 0, Size, DL);
+ if (isa<IntrinsicInst>(CI))
return nullptr;
if (auto *Calloc = foldMallocMemset(CI, B))
@@ -1078,7 +1183,8 @@ Value *LibCallSimplifier::optimizeMemSet
// memset(p, v, n) -> llvm.memset(align 1 p, v, n)
Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);
- B.CreateMemSet(CI->getArgOperand(0), Val, Size, 1);
+ CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val, Size, 1);
+ NewCI->setAttributes(CI->getAttributes());
return CI->getArgOperand(0);
}
@@ -2187,6 +2293,7 @@ Value *LibCallSimplifier::optimizePrintF
return New;
}
+ annotateNonNullBasedOnAccess(CI, 0);
return nullptr;
}
@@ -2281,21 +2388,21 @@ Value *LibCallSimplifier::optimizeSPrint
return New;
}
+ annotateNonNullBasedOnAccess(CI, {0, 1});
return nullptr;
}
Value *LibCallSimplifier::optimizeSnPrintFString(CallInst *CI, IRBuilder<> &B) {
- // Check for a fixed format string.
- StringRef FormatStr;
- if (!getConstantStringInfo(CI->getArgOperand(2), FormatStr))
- return nullptr;
-
// Check for size
ConstantInt *Size = dyn_cast<ConstantInt>(CI->getArgOperand(1));
if (!Size)
return nullptr;
uint64_t N = Size->getZExtValue();
+ // Check for a fixed format string.
+ StringRef FormatStr;
+ if (!getConstantStringInfo(CI->getArgOperand(2), FormatStr))
+ return nullptr;
// If we just have a format string (nothing else crazy) transform it.
if (CI->getNumArgOperands() == 3) {
@@ -2368,6 +2475,8 @@ Value *LibCallSimplifier::optimizeSnPrin
return V;
}
+ if (isKnownNonZero(CI->getOperand(1), DL))
+ annotateNonNullBasedOnAccess(CI, 0);
return nullptr;
}
@@ -2553,6 +2662,7 @@ Value *LibCallSimplifier::optimizeFRead(
}
Value *LibCallSimplifier::optimizePuts(CallInst *CI, IRBuilder<> &B) {
+ annotateNonNullBasedOnAccess(CI, 0);
if (!CI->use_empty())
return nullptr;
@@ -2623,6 +2733,8 @@ Value *LibCallSimplifier::optimizeString
return optimizeStrStr(CI, Builder);
case LibFunc_memchr:
return optimizeMemChr(CI, Builder);
+ case LibFunc_memrchr:
+ return optimizeMemRChr(CI, Builder);
case LibFunc_bcmp:
return optimizeBCmp(CI, Builder);
case LibFunc_memcmp:
@@ -2778,11 +2890,11 @@ Value *LibCallSimplifier::optimizeCall(C
return optimizeSqrt(CI, Builder);
// TODO: Use foldMallocMemset() with memset intrinsic.
case Intrinsic::memset:
- return optimizeMemSet(CI, Builder, true);
+ return optimizeMemSet(CI, Builder);
case Intrinsic::memcpy:
- return optimizeMemCpy(CI, Builder, true);
+ return optimizeMemCpy(CI, Builder);
case Intrinsic::memmove:
- return optimizeMemMove(CI, Builder, true);
+ return optimizeMemMove(CI, Builder);
default:
return nullptr;
}
@@ -2955,7 +3067,9 @@ FortifiedLibCallSimplifier::isFortifiedC
uint64_t Len = GetStringLength(CI->getArgOperand(*StrOp));
// If the length is 0 we don't know how long it is and so we can't
// remove the check.
- if (Len == 0)
+ if (Len)
+ annotateDereferenceableBytes(CI, *StrOp, Len);
+ else
return false;
return ObjSizeCI->getZExtValue() >= Len;
}
@@ -2972,8 +3086,9 @@ FortifiedLibCallSimplifier::isFortifiedC
Value *FortifiedLibCallSimplifier::optimizeMemCpyChk(CallInst *CI,
IRBuilder<> &B) {
if (isFortifiedCallFoldable(CI, 3, 2)) {
- B.CreateMemCpy(CI->getArgOperand(0), 1, CI->getArgOperand(1), 1,
- CI->getArgOperand(2));
+ CallInst *NewCI = B.CreateMemCpy(
+ CI->getArgOperand(0), 1, CI->getArgOperand(1), 1, CI->getArgOperand(2));
+ NewCI->setAttributes(CI->getAttributes());
return CI->getArgOperand(0);
}
return nullptr;
@@ -2982,8 +3097,9 @@ Value *FortifiedLibCallSimplifier::optim
Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(CallInst *CI,
IRBuilder<> &B) {
if (isFortifiedCallFoldable(CI, 3, 2)) {
- B.CreateMemMove(CI->getArgOperand(0), 1, CI->getArgOperand(1), 1,
- CI->getArgOperand(2));
+ CallInst *NewCI = B.CreateMemMove(
+ CI->getArgOperand(0), 1, CI->getArgOperand(1), 1, CI->getArgOperand(2));
+ NewCI->setAttributes(CI->getAttributes());
return CI->getArgOperand(0);
}
return nullptr;
@@ -2995,7 +3111,9 @@ Value *FortifiedLibCallSimplifier::optim
if (isFortifiedCallFoldable(CI, 3, 2)) {
Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);
- B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
+ CallInst *NewCI =
+ B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
+ NewCI->setAttributes(CI->getAttributes());
return CI->getArgOperand(0);
}
return nullptr;
@@ -3031,7 +3149,9 @@ Value *FortifiedLibCallSimplifier::optim
// Maybe we can stil fold __st[rp]cpy_chk to __memcpy_chk.
uint64_t Len = GetStringLength(Src);
- if (Len == 0)
+ if (Len)
+ annotateDereferenceableBytes(CI, 1, Len);
+ else
return nullptr;
Type *SizeTTy = DL.getIntPtrType(CI->getContext());
Modified: llvm/trunk/test/Analysis/BasicAA/gep-alias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/gep-alias.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/BasicAA/gep-alias.ll (original)
+++ llvm/trunk/test/Analysis/BasicAA/gep-alias.ll Tue Sep 17 02:32:52 2019
@@ -247,7 +247,7 @@ define i32 @test12(i32 %x, i32 %y, i8* %
; CHECK: [[U0ADDR:%[a-zA-Z0-9_]+]] = getelementptr inbounds [3 x i8], [3 x i8]* %u, i32 0, i32 0
; CHECK: [[U0:%[a-zA-Z0-9_]+]] = load i8, i8* [[U0ADDR]], align 1
; CHECK: [[U0ARG:%[a-zA-Z0-9_]+]] = zext i8 [[U0]] to i32
-; CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i32 [[T0ARG]], i32 [[U0ARG]])
+; CHECK: call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i32 [[T0ARG]], i32 [[U0ARG]])
; CHECK: ret
define void @test13() {
entry:
Modified: llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll (original)
+++ llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll Tue Sep 17 02:32:52 2019
@@ -8,7 +8,7 @@ target datalayout = "e-p:64:64:64"
define void @foo(i8* nocapture %p, i8* nocapture %q, i8* nocapture %s) nounwind {
; CHECK: @foo
-; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 dereferenceable(16) %p, i8* align 1 dereferenceable(16) %q, i64 16, i1 false), !tbaa !0
+; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(16) %p, i8* nonnull align 1 dereferenceable(16) %q, i64 16, i1 false), !tbaa !0
; CHECK-NEXT: store i8 2, i8* %s, align 1, !tbaa [[TAGA:!.*]]
; CHECK-NEXT: ret void
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 16, i1 false), !tbaa !2
Modified: llvm/trunk/test/CodeGen/X86/no-plt-libcalls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/no-plt-libcalls.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/no-plt-libcalls.ll (original)
+++ llvm/trunk/test/CodeGen/X86/no-plt-libcalls.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Check if "RtLibUseGOT" works correctly when lib calls are simplified.
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -5,10 +6,13 @@
@hello_world = constant [13 x i8] c"hello world\0A\00"
declare i32 @printf(i8*, ...)
define void @printf_call() {
+; CHECK-LABEL: @printf_call(
+; CHECK-NEXT: [[PUTS:%.*]] = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i64 0, i64 0))
+; CHECK-NEXT: ret void
+;
%fmt = getelementptr [4 x i8], [4 x i8]* @percent_s, i32 0, i32 0
%str = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt, i8* %str)
-; CHECK: call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i64 0, i64 0))
ret void
}
Modified: llvm/trunk/test/Other/cgscc-libcall-update.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/cgscc-libcall-update.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Other/cgscc-libcall-update.ll (original)
+++ llvm/trunk/test/Other/cgscc-libcall-update.ll Tue Sep 17 02:32:52 2019
@@ -14,11 +14,12 @@ bb:
%tmp = alloca [1024 x i8], align 16
%tmp2 = getelementptr inbounds [1024 x i8], [1024 x i8]* %tmp, i64 0, i64 0
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp2, i8* %arg1, i64 1024, i1 false)
-; CHECK: call void @llvm.memcpy
+; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 16 dereferenceable(1024)
%tmp3 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp2, i1 false, i1 true, i1 false)
%tmp4 = call i8* @__strncpy_chk(i8* %arg2, i8* %tmp2, i64 1023, i64 %tmp3)
; CHECK-NOT: call
-; CHECK: call i8* @strncpy(i8* %arg2, i8* nonnull %tmp2, i64 1023)
+; CHECK: call i8* @strncpy(i8* nonnull dereferenceable(1) %arg2, i8* nonnull dereferenceable(1) %tmp2, i64 1023)
+
; CHECK-NOT: call
ret i8* %tmp4
@@ -27,6 +28,7 @@ bb:
define i8* @strncpy(i8* %arg1, i8* %arg2, i64 %size) noinline {
bb:
+; CHECK: call i8* @my_special_strncpy(i8* %arg1, i8* %arg2, i64 %size)
%result = call i8* @my_special_strncpy(i8* %arg1, i8* %arg2, i64 %size)
ret i8* %result
}
Modified: llvm/trunk/test/Transforms/InstCombine/ARM/strcmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/ARM/strcmp.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/ARM/strcmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/ARM/strcmp.ll Tue Sep 17 02:32:52 2019
@@ -67,7 +67,7 @@ define arm_aapcscc i32 @test4() {
define arm_aapcscc i32 @test5(i1 %b) {
; CHECK-LABEL: @test5(
; CHECK-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)
-; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* dereferenceable(5) [[STR2]], i32 5)
+; CHECK-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)
; CHECK-NEXT: ret i32 [[MEMCMP]]
;
@@ -145,7 +145,7 @@ define arm_aapcs_vfpcc i32 @test4_vfp()
define arm_aapcs_vfpcc i32 @test5_vfp(i1 %b) {
; CHECK-LABEL: @test5_vfp(
; CHECK-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)
-; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* dereferenceable(5) [[STR2]], i32 5)
+; CHECK-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)
; CHECK-NEXT: ret i32 [[MEMCMP]]
;
Modified: llvm/trunk/test/Transforms/InstCombine/align-addr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/align-addr.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/align-addr.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/align-addr.ll Tue Sep 17 02:32:52 2019
@@ -114,7 +114,7 @@ define void @test3(%struct.s* sret %a4)
; Check that the alignment is bumped up the alignment of the sret type.
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[A4_CAST:%.*]] = bitcast %struct.s* [[A4:%.*]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 dereferenceable(16) [[A4_CAST]], i8 0, i64 16, i1 false)
+; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 4 dereferenceable(16) [[A4_CAST]], i8 0, i64 16, i1 false)
; CHECK-NEXT: call void @use(i8* [[A4_CAST]])
; CHECK-NEXT: ret void
;
Modified: llvm/trunk/test/Transforms/InstCombine/fortify-folding.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fortify-folding.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fortify-folding.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fortify-folding.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s --dump-input-on-failure
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
@@ -9,9 +10,10 @@ target datalayout = "e-m:o-i64:64-f80:12
%struct.__va_list_tag = type { i32, i32, i8*, i8* }
define i8* @test_memccpy() {
- ; CHECK-LABEL: define i8* @test_memccpy
- ; CHECK-NEXT: 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: ret i8*
+; 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: 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)
@@ -19,9 +21,10 @@ define i8* @test_memccpy() {
}
define i8* @test_not_memccpy() {
- ; CHECK-LABEL: define i8* @test_not_memccpy
- ; CHECK-NEXT: call i8* @__memccpy_chk
- ; CHECK-NEXT: ret i8*
+; CHECK-LABEL: @test_not_memccpy(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @__memccpy_chk(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, i64 59)
+; CHECK-NEXT: ret i8* [[RET]]
+;
%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 59)
@@ -29,9 +32,10 @@ define i8* @test_not_memccpy() {
}
define i32 @test_snprintf() {
- ; CHECK-LABEL: define i32 @test_snprintf
- ; CHECK-NEXT: call i32 (i8*, i64, i8*, ...) @snprintf(i8* 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: ret i32
+; 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: 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)
@@ -39,10 +43,11 @@ define i32 @test_snprintf() {
}
define i32 @test_not_snprintf() {
- ; CHECK-LABEL: define i32 @test_not_snprintf
- ; CHECK-NEXT: call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk
- ; CHECK-NEXT: call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk
- ; CHECK-NEXT: ret i32
+; CHECK-LABEL: @test_not_snprintf(
+; CHECK-NEXT: [[RET:%.*]] = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 60, i32 0, i64 59, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
+; CHECK-NEXT: [[IGN:%.*]] = call i32 (i8*, i64, i32, i64, i8*, ...) @__snprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 60, i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
+; CHECK-NEXT: ret i32 [[RET]]
+;
%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 59, i8* %fmt)
@@ -51,9 +56,10 @@ define i32 @test_not_snprintf() {
}
define i32 @test_sprintf() {
- ; CHECK-LABEL: define i32 @test_sprintf
- ; CHECK-NEXT: call i32 (i8*, i8*, ...) @sprintf(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))
- ; CHECK-NEXT: ret i32
+; 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: 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)
@@ -61,10 +67,11 @@ define i32 @test_sprintf() {
}
define i32 @test_not_sprintf() {
- ; CHECK-LABEL: define i32 @test_not_sprintf
- ; CHECK-NEXT: call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk
- ; CHECK-NEXT: call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk
- ; CHECK-NEXT: ret i32
+; CHECK-LABEL: @test_not_sprintf(
+; CHECK-NEXT: [[RET:%.*]] = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 0, i64 59, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
+; CHECK-NEXT: [[IGNORED:%.*]] = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0))
+; CHECK-NEXT: ret i32 [[RET]]
+;
%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 59, i8* %fmt)
@@ -73,9 +80,10 @@ define i32 @test_not_sprintf() {
}
define i8* @test_strcat() {
- ; CHECK-LABEL: define i8* @test_strcat
- ; CHECK-NEXT: call i8* @strcat(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))
- ; CHECK-NEXT: ret i8*
+; 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: ret i8* [[STRCAT]]
+;
%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)
@@ -83,9 +91,10 @@ define i8* @test_strcat() {
}
define i8* @test_not_strcat() {
- ; CHECK-LABEL: define i8* @test_not_strcat
- ; CHECK-NEXT: call i8* @__strcat_chk
- ; CHECK-NEXT: ret i8*
+; CHECK-LABEL: @test_not_strcat(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @__strcat_chk(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 0)
+; CHECK-NEXT: ret i8* [[RET]]
+;
%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 0)
@@ -93,9 +102,10 @@ define i8* @test_not_strcat() {
}
define i64 @test_strlcat() {
- ; CHECK-LABEL: define i64 @test_strlcat
- ; CHECK-NEXT: 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: ret i64
+; 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: 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)
@@ -103,9 +113,10 @@ define i64 @test_strlcat() {
}
define i64 @test_not_strlcat() {
- ; CHECK-LABEL: define i64 @test_not_strlcat
- ; CHECK-NEXT: call i64 @__strlcat_chk
- ; CHECK-NEXT: ret i64
+; CHECK-LABEL: @test_not_strlcat(
+; CHECK-NEXT: [[RET:%.*]] = call i64 @__strlcat_chk(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, i64 0)
+; CHECK-NEXT: ret i64 [[RET]]
+;
%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 0)
@@ -113,9 +124,10 @@ define i64 @test_not_strlcat() {
}
define i8* @test_strncat() {
- ; CHECK-LABEL: define i8* @test_strncat
- ; CHECK-NEXT: call i8* @strncat(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: ret i8*
+; 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: ret i8* [[STRNCAT]]
+;
%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)
@@ -123,9 +135,10 @@ define i8* @test_strncat() {
}
define i8* @test_not_strncat() {
- ; CHECK-LABEL: define i8* @test_not_strncat
- ; CHECK-NEXT: call i8* @__strncat_chk(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, i64 3)
- ; CHECK-NEXT: ret i8*
+; CHECK-LABEL: @test_not_strncat(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @__strncat_chk(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, i64 3)
+; CHECK-NEXT: ret i8* [[RET]]
+;
%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 3)
@@ -133,9 +146,10 @@ define i8* @test_not_strncat() {
}
define i64 @test_strlcpy() {
- ; CHECK-LABEL: define i64 @test_strlcpy
- ; CHECK-NEXT: 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: ret i64
+; 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: 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)
@@ -143,9 +157,10 @@ define i64 @test_strlcpy() {
}
define i64 @test_not_strlcpy() {
- ; CHECK-LABEL: define i64 @test_not_strlcpy
- ; CHECK-NEXT: call i64 @__strlcpy_chk(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, i64 2)
- ; CHECK-NEXT: ret i64
+; CHECK-LABEL: @test_not_strlcpy(
+; CHECK-NEXT: [[RET:%.*]] = call i64 @__strlcpy_chk(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, i64 2)
+; CHECK-NEXT: ret i64 [[RET]]
+;
%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 2)
@@ -153,8 +168,10 @@ define i64 @test_not_strlcpy() {
}
define i32 @test_vsnprintf() {
- ; CHECK-LABEL: define i32 @test_vsnprintf
- ; CHECK-NEXT: 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-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: 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
@@ -163,9 +180,11 @@ define i32 @test_vsnprintf() {
}
define i32 @test_not_vsnprintf() {
- ; CHECK-LABEL: define i32 @test_not_vsnprintf
- ; CHECK-NEXT: call i32 @__vsnprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i32 0, i64 3, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
- ; CHECK-NEXT: call i32 @__vsnprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
+; CHECK-LABEL: @test_not_vsnprintf(
+; CHECK-NEXT: [[RET:%.*]] = call i32 @__vsnprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i32 0, i64 3, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
+; CHECK-NEXT: [[IGN:%.*]] = call i32 @__vsnprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i64 4, i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
+; CHECK-NEXT: ret i32 [[RET]]
+;
; 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
@@ -175,8 +194,10 @@ define i32 @test_not_vsnprintf() {
}
define i32 @test_vsprintf() {
- ; CHECK-LABEL: define i32 @test_vsprintf
- ; CHECK-NEXT: 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-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: 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
@@ -185,9 +206,11 @@ define i32 @test_vsprintf() {
}
define i32 @test_not_vsprintf() {
- ; CHECK-LABEL: define i32 @test_not_vsprintf
- ; CHECK-NEXT: call i32 @__vsprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 0, i64 3, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
- ; CHECK-NEXT: call i32 @__vsprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
+; CHECK-LABEL: @test_not_vsprintf(
+; CHECK-NEXT: [[RET:%.*]] = call i32 @__vsprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 0, i64 3, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
+; CHECK-NEXT: [[IGN:%.*]] = call i32 @__vsprintf_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i64 0, i64 0), i32 1, i64 -1, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i64 0, i64 0), %struct.__va_list_tag* null)
+; CHECK-NEXT: ret i32 [[RET]]
+;
; 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
Modified: llvm/trunk/test/Transforms/InstCombine/getelementptr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/getelementptr.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/getelementptr.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/getelementptr.ll Tue Sep 17 02:32:52 2019
@@ -491,7 +491,7 @@ bb10:
%tmp.0.reg2mem.0.rec = mul i32 %indvar, -1
%tmp12.rec = add i32 %tmp.0.reg2mem.0.rec, -1
%tmp12 = getelementptr inbounds %struct.x, %struct.x* %tmp45, i32 %tmp12.rec
- %tmp16 = call i32 (i8*, ...) @printf( i8* getelementptr ([12 x i8], [12 x i8]* @.str1, i32 0, i32 0), %struct.x* %tmp12 ) nounwind
+ %tmp16 = call i32 (i8*, ...) @printf( i8* nonnull dereferenceable(1) getelementptr ([12 x i8], [12 x i8]* @.str1, i32 0, i32 0), %struct.x* %tmp12 ) nounwind
%tmp84 = icmp eq %struct.x* %tmp12, %orientations62
%indvar.next = add i32 %indvar, 1
br i1 %tmp84, label %bb17, label %bb10
@@ -652,7 +652,7 @@ define i32 @test35() nounwind {
i8* getelementptr (%t1, %t1* bitcast (%t0* @s to %t1*), i32 0, i32 1, i32 0)) nounwind
ret i32 0
; CHECK-LABEL: @test35(
-; CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @"\01LC8", i64 0, i64 0), i8* getelementptr inbounds (%t0, %t0* @s, i64 0, i32 1, i64 0)) [[$NUW:#[0-9]+]]
+; CHECK: call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([17 x i8], [17 x i8]* @"\01LC8", i64 0, i64 0), i8* getelementptr inbounds (%t0, %t0* @s, i64 0, i32 1, i64 0)) [[$NUW:#[0-9]+]]
}
; Don't treat signed offsets as unsigned.
Modified: llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll Tue Sep 17 02:32:52 2019
@@ -72,8 +72,8 @@ define void @test5(i8* %ptr, i8** %esc)
; CHECK-NEXT: [[E:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700)
; CHECK-NEXT: [[F:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700)
; CHECK-NEXT: [[G:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700)
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(32) [[PTR:%.*]], i8* align 1 dereferenceable(32) [[A]], i32 32, i1 false)
-; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* align 1 dereferenceable(32) [[PTR]], i8* align 1 dereferenceable(32) [[B]], i32 32, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(32) [[PTR:%.*]], i8* nonnull align 1 dereferenceable(32) [[A]], i32 32, i1 false)
+; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(32) [[PTR]], i8* nonnull align 1 dereferenceable(32) [[B]], i32 32, i1 false)
; CHECK-NEXT: store i8* [[C]], i8** [[ESC:%.*]], align 8
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[D]], i8* [[PTR]], i32 32, i1 true)
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* [[E]], i8* [[PTR]], i32 32, i1 true)
Modified: llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes-addrspaces.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes-addrspaces.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes-addrspaces.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes-addrspaces.ll Tue Sep 17 02:32:52 2019
@@ -3,11 +3,20 @@
declare i32 @memcmp(i8 addrspace(1)* nocapture, i8* nocapture, i64)
-define i32 @memcmp_const_size_update_deref8(i8 addrspace(1)* nocapture readonly %d, i8* nocapture readonly %s) {
-; CHECK-LABEL: @memcmp_const_size_update_deref8(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8 addrspace(1)* dereferenceable(16) dereferenceable_or_null(40) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16)
+define i32 @memcmp_const_size_update_deref(i8 addrspace(1)* nocapture readonly %d, i8* nocapture readonly %s) {
+; CHECK-LABEL: @memcmp_const_size_update_deref(
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8 addrspace(1)* dereferenceable(16) dereferenceable_or_null(40) [[D:%.*]], i8* nonnull dereferenceable(16) [[S:%.*]], i64 16)
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = tail call i32 @memcmp(i8 addrspace(1)* dereferenceable_or_null(40) %d, i8* %s, i64 16)
ret i32 %call
}
+
+define i32 @memcmp_nonconst_size_nonnnull(i8 addrspace(1)* nocapture readonly %d, i8* nocapture readonly %s, i64 %n) {
+; CHECK-LABEL: @memcmp_nonconst_size_nonnnull(
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8 addrspace(1)* nonnull dereferenceable_or_null(40) [[D:%.*]], i8* nonnull [[S:%.*]], i64 [[N:%.*]])
+; CHECK-NEXT: ret i32 [[CALL]]
+;
+ %call = tail call i32 @memcmp(i8 addrspace(1)* nonnull dereferenceable_or_null(40) %d, i8* nonnull %s, i64 %n)
+ ret i32 %call
+}
Modified: llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes.ll Tue Sep 17 02:32:52 2019
@@ -12,7 +12,7 @@ declare void @llvm.memset.p0i8.i64(i8* n
define i32 @memcmp_const_size_set_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @memcmp_const_size_set_deref(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(16) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16)
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(16) [[D:%.*]], i8* nonnull dereferenceable(16) [[S:%.*]], i64 16)
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = tail call i32 @memcmp(i8* %d, i8* %s, i64 16)
@@ -21,7 +21,7 @@ define i32 @memcmp_const_size_set_deref(
define i32 @memcmp_const_size_update_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @memcmp_const_size_update_deref(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(16) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16)
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(16) [[D:%.*]], i8* nonnull dereferenceable(16) [[S:%.*]], i64 16)
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = tail call i32 @memcmp(i8* dereferenceable(4) %d, i8* dereferenceable(8) %s, i64 16)
@@ -30,7 +30,7 @@ define i32 @memcmp_const_size_update_der
define i32 @memcmp_const_size_update_deref2(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @memcmp_const_size_update_deref2(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(16) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16)
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(16) [[D:%.*]], i8* nonnull dereferenceable(16) [[S:%.*]], i64 16)
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = tail call i32 @memcmp(i8* %d, i8* dereferenceable_or_null(8) %s, i64 16)
@@ -39,7 +39,7 @@ define i32 @memcmp_const_size_update_der
define i32 @memcmp_const_size_update_deref3(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @memcmp_const_size_update_deref3(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(40) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16)
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(40) [[D:%.*]], i8* nonnull dereferenceable(16) [[S:%.*]], i64 16)
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = tail call i32 @memcmp(i8* dereferenceable(40) %d, i8* %s, i64 16)
@@ -48,7 +48,7 @@ define i32 @memcmp_const_size_update_der
define i32 @memcmp_const_size_update_deref4(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @memcmp_const_size_update_deref4(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(16) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16)
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(16) [[D:%.*]], i8* nonnull dereferenceable(16) [[S:%.*]], i64 16)
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = tail call i32 @memcmp(i8* dereferenceable_or_null(16) %d, i8* %s, i64 16)
@@ -57,7 +57,7 @@ define i32 @memcmp_const_size_update_der
define i32 @memcmp_const_size_update_deref5(i8* nocapture readonly %d, i8* nocapture readonly %s) "null-pointer-is-valid"="false" {
; CHECK-LABEL: @memcmp_const_size_update_deref5(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(40) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16)
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(40) [[D:%.*]], i8* nonnull dereferenceable(16) [[S:%.*]], i64 16)
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = tail call i32 @memcmp(i8* dereferenceable_or_null(40) %d, i8* %s, i64 16)
@@ -73,9 +73,18 @@ define i32 @memcmp_const_size_update_der
ret i32 %call
}
+define i32 @memcmp_const_size_update_deref7(i8* nocapture readonly %d, i8* nocapture readonly %s) "null-pointer-is-valid"="true" {
+; CHECK-LABEL: @memcmp_const_size_update_deref7(
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(40) [[D:%.*]], i8* dereferenceable(16) [[S:%.*]], i64 16)
+; CHECK-NEXT: ret i32 [[CALL]]
+;
+ %call = tail call i32 @memcmp(i8* nonnull dereferenceable_or_null(40) %d, i8* %s, i64 16)
+ ret i32 %call
+}
+
define i32 @memcmp_const_size_no_update_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @memcmp_const_size_no_update_deref(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(40) [[D:%.*]], i8* dereferenceable(20) [[S:%.*]], i64 16)
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(40) [[D:%.*]], i8* nonnull dereferenceable(20) [[S:%.*]], i64 16)
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = tail call i32 @memcmp(i8* dereferenceable(40) %d, i8* dereferenceable(20) %s, i64 16)
@@ -93,7 +102,7 @@ define i32 @memcmp_nonconst_size(i8* noc
define i8* @memcpy_const_size_set_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @memcpy_const_size_set_deref(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 dereferenceable(64) [[D:%.*]], i8* align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(64) [[D:%.*]], i8* nonnull align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false)
; CHECK-NEXT: ret i8* [[D]]
;
%call = tail call i8* @memcpy(i8* %d, i8* %s, i64 64)
@@ -102,7 +111,7 @@ define i8* @memcpy_const_size_set_deref(
define i8* @memmove_const_size_set_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @memmove_const_size_set_deref(
-; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* align 1 dereferenceable(64) [[D:%.*]], i8* align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false)
+; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(64) [[D:%.*]], i8* nonnull align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false)
; CHECK-NEXT: ret i8* [[D]]
;
%call = tail call i8* @memmove(i8* %d, i8* %s, i64 64)
@@ -111,7 +120,7 @@ define i8* @memmove_const_size_set_deref
define i8* @memset_const_size_set_deref(i8* nocapture readonly %s, i8 %c) {
; CHECK-LABEL: @memset_const_size_set_deref(
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 dereferenceable(64) [[S:%.*]], i8 [[C:%.*]], i64 64, i1 false)
+; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 1 dereferenceable(64) [[S:%.*]], i8 [[C:%.*]], i64 64, i1 false)
; CHECK-NEXT: ret i8* [[S]]
;
%call = tail call i8* @memset(i8* %s, i8 %c, i64 64)
@@ -120,7 +129,7 @@ define i8* @memset_const_size_set_deref(
define i8* @memchr_const_size_set_deref(i8* nocapture readonly %s, i32 %c) {
; CHECK-LABEL: @memchr_const_size_set_deref(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @memchr(i8* dereferenceable(64) [[S:%.*]], i32 [[C:%.*]], i64 64)
+; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @memchr(i8* nonnull dereferenceable(64) [[S:%.*]], i32 [[C:%.*]], i64 64)
; CHECK-NEXT: ret i8* [[CALL]]
;
%call = tail call i8* @memchr(i8* %s, i32 %c, i64 64)
@@ -129,7 +138,7 @@ define i8* @memchr_const_size_set_deref(
define i8* @llvm_memcpy_const_size_set_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @llvm_memcpy_const_size_set_deref(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 dereferenceable(16) [[D:%.*]], i8* align 1 dereferenceable(16) [[S:%.*]], i64 16, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(16) [[D:%.*]], i8* nonnull align 1 dereferenceable(16) [[S:%.*]], i64 16, i1 false)
; CHECK-NEXT: ret i8* [[D]]
;
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %d, i8* align 1 %s, i64 16, i1 false)
@@ -138,7 +147,7 @@ define i8* @llvm_memcpy_const_size_set_d
define i8* @llvm_memmove_const_size_set_deref(i8* nocapture readonly %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @llvm_memmove_const_size_set_deref(
-; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* align 1 dereferenceable(16) [[D:%.*]], i8* align 1 dereferenceable(16) [[S:%.*]], i64 16, i1 false)
+; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(16) [[D:%.*]], i8* nonnull align 1 dereferenceable(16) [[S:%.*]], i64 16, i1 false)
; CHECK-NEXT: ret i8* [[D]]
;
call void @llvm.memmove.p0i8.p0i8.i64(i8* align 1 %d, i8* align 1 %s, i64 16, i1 false)
@@ -146,7 +155,7 @@ define i8* @llvm_memmove_const_size_set_
}
define i8* @llvm_memset_const_size_set_deref(i8* nocapture readonly %s, i8 %c) {
; CHECK-LABEL: @llvm_memset_const_size_set_deref(
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 dereferenceable(16) [[S:%.*]], i8 [[C:%.*]], i64 16, i1 false)
+; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 1 dereferenceable(16) [[S:%.*]], i8 [[C:%.*]], i64 16, i1 false)
; CHECK-NEXT: ret i8* [[S]]
;
call void @llvm.memset.p0i8.i64(i8* align 1 %s, i8 %c, i64 16, i1 false)
Modified: llvm/trunk/test/Transforms/InstCombine/memchr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memchr.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memchr.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memchr.ll Tue Sep 17 02:32:52 2019
@@ -50,7 +50,7 @@ define void @test3() {
define void @test4(i32 %chr) {
; CHECK-LABEL: @test4(
-; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* dereferenceable(14) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]], i32 14)
+; CHECK-NEXT: [[DST:%.*]] = 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: store i8* [[DST]], i8** @chp, align 4
; CHECK-NEXT: ret void
;
@@ -148,7 +148,7 @@ define i1 @test11(i32 %C) {
; No 64 bits here
define i1 @test12(i32 %C) {
; CHECK-LABEL: @test12(
-; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* dereferenceable(3) getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i32 0, i32 0), i32 [[C:%.*]], i32 3)
+; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* nonnull dereferenceable(3) getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i32 0, i32 0), i32 [[C:%.*]], i32 3)
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[DST]], null
; CHECK-NEXT: ret i1 [[CMP]]
;
@@ -185,7 +185,7 @@ define i1 @test14(i32 %C) {
define i1 @test15(i32 %C) {
; CHECK-LABEL: @test15(
-; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* dereferenceable(3) getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i32 0, i32 0), i32 [[C:%.*]], i32 3)
+; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* nonnull dereferenceable(3) getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i32 0, i32 0), i32 [[C:%.*]], i32 3)
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[DST]], null
; CHECK-NEXT: ret i1 [[CMP]]
;
@@ -202,3 +202,43 @@ define i8* @pr32124() {
%res = tail call i8* @memchr(i8* getelementptr ([1 x i8], [1 x i8]* @s, i64 0, i64 0), i32 0, i32 1)
ret i8* %res
}
+
+define i8* @test16(i8* %str, i32 %c, i32 %n) {
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @memchr(i8* %str, i32 %c, i32 %n)
+ ret i8* %ret
+}
+
+define i8* @test17(i8* %str, i32 %c, i32 %n) {
+; CHECK-LABEL: @test17(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* nonnull [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @memchr(i8* nonnull %str, i32 %c, i32 %n)
+ ret i8* %ret
+}
+
+define i8* @test18(i8* %str, i32 %c) {
+; CHECK-LABEL: @test18(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* nonnull dereferenceable(5) [[STR:%.*]], i32 [[C:%.*]], i32 5)
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @memchr(i8* %str, i32 %c, i32 5)
+ ret i8* %ret
+}
+
+define i8* @test19(i8* %str, i32 %c) "null-pointer-is-valid"="true" {
+; CHECK-LABEL: @test19(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* dereferenceable(5) [[STR:%.*]], i32 [[C:%.*]], i32 5)
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @memchr(i8* %str, i32 %c, i32 5)
+ ret i8* %ret
+}
Modified: llvm/trunk/test/Transforms/InstCombine/memcmp-constant-fold.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memcmp-constant-fold.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memcmp-constant-fold.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memcmp-constant-fold.ll Tue Sep 17 02:32:52 2019
@@ -55,7 +55,7 @@ define i1 @memcmp_4bytes_unaligned_const
define i1 @memcmp_3bytes_aligned_constant_i32(i8* align 4 %x) {
; ALL-LABEL: @memcmp_3bytes_aligned_constant_i32(
-; ALL-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(3) bitcast (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @intbuf, i64 0, i64 1) to i8*), i8* dereferenceable(3) bitcast ([2 x i32]* @intbuf to i8*), i64 3)
+; ALL-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(3) bitcast (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @intbuf, i64 0, i64 1) to i8*), i8* nonnull dereferenceable(3) bitcast ([2 x i32]* @intbuf to i8*), i64 3)
; ALL-NEXT: [[CMPEQ0:%.*]] = icmp eq i32 [[CALL]], 0
; ALL-NEXT: ret i1 [[CMPEQ0]]
;
@@ -68,7 +68,7 @@ define i1 @memcmp_3bytes_aligned_constan
define i1 @memcmp_4bytes_one_unaligned_i8(i8* align 4 %x, i8* align 1 %y) {
; ALL-LABEL: @memcmp_4bytes_one_unaligned_i8(
-; ALL-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* dereferenceable(4) [[X:%.*]], i8* dereferenceable(4) [[Y:%.*]], i64 4)
+; ALL-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* nonnull dereferenceable(4) [[X:%.*]], i8* nonnull dereferenceable(4) [[Y:%.*]], i64 4)
; ALL-NEXT: [[CMPEQ0:%.*]] = icmp eq i32 [[CALL]], 0
; ALL-NEXT: ret i1 [[CMPEQ0]]
;
Modified: llvm/trunk/test/Transforms/InstCombine/memcpy-from-global.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memcpy-from-global.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memcpy-from-global.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memcpy-from-global.ll Tue Sep 17 02:32:52 2019
@@ -78,7 +78,7 @@ define void @test2() {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[B1:%.*]] = alloca [124 x i8], align 8
; CHECK-NEXT: [[B1_SUB:%.*]] = getelementptr inbounds [124 x i8], [124 x i8]* [[B1]], i64 0, i64 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 dereferenceable(124) [[B1_SUB]], i8* align 16 dereferenceable(124) getelementptr inbounds (%T, %T* @G, i64 0, i32 0), i64 124, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 dereferenceable(124) [[B1_SUB]], i8* nonnull align 16 dereferenceable(124) getelementptr inbounds (%T, %T* @G, i64 0, i32 0), i64 124, i1 false)
; CHECK-NEXT: call void @bar(i8* nonnull [[B1_SUB]])
; CHECK-NEXT: ret void
;
@@ -234,7 +234,7 @@ define void @test8() {
; CHECK-LABEL: @test8(
; CHECK-NEXT: [[AL:%.*]] = alloca [[U:%.*]], align 16
; CHECK-NEXT: [[A:%.*]] = bitcast %U* [[AL]] to i8*
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 16 dereferenceable(20) [[A]], i8* align 4 dereferenceable(20) bitcast (%U* getelementptr inbounds ([2 x %U], [2 x %U]* @H, i64 0, i64 1) to i8*), i64 20, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 16 dereferenceable(20) [[A]], i8* nonnull align 4 dereferenceable(20) bitcast (%U* getelementptr inbounds ([2 x %U], [2 x %U]* @H, i64 0, i64 1) to i8*), i64 20, i1 false)
; CHECK-NEXT: call void @bar(i8* nonnull [[A]]) #2
; CHECK-NEXT: ret void
;
@@ -294,8 +294,8 @@ define void @test9_small_global() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CC:%.*]] = alloca [1000000 x i8], align 16
; CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [1000000 x i8], [1000000 x i8]* [[CC]], i64 0, i64 0
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 16 dereferenceable(3) [[ARRAYDECAY]], i8* align 16 dereferenceable(3) getelementptr inbounds ([3 x i8], [3 x i8]* @_ZL3KKK, i64 0, i64 0), i64 3, i1 false)
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 dereferenceable(1000000) getelementptr inbounds ([1000000 x i8], [1000000 x i8]* @bbb, i64 0, i64 0), i8* nonnull align 16 dereferenceable(1000000) [[ARRAYDECAY]], i64 1000000, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 16 dereferenceable(3) [[ARRAYDECAY]], i8* nonnull align 16 dereferenceable(3) getelementptr inbounds ([3 x i8], [3 x i8]* @_ZL3KKK, i64 0, i64 0), i64 3, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 16 dereferenceable(1000000) getelementptr inbounds ([1000000 x i8], [1000000 x i8]* @bbb, i64 0, i64 0), i8* nonnull align 16 dereferenceable(1000000) [[ARRAYDECAY]], i64 1000000, i1 false)
; CHECK-NEXT: ret void
;
entry:
@@ -311,7 +311,7 @@ entry:
define void @test10_same_global() {
; CHECK-LABEL: @test10_same_global(
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 dereferenceable(3) getelementptr inbounds ([1000000 x i8], [1000000 x i8]* @bbb, i64 0, i64 0), i8* align 16 dereferenceable(3) getelementptr inbounds ([3 x i8], [3 x i8]* @_ZL3KKK, i64 0, i64 0), i64 3, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 16 dereferenceable(3) getelementptr inbounds ([1000000 x i8], [1000000 x i8]* @bbb, i64 0, i64 0), i8* nonnull align 16 dereferenceable(3) getelementptr inbounds ([3 x i8], [3 x i8]* @_ZL3KKK, i64 0, i64 0), i64 3, i1 false)
; CHECK-NEXT: ret void
;
entry:
Modified: llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll Tue Sep 17 02:32:52 2019
@@ -34,7 +34,7 @@ define void @copy_2_bytes(i8* %d, i8* %s
define void @copy_3_bytes(i8* %d, i8* %s) {
; ALL-LABEL: @copy_3_bytes(
-; ALL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(3) [[D:%.*]], i8* align 1 dereferenceable(3) [[S:%.*]], i32 3, i1 false)
+; ALL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(3) [[D:%.*]], i8* nonnull align 1 dereferenceable(3) [[S:%.*]], i32 3, i1 false)
; ALL-NEXT: ret void
;
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %d, i8* %s, i32 3, i1 false)
@@ -57,7 +57,7 @@ define void @copy_4_bytes(i8* %d, i8* %s
define void @copy_5_bytes(i8* %d, i8* %s) {
; ALL-LABEL: @copy_5_bytes(
-; ALL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(5) [[D:%.*]], i8* align 1 dereferenceable(5) [[S:%.*]], i32 5, i1 false)
+; ALL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(5) [[D:%.*]], i8* nonnull align 1 dereferenceable(5) [[S:%.*]], i32 5, i1 false)
; ALL-NEXT: ret void
;
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %d, i8* %s, i32 5, i1 false)
@@ -78,7 +78,7 @@ define void @copy_8_bytes(i8* %d, i8* %s
define void @copy_16_bytes(i8* %d, i8* %s) {
; ALL-LABEL: @copy_16_bytes(
-; ALL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(16) [[D:%.*]], i8* align 1 dereferenceable(16) [[S:%.*]], i32 16, i1 false)
+; ALL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(16) [[D:%.*]], i8* nonnull align 1 dereferenceable(16) [[S:%.*]], i32 16, i1 false)
; ALL-NEXT: ret void
;
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %d, i8* %s, i32 16, i1 false)
Modified: llvm/trunk/test/Transforms/InstCombine/memcpy.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memcpy.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memcpy.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memcpy.ll Tue Sep 17 02:32:52 2019
@@ -29,7 +29,7 @@ define void @test2(i8* %a) {
define void @test3(i8* %d, i8* %s) {
; CHECK-LABEL: @test3(
-; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 dereferenceable(17179869184) [[D:%.*]], i8* align 4 dereferenceable(17179869184) [[S:%.*]], i64 17179869184, i1 false)
+; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(17179869184) [[D:%.*]], i8* nonnull align 4 dereferenceable(17179869184) [[S:%.*]], i64 17179869184, i1 false)
; CHECK-NEXT: ret void
;
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %d, i8* align 4 %s, i64 17179869184, i1 false)
Modified: llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll Tue Sep 17 02:32:52 2019
@@ -18,7 +18,7 @@ target datalayout = "e-p:64:64:64-i1:8:8
define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* 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)
; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
;
%dst = bitcast %struct.T1* @t1 to i8*
@@ -29,7 +29,7 @@ define i8* @test_simplify1() {
define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* 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)
; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
;
%dst = bitcast %struct.T1* @t1 to i8*
@@ -65,7 +65,7 @@ define i8* @test_no_simplify2() {
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* align 1 dereferenceable(1824) [[DST]], i8* 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)
; CHECK-NEXT: ret i8* [[DST]]
;
%src = bitcast %struct.T2* @t2 to i8*
Modified: llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll Tue Sep 17 02:32:52 2019
@@ -18,7 +18,7 @@ target datalayout = "e-p:64:64:64-i1:8:8
define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* 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)
; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
;
%dst = bitcast %struct.T1* @t1 to i8*
@@ -30,7 +30,7 @@ define i8* @test_simplify1() {
define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
-; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* 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)
; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
;
%dst = bitcast %struct.T1* @t1 to i8*
Modified: llvm/trunk/test/Transforms/InstCombine/mempcpy.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/mempcpy.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/mempcpy.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/mempcpy.ll Tue Sep 17 02:32:52 2019
@@ -45,7 +45,7 @@ define i8* @memcpy_small_const_n(i8* %d,
define i8* @memcpy_big_const_n(i8* %d, i8* nocapture readonly %s) {
; CHECK-LABEL: @memcpy_big_const_n(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 dereferenceable(1024) [[D:%.*]], i8* align 1 dereferenceable(1024) [[S:%.*]], i64 1024, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(1024) [[D:%.*]], i8* nonnull align 1 dereferenceable(1024) [[S:%.*]], i64 1024, i1 false)
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[D]], i64 1024
; CHECK-NEXT: ret i8* [[TMP1]]
;
Added: llvm/trunk/test/Transforms/InstCombine/memrchr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memrchr.ll?rev=372091&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memrchr.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/memrchr.ll Tue Sep 17 02:32:52 2019
@@ -0,0 +1,55 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+
+declare i8* @memrchr(i8*, i32, i32)
+
+define i8* @test1(i8* %str, i32 %c, i32 %n) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @memrchr(i8* %str, i32 %c, i32 %n)
+ ret i8* %ret
+}
+
+define i8* @test2(i8* %str, i32 %c, i32 %n) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* nonnull [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @memrchr(i8* nonnull %str, i32 %c, i32 %n)
+ ret i8* %ret
+}
+
+define i8* @test3(i8* %str, i32 %c) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* [[STR:%.*]], i32 [[C:%.*]], i32 5)
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @memrchr(i8* %str, i32 %c, i32 5)
+ ret i8* %ret
+}
+
+define i8* @test4(i8* %str, i32 %c) "null-pointer-is-valid"="true" {
+; CHECK-LABEL: @test4(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* [[STR:%.*]], i32 [[C:%.*]], i32 5)
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @memrchr(i8* %str, i32 %c, i32 5)
+ ret i8* %ret
+}
+
+define i8* @test5(i8* %str, i32 %c) {
+; CHECK-LABEL: @test5(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* [[STR:%.*]], i32 [[C:%.*]], i32 0)
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @memrchr(i8* %str, i32 %c, i32 0)
+ ret i8* %ret
+}
Modified: llvm/trunk/test/Transforms/InstCombine/memset-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memset-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memset-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memset-1.ll Tue Sep 17 02:32:52 2019
@@ -49,7 +49,7 @@ define i8* @malloc_and_memset_intrinsic(
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)
+; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[CALL1]], i8 0, i32 [[SIZE]], i1 false) #0
; CHECK-NEXT: ret i8* [[CALL1]]
;
%call1 = call i8* %notmalloc(i32 %size) #1
@@ -68,7 +68,7 @@ define float* @pr25892(i32 %size) #0 {
; 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)
+; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[CALL]], i8 0, i32 [[SIZE]], i1 false) #0
; CHECK-NEXT: br label [[CLEANUP]]
; CHECK: cleanup:
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi float* [ [[BC]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ]
@@ -93,7 +93,7 @@ define i8* @buffer_is_modified_then_mems
; 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* align 1 [[PTR]], i8 0, i32 [[SIZE]], i1 false)
+; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[PTR]], i8 0, i32 [[SIZE]], i1 false) #0
; CHECK-NEXT: ret i8* [[PTR]]
;
%ptr = tail call i8* @malloc(i32 %size) #1
@@ -102,6 +102,103 @@ define i8* @buffer_is_modified_then_mems
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: ret i8* [[PTR]]
+;
+ %size = select i1 %b, i32 10, i32 50
+ %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1
+ ret i8* %memset
+}
+
+
+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: 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
+ 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: 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)
+ 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: 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
+ 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: ret i8* [[PTR]]
+;
+ %size = ashr i32 -2, %v
+ %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1
+ 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: ret i8* [[PTR]]
+;
+ %memset = tail call i8* @memset(i8* dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1
+ ret i8* %memset
+}
+
+; be sure to drop nonnull since size is unknown and can be 0
+; 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: ret i8* [[PTR]]
+;
+ %memset = tail call i8* @memset(i8* nonnull dereferenceable(40) %ptr, i32 0, i32 %size) #1
+ 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: ret i8* [[PTR]]
+;
+ %memset = tail call i8* @memset(i8* nonnull dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1
+ 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: ret i8* [[PTR]]
+;
+ %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1
+ ret i8* %memset
+}
+
+
attributes #0 = { nounwind ssp uwtable }
attributes #1 = { nounwind }
attributes #2 = { nounwind readnone }
Modified: llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll Tue Sep 17 02:32:52 2019
@@ -14,7 +14,7 @@ target datalayout = "e-p:64:64:64-i1:8:8
define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* 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)
; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
;
%dst = bitcast %struct.T* @t to i8*
@@ -25,7 +25,7 @@ define i8* @test_simplify1() {
define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* 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)
; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
;
%dst = bitcast %struct.T* @t to i8*
@@ -36,7 +36,7 @@ define i8* @test_simplify2() {
define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* 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)
; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
;
%dst = bitcast %struct.T* @t to i8*
@@ -73,11 +73,11 @@ define i8* @test_no_simplify2() {
define i32 @test_rauw(i8* %a, i8* %b, i8** %c) {
; CHECK-LABEL: @test_rauw(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL49:%.*]] = call i64 @strlen(i8* [[A:%.*]])
+; CHECK-NEXT: [[CALL49:%.*]] = call i64 @strlen(i8* nonnull dereferenceable(1) [[A:%.*]])
; 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* [[B]])
+; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(i8* nonnull dereferenceable(1) [[B]])
; CHECK-NEXT: [[STRCHR2:%.*]] = getelementptr i8, i8* [[B]], i64 [[STRLEN]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8** [[C:%.*]] to i64*
; CHECK-NEXT: [[D1:%.*]] = load i64, i64* [[TMP0]], align 8
Modified: llvm/trunk/test/Transforms/InstCombine/objsize.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/objsize.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/objsize.ll Tue Sep 17 02:32:52 2019
@@ -163,7 +163,7 @@ define i8* @test5(i32 %n) nounwind ssp {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = tail call noalias dereferenceable_or_null(20) i8* @malloc(i32 20) #0
; CHECK-NEXT: [[TMP1:%.*]] = load i8*, i8** @s, align 8
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(10) [[TMP0]], i8* align 1 dereferenceable(10) [[TMP1]], i32 10, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(10) [[TMP0]], i8* nonnull align 1 dereferenceable(10) [[TMP1]], i32 10, i1 false)
; CHECK-NEXT: ret i8* [[TMP0]]
;
entry:
Modified: llvm/trunk/test/Transforms/InstCombine/printf-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/printf-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/printf-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/printf-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the printf library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -22,110 +23,164 @@ declare i32 @printf(i8*, ...)
define void @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
+; CHECK-NEXT: ret void
+;
+; CHECK-IPRINTF-LABEL: @test_simplify1(
+; CHECK-IPRINTF-NEXT: ret void
+;
%fmt = getelementptr [1 x i8], [1 x i8]* @empty, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt)
ret void
-; CHECK-NEXT: ret void
}
; Check printf("x") -> putchar('x'), even for '%'.
define void @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
+; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 104)
+; CHECK-NEXT: ret void
+;
+; CHECK-IPRINTF-LABEL: @test_simplify2(
+; CHECK-IPRINTF-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 104)
+; CHECK-IPRINTF-NEXT: ret void
+;
%fmt = getelementptr [2 x i8], [2 x i8]* @h, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt)
-; CHECK-NEXT: call i32 @putchar(i32 104)
ret void
-; CHECK-NEXT: ret void
}
; Special case: printf("%%") -> putchar('%').
define void @test_simplify2b() {
; CHECK-LABEL: @test_simplify2b(
+; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 37)
+; CHECK-NEXT: ret void
+;
+; CHECK-IPRINTF-LABEL: @test_simplify2b(
+; CHECK-IPRINTF-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 37)
+; CHECK-IPRINTF-NEXT: ret void
+;
%fmt = getelementptr [3 x i8], [3 x i8]* @h2, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt)
-; CHECK-NEXT: call i32 @putchar(i32 37)
ret void
-; CHECK-NEXT: ret void
}
define void @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
+; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 37)
+; CHECK-NEXT: ret void
+;
+; CHECK-IPRINTF-LABEL: @test_simplify3(
+; CHECK-IPRINTF-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 37)
+; CHECK-IPRINTF-NEXT: ret void
+;
%fmt = getelementptr [2 x i8], [2 x i8]* @percent, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt)
-; CHECK-NEXT: call i32 @putchar(i32 37)
ret void
-; CHECK-NEXT: ret void
}
; Check printf("foo\n") -> puts("foo").
define void @test_simplify4() {
; CHECK-LABEL: @test_simplify4(
+; CHECK-NEXT: [[PUTS:%.*]] = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @str, i32 0, i32 0))
+; CHECK-NEXT: ret void
+;
+; CHECK-IPRINTF-LABEL: @test_simplify4(
+; CHECK-IPRINTF-NEXT: [[PUTS:%.*]] = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @str, i32 0, i32 0))
+; CHECK-IPRINTF-NEXT: ret void
+;
%fmt = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt)
-; CHECK-NEXT: call i32 @puts(i8* getelementptr inbounds ([12 x i8], [12 x i8]* [[$STR]], i32 0, i32 0))
ret void
-; CHECK-NEXT: ret void
}
; Check printf("%c", chr) -> putchar(chr).
define void @test_simplify5() {
; CHECK-LABEL: @test_simplify5(
+; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 104)
+; CHECK-NEXT: ret void
+;
+; CHECK-IPRINTF-LABEL: @test_simplify5(
+; CHECK-IPRINTF-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 104)
+; CHECK-IPRINTF-NEXT: ret void
+;
%fmt = getelementptr [3 x i8], [3 x i8]* @percent_c, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt, i8 104)
-; CHECK-NEXT: call i32 @putchar(i32 104)
ret void
-; CHECK-NEXT: ret void
}
; Check printf("%s\n", str) -> puts(str).
define void @test_simplify6() {
; CHECK-LABEL: @test_simplify6(
+; CHECK-NEXT: [[PUTS:%.*]] = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0))
+; CHECK-NEXT: ret void
+;
+; CHECK-IPRINTF-LABEL: @test_simplify6(
+; CHECK-IPRINTF-NEXT: [[PUTS:%.*]] = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0))
+; CHECK-IPRINTF-NEXT: ret void
+;
%fmt = getelementptr [4 x i8], [4 x i8]* @percent_s, i32 0, i32 0
%str = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt, i8* %str)
-; CHECK-NEXT: call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0))
ret void
-; CHECK-NEXT: ret void
}
; Check printf(format, ...) -> iprintf(format, ...) if no floating point.
define void @test_simplify7() {
+; CHECK-LABEL: @test_simplify7(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187)
+; CHECK-NEXT: ret void
+;
; CHECK-IPRINTF-LABEL: @test_simplify7(
+; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, ...) @iprintf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187)
+; CHECK-IPRINTF-NEXT: ret void
+;
%fmt = getelementptr [3 x i8], [3 x i8]* @percent_d, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt, i32 187)
-; CHECK-IPRINTF-NEXT: call i32 (i8*, ...) @iprintf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187)
ret void
-; CHECK-IPRINTF-NEXT: ret void
}
define void @test_no_simplify1() {
+; CHECK-LABEL: @test_no_simplify1(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
+; CHECK-NEXT: ret void
+;
; CHECK-IPRINTF-LABEL: @test_no_simplify1(
+; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
+; CHECK-IPRINTF-NEXT: ret void
+;
%fmt = getelementptr [3 x i8], [3 x i8]* @percent_f, i32 0, i32 0
call i32 (i8*, ...) @printf(i8* %fmt, double 1.87)
-; CHECK-IPRINTF-NEXT: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
ret void
-; CHECK-IPRINTF-NEXT: ret void
}
define void @test_no_simplify2(i8* %fmt, double %d) {
; CHECK-LABEL: @test_no_simplify2(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]])
+; CHECK-NEXT: ret void
+;
+; CHECK-IPRINTF-LABEL: @test_no_simplify2(
+; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]])
+; CHECK-IPRINTF-NEXT: ret void
+;
call i32 (i8*, ...) @printf(i8* %fmt, double %d)
-; CHECK-NEXT: call i32 (i8*, ...) @printf(i8* %fmt, double %d)
ret void
-; CHECK-NEXT: ret void
}
define i32 @test_no_simplify3() {
; CHECK-LABEL: @test_no_simplify3(
+; CHECK-NEXT: [[RET:%.*]] = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @h, i32 0, i32 0))
+; CHECK-NEXT: ret i32 [[RET]]
+;
+; CHECK-IPRINTF-LABEL: @test_no_simplify3(
+; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, ...) @iprintf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @h, i32 0, i32 0))
+; CHECK-IPRINTF-NEXT: ret i32 [[TMP1]]
+;
%fmt = getelementptr [2 x i8], [2 x i8]* @h, i32 0, i32 0
%ret = call i32 (i8*, ...) @printf(i8* %fmt)
-; CHECK-NEXT: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @h, i32 0, i32 0))
ret i32 %ret
-; CHECK-NEXT: ret i32 %ret
}
Modified: llvm/trunk/test/Transforms/InstCombine/printf-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/printf-2.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/printf-2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/printf-2.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the printf library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -16,38 +17,42 @@ declare void @printf(i8*, ...)
define void @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
+; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 104)
+; CHECK-NEXT: ret void
+;
%fmt = getelementptr [2 x i8], [2 x i8]* @h, i32 0, i32 0
call void (i8*, ...) @printf(i8* %fmt)
-; CHECK-NEXT: call i32 @putchar(i32 104)
ret void
-; CHECK-NEXT: ret void
}
define void @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
+; CHECK-NEXT: [[PUTS:%.*]] = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @str, i32 0, i32 0))
+; CHECK-NEXT: ret void
+;
%fmt = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0
call void (i8*, ...) @printf(i8* %fmt)
-; CHECK-NEXT: call i32 @puts(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @str, i32 0, i32 0))
ret void
-; CHECK-NEXT: ret void
}
define void @test_simplify6() {
; CHECK-LABEL: @test_simplify6(
+; CHECK-NEXT: [[PUTS:%.*]] = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0))
+; CHECK-NEXT: ret void
+;
%fmt = getelementptr [4 x i8], [4 x i8]* @percent_s, i32 0, i32 0
%str = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0
call void (i8*, ...) @printf(i8* %fmt, i8* %str)
-; CHECK-NEXT: call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0))
ret void
-; CHECK-NEXT: ret void
}
define void @test_simplify7() {
; CHECK-LABEL: @test_simplify7(
+; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 97)
+; CHECK-NEXT: ret void
+;
%fmt = getelementptr [3 x i8], [3 x i8]* @format_str, i32 0, i32 0
%str = getelementptr [2 x i8], [2 x i8]* @charstr, i32 0, i32 0
call void (i8*, ...) @printf(i8* %fmt, i8* %str)
-; CHECK-NEXT: call i32 @putchar(i32 97)
ret void
-; CHECK-NEXT: ret void
}
Modified: llvm/trunk/test/Transforms/InstCombine/puts-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/puts-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/puts-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/puts-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the puts library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -12,20 +13,22 @@ declare i32 @puts(i8*)
define void @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
+; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 10)
+; CHECK-NEXT: ret void
+;
%str = getelementptr [1 x i8], [1 x i8]* @empty, i32 0, i32 0
call i32 @puts(i8* %str)
-; CHECK-NEXT: call i32 @putchar(i32 10)
ret void
-; CHECK-NEXT: ret void
}
; Don't simplify if the return value is used.
define i32 @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
+; CHECK-NEXT: [[RET:%.*]] = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([1 x i8], [1 x i8]* @empty, i32 0, i32 0))
+; CHECK-NEXT: ret i32 [[RET]]
+;
%str = getelementptr [1 x i8], [1 x i8]* @empty, i32 0, i32 0
%ret = call i32 @puts(i8* %str)
-; CHECK-NEXT: call i32 @puts(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @empty, i32 0, i32 0))
ret i32 %ret
-; CHECK-NEXT: ret i32 %ret
}
Modified: llvm/trunk/test/Transforms/InstCombine/snprintf.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/snprintf.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/snprintf.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/snprintf.ll Tue Sep 17 02:32:52 2019
@@ -10,13 +10,14 @@ declare i32 @snprintf(i8*, i64, i8*, ...
define void @test_not_const_fmt(i8* %buf, i8* %fmt) #0 {
; CHECK-LABEL: @test_not_const_fmt(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 32, i8* [[FMT:%.*]])
+; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* nonnull dereferenceable(1) [[BUF:%.*]], i64 32, i8* [[FMT:%.*]])
; CHECK-NEXT: ret void
;
%call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* %fmt) #2
ret void
}
+; size is '0', do not add nonnull attribute
define void @test_not_const_fmt_zero_size_return_value(i8* %buf, i8* %fmt) #0 {
; CHECK-LABEL: @test_not_const_fmt_zero_size_return_value(
; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 0, i8* [[FMT:%.*]])
@@ -26,7 +27,6 @@ define void @test_not_const_fmt_zero_siz
ret void
}
-
define void @test_not_const_size(i8* %buf, i64 %size) #0 {
; CHECK-LABEL: @test_not_const_size(
; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 [[SIZE:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0))
@@ -47,7 +47,7 @@ define i32 @test_return_value(i8* %buf)
define void @test_percentage(i8* %buf) #0 {
; CHECK-LABEL: @test_percentage(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
+; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* nonnull dereferenceable(1) [[BUF:%.*]], i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
; CHECK-NEXT: ret void
;
%call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0)) #2
@@ -92,7 +92,7 @@ define i32 @test_char_zero_size(i8* %buf
define i32 @test_char_wrong_size(i8* %buf) #0 {
; CHECK-LABEL: @test_char_wrong_size(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65)
+; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* nonnull dereferenceable(1) [[BUF:%.*]], i64 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65)
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65) #2
@@ -120,7 +120,7 @@ define i32 @test_str_zero_size(i8* %buf)
define i32 @test_str_wrong_size(i8* %buf) #0 {
; CHECK-LABEL: @test_str_wrong_size(
-; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 1, 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))
+; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* nonnull dereferenceable(1) [[BUF:%.*]], i64 1, 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))
; CHECK-NEXT: ret i32 [[CALL]]
;
%call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 1, 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
Modified: llvm/trunk/test/Transforms/InstCombine/sprintf-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sprintf-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/sprintf-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/sprintf-1.ll Tue Sep 17 02:32:52 2019
@@ -21,11 +21,11 @@ declare i32 @sprintf(i8*, i8*, ...)
define void @test_simplify1(i8* %dst) {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(13) [[DST:%.*]], i8* 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)
; CHECK-NEXT: ret void
;
; CHECK-IPRINTF-LABEL: @test_simplify1(
-; CHECK-IPRINTF-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(13) [[DST:%.*]], i8* align 1 dereferenceable(13) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0), i32 13, i1 false)
+; CHECK-IPRINTF-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-IPRINTF-NEXT: ret void
;
%fmt = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0
@@ -85,13 +85,13 @@ define void @test_simplify4(i8* %dst) {
define void @test_simplify5(i8* %dst, i8* %str) {
; CHECK-LABEL: @test_simplify5(
-; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* [[STR:%.*]])
+; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]])
; CHECK-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false)
; CHECK-NEXT: ret void
;
; CHECK-IPRINTF-LABEL: @test_simplify5(
-; CHECK-IPRINTF-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* [[STR:%.*]])
+; CHECK-IPRINTF-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]])
; CHECK-IPRINTF-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1
; CHECK-IPRINTF-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false)
; CHECK-IPRINTF-NEXT: ret void
@@ -105,7 +105,7 @@ define void @test_simplify5(i8* %dst, i8
define void @test_simplify6(i8* %dst) {
; CHECK-LABEL: @test_simplify6(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* [[DST:%.*]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187)
+; CHECK-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)
; CHECK-NEXT: ret void
;
; CHECK-IPRINTF-LABEL: @test_simplify6(
@@ -119,11 +119,11 @@ define void @test_simplify6(i8* %dst) {
define void @test_no_simplify1(i8* %dst) {
; CHECK-LABEL: @test_no_simplify1(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* [[DST:%.*]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
+; CHECK-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_f, i32 0, i32 0), double 1.870000e+00)
; CHECK-NEXT: ret void
;
; CHECK-IPRINTF-LABEL: @test_no_simplify1(
-; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* [[DST:%.*]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
+; CHECK-IPRINTF-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_f, i32 0, i32 0), double 1.870000e+00)
; CHECK-IPRINTF-NEXT: ret void
;
%fmt = getelementptr [3 x i8], [3 x i8]* @percent_f, i32 0, i32 0
@@ -133,11 +133,11 @@ define void @test_no_simplify1(i8* %dst)
define void @test_no_simplify2(i8* %dst, i8* %fmt, double %d) {
; CHECK-LABEL: @test_no_simplify2(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* [[DST:%.*]], i8* [[FMT:%.*]], double [[D:%.*]])
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]])
; CHECK-NEXT: ret void
;
; CHECK-IPRINTF-LABEL: @test_no_simplify2(
-; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* [[DST:%.*]], i8* [[FMT:%.*]], double [[D:%.*]])
+; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]])
; CHECK-IPRINTF-NEXT: ret void
;
call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, double %d)
Modified: llvm/trunk/test/Transforms/InstCombine/stpcpy-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/stpcpy-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/stpcpy-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/stpcpy-1.ll Tue Sep 17 02:32:52 2019
@@ -14,7 +14,7 @@ declare i8* @stpcpy(i8*, i8*)
define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(6) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* 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)
; CHECK-NEXT: ret i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 5)
;
@@ -27,7 +27,7 @@ define i8* @test_simplify1() {
define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
-; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* 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))
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @a, i32 0, i32 [[STRLEN]]
; CHECK-NEXT: ret i8* [[TMP1]]
;
@@ -38,6 +38,18 @@ define i8* @test_simplify2() {
ret i8* %ret
}
+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: ret void
+;
+
+ %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0
+
+ call i8* @stpcpy(i8* dereferenceable(80) %dst, i8* %src)
+ ret void
+}
+
define i8* @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
; CHECK-NEXT: [[RET:%.*]] = call i8* @stpcpy(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([32 x i8], [32 x i8]* @b, i32 0, i32 0))
Modified: llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll Tue Sep 17 02:32:52 2019
@@ -14,7 +14,7 @@ target datalayout = "e-p:32:32:32-i1:8:8
define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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)
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
@@ -26,7 +26,7 @@ define i8* @test_simplify1() {
define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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)
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
@@ -38,7 +38,7 @@ define i8* @test_simplify2() {
define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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)
; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
@@ -82,7 +82,7 @@ define i8* @test_simplify5() {
define i8* @test_simplify6() {
; CHECK-LABEL: @test_simplify6(
-; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0))
+; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0))
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 [[STRLEN]]
; CHECK-NEXT: ret i8* [[TMP1]]
;
Modified: llvm/trunk/test/Transforms/InstCombine/strchr-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strchr-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strchr-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strchr-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strchr library call simplifier works correctly.
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -11,9 +12,10 @@ target datalayout = "e-p:32:32:32-i1:8:8
declare i8* @strchr(i8*, i32)
define void @test_simplify1() {
-; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6)
-; CHECK-NOT: call i8* @strchr
-; CHECK: ret void
+; CHECK-LABEL: @test_simplify1(
+; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6), i8** @chp, align 4
+; CHECK-NEXT: ret void
+;
%str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
%dst = call i8* @strchr(i8* %str, i32 119)
@@ -22,9 +24,10 @@ define void @test_simplify1() {
}
define void @test_simplify2() {
-; CHECK: store i8* null, i8** @chp, align 4
-; CHECK-NOT: call i8* @strchr
-; CHECK: ret void
+; CHECK-LABEL: @test_simplify2(
+; CHECK-NEXT: store i8* null, i8** @chp, align 4
+; CHECK-NEXT: ret void
+;
%str = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
%dst = call i8* @strchr(i8* %str, i32 119)
@@ -33,9 +36,10 @@ define void @test_simplify2() {
}
define void @test_simplify3() {
-; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13)
-; CHECK-NOT: call i8* @strchr
-; CHECK: ret void
+; CHECK-LABEL: @test_simplify3(
+; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), 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 0)
@@ -44,9 +48,11 @@ define void @test_simplify3() {
}
define void @test_simplify4(i32 %chr) {
-; CHECK: call i8* @memchr
-; CHECK-NOT: call i8* @strchr
-; CHECK: ret void
+; 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: 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)
@@ -55,9 +61,10 @@ define void @test_simplify4(i32 %chr) {
}
define void @test_simplify5() {
-; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13)
-; CHECK-NOT: call i8* @strchr
-; CHECK: ret void
+; CHECK-LABEL: @test_simplify5(
+; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), 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 65280)
@@ -67,11 +74,12 @@ define void @test_simplify5() {
; Check transformation strchr(p, 0) -> p + strlen(p)
define void @test_simplify6(i8* %str) {
-; CHECK: %strlen = call i32 @strlen(i8* %str)
-; CHECK-NOT: call i8* @strchr
-; CHECK: %strchr = getelementptr i8, i8* %str, i32 %strlen
-; CHECK: store i8* %strchr, i8** @chp, align 4
-; CHECK: ret void
+; CHECK-LABEL: @test_simplify6(
+; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]])
+; 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)
store i8* %dst, i8** @chp
@@ -80,17 +88,38 @@ define void @test_simplify6(i8* %str) {
; Check transformation strchr("\r\n", C) != nullptr -> (C & 9217) != 0
define i1 @test_simplify7(i32 %C) {
-; CHECK-LABEL: @test_simplify7
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 %C to i16
-; CHECK-NEXT: [[TRUNC_AND:%.*]] = and i16 [[TRUNC]], 255
-; CHECK-NEXT: %memchr.bounds = icmp ult i16 [[TRUNC_AND]], 16
-; CHECK-NEXT: [[SHL:%.*]] = shl i16 1, [[TRUNC_AND]]
-; CHECK-NEXT: [[AND:%.*]] = and i16 [[SHL]], 9217
-; CHECK-NEXT: %memchr.bits = icmp ne i16 [[AND]], 0
-; CHECK-NEXT: %memchr1 = and i1 %memchr.bounds, %memchr.bits
-; CHECK-NEXT: ret i1 %memchr1
+; CHECK-LABEL: @test_simplify7(
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i16
+; CHECK-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 255
+; CHECK-NEXT: [[MEMCHR_BOUNDS:%.*]] = icmp ult i16 [[TMP2]], 16
+; CHECK-NEXT: [[TMP3:%.*]] = shl i16 1, [[TMP2]]
+; CHECK-NEXT: [[TMP4:%.*]] = and i16 [[TMP3]], 9217
+; CHECK-NEXT: [[MEMCHR_BITS:%.*]] = icmp ne i16 [[TMP4]], 0
+; CHECK-NEXT: [[MEMCHR1:%.*]] = and i1 [[MEMCHR_BOUNDS]], [[MEMCHR_BITS]]
+; CHECK-NEXT: ret i1 [[MEMCHR1]]
+;
%dst = call i8* @strchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @newlines, i64 0, i64 0), i32 %C)
%cmp = icmp ne i8* %dst, null
ret i1 %cmp
}
+
+define i8* @test1(i8* %str, i32 %c) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @strchr(i8* nonnull dereferenceable(1) [[STR:%.*]], i32 [[C:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @strchr(i8* %str, i32 %c)
+ ret i8* %ret
+}
+
+define i8* @test2(i8* %str, i32 %c) "null-pointer-is-valid"="true" {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @strchr(i8* [[STR:%.*]], i32 [[C:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @strchr(i8* %str, i32 %c)
+ ret i8* %ret
+}
Modified: llvm/trunk/test/Transforms/InstCombine/strcmp-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strcmp-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strcmp-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strcmp-1.ll Tue Sep 17 02:32:52 2019
@@ -97,12 +97,12 @@ define i32 @test5(i1 %b) {
; 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* dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* 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)
; 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* dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* 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)
; BCMP-NEXT: ret i32 [[MEMCMP]]
;
%str1 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0
@@ -131,13 +131,13 @@ define i32 @test6(i8* %str) {
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* dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* 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)
; 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* dereferenceable(5) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* 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)
; BCMP-NEXT: [[RES:%.*]] = icmp eq i32 [[BCMP]], 0
; BCMP-NEXT: ret i1 [[RES]]
;
Modified: llvm/trunk/test/Transforms/InstCombine/strcmp-memcmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strcmp-memcmp.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strcmp-memcmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strcmp-memcmp.ll Tue Sep 17 02:32:52 2019
@@ -11,7 +11,7 @@ declare void @use(i32)
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -28,7 +28,7 @@ declare i32 @strcmp(i8* nocapture, i8* n
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -43,7 +43,7 @@ define i32 @strcmp_memcmp2([12 x i8]* de
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -58,7 +58,7 @@ define i32 @strcmp_memcmp3([12 x i8]* de
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -73,7 +73,7 @@ define i32 @strcmp_memcmp4([12 x i8]* de
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -88,7 +88,7 @@ define i32 @strcmp_memcmp5([5 x i8]* der
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -103,7 +103,7 @@ define i32 @strcmp_memcmp6([12 x i8]* de
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* 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)
; CHECK-NEXT: [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31
; CHECK-NEXT: ret i32 [[MEMCMP_LOBIT]]
;
@@ -117,7 +117,7 @@ define i32 @strcmp_memcmp7([12 x i8]* de
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -132,7 +132,7 @@ define i32 @strcmp_memcmp8([4 x i8]* der
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -148,7 +148,7 @@ define i32 @strcmp_memcmp9([12 x i8]* de
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -165,7 +165,7 @@ declare i32 @strncmp(i8* nocapture, i8*
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -180,7 +180,7 @@ define i32 @strncmp_memcmp2([12 x i8]* d
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -195,7 +195,7 @@ define i32 @strncmp_memcmp3([12 x i8]* d
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -210,7 +210,7 @@ define i32 @strncmp_memcmp4([12 x i8]* d
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -226,7 +226,7 @@ define i32 @strncmp_memcmp5([12 x i8]* d
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -241,7 +241,7 @@ define i32 @strncmp_memcmp6([12 x i8]* d
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -256,7 +256,7 @@ define i32 @strncmp_memcmp7([12 x i8]* d
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -271,7 +271,7 @@ define i32 @strncmp_memcmp8([12 x i8]* d
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -286,7 +286,7 @@ define i32 @strncmp_memcmp9([12 x i8]* d
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* 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)
; CHECK-NEXT: [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31
; CHECK-NEXT: ret i32 [[MEMCMP_LOBIT]]
;
@@ -300,7 +300,7 @@ define i32 @strncmp_memcmp10([12 x i8]*
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -315,7 +315,7 @@ define i32 @strncmp_memcmp11([12 x i8]*
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -330,7 +330,7 @@ define i32 @strncmp_memcmp12([12 x i8]*
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -345,7 +345,7 @@ define i32 @strncmp_memcmp13([12 x i8]*
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* 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)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -361,7 +361,7 @@ define i32 @strncmp_memcmp14([12 x i8]*
define i32 @strcmp_memcmp_bad([12 x i8]* dereferenceable (12) %buf) {
; CHECK-LABEL: @strcmp_memcmp_bad(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 3
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -376,7 +376,7 @@ define i32 @strcmp_memcmp_bad([12 x i8]*
define i32 @strcmp_memcmp_bad2([12 x i8]* dereferenceable (12) %buf) {
; CHECK-LABEL: @strcmp_memcmp_bad2(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]])
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]])
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 3
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -391,7 +391,7 @@ define i32 @strcmp_memcmp_bad2([12 x i8]
define i32 @strcmp_memcmp_bad3([12 x i8]* dereferenceable (12) %buf) {
; CHECK-LABEL: @strcmp_memcmp_bad3(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
; CHECK-NEXT: ret i32 [[CALL]]
;
%string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0
@@ -402,7 +402,7 @@ define i32 @strcmp_memcmp_bad3([12 x i8]
define i32 @strcmp_memcmp_bad4(i8* nocapture readonly %buf) {
; CHECK-LABEL: @strcmp_memcmp_bad4(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* [[BUF:%.*]])
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(1) [[BUF:%.*]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -417,7 +417,7 @@ define i32 @strcmp_memcmp_bad4(i8* nocap
define i32 @strcmp_memcmp_bad5([3 x i8]* dereferenceable (3) %buf) {
; CHECK-LABEL: @strcmp_memcmp_bad5(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -432,7 +432,7 @@ define i32 @strcmp_memcmp_bad5([3 x i8]*
define i32 @strcmp_memcmp_bad6([4 x i8]* dereferenceable (4) %buf, i8* nocapture readonly %k) {
; CHECK-LABEL: @strcmp_memcmp_bad6(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* [[K:%.*]])
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(1) [[K:%.*]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -446,7 +446,7 @@ define i32 @strcmp_memcmp_bad6([4 x i8]*
define i32 @strcmp_memcmp_bad7(i8* nocapture readonly %k) {
; CHECK-LABEL: @strcmp_memcmp_bad7(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* [[K:%.*]])
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strcmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(1) [[K:%.*]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -460,7 +460,7 @@ define i32 @strcmp_memcmp_bad7(i8* nocap
define i32 @strcmp_memcmp_bad8([4 x i8]* dereferenceable (4) %buf) {
; CHECK-LABEL: @strcmp_memcmp_bad8(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
; CHECK-NEXT: tail call void @use(i32 [[CALL]])
; CHECK-NEXT: ret i32 0
;
@@ -473,7 +473,7 @@ define i32 @strcmp_memcmp_bad8([4 x i8]*
define i32 @strncmp_memcmp_bad([12 x i8]* dereferenceable (12) %buf) {
; CHECK-LABEL: @strncmp_memcmp_bad(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 5)
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 5)
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 3
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -489,7 +489,7 @@ define i32 @strncmp_memcmp_bad([12 x i8]
define i32 @strncmp_memcmp_bad1([12 x i8]* dereferenceable (12) %buf) {
; CHECK-LABEL: @strncmp_memcmp_bad1(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 5)
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 5)
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 3
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -518,7 +518,7 @@ define i32 @strncmp_memcmp_bad2([12 x i8
define i32 @strncmp_memcmp_bad3(i8* nocapture readonly %k) {
; CHECK-LABEL: @strncmp_memcmp_bad3(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* [[K:%.*]], i64 2)
+; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strncmp(i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull dereferenceable(1) [[K:%.*]], i64 2)
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
@@ -532,7 +532,7 @@ define i32 @strncmp_memcmp_bad3(i8* noca
define i32 @strncmp_memcmp_bad4([4 x i8]* dereferenceable (4) %buf) {
; CHECK-LABEL: @strncmp_memcmp_bad4(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2)
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2)
; CHECK-NEXT: tail call void @use(i32 [[CALL]])
; CHECK-NEXT: ret i32 0
;
@@ -545,7 +545,7 @@ define i32 @strncmp_memcmp_bad4([4 x i8]
define i32 @strcmp_memcmp_msan([12 x i8]* dereferenceable (12) %buf) sanitize_memory {
; CHECK-LABEL: @strcmp_memcmp_msan(
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
Modified: llvm/trunk/test/Transforms/InstCombine/strcpy-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strcpy-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strcpy-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strcpy-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strcpy library call simplifier works correctly.
; rdar://6839935
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -14,32 +15,50 @@ declare i8* @strcpy(i8*, i8*)
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: 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)
-; CHECK: @llvm.memcpy.p0i8.p0i8.i32
ret void
}
define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
+; CHECK-NEXT: ret i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0)
+;
%dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0
%ret = call i8* @strcpy(i8* %dst, i8* %dst)
-; CHECK: ret i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0)
ret i8* %ret
}
+
+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: ret void
+;
+
+ %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0
+
+ call i8* @strcpy(i8* dereferenceable(80) %dst, i8* %src)
+ ret void
+}
+
define i8* @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @strcpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @b, i32 0, i32 0))
+; CHECK-NEXT: ret i8* [[RET]]
+;
%dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0
%src = getelementptr [32 x i8], [32 x i8]* @b, i32 0, i32 0
%ret = call i8* @strcpy(i8* %dst, i8* %src)
-; CHECK: call i8* @strcpy
ret i8* %ret
}
Modified: llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll Tue Sep 17 02:32:52 2019
@@ -14,7 +14,7 @@ target datalayout = "e-p:32:32:32-i1:8:8
define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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)
; 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
@@ -26,7 +26,7 @@ define i8* @test_simplify1() {
define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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)
; 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
@@ -38,7 +38,7 @@ define i8* @test_simplify2() {
define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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)
; 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
@@ -52,7 +52,7 @@ define i8* @test_simplify3() {
define i8* @test_simplify4() {
; CHECK-LABEL: @test_simplify4(
-; CHECK-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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))
; CHECK-NEXT: ret i8* [[STRCPY]]
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
Modified: llvm/trunk/test/Transforms/InstCombine/strcspn-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strcspn-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strcspn-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strcspn-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strcspn library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -14,44 +15,48 @@ declare i64 @strcspn(i8*, i8*)
define i64 @test_simplify1(i8* %str) {
; CHECK-LABEL: @test_simplify1(
+; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]])
+; CHECK-NEXT: ret i64 [[STRLEN]]
+;
%pat = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
%ret = call i64 @strcspn(i8* %str, i8* %pat)
-; CHECK-NEXT: [[VAR:%[a-z]+]] = call i64 @strlen(i8* %str)
ret i64 %ret
-; CHECK-NEXT: ret i64 [[VAR]]
}
; Check strcspn("", s) -> 0.
define i64 @test_simplify2(i8* %pat) {
; CHECK-LABEL: @test_simplify2(
+; CHECK-NEXT: ret i64 0
+;
%str = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
%ret = call i64 @strcspn(i8* %str, i8* %pat)
ret i64 %ret
-; CHECK-NEXT: ret i64 0
}
; Check strcspn(s1, s2), where s1 and s2 are constants.
define i64 @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
+; CHECK-NEXT: ret i64 0
+;
%str = getelementptr [6 x i8], [6 x i8]* @abcba, i32 0, i32 0
%pat = getelementptr [4 x i8], [4 x i8]* @abc, i32 0, i32 0
%ret = call i64 @strcspn(i8* %str, i8* %pat)
ret i64 %ret
-; CHECK-NEXT: ret i64 0
}
; Check cases that shouldn't be simplified.
define i64 @test_no_simplify1(i8* %str, i8* %pat) {
; CHECK-LABEL: @test_no_simplify1(
+; CHECK-NEXT: [[RET:%.*]] = call i64 @strcspn(i8* [[STR:%.*]], i8* [[PAT:%.*]])
+; CHECK-NEXT: ret i64 [[RET]]
+;
%ret = call i64 @strcspn(i8* %str, i8* %pat)
-; CHECK-NEXT: %ret = call i64 @strcspn(i8* %str, i8* %pat)
ret i64 %ret
-; CHECK-NEXT: ret i64 %ret
}
Modified: llvm/trunk/test/Transforms/InstCombine/strlen-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strlen-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strlen-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strlen-1.ll Tue Sep 17 02:32:52 2019
@@ -100,7 +100,7 @@ define i1 @test_simplify8(i8* %str_p) {
define i32 @test_simplify9(i1 %x) {
; CHECK-LABEL: @test_simplify9(
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 %x, i32 5, i32 6
+; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i32 5, i32 6
; CHECK-NEXT: ret i32 [[TMP1]]
;
%hello = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0
@@ -115,7 +115,7 @@ define i32 @test_simplify9(i1 %x) {
define i32 @test_simplify10(i32 %x) {
; CHECK-LABEL: @test_simplify10(
-; CHECK-NEXT: [[TMP1:%.*]] = sub i32 5, %x
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 5, [[X:%.*]]
; CHECK-NEXT: ret i32 [[TMP1]]
;
%hello_p = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 %x
@@ -127,7 +127,7 @@ define i32 @test_simplify10(i32 %x) {
define i32 @test_simplify11(i32 %x) {
; CHECK-LABEL: @test_simplify11(
-; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 7
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 7
; CHECK-NEXT: [[TMP1:%.*]] = sub nuw nsw i32 9, [[AND]]
; CHECK-NEXT: ret i32 [[TMP1]]
;
@@ -141,7 +141,7 @@ define i32 @test_simplify11(i32 %x) {
define i32 @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
-; CHECK-NEXT: [[A_L:%.*]] = call i32 @strlen(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0))
+; CHECK-NEXT: [[A_L:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0))
; CHECK-NEXT: ret i32 [[A_L]]
;
%a_p = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0
@@ -153,7 +153,7 @@ define i32 @test_no_simplify1() {
define i32 @test_no_simplify2(i32 %x) {
; CHECK-LABEL: @test_no_simplify2(
-; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 %x
+; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 [[X:%.*]]
; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* nonnull [[HELLO_P]])
; CHECK-NEXT: ret i32 [[HELLO_L]]
;
@@ -164,7 +164,7 @@ define i32 @test_no_simplify2(i32 %x) {
define i32 @test_no_simplify2_no_null_opt(i32 %x) #0 {
; CHECK-LABEL: @test_no_simplify2_no_null_opt(
-; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 %x
+; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 [[X:%.*]]
; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* [[HELLO_P]])
; CHECK-NEXT: ret i32 [[HELLO_L]]
;
@@ -177,7 +177,7 @@ define i32 @test_no_simplify2_no_null_op
define i32 @test_no_simplify3(i32 %x) {
; CHECK-LABEL: @test_no_simplify3(
-; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 15
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 15
; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 [[AND]]
; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* nonnull [[HELLO_P]])
; CHECK-NEXT: ret i32 [[HELLO_L]]
@@ -190,7 +190,7 @@ define i32 @test_no_simplify3(i32 %x) {
define i32 @test_no_simplify3_on_null_opt(i32 %x) #0 {
; CHECK-LABEL: @test_no_simplify3_on_null_opt(
-; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 15
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 15
; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 [[AND]]
; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* [[HELLO_P]])
; CHECK-NEXT: ret i32 [[HELLO_L]]
@@ -201,4 +201,22 @@ define i32 @test_no_simplify3_on_null_op
ret i32 %hello_l
}
+define i32 @test1(i8* %str) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[LEN:%.*]] = tail call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]]) #1
+; CHECK-NEXT: ret i32 [[LEN]]
+;
+ %len = tail call i32 @strlen(i8* %str) nounwind
+ ret i32 %len
+}
+
+define i32 @test2(i8* %str) #0 {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: [[LEN:%.*]] = tail call i32 @strlen(i8* [[STR:%.*]]) #1
+; CHECK-NEXT: ret i32 [[LEN]]
+;
+ %len = tail call i32 @strlen(i8* %str) nounwind
+ ret i32 %len
+}
+
attributes #0 = { "null-pointer-is-valid"="true" }
Modified: llvm/trunk/test/Transforms/InstCombine/strncat-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strncat-2.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strncat-2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strncat-2.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strncat libcall simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -7,13 +8,15 @@ target datalayout = "e-p:32:32:32-i1:8:8
@hello = constant [6 x i8] c"hello\00"
@empty = constant [1 x i8] c"\00"
@a = common global [32 x i8] zeroinitializer, align 1
-
declare i8* @strncat(i8*, i8*, i32)
define void @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NOT: call i8* @strncat
-; CHECK: ret void
+; 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: [[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: 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
@@ -23,7 +26,8 @@ define void @test_simplify1() {
define void @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
-; CHECK-NEXT: ret void
+; 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]* @empty, i32 0, i32 0
@@ -33,7 +37,8 @@ define void @test_simplify2() {
define void @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
-; CHECK-NEXT: ret void
+; 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
@@ -43,11 +48,66 @@ define void @test_simplify3() {
define void @test_nosimplify1() {
; CHECK-LABEL: @test_nosimplify1(
-; CHECK: call i8* @strncat
-; CHECK: ret void
+; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncat(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 1)
+; 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 1)
ret void
}
+
+; strncat(nonnull x, nonnull y, n) -> strncat(nonnull x, y, n)
+define i8* @test1(i8* %str1, i8* %str2, i32 %n) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* nonnull [[STR1:%.*]], i8* nonnull [[STR2:%.*]], i32 [[N:%.*]])
+; CHECK-NEXT: ret i8* [[TEMP1]]
+;
+
+ %temp1 = call i8* @strncat(i8* nonnull %str1, i8* nonnull %str2, i32 %n)
+ ret i8* %temp1
+}
+
+; strncat(x, y, 0) -> x
+define i8* @test2(i8* %str1, i8* %str2, i32 %n) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: ret i8* [[STR1:%.*]]
+;
+
+ %temp1 = call i8* @strncat(i8* %str1, i8* %str2, i32 0)
+ ret i8* %temp1
+}
+
+; strncat(x, y, 5) -> strncat(nonnull x, nonnull y, 5)
+define i8* @test3(i8* %str1, i8* %str2, i32 %n) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* nonnull dereferenceable(1) [[STR1:%.*]], i8* nonnull dereferenceable(1) [[STR2:%.*]], i32 5)
+; CHECK-NEXT: ret i8* [[TEMP1]]
+;
+
+ %temp1 = call i8* @strncat(i8* %str1, i8* %str2, i32 5)
+ ret i8* %temp1
+}
+
+define i8* @test4(i8* %str1, i8* %str2, i32 %n) "null-pointer-is-valid"="true" {
+; CHECK-LABEL: @test4(
+; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* [[STR1:%.*]], i8* [[STR2:%.*]], i32 [[N:%.*]])
+; CHECK-NEXT: ret i8* [[TEMP1]]
+;
+
+ %temp1 = call i8* @strncat(i8* %str1, i8* %str2, i32 %n)
+ ret i8* %temp1
+}
+
+define i8* @test5(i8* %str, i32 %n) {
+; CHECK-LABEL: @test5(
+; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]])
+; 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: 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)
+ ret i8* %temp1
+}
Modified: llvm/trunk/test/Transforms/InstCombine/strncat-3.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strncat-3.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strncat-3.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strncat-3.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strncat libcall simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -12,8 +13,9 @@ declare i16* @strncat(i8*, i8*, i32)
define void @test_nosimplify1() {
; CHECK-LABEL: @test_nosimplify1(
-; CHECK: call i16* @strncat
-; CHECK: ret void
+; CHECK-NEXT: [[TMP1:%.*]] = call i16* @strncat(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 13)
+; 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
Modified: llvm/trunk/test/Transforms/InstCombine/strncmp-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strncmp-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strncmp-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strncmp-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strncmp library call simplifier works correctly.
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -13,10 +14,11 @@ declare i32 @strncmp(i8*, i8*, i32)
; strncmp("", x, n) -> -*x
define i32 @test1(i8* %str2) {
; CHECK-LABEL: @test1(
-; CHECK: %strcmpload = load i8, i8* %str
-; CHECK: %1 = zext i8 %strcmpload to i32
-; CHECK: %2 = sub nsw i32 0, %1
-; CHECK: ret i32 %2
+; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR2:%.*]], align 1
+; 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)
@@ -26,9 +28,10 @@ define i32 @test1(i8* %str2) {
; strncmp(x, "", n) -> *x
define i32 @test2(i8* %str1) {
; CHECK-LABEL: @test2(
-; CHECK: %strcmpload = load i8, i8* %str1
-; CHECK: %1 = zext i8 %strcmpload to i32
-; CHECK: ret i32 %1
+; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR1:%.*]], align 1
+; 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)
@@ -38,7 +41,8 @@ define i32 @test2(i8* %str1) {
; strncmp(x, y, n) -> cnst
define i32 @test3() {
; CHECK-LABEL: @test3(
-; CHECK: ret i32 -1
+; CHECK-NEXT: ret i32 -1
+;
%str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0
%str2 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0
@@ -48,7 +52,8 @@ define i32 @test3() {
define i32 @test4() {
; CHECK-LABEL: @test4(
-; CHECK: ret i32 1
+; CHECK-NEXT: ret i32 1
+;
%str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0
%str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0
@@ -58,7 +63,8 @@ define i32 @test4() {
define i32 @test5() {
; CHECK-LABEL: @test5(
-; CHECK: ret i32 0
+; CHECK-NEXT: ret i32 0
+;
%str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0
%str2 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0
@@ -69,12 +75,13 @@ define i32 @test5() {
; strncmp(x,y,1) -> memcmp(x,y,1)
define i32 @test6(i8* %str1, i8* %str2) {
; CHECK-LABEL: @test6(
-; CHECK: [[LOAD1:%[a-z]+]] = load i8, i8* %str1, align 1
-; CHECK: [[ZEXT1:%[a-z]+]] = zext i8 [[LOAD1]] to i32
-; CHECK: [[LOAD2:%[a-z]+]] = load i8, i8* %str2, align 1
-; CHECK: [[ZEXT2:%[a-z]+]] = zext i8 [[LOAD2]] to i32
-; CHECK: [[RET:%[a-z]+]] = sub nsw i32 [[ZEXT1]], [[ZEXT2]]
-; CHECK: ret i32 [[RET]]
+; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* [[STR1:%.*]], align 1
+; CHECK-NEXT: [[LHSV:%.*]] = zext i8 [[LHSC]] to i32
+; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* [[STR2:%.*]], align 1
+; 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)
ret i32 %temp1
@@ -83,7 +90,8 @@ define i32 @test6(i8* %str1, i8* %str2)
; strncmp(x,y,0) -> 0
define i32 @test7(i8* %str1, i8* %str2) {
; CHECK-LABEL: @test7(
-; CHECK: ret i32 0
+; CHECK-NEXT: ret i32 0
+;
%temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 0)
ret i32 %temp1
@@ -92,8 +100,51 @@ define i32 @test7(i8* %str1, i8* %str2)
; strncmp(x,x,n) -> 0
define i32 @test8(i8* %str, i32 %n) {
; CHECK-LABEL: @test8(
-; CHECK: ret i32 0
+; CHECK-NEXT: ret i32 0
+;
%temp1 = call i32 @strncmp(i8* %str, i8* %str, i32 %n)
ret i32 %temp1
}
+
+; strncmp(nonnull x, nonnull y, n) -> strncmp(x, y, n)
+define i32 @test9(i8* %str1, i8* %str2, i32 %n) {
+; CHECK-LABEL: @test9(
+; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @strncmp(i8* nonnull [[STR1:%.*]], i8* nonnull [[STR2:%.*]], i32 [[N:%.*]])
+; CHECK-NEXT: ret i32 [[TEMP1]]
+;
+
+ %temp1 = call i32 @strncmp(i8* nonnull %str1, i8* nonnull %str2, i32 %n)
+ ret i32 %temp1
+}
+
+; strncmp(nonnull x, nonnull y, 0) -> 0
+define i32 @test10(i8* %str1, i8* %str2, i32 %n) {
+; CHECK-LABEL: @test10(
+; CHECK-NEXT: ret i32 0
+;
+
+ %temp1 = call i32 @strncmp(i8* nonnull %str1, i8* nonnull %str2, i32 0)
+ ret i32 %temp1
+}
+
+; strncmp(x, y, 5) -> strncmp(nonnull x, nonnull y, 5)
+define i32 @test11(i8* %str1, i8* %str2, i32 %n) {
+; CHECK-LABEL: @test11(
+; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @strncmp(i8* nonnull dereferenceable(1) [[STR1:%.*]], i8* nonnull dereferenceable(1) [[STR2:%.*]], i32 5)
+; CHECK-NEXT: ret i32 [[TEMP1]]
+;
+
+ %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 5)
+ ret i32 %temp1
+}
+
+define i32 @test12(i8* %str1, i8* %str2, i32 %n) "null-pointer-is-valid"="true" {
+; CHECK-LABEL: @test12(
+; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @strncmp(i8* [[STR1:%.*]], i8* [[STR2:%.*]], i32 [[N:%.*]])
+; CHECK-NEXT: ret i32 [[TEMP1]]
+;
+
+ %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 %n)
+ ret i32 %temp1
+}
Modified: llvm/trunk/test/Transforms/InstCombine/strncmp-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strncmp-2.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strncmp-2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strncmp-2.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strncmp library call simplifier works correctly.
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -10,8 +11,9 @@ declare i16 @strncmp(i8*, i8*, i32)
define i16 @test_nosimplify() {
; CHECK-LABEL: @test_nosimplify(
-; CHECK: call i16 @strncmp
-; CHECK: ret i16 %temp1
+; CHECK-NEXT: [[TEMP1:%.*]] = call i16 @strncmp(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 10)
+; CHECK-NEXT: ret i16 [[TEMP1]]
+;
%str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0
%str2 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0
Modified: llvm/trunk/test/Transforms/InstCombine/strncpy-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strncpy-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strncpy-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strncpy-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strncpy library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -17,8 +18,15 @@ declare i32 @puts(i8*)
define i32 @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NOT: call i8* @strncpy
-; CHECK: call i32 @puts
+; 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: [[TMP1:%.*]] = call i32 @puts(i8* nonnull [[ARG1]])
+; CHECK-NEXT: ret i32 0
+;
%target = alloca [1024 x i8]
%arg1 = getelementptr [1024 x i8], [1024 x i8]* %target, i32 0, i32 0
store i8 0, i8* %arg1
@@ -40,11 +48,13 @@ define i32 @test_simplify1() {
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: 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)
-; CHECK: call void @llvm.memset.p0i8.i32
ret void
}
@@ -52,44 +62,100 @@ define void @test_simplify2() {
define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
+; CHECK-NEXT: ret i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0)
+;
%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
%ret = call i8* @strncpy(i8* %dst, i8* %src, i32 0)
ret i8* %ret
-; CHECK: ret i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0)
}
; Check strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant].
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: 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)
-; CHECK: call void @llvm.memcpy.p0i8.p0i8.i32
ret void
}
+define void @test_simplify5(i8* %dst) {
+; CHECK-LABEL: @test_simplify5(
+; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncpy(i8* nonnull dereferenceable(8) [[DST:%.*]], i8* nonnull dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 32)
+; 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)
+ ret void
+}
+
+define void @test_simplify6(i8* %dst) {
+; CHECK-LABEL: @test_simplify6(
+; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncpy(i8* nonnull dereferenceable(80) [[DST:%.*]], i8* nonnull dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 32)
+; 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)
+ ret void
+}
+
+define void @test_simplify7(i8* %dst, i32 %n) {
+; CHECK-LABEL: @test_simplify7(
+; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncpy(i8* nonnull dereferenceable(80) [[DST:%.*]], i8* getelementptr inbounds ([1 x i8], [1 x i8]* @null, i32 0, i32 0), i32 [[N:%.*]])
+; CHECK-NEXT: ret void
+;
+ %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
+ call i8* @strncpy(i8* dereferenceable(80) %dst, i8* %src, i32 %n)
+ ret void
+}
+
+define i8* @test1(i8* %dst, i8* %src, i32 %n) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @strncpy(i8* nonnull [[DST:%.*]], i8* nonnull [[SRC:%.*]], i32 [[N:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+ %ret = call i8* @strncpy(i8* nonnull %dst, i8* nonnull %src, i32 %n)
+ ret i8* %ret
+}
+
+define i8* @test2(i8* %dst) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(5) [[DST:%.*]], i8* nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 5, i1 false)
+; 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 i8* %ret
+}
+
; Check cases that shouldn't be simplified.
define void @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
+; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @b, i32 0, i32 0), i32 32)
+; CHECK-NEXT: ret void
+;
%dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0
%src = getelementptr [32 x i8], [32 x i8]* @b, i32 0, i32 0
call i8* @strncpy(i8* %dst, i8* %src, i32 32)
-; CHECK: call i8* @strncpy
ret void
}
define void @test_no_simplify2() {
; CHECK-LABEL: @test_no_simplify2(
+; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 8)
+; 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 8)
-; CHECK: call i8* @strncpy
ret void
}
Modified: llvm/trunk/test/Transforms/InstCombine/strncpy-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strncpy-2.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strncpy-2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strncpy-2.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strncpy library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -13,10 +14,12 @@ declare i16* @strncpy(i8*, i8*, i32)
define void @test_no_simplify1() {
; CHECK-LABEL: @test_no_simplify1(
+; CHECK-NEXT: [[TMP1:%.*]] = call i16* @strncpy(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6)
+; 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 i16* @strncpy(i8* %dst, i8* %src, i32 6)
-; CHECK: call i16* @strncpy
ret void
}
Modified: llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll Tue Sep 17 02:32:52 2019
@@ -14,7 +14,7 @@ target datalayout = "e-p:32:32:32-i1:8:8
define i8* @test_simplify1() {
; CHECK-LABEL: @test_simplify1(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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)
; 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
@@ -26,7 +26,7 @@ define i8* @test_simplify1() {
define i8* @test_simplify2() {
; CHECK-LABEL: @test_simplify2(
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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)
; 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
@@ -38,7 +38,7 @@ define i8* @test_simplify2() {
define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
-; CHECK-NEXT: [[STRNCPY:%.*]] = call i8* @strncpy(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* 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)
; CHECK-NEXT: ret i8* [[STRNCPY]]
;
%dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
Modified: llvm/trunk/test/Transforms/InstCombine/strpbrk-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strpbrk-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strpbrk-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strpbrk-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strpbrk library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -14,55 +15,60 @@ declare i8* @strpbrk(i8*, i8*)
define i8* @test_simplify1(i8* %str) {
; CHECK-LABEL: @test_simplify1(
+; CHECK-NEXT: ret i8* null
+;
%pat = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
%ret = call i8* @strpbrk(i8* %str, i8* %pat)
ret i8* %ret
-; CHECK-NEXT: ret i8* null
}
; Check strpbrk("", s) -> NULL.
define i8* @test_simplify2(i8* %pat) {
; CHECK-LABEL: @test_simplify2(
+; CHECK-NEXT: ret i8* null
+;
%str = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
%ret = call i8* @strpbrk(i8* %str, i8* %pat)
ret i8* %ret
-; CHECK-NEXT: ret i8* null
}
; Check strpbrk(s1, s2), where s1 and s2 are constants.
define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
+; CHECK-NEXT: ret i8* getelementptr inbounds ([12 x i8], [12 x i8]* @hello, i32 0, i32 6)
+;
%str = getelementptr [12 x i8], [12 x i8]* @hello, i32 0, i32 0
%pat = getelementptr [2 x i8], [2 x i8]* @w, i32 0, i32 0
%ret = call i8* @strpbrk(i8* %str, i8* %pat)
ret i8* %ret
-; CHECK-NEXT: ret i8* getelementptr inbounds ([12 x i8], [12 x i8]* @hello, i32 0, i32 6)
}
; Check strpbrk(s, "a") -> strchr(s, 'a').
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: ret i8* [[STRCHR]]
+;
%pat = getelementptr [2 x i8], [2 x i8]* @w, i32 0, i32 0
%ret = call i8* @strpbrk(i8* %str, i8* %pat)
-; CHECK-NEXT: [[VAR:%[a-z]+]] = call i8* @strchr(i8* %str, i32 119)
ret i8* %ret
-; CHECK-NEXT: ret i8* [[VAR]]
}
; Check cases that shouldn't be simplified.
define i8* @test_no_simplify1(i8* %str, i8* %pat) {
; CHECK-LABEL: @test_no_simplify1(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @strpbrk(i8* [[STR:%.*]], i8* [[PAT:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
%ret = call i8* @strpbrk(i8* %str, i8* %pat)
-; CHECK-NEXT: %ret = call i8* @strpbrk(i8* %str, i8* %pat)
ret i8* %ret
-; CHECK-NEXT: ret i8* %ret
}
Modified: llvm/trunk/test/Transforms/InstCombine/strrchr-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strrchr-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strrchr-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strrchr-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strrchr library call simplifier works correctly.
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -10,9 +11,10 @@ target datalayout = "e-p:32:32:32-i1:8:8
declare i8* @strrchr(i8*, i32)
define void @test_simplify1() {
-; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6)
-; CHECK-NOT: call i8* @strrchr
-; CHECK: ret void
+; CHECK-LABEL: @test_simplify1(
+; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6), i8** @chp, align 4
+; CHECK-NEXT: ret void
+;
%str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
%dst = call i8* @strrchr(i8* %str, i32 119)
@@ -21,9 +23,10 @@ define void @test_simplify1() {
}
define void @test_simplify2() {
-; CHECK: store i8* null, i8** @chp, align 4
-; CHECK-NOT: call i8* @strrchr
-; CHECK: ret void
+; CHECK-LABEL: @test_simplify2(
+; CHECK-NEXT: store i8* null, i8** @chp, align 4
+; CHECK-NEXT: ret void
+;
%str = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
%dst = call i8* @strrchr(i8* %str, i32 119)
@@ -32,9 +35,10 @@ define void @test_simplify2() {
}
define void @test_simplify3() {
-; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13)
-; CHECK-NOT: call i8* @strrchr
-; CHECK: ret void
+; CHECK-LABEL: @test_simplify3(
+; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), i8** @chp, align 4
+; CHECK-NEXT: ret void
+;
%src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
%dst = call i8* @strrchr(i8* %src, i32 0)
@@ -43,9 +47,10 @@ define void @test_simplify3() {
}
define void @test_simplify4() {
-; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13)
-; CHECK-NOT: call i8* @strrchr
-; CHECK: ret void
+; CHECK-LABEL: @test_simplify4(
+; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), i8** @chp, align 4
+; CHECK-NEXT: ret void
+;
%src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
%dst = call i8* @strrchr(i8* %src, i32 65280)
@@ -55,11 +60,33 @@ define void @test_simplify4() {
define void @test_nosimplify1(i32 %chr) {
; CHECK-LABEL: @test_nosimplify1(
-; CHECK: call i8* @strrchr
-; CHECK: ret void
+; CHECK-NEXT: [[DST:%.*]] = call i8* @strrchr(i8* nonnull dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]])
+; CHECK-NEXT: store i8* [[DST]], i8** @chp, align 4
+; CHECK-NEXT: ret void
+;
%src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
%dst = call i8* @strrchr(i8* %src, i32 %chr)
store i8* %dst, i8** @chp
ret void
}
+
+define i8* @test1(i8* %str, i32 %c) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @strrchr(i8* nonnull dereferenceable(1) [[STR:%.*]], i32 [[C:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @strrchr(i8* %str, i32 %c)
+ ret i8* %ret
+}
+
+define i8* @test2(i8* %str, i32 %c) "null-pointer-is-valid"="true" {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @strrchr(i8* [[STR:%.*]], i32 [[C:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+
+ %ret = call i8* @strrchr(i8* %str, i32 %c)
+ ret i8* %ret
+}
Modified: llvm/trunk/test/Transforms/InstCombine/strstr-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strstr-1.ll?rev=372091&r1=372090&r2=372091&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/strstr-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strstr-1.ll Tue Sep 17 02:32:52 2019
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strstr library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s
@@ -15,51 +16,75 @@ declare i8* @strstr(i8*, i8*)
define i8* @test_simplify1(i8* %str) {
; CHECK-LABEL: @test_simplify1(
+; CHECK-NEXT: ret i8* [[STR:%.*]]
+;
%pat = getelementptr inbounds [1 x i8], [1 x i8]* @.str, i32 0, i32 0
%ret = call i8* @strstr(i8* %str, i8* %pat)
ret i8* %ret
-; CHECK-NEXT: ret i8* %str
}
; Check strstr(str, "a") -> strchr(str, 'a').
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: 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 i8* %ret
-; CHECK-NEXT: @strchr(i8* %str, i32 97)
}
; Check strstr("abcde", "bcd") -> "abcde" + 1.
define i8* @test_simplify3() {
; CHECK-LABEL: @test_simplify3(
+; CHECK-NEXT: ret i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str2, i64 0, i64 1)
+;
%str = getelementptr inbounds [6 x i8], [6 x i8]* @.str2, i32 0, i32 0
%pat = getelementptr inbounds [4 x i8], [4 x i8]* @.str3, i32 0, i32 0
%ret = call i8* @strstr(i8* %str, i8* %pat)
ret i8* %ret
-; CHECK-NEXT: getelementptr inbounds ([6 x i8], [6 x i8]* @.str2, i64 0, i64 1)
}
; Check strstr(str, str) -> str.
define i8* @test_simplify4(i8* %str) {
; CHECK-LABEL: @test_simplify4(
+; CHECK-NEXT: ret i8* [[STR:%.*]]
+;
%ret = call i8* @strstr(i8* %str, i8* %str)
ret i8* %ret
-; CHECK-NEXT: ret i8* %str
}
; Check strstr(str, pat) == str -> strncmp(str, pat, strlen(str)) == 0.
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: [[CMP1:%.*]] = icmp eq i32 [[STRNCMP]], 0
+; CHECK-NEXT: ret i1 [[CMP1]]
+;
%ret = call i8* @strstr(i8* %str, i8* %pat)
%cmp = icmp eq i8* %ret, %str
ret i1 %cmp
-; CHECK: [[LEN:%[a-z]+]] = call {{i[0-9]+}} @strlen(i8* %pat)
-; CHECK: [[NCMP:%[a-z]+]] = call {{i[0-9]+}} @strncmp(i8* %str, i8* %pat, {{i[0-9]+}} [[LEN]])
-; CHECK: icmp eq {{i[0-9]+}} [[NCMP]], 0
-; CHECK: ret i1
+}
+
+define i8* @test1(i8* %str1, i8* %str2) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @strstr(i8* nonnull dereferenceable(1) [[STR1:%.*]], i8* nonnull dereferenceable(1) [[STR2:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+ %ret = call i8* @strstr(i8* %str1, i8* %str2)
+ ret i8* %ret
+}
+
+define i8* @test2(i8* %str1, i8* %str2) "null-pointer-is-valid"="true" {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: [[RET:%.*]] = call i8* @strstr(i8* [[STR1:%.*]], i8* [[STR2:%.*]])
+; CHECK-NEXT: ret i8* [[RET]]
+;
+ %ret = call i8* @strstr(i8* %str1, i8* %str2)
+ ret i8* %ret
}
More information about the llvm-commits
mailing list