[llvm] r368657 - [SimplifyLibCalls] Add dereferenceable bytes from known callsites
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 13 11:20:11 PDT 2019
Thanks!
Philip
On 8/13/19 9:47 AM, Dávid Bolvanský wrote:
> rL368715
>
>
> Thanks!
>
>
> Dňa 13. 8. 2019 o 18:14 užívateľ Philip Reames
> <listmail at philipreames.com <mailto:listmail at philipreames.com>> napísal:
>
>> In rare cases, it looks like this could loose information. I think
>> what you actually want would be the max of the original deref
>> information, and the length.
>>
>> Philip
>>
>> On 8/13/19 2:11 AM, David Bolvansky via llvm-commits wrote:
>>> Author: xbolva00
>>> Date: Tue Aug 13 02:11:49 2019
>>> New Revision: 368657
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=368657&view=rev
>>> Log:
>>> [SimplifyLibCalls] Add dereferenceable bytes from known callsites
>>>
>>> Summary:
>>> int mm(char *a, char *b) {
>>> return memcmp(a,b,16);
>>> }
>>>
>>> Currently:
>>> define dso_local i32 @mm(i8* nocapture readonly %a, i8* nocapture
>>> readonly %b) local_unnamed_addr #1 {
>>> entry:
>>> %call = tail call i32 @memcmp(i8* %a, i8* %b, i64 16)
>>> ret i32 %call
>>> }
>>>
>>> After patch:
>>> define dso_local i32 @mm(i8* nocapture readonly %a, i8* nocapture
>>> readonly %b) local_unnamed_addr #1 {
>>> entry:
>>> %call = tail call i32 @memcmp(i8* dereferenceable(16) %a, i8*
>>> dereferenceable(16) %b, i64 16)
>>> ret i32 %call
>>> }
>>>
>>>
>>>
>>>
>>> Reviewers: jdoerfert, efriedma
>>>
>>> Reviewed By: jdoerfert
>>>
>>> Subscribers: javed.absar, spatel, llvm-commits
>>>
>>> Tags: #llvm
>>>
>>> Differential Revision: https://reviews.llvm.org/D66079
>>>
>>> Added:
>>> llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes.ll
>>> Modified:
>>> llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
>>> llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
>>> llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll
>>> llvm/trunk/test/Transforms/InstCombine/ARM/strcmp.ll
>>> llvm/trunk/test/Transforms/InstCombine/align-addr.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/memset_chk-1.ll
>>> llvm/trunk/test/Transforms/InstCombine/objsize.ll
>>> llvm/trunk/test/Transforms/InstCombine/sprintf-1.ll
>>> llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll
>>> llvm/trunk/test/Transforms/InstCombine/strcmp-1.ll
>>> llvm/trunk/test/Transforms/InstCombine/strcmp-memcmp.ll
>>> llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll
>>> llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll
>>> llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset-with-lifetimes.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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
>>> (original)
>>> +++ llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h Tue
>>> Aug 13 02:11:49 2019
>>> @@ -167,9 +167,9 @@ private:
>>> Value *optimizeMemCmp(CallInst *CI, IRBuilder<> &B);
>>> Value *optimizeBCmp(CallInst *CI, IRBuilder<> &B);
>>> Value *optimizeMemCmpBCmpCommon(CallInst *CI, IRBuilder<> &B);
>>> - Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B);
>>> - Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B);
>>> - Value *optimizeMemSet(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 *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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Tue Aug 13
>>> 02:11:49 2019
>>> @@ -186,6 +186,20 @@ static bool canTransformToMemCmp(CallIns
>>> return true;
>>> }
>>> +static void annotateDereferenceableBytes(CallInst *CI,
>>> + ArrayRef<unsigned> ArgNos,
>>> + uint64_t DerefBytes) {
>>> + for (unsigned ArgNo : ArgNos) {
>>> + if (CI->getDereferenceableBytes(ArgNo +
>>> AttributeList::FirstArgIndex) <
>>> + DerefBytes) {
>>> + CI->removeParamAttr(ArgNo, Attribute::Dereferenceable);
>>> + CI->removeParamAttr(ArgNo, Attribute::DereferenceableOrNull);
>>> + CI->addParamAttr(ArgNo, Attribute::getWithDereferenceableBytes(
>>> + CI->getContext(), DerefBytes));
>>> + }
>>> + }
>>> +}
>>> +
>>> //===----------------------------------------------------------------------===//
>>> // String and Memory Library Call Optimizations
>>> //===----------------------------------------------------------------------===//
>>> @@ -765,9 +779,11 @@ Value *LibCallSimplifier::optimizeMemChr
>>> ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
>>> // memchr(x, y, 0) -> null
>>> - if (LenC && LenC->isZero())
>>> - return Constant::getNullValue(CI->getType());
>>> -
>>> + if (LenC) {
>>> + if (LenC->isZero())
>>> + return Constant::getNullValue(CI->getType());
>>> + annotateDereferenceableBytes(CI, {0}, LenC->getZExtValue());
>>> + }
>>> // From now on we need at least constant length and string.
>>> StringRef Str;
>>> if (!LenC || !getConstantStringInfo(SrcStr, Str, 0,
>>> /*TrimAtNul=*/false))
>>> @@ -926,10 +942,12 @@ Value *LibCallSimplifier::optimizeMemCmp
>>> return Constant::getNullValue(CI->getType());
>>> // Handle constant lengths.
>>> - if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size))
>>> + 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());
>>> + }
>>> return nullptr;
>>> }
>>> @@ -955,18 +973,31 @@ Value *LibCallSimplifier::optimizeBCmp(C
>>> return optimizeMemCmpBCmpCommon(CI, B);
>>> }
>>> -Value *LibCallSimplifier::optimizeMemCpy(CallInst *CI, IRBuilder<>
>>> &B) {
>>> +Value *LibCallSimplifier::optimizeMemCpy(CallInst *CI, IRBuilder<> &B,
>>> + bool isIntrinsic) {
>>> + Value *Size = CI->getArgOperand(2);
>>> + if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size))
>>> + annotateDereferenceableBytes(CI, {0, 1}, LenC->getZExtValue());
>>> +
>>> + if (isIntrinsic)
>>> + 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,
>>> - CI->getArgOperand(2));
>>> + B.CreateMemCpy(CI->getArgOperand(0), 1, CI->getArgOperand(1), 1,
>>> Size);
>>> return CI->getArgOperand(0);
>>> }
>>> -Value *LibCallSimplifier::optimizeMemMove(CallInst *CI,
>>> IRBuilder<> &B) {
>>> +Value *LibCallSimplifier::optimizeMemMove(CallInst *CI, IRBuilder<>
>>> &B, bool isIntrinsic) {
>>> + Value *Size = CI->getArgOperand(2);
>>> + if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size))
>>> + annotateDereferenceableBytes(CI, {0, 1}, LenC->getZExtValue());
>>> +
>>> + if (isIntrinsic)
>>> + 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,
>>> - CI->getArgOperand(2));
>>> - return CI->getArgOperand(0);
>>> + B.CreateMemMove( CI->getArgOperand(0), 1, CI->getArgOperand(1),
>>> 1, Size);
>>> + return CI->getArgOperand(0);
>>> }
>>> /// Fold memset[_chk](malloc(n), 0, n) --> calloc(1, n).
>>> @@ -1015,13 +1046,21 @@ Value *LibCallSimplifier::foldMallocMems
>>> return Calloc;
>>> }
>>> -Value *LibCallSimplifier::optimizeMemSet(CallInst *CI, IRBuilder<>
>>> &B) {
>>> +Value *LibCallSimplifier::optimizeMemSet(CallInst *CI, IRBuilder<> &B,
>>> + bool isIntrinsic) {
>>> + Value *Size = CI->getArgOperand(2);
>>> + if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size))
>>> + annotateDereferenceableBytes(CI, {0}, LenC->getZExtValue());
>>> +
>>> + if (isIntrinsic)
>>> + return nullptr;
>>> +
>>> if (auto *Calloc = foldMallocMemset(CI, B))
>>> return Calloc;
>>> // 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, CI->getArgOperand(2), 1);
>>> + B.CreateMemSet(CI->getArgOperand(0), Val, Size, 1);
>>> return CI->getArgOperand(0);
>>> }
>>> @@ -2710,6 +2749,12 @@ Value *LibCallSimplifier::optimizeCall(C
>>> case Intrinsic::sqrt:
>>> return optimizeSqrt(CI, Builder);
>>> // TODO: Use foldMallocMemset() with memset intrinsic.
>>> + case Intrinsic::memset:
>>> + return optimizeMemSet(CI, Builder, true);
>>> + case Intrinsic::memcpy:
>>> + return optimizeMemCpy(CI, Builder, true);
>>> + case Intrinsic::memmove:
>>> + return optimizeMemMove(CI, Builder, true);
>>> default:
>>> return nullptr;
>>> }
>>>
>>> Modified: llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll?rev=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll
>>> (original)
>>> +++ llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll Tue
>>> Aug 13 02:11:49 2019
>>> @@ -6,7 +6,7 @@ target datalayout = "e-p:64:64:64"
>>> ; it has a TBAA tag which declares that it is unrelated.
>>> ; CHECK: @foo
>>> -; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1
>>> %p, i8* align 1 %q, i64 16, i1 false), !tbaa !0
>>> +; 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: store i8 2, i8* %s, align 1, !tbaa [[TAGA:!.*]]
>>> ; CHECK-NEXT: ret void
>>> define void @foo(i8* nocapture %p, i8* nocapture %q, i8* nocapture
>>> %s) nounwind {
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/ARM/strcmp.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/ARM/strcmp.ll Tue Aug 13
>>> 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test that the strcmp library call simplifier works correctly.
>>> ; RUN: opt < %s -instcombine -S | FileCheck %s
>>> @@ -13,10 +14,11 @@ declare i32 @strcmp(i8*, i8*)
>>> ; strcmp("", x) -> -*x
>>> define arm_aapcscc 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 arm_apcscc i32 @strcmp(i8* %str1, i8* %str2)
>>> @@ -27,9 +29,10 @@ define arm_aapcscc i32 @test1(i8* %str2)
>>> ; strcmp(x, "") -> *x
>>> define arm_aapcscc i32 @test2(i8* %str1) {
>>> ; CHECK-LABEL: @test2(
>>> -; CHECK: %strcmpload = load i8, i8* %str
>>> -; 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 arm_aapcscc i32 @strcmp(i8* %str1, i8* %str2)
>>> @@ -39,7 +42,8 @@ define arm_aapcscc i32 @test2(i8* %str1)
>>> ; strcmp(x, y) -> cnst
>>> define arm_aapcscc 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
>>> @@ -49,7 +53,8 @@ define arm_aapcscc i32 @test3() {
>>> define arm_aapcscc 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
>>> @@ -61,8 +66,10 @@ define arm_aapcscc i32 @test4() {
>>> ; (This transform is rather difficult to trigger in a useful manner)
>>> define arm_aapcscc i32 @test5(i1 %b) {
>>> ; CHECK-LABEL: @test5(
>>> -; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6
>>> x i8], [6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5)
>>> -; CHECK: ret i32 %memcmp
>>> +; 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: ret i32 [[MEMCMP]]
>>> +;
>>> %str1 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32
>>> 0, i32 0
>>> %temp1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0,
>>> i32 0
>>> @@ -75,7 +82,8 @@ define arm_aapcscc i32 @test5(i1 %b) {
>>> ; strcmp(x,x) -> 0
>>> define arm_aapcscc i32 @test6(i8* %str) {
>>> ; CHECK-LABEL: @test6(
>>> -; CHECK: ret i32 0
>>> +; CHECK-NEXT: ret i32 0
>>> +;
>>> %temp1 = call arm_aapcscc i32 @strcmp(i8* %str, i8* %str)
>>> ret i32 %temp1
>>> @@ -84,10 +92,11 @@ define arm_aapcscc i32 @test6(i8* %str)
>>> ; strcmp("", x) -> -*x
>>> define arm_aapcs_vfpcc i32 @test1_vfp(i8* %str2) {
>>> ; CHECK-LABEL: @test1_vfp(
>>> -; 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 arm_aapcs_vfpcc i32 @strcmp(i8* %str1, i8* %str2)
>>> @@ -98,9 +107,10 @@ define arm_aapcs_vfpcc i32 @test1_vfp(i8
>>> ; strcmp(x, "") -> *x
>>> define arm_aapcs_vfpcc i32 @test2_vfp(i8* %str1) {
>>> ; CHECK-LABEL: @test2_vfp(
>>> -; CHECK: %strcmpload = load i8, i8* %str
>>> -; 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 arm_aapcs_vfpcc i32 @strcmp(i8* %str1, i8* %str2)
>>> @@ -110,7 +120,8 @@ define arm_aapcs_vfpcc i32 @test2_vfp(i8
>>> ; strcmp(x, y) -> cnst
>>> define arm_aapcs_vfpcc i32 @test3_vfp() {
>>> ; CHECK-LABEL: @test3_vfp(
>>> -; 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
>>> @@ -120,7 +131,8 @@ define arm_aapcs_vfpcc i32 @test3_vfp()
>>> define arm_aapcs_vfpcc i32 @test4_vfp() {
>>> ; CHECK-LABEL: @test4_vfp(
>>> -; 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
>>> @@ -132,8 +144,10 @@ define arm_aapcs_vfpcc i32 @test4_vfp()
>>> ; (This transform is rather difficult to trigger in a useful manner)
>>> define arm_aapcs_vfpcc i32 @test5_vfp(i1 %b) {
>>> ; CHECK-LABEL: @test5_vfp(
>>> -; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6
>>> x i8], [6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5)
>>> -; CHECK: ret i32 %memcmp
>>> +; 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: ret i32 [[MEMCMP]]
>>> +;
>>> %str1 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32
>>> 0, i32 0
>>> %temp1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0,
>>> i32 0
>>> @@ -146,7 +160,8 @@ define arm_aapcs_vfpcc i32 @test5_vfp(i1
>>> ; strcmp(x,x) -> 0
>>> define arm_aapcs_vfpcc i32 @test6_vfp(i8* %str) {
>>> ; CHECK-LABEL: @test6_vfp(
>>> -; CHECK: ret i32 0
>>> +; CHECK-NEXT: ret i32 0
>>> +;
>>> %temp1 = call arm_aapcs_vfpcc i32 @strcmp(i8* %str, i8* %str)
>>> ret i32 %temp1
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/align-addr.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/align-addr.ll Tue Aug 13
>>> 02:11:49 2019
>>> @@ -1,13 +1,33 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; RUN: opt < %s -instcombine -S | FileCheck %s
>>> target datalayout =
>>> "E-p:64:64:64-p1:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
>>> ; Instcombine should be able to prove vector alignment in the
>>> ; presence of a few mild address computation tricks.
>>> -; CHECK-LABEL: @test0(
>>> -; CHECK: align 16
>>> -
>>> define void @test0(i8* %b, i64 %n, i64 %u, i64 %y) nounwind {
>>> +; CHECK-LABEL: @test0(
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[C:%.*]] = ptrtoint i8* [[B:%.*]] to i64
>>> +; CHECK-NEXT: [[D:%.*]] = and i64 [[C]], -16
>>> +; CHECK-NEXT: [[E:%.*]] = inttoptr i64 [[D]] to double*
>>> +; CHECK-NEXT: [[V:%.*]] = shl i64 [[U:%.*]], 1
>>> +; CHECK-NEXT: [[Z:%.*]] = and i64 [[Y:%.*]], -2
>>> +; CHECK-NEXT: [[T1421:%.*]] = icmp eq i64 [[N:%.*]], 0
>>> +; CHECK-NEXT: br i1 [[T1421]], label [[RETURN:%.*]], label
>>> [[BB:%.*]]
>>> +; CHECK: bb:
>>> +; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[INDVAR_NEXT:%.*]], [[BB]]
>>> ], [ 20, [[ENTRY:%.*]] ]
>>> +; CHECK-NEXT: [[J:%.*]] = mul i64 [[I]], [[V]]
>>> +; CHECK-NEXT: [[H:%.*]] = add i64 [[J]], [[Z]]
>>> +; CHECK-NEXT: [[T8:%.*]] = getelementptr double, double* [[E]],
>>> i64 [[H]]
>>> +; CHECK-NEXT: [[P:%.*]] = bitcast double* [[T8]] to <2 x double>*
>>> +; CHECK-NEXT: store <2 x double> zeroinitializer, <2 x double>*
>>> [[P]], align 16
>>> +; CHECK-NEXT: [[INDVAR_NEXT]] = add i64 [[I]], 1
>>> +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVAR_NEXT]], [[N]]
>>> +; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
>>> +; CHECK: return:
>>> +; CHECK-NEXT: ret void
>>> +;
>>> entry:
>>> %c = ptrtoint i8* %b to i64
>>> %d = and i64 %c, -16
>>> @@ -35,24 +55,26 @@ return:
>>> ; When we see a unaligned load from an insufficiently aligned global or
>>> ; alloca, increase the alignment of the load, turning it into an
>>> aligned load.
>>> -; CHECK-LABEL: @test1(
>>> -; CHECK: tmp = load
>>> -; CHECK: GLOBAL{{.*}}align 16
>>> -
>>> @GLOBAL = internal global [4 x i32] zeroinitializer
>>> define <16 x i8> @test1(<2 x i64> %x) {
>>> +; CHECK-LABEL: @test1(
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[TMP:%.*]] = load <16 x i8>, <16 x i8>* bitcast
>>> ([4 x i32]* @GLOBAL to <16 x i8>*), align 16
>>> +; CHECK-NEXT: ret <16 x i8> [[TMP]]
>>> +;
>>> entry:
>>> - %tmp = load <16 x i8>, <16 x i8>* bitcast ([4 x i32]* @GLOBAL
>>> to <16 x i8>*), align 1
>>> - ret <16 x i8> %tmp
>>> + %tmp = load <16 x i8>, <16 x i8>* bitcast ([4 x i32]* @GLOBAL to
>>> <16 x i8>*), align 1
>>> + ret <16 x i8> %tmp
>>> }
>>> @GLOBAL_as1 = internal addrspace(1) global [4 x i32] zeroinitializer
>>> define <16 x i8> @test1_as1(<2 x i64> %x) {
>>> ; CHECK-LABEL: @test1_as1(
>>> -; CHECK: tmp = load
>>> -; CHECK: GLOBAL_as1{{.*}}align 16
>>> +; CHECK-NEXT: [[TMP:%.*]] = load <16 x i8>, <16 x i8>
>>> addrspace(1)* bitcast ([4 x i32] addrspace(1)* @GLOBAL_as1 to <16 x
>>> i8> addrspace(1)*), align 16
>>> +; CHECK-NEXT: ret <16 x i8> [[TMP]]
>>> +;
>>> %tmp = load <16 x i8>, <16 x i8> addrspace(1)* bitcast ([4 x i32]
>>> addrspace(1)* @GLOBAL_as1 to <16 x i8> addrspace(1)*), align 1
>>> ret <16 x i8> %tmp
>>> }
>>> @@ -61,8 +83,9 @@ define <16 x i8> @test1_as1(<2 x i64> %x
>>> define <16 x i8> @test1_as1_gep(<2 x i64> %x) {
>>> ; CHECK-LABEL: @test1_as1_gep(
>>> -; CHECK: tmp = load
>>> -; CHECK: GLOBAL_as1_gep{{.*}}align 16
>>> +; CHECK-NEXT: [[TMP:%.*]] = load <16 x i8>, <16 x i8>
>>> addrspace(1)* bitcast (i32 addrspace(1)* getelementptr inbounds ([8
>>> x i32], [8 x i32] addrspace(1)* @GLOBAL_as1_gep, i32 0, i32 4) to
>>> <16 x i8> addrspace(1)*), align 16
>>> +; CHECK-NEXT: ret <16 x i8> [[TMP]]
>>> +;
>>> %tmp = load <16 x i8>, <16 x i8> addrspace(1)* bitcast (i32
>>> addrspace(1)* getelementptr ([8 x i32], [8 x i32] addrspace(1)*
>>> @GLOBAL_as1_gep, i16 0, i16 4) to <16 x i8> addrspace(1)*), align 1
>>> ret <16 x i8> %tmp
>>> }
>>> @@ -70,11 +93,12 @@ define <16 x i8> @test1_as1_gep(<2 x i64
>>> ; When a load or store lacks an explicit alignment, add one.
>>> -; CHECK-LABEL: @test2(
>>> -; CHECK: load double, double* %p, align 8
>>> -; CHECK: store double %n, double* %p, align 8
>>> -
>>> define double @test2(double* %p, double %n) nounwind {
>>> +; CHECK-LABEL: @test2(
>>> +; CHECK-NEXT: [[T:%.*]] = load double, double* [[P:%.*]], align 8
>>> +; CHECK-NEXT: store double [[N:%.*]], double* [[P]], align 8
>>> +; CHECK-NEXT: ret double [[T]]
>>> +;
>>> %t = load double, double* %p
>>> store double %n, double* %p
>>> ret double %t
>>> @@ -89,9 +113,13 @@ declare void @use(i8*)
>>> 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 @use(i8* [[A4_CAST]])
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %a4.cast = bitcast %struct.s* %a4 to i8*
>>> call void @llvm.memset.p0i8.i64(i8* %a4.cast, i8 0, i64 16, i1 false)
>>> -; CHECK: call void @llvm.memset.p0i8.i64(i8* align 4 %a4.cast, i8
>>> 0, i64 16, i1 false)
>>> call void @use(i8* %a4.cast)
>>> ret void
>>> }
>>>
>>> Added: 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=368657&view=auto
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes.ll (added)
>>> +++ llvm/trunk/test/Transforms/InstCombine/mem-deref-bytes.ll Tue
>>> Aug 13 02:11:49 2019
>>> @@ -0,0 +1,127 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> +; RUN: opt -instcombine -S < %s | FileCheck %s
>>> +
>>> +declare i32 @memcmp(i8* nocapture, i8* nocapture, i64)
>>> +declare i8* @memcpy(i8* nocapture, i8* nocapture, i64)
>>> +declare i8* @memmove(i8* nocapture, i8* nocapture, i64)
>>> +declare i8* @memset(i8* nocapture, i8, i64)
>>> +declare i8* @memchr(i8* nocapture, i32, i64)
>>> +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8*
>>> nocapture, i64, i1)
>>> +declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8*
>>> nocapture, i64, i1)
>>> +declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1)
>>> +
>>> +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: ret i32 [[CALL]]
>>> +;
>>> + %call = tail call i32 @memcmp(i8* %d, i8* %s, i64 16)
>>> + ret i32 %call
>>> +}
>>> +
>>> +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: ret i32 [[CALL]]
>>> +;
>>> + %call = tail call i32 @memcmp(i8* dereferenceable(4) %d, i8*
>>> dereferenceable(8) %s, i64 16)
>>> + ret i32 %call
>>> +}
>>> +
>>> +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: ret i32 [[CALL]]
>>> +;
>>> + %call = tail call i32 @memcmp(i8* %d, i8*
>>> dereferenceable_or_null(8) %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(16) [[S:%.*]],
>>> i64 16)
>>> +; CHECK-NEXT: ret i32 [[CALL]]
>>> +;
>>> + %call = tail call i32 @memcmp(i8* dereferenceable(40) %d, i8* %s,
>>> i64 16)
>>> + ret i32 %call
>>> +}
>>> +
>>> +define i32 @memcmp_const_size_no_update_deref2(i8* nocapture
>>> readonly %d, i8* nocapture readonly %s) {
>>> +; CHECK-LABEL: @memcmp_const_size_no_update_deref2(
>>> +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8*
>>> dereferenceable(16) [[D:%.*]], i8* 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)
>>> + ret i32 %call
>>> +}
>>> +
>>> +define i32 @memcmp_nonconst_size(i8* nocapture readonly %d, i8*
>>> nocapture readonly %s, i64 %n) {
>>> +; CHECK-LABEL: @memcmp_nonconst_size(
>>> +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8*
>>> [[D:%.*]], i8* [[S:%.*]], i64 [[N:%.*]])
>>> +; CHECK-NEXT: ret i32 [[CALL]]
>>> +;
>>> + %call = tail call i32 @memcmp(i8* %d, i8* %s, i64 %n)
>>> + ret i32 %call
>>> +}
>>> +
>>> +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: ret i8* [[D]]
>>> +;
>>> + %call = tail call i8* @memcpy(i8* %d, i8* %s, i64 64)
>>> + ret i8* %call
>>> +}
>>> +
>>> +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: ret i8* [[D]]
>>> +;
>>> + %call = tail call i8* @memmove(i8* %d, i8* %s, i64 64)
>>> + ret i8* %call
>>> +}
>>> +
>>> +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: ret i8* [[S]]
>>> +;
>>> + %call = tail call i8* @memset(i8* %s, i8 %c, i64 64)
>>> + ret i8* %call
>>> +}
>>> +
>>> +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: ret i8* [[CALL]]
>>> +;
>>> + %call = tail call i8* @memchr(i8* %s, i32 %c, i64 64)
>>> + ret i8* %call
>>> +}
>>> +
>>> +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: ret i8* [[D]]
>>> +;
>>> + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %d, i8* align 1
>>> %s, i64 16, i1 false)
>>> + ret i8* %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: ret i8* [[D]]
>>> +;
>>> + call void @llvm.memmove.p0i8.p0i8.i64(i8* align 1 %d, i8* align 1
>>> %s, i64 16, i1 false)
>>> + ret i8* %d
>>> +}
>>> +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: ret i8* [[S]]
>>> +;
>>> + call void @llvm.memset.p0i8.i64(i8* align 1 %s, i8 %c, i64 16, i1
>>> false)
>>> + ret i8* %s
>>> +}
>>>
>>> Modified: llvm/trunk/test/Transforms/InstCombine/memchr.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memchr.ll?rev=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/memchr.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/memchr.ll Tue Aug 13
>>> 02:11:49 2019
>>> @@ -50,7 +50,7 @@ define void @test3() {
>>> define void @test4(i32 %chr) {
>>> ; CHECK-LABEL: @test4(
>>> -; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* getelementptr
>>> inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32
>>> [[CHR:%.*]], i32 14)
>>> +; 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: 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* getelementptr
>>> inbounds ([4 x i8], [4 x i8]* @spaces, i32 0, i32 0), i32 [[C:%.*]],
>>> i32 3)
>>> +; 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: [[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* getelementptr
>>> inbounds ([3 x i8], [3 x i8]* @negative, i32 0, i32 0), i32
>>> [[C:%.*]], i32 3)
>>> +; 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: [[CMP:%.*]] = icmp ne i8* [[DST]], null
>>> ; CHECK-NEXT: ret i1 [[CMP]]
>>> ;
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/memcmp-constant-fold.ll
>>> (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/memcmp-constant-fold.ll
>>> Tue Aug 13 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; RUN: opt < %s -instcombine -S -data-layout=e-n32 | FileCheck %s
>>> --check-prefix=ALL --check-prefix=LE
>>> ; RUN: opt < %s -instcombine -S -data-layout=E-n32 | FileCheck %s
>>> --check-prefix=ALL --check-prefix=BE
>>> @@ -9,13 +10,13 @@ declare i32 @memcmp(i8*, i8*, i64)
>>> define i1 @memcmp_4bytes_unaligned_constant_i8(i8* align 4 %x) {
>>> ; LE-LABEL: @memcmp_4bytes_unaligned_constant_i8(
>>> -; LE-NEXT: [[TMP1:%.*]] = bitcast i8* %x to i32*
>>> +; LE-NEXT: [[TMP1:%.*]] = bitcast i8* [[X:%.*]] to i32*
>>> ; LE-NEXT: [[LHSV:%.*]] = load i32, i32* [[TMP1]], align 4
>>> ; LE-NEXT: [[TMP2:%.*]] = icmp eq i32 [[LHSV]], 16777216
>>> ; LE-NEXT: ret i1 [[TMP2]]
>>> ;
>>> ; BE-LABEL: @memcmp_4bytes_unaligned_constant_i8(
>>> -; BE-NEXT: [[TMP1:%.*]] = bitcast i8* %x to i32*
>>> +; BE-NEXT: [[TMP1:%.*]] = bitcast i8* [[X:%.*]] to i32*
>>> ; BE-NEXT: [[LHSV:%.*]] = load i32, i32* [[TMP1]], align 4
>>> ; BE-NEXT: [[TMP2:%.*]] = icmp eq i32 [[LHSV]], 1
>>> ; BE-NEXT: ret i1 [[TMP2]]
>>> @@ -32,13 +33,13 @@ define i1 @memcmp_4bytes_unaligned_const
>>> define i1 @memcmp_4bytes_unaligned_constant_i16(i8* align 4 %x) {
>>> ; LE-LABEL: @memcmp_4bytes_unaligned_constant_i16(
>>> -; LE-NEXT: [[TMP1:%.*]] = bitcast i8* %x to i32*
>>> +; LE-NEXT: [[TMP1:%.*]] = bitcast i8* [[X:%.*]] to i32*
>>> ; LE-NEXT: [[RHSV:%.*]] = load i32, i32* [[TMP1]], align 4
>>> ; LE-NEXT: [[TMP2:%.*]] = icmp eq i32 [[RHSV]], 131073
>>> ; LE-NEXT: ret i1 [[TMP2]]
>>> ;
>>> ; BE-LABEL: @memcmp_4bytes_unaligned_constant_i16(
>>> -; BE-NEXT: [[TMP1:%.*]] = bitcast i8* %x to i32*
>>> +; BE-NEXT: [[TMP1:%.*]] = bitcast i8* [[X:%.*]] to i32*
>>> ; BE-NEXT: [[RHSV:%.*]] = load i32, i32* [[TMP1]], align 4
>>> ; BE-NEXT: [[TMP2:%.*]] = icmp eq i32 [[RHSV]], 65538
>>> ; BE-NEXT: ret i1 [[TMP2]]
>>> @@ -54,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* bitcast
>>> (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @intbuf, i64 0,
>>> i64 1) to i8*), i8* bitcast ([2 x i32]* @intbuf to i8*), i64 3)
>>> +; 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: [[CMPEQ0:%.*]] = icmp eq i32 [[CALL]], 0
>>> ; ALL-NEXT: ret i1 [[CMPEQ0]]
>>> ;
>>> @@ -67,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* %x, i8* %y,
>>> i64 4)
>>> +; ALL-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8*
>>> dereferenceable(4) [[X:%.*]], i8* 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/memcpy-from-global.ll
>>> (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/memcpy-from-global.ll Tue
>>> Aug 13 02:11:49 2019
>>> @@ -1,39 +1,66 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; RUN: opt < %s -instcombine -S | FileCheck %s
>>> target datalayout =
>>> "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
>>> @C.0.1248 = internal constant [128 x float] [ float -1.000000e+00,
>>> float -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float
>>> -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float
>>> -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float
>>> 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float
>>> -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float
>>> -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float
>>> -1.000000e+00, float -1.000000e+00, float 0.000000e+00, float
>>> -1.000000e+00, float 1.000000e+00, float -1.000000e+00, float
>>> 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float
>>> -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float
>>> 1.000000e+00, float -1.000000e+00, float 1.000000e+00, float
>>> -1.000000e+00, float 0.000000e+00, float -1.000000e+00, float
>>> 1.000000e+00, float 0.000000e+00, float -1.000000e+00, float
>>> -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float
>>> 1.000000e+00, float -1.000000e+00, float 1.000000e+00, float
>>> 1.000000e+00, float 0.000000e+00, float 0.000000e+00, float
>>> -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float
>>> 0.000000e+00, float -1.000000e+00, float -1.000000e+00, float
>>> 1.000000e+00, float 0.000000e+00, float -1.000000e+00, float
>>> 1.000000e+00, float -1.000000e+00, float 0.000000e+00, float
>>> -1.000000e+00, float 1.000000e+00, float 1.000000e+00, float
>>> 1.000000e+00, float -1.000000e+00, float -1.000000e+00, float
>>> 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float
>>> 0.000000e+00, float -1.000000e+00, float 1.000000e+00, float
>>> -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float
>>> 1.000000e+00, float -1.000000e+00, float 1.000000e+00, float
>>> 0.000000e+00, float 1.000000e+00, float 0.000000e+00, float
>>> -1.000000e+00, float -1.000000e+00, float 1.000000e+00, float
>>> 0.000000e+00, float -1.000000e+00, float 1.000000e+00, float
>>> 1.000000e+00, float 0.000000e+00, float 1.000000e+00, float
>>> -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float
>>> 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float
>>> 1.000000e+00, float -1.000000e+00, float 0.000000e+00, float
>>> 1.000000e+00, float 1.000000e+00, float 0.000000e+00, float
>>> -1.000000e+00, float 1.000000e+00, float 1.000000e+00, float
>>> 0.000000e+00, float 1.000000e+00, float 1.000000e+00, float
>>> 1.000000e+00, float 1.000000e+00, float 0.000000e+00, float
>>> 0.000000e+00, float 1.000000e+00, float -1.000000e+00, float
>>> -1.000000e+00, float 0.000000e+00, float 1.000000e+00, float
>>> -1.000000e+00, float 1.000000e+00, float 0.000000e+00, float
>>> 1.000000e+00, float 1.000000e+00, float -1.000000e+00, float
>>> 0.000000e+00, float 1.000000e+00, float 1.000000e+00, float
>>> 1.000000e+00 ], align 32 ; <[128 x float]*> [#uses=1]
>>> define float @test1(i32 %hash, float %x, float %y, float %z,
>>> float %w) {
>>> -entry:
>>> - %lookupTable = alloca [128 x float], align 16 ; <[128 x
>>> float]*> [#uses=5]
>>> - %lookupTable1 = bitcast [128 x float]* %lookupTable to i8*
>>> ; <i8*> [#uses=1]
>>> - call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16
>>> %lookupTable1, i8* align 16 bitcast ([128 x float]* @C.0.1248 to
>>> i8*), i64 512, i1 false)
>>> -
>>> ; CHECK-LABEL: @test1(
>>> -; CHECK-NOT: alloca
>>> -; CHECK-NOT: call{{.*}}@llvm.memcpy <mailto:call{{.*}}@llvm.memcpy>
>>> -
>>> - %tmp3 = shl i32 %hash, 2 ; <i32> [#uses=1]
>>> - %tmp5 = and i32 %tmp3, 124 ; <i32> [#uses=4]
>>> - %tmp753 = getelementptr [128 x float], [128 x float]*
>>> %lookupTable, i32 0, i32 %tmp5 ; <float*> [#uses=1]
>>> - %tmp9 = load float, float* %tmp753 ; <float> [#uses=1]
>>> - %tmp11 = fmul float %tmp9, %x ; <float> [#uses=1]
>>> - %tmp13 = fadd float %tmp11, 0.000000e+00 ; <float> [#uses=1]
>>> - %tmp17.sum52 = or i32 %tmp5, 1 ; <i32> [#uses=1]
>>> - %tmp1851 = getelementptr [128 x float], [128 x float]*
>>> %lookupTable, i32 0, i32 %tmp17.sum52 ; <float*> [#uses=1]
>>> - %tmp19 = load float, float* %tmp1851 ; <float> [#uses=1]
>>> - %tmp21 = fmul float %tmp19, %y ; <float> [#uses=1]
>>> - %tmp23 = fadd float %tmp21, %tmp13 ; <float> [#uses=1]
>>> - %tmp27.sum50 = or i32 %tmp5, 2 ; <i32> [#uses=1]
>>> - %tmp2849 = getelementptr [128 x float], [128 x float]*
>>> %lookupTable, i32 0, i32 %tmp27.sum50 ; <float*> [#uses=1]
>>> - %tmp29 = load float, float* %tmp2849 ; <float> [#uses=1]
>>> - %tmp31 = fmul float %tmp29, %z ; <float> [#uses=1]
>>> - %tmp33 = fadd float %tmp31, %tmp23 ; <float> [#uses=1]
>>> - %tmp37.sum48 = or i32 %tmp5, 3 ; <i32> [#uses=1]
>>> - %tmp3847 = getelementptr [128 x float], [128 x float]*
>>> %lookupTable, i32 0, i32 %tmp37.sum48 ; <float*> [#uses=1]
>>> - %tmp39 = load float, float* %tmp3847 ; <float> [#uses=1]
>>> - %tmp41 = fmul float %tmp39, %w ; <float> [#uses=1]
>>> - %tmp43 = fadd float %tmp41, %tmp33 ; <float> [#uses=1]
>>> - ret float %tmp43
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[TMP3:%.*]] = shl i32 [[HASH:%.*]], 2
>>> +; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP3]], 124
>>> +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[TMP5]] to i64
>>> +; CHECK-NEXT: [[TMP753:%.*]] = getelementptr [128 x float], [128
>>> x float]* @C.0.1248, i64 0, i64 [[TMP0]]
>>> +; CHECK-NEXT: [[TMP9:%.*]] = load float, float* [[TMP753]], align 16
>>> +; CHECK-NEXT: [[TMP11:%.*]] = fmul float [[TMP9]], [[X:%.*]]
>>> +; CHECK-NEXT: [[TMP13:%.*]] = fadd float [[TMP11]], 0.000000e+00
>>> +; CHECK-NEXT: [[TMP17_SUM52:%.*]] = or i32 [[TMP5]], 1
>>> +; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP17_SUM52]] to i64
>>> +; CHECK-NEXT: [[TMP1851:%.*]] = getelementptr [128 x float],
>>> [128 x float]* @C.0.1248, i64 0, i64 [[TMP1]]
>>> +; CHECK-NEXT: [[TMP19:%.*]] = load float, float* [[TMP1851]],
>>> align 4
>>> +; CHECK-NEXT: [[TMP21:%.*]] = fmul float [[TMP19]], [[Y:%.*]]
>>> +; CHECK-NEXT: [[TMP23:%.*]] = fadd float [[TMP21]], [[TMP13]]
>>> +; CHECK-NEXT: [[TMP27_SUM50:%.*]] = or i32 [[TMP5]], 2
>>> +; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP27_SUM50]] to i64
>>> +; CHECK-NEXT: [[TMP2849:%.*]] = getelementptr [128 x float],
>>> [128 x float]* @C.0.1248, i64 0, i64 [[TMP2]]
>>> +; CHECK-NEXT: [[TMP29:%.*]] = load float, float* [[TMP2849]],
>>> align 8
>>> +; CHECK-NEXT: [[TMP31:%.*]] = fmul float [[TMP29]], [[Z:%.*]]
>>> +; CHECK-NEXT: [[TMP33:%.*]] = fadd float [[TMP31]], [[TMP23]]
>>> +; CHECK-NEXT: [[TMP37_SUM48:%.*]] = or i32 [[TMP5]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = zext i32 [[TMP37_SUM48]] to i64
>>> +; CHECK-NEXT: [[TMP3847:%.*]] = getelementptr [128 x float],
>>> [128 x float]* @C.0.1248, i64 0, i64 [[TMP3]]
>>> +; CHECK-NEXT: [[TMP39:%.*]] = load float, float* [[TMP3847]],
>>> align 4
>>> +; CHECK-NEXT: [[TMP41:%.*]] = fmul float [[TMP39]], [[W:%.*]]
>>> +; CHECK-NEXT: [[TMP43:%.*]] = fadd float [[TMP41]], [[TMP33]]
>>> +; CHECK-NEXT: ret float [[TMP43]]
>>> +;
>>> +entry:
>>> + %lookupTable = alloca [128 x float], align 16 ; <[128 x
>>> float]*> [#uses=5]
>>> + %lookupTable1 = bitcast [128 x float]* %lookupTable to i8*
>>> ; <i8*> [#uses=1]
>>> + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %lookupTable1,
>>> i8* align 16 bitcast ([128 x float]* @C.0.1248 to i8*), i64 512, i1
>>> false)
>>> +
>>> +
>>> + %tmp3 = shl i32 %hash, 2 ; <i32> [#uses=1]
>>> + %tmp5 = and i32 %tmp3, 124 ; <i32> [#uses=4]
>>> + %tmp753 = getelementptr [128 x float], [128 x float]*
>>> %lookupTable, i32 0, i32 %tmp5 ; <float*> [#uses=1]
>>> + %tmp9 = load float, float* %tmp753 ; <float> [#uses=1]
>>> + %tmp11 = fmul float %tmp9, %x ; <float> [#uses=1]
>>> + %tmp13 = fadd float %tmp11, 0.000000e+00 ; <float> [#uses=1]
>>> + %tmp17.sum52 = or i32 %tmp5, 1 ; <i32> [#uses=1]
>>> + %tmp1851 = getelementptr [128 x float], [128 x float]*
>>> %lookupTable, i32 0, i32 %tmp17.sum52 ; <float*> [#uses=1]
>>> + %tmp19 = load float, float* %tmp1851 ; <float> [#uses=1]
>>> + %tmp21 = fmul float %tmp19, %y ; <float> [#uses=1]
>>> + %tmp23 = fadd float %tmp21, %tmp13 ; <float> [#uses=1]
>>> + %tmp27.sum50 = or i32 %tmp5, 2 ; <i32> [#uses=1]
>>> + %tmp2849 = getelementptr [128 x float], [128 x float]*
>>> %lookupTable, i32 0, i32 %tmp27.sum50 ; <float*> [#uses=1]
>>> + %tmp29 = load float, float* %tmp2849 ; <float> [#uses=1]
>>> + %tmp31 = fmul float %tmp29, %z ; <float> [#uses=1]
>>> + %tmp33 = fadd float %tmp31, %tmp23 ; <float> [#uses=1]
>>> + %tmp37.sum48 = or i32 %tmp5, 3 ; <i32> [#uses=1]
>>> + %tmp3847 = getelementptr [128 x float], [128 x float]*
>>> %lookupTable, i32 0, i32 %tmp37.sum48 ; <float*> [#uses=1]
>>> + %tmp39 = load float, float* %tmp3847 ; <float> [#uses=1]
>>> + %tmp41 = fmul float %tmp39, %w ; <float> [#uses=1]
>>> + %tmp43 = fadd float %tmp41, %tmp33 ; <float> [#uses=1]
>>> + ret float %tmp43
>>> }
>>> declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8*
>>> nocapture, i64, i1) nounwind
>>> @@ -48,19 +75,22 @@ declare void @llvm.memcpy.p1i8.p1i8.i64(
>>> @H = constant [2 x %U] zeroinitializer, align 16
>>> 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 @bar(i8* nonnull [[B1_SUB]])
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %T
>>> %B = alloca %T
>>> %a = bitcast %T* %A to i8*
>>> %b = bitcast %T* %B to i8*
>>> -; CHECK-LABEL: @test2(
>>> ; %A alloca is deleted
>>> -; CHECK-NEXT: alloca [124 x i8]
>>> -; CHECK-NEXT: getelementptr inbounds [124 x i8], [124 x i8]*
>>> ; use @G instead of %A
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull
>>> align 8 %{{.*}}, i8* align 16 getelementptr inbounds (%T, %T* @G,
>>> i64 0, i32 0)
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4
>>> bitcast (%T* @G to i8*), i64 124, i1 false)
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %b, i8* align 4
>>> %a, i64 124, i1 false)
>>> call void @bar(i8* %b)
>>> @@ -68,19 +98,22 @@ define void @test2() {
>>> }
>>> define void @test2_no_null_opt() #0 {
>>> +; CHECK-LABEL: @test2_no_null_opt(
>>> +; 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* 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 @bar(i8* [[B1_SUB]])
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %T
>>> %B = alloca %T
>>> %a = bitcast %T* %A to i8*
>>> %b = bitcast %T* %B to i8*
>>> -; CHECK-LABEL: @test2_no_null_opt(
>>> ; %A alloca is deleted
>>> -; CHECK-NEXT: alloca [124 x i8]
>>> -; CHECK-NEXT: getelementptr inbounds [124 x i8], [124 x i8]*
>>> ; use @G instead of %A
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8
>>> %{{.*}}, i8* align 16 getelementptr inbounds (%T, %T* @G, i64 0, i32 0)
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4
>>> bitcast (%T* @G to i8*), i64 124, i1 false)
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %b, i8* align 4
>>> %a, i64 124, i1 false)
>>> call void @bar(i8* %b)
>>> @@ -88,22 +121,25 @@ define void @test2_no_null_opt() #0 {
>>> }
>>> define void @test2_addrspacecast() {
>>> +; CHECK-LABEL: @test2_addrspacecast(
>>> +; 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: [[B:%.*]] = addrspacecast i8* [[B1_SUB]] to i8
>>> addrspace(1)*
>>> +; CHECK-NEXT: call void @llvm.memcpy.p1i8.p1i8.i64(i8
>>> addrspace(1)* align 4 dereferenceable(124) [[B]], i8 addrspace(1)*
>>> align 4 dereferenceable(124) addrspacecast (i8* getelementptr
>>> inbounds (%T, %T* @G, i64 0, i32 0) to i8 addrspace(1)*), i64 124,
>>> i1 false)
>>> +; CHECK-NEXT: call void @bar_as1(i8 addrspace(1)* [[B]])
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %T
>>> %B = alloca %T
>>> %a = addrspacecast %T* %A to i8 addrspace(1)*
>>> %b = addrspacecast %T* %B to i8 addrspace(1)*
>>> -; CHECK-LABEL: @test2_addrspacecast(
>>> ; %A alloca is deleted
>>> ; This doesn't exactly match what test2 does, because folding the type
>>> ; cast into the alloca doesn't work for the addrspacecast yet.
>>> -; CHECK-NEXT: alloca [124 x i8]
>>> -; CHECK-NEXT: getelementptr
>>> -; CHECK-NEXT: addrspacecast
>>> ; use @G instead of %A
>>> -; CHECK-NEXT: call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)*
>>> align 4 %{{.*}},
>>> call void @llvm.memcpy.p1i8.p0i8.i64(i8 addrspace(1)* align 4 %a,
>>> i8* align 4 bitcast (%T* @G to i8*), i64 124, i1 false)
>>> call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* align 4 %b,
>>> i8 addrspace(1)* align 4 %a, i64 124, i1 false)
>>> call void @bar_as1(i8 addrspace(1)* %b)
>>> @@ -116,45 +152,53 @@ declare void @bar_as1(i8 addrspace(1)*)
>>> ;; Should be able to eliminate the alloca.
>>> define void @test3() {
>>> +; CHECK-LABEL: @test3(
>>> +; CHECK-NEXT: call void @bar(i8* getelementptr inbounds (%T, %T*
>>> @G, i64 0, i32 0)) #2
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %T
>>> %a = bitcast %T* %A to i8*
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4
>>> bitcast (%T* @G to i8*), i64 124, i1 false)
>>> call void @bar(i8* %a) readonly
>>> -; CHECK-LABEL: @test3(
>>> -; CHECK-NEXT: call void @bar(i8* getelementptr inbounds (%T, %T*
>>> @G, i64 0, i32 0))
>>> ret void
>>> }
>>> define void @test3_addrspacecast() {
>>> +; CHECK-LABEL: @test3_addrspacecast(
>>> +; CHECK-NEXT: call void @bar(i8* getelementptr inbounds (%T, %T*
>>> @G, i64 0, i32 0)) #2
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %T
>>> %a = bitcast %T* %A to i8*
>>> call void @llvm.memcpy.p0i8.p1i8.i64(i8* align 4 %a, i8
>>> addrspace(1)* align 4 addrspacecast (%T* @G to i8 addrspace(1)*),
>>> i64 124, i1 false)
>>> call void @bar(i8* %a) readonly
>>> -; CHECK-LABEL: @test3_addrspacecast(
>>> -; CHECK-NEXT: call void @bar(i8* getelementptr inbounds (%T, %T*
>>> @G, i64 0, i32 0))
>>> ret void
>>> }
>>> define void @test4() {
>>> +; CHECK-LABEL: @test4(
>>> +; CHECK-NEXT: call void @baz(i8* byval getelementptr inbounds
>>> (%T, %T* @G, i64 0, i32 0))
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %T
>>> %a = bitcast %T* %A to i8*
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4
>>> bitcast (%T* @G to i8*), i64 124, i1 false)
>>> call void @baz(i8* byval %a)
>>> -; CHECK-LABEL: @test4(
>>> -; CHECK-NEXT: call void @baz(i8* byval getelementptr inbounds (%T,
>>> %T* @G, i64 0, i32 0))
>>> ret void
>>> }
>>> declare void @llvm.lifetime.start.p0i8(i64, i8*)
>>> define void @test5() {
>>> +; CHECK-LABEL: @test5(
>>> +; CHECK-NEXT: call void @baz(i8* byval getelementptr inbounds
>>> (%T, %T* @G, i64 0, i32 0))
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %T
>>> %a = bitcast %T* %A to i8*
>>> call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a)
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4
>>> bitcast (%T* @G to i8*), i64 124, i1 false)
>>> call void @baz(i8* byval %a)
>>> -; CHECK-LABEL: @test5(
>>> -; CHECK-NEXT: call void @baz(i8* byval getelementptr inbounds (%T,
>>> %T* @G, i64 0, i32 0))
>>> ret void
>>> }
>>> @@ -163,65 +207,81 @@ declare void @baz(i8* byval)
>>> define void @test6() {
>>> +; CHECK-LABEL: @test6(
>>> +; CHECK-NEXT: call void @bar(i8* bitcast ([2 x %U]* @H to i8*)) #2
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %U, align 16
>>> %a = bitcast %U* %A to i8*
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align
>>> 16 bitcast ([2 x %U]* @H to i8*), i64 20, i1 false)
>>> call void @bar(i8* %a) readonly
>>> -; CHECK-LABEL: @test6(
>>> -; CHECK-NEXT: call void @bar(i8* bitcast ([2 x %U]* @H to i8*))
>>> ret void
>>> }
>>> define void @test7() {
>>> +; CHECK-LABEL: @test7(
>>> +; CHECK-NEXT: call void @bar(i8* bitcast ([2 x %U]* @H to i8*)) #2
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %U, align 16
>>> %a = bitcast %U* %A to i8*
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4
>>> bitcast (%U* getelementptr ([2 x %U], [2 x %U]* @H, i64 0, i32 0) to
>>> i8*), i64 20, i1 false)
>>> call void @bar(i8* %a) readonly
>>> -; CHECK-LABEL: @test7(
>>> -; CHECK-NEXT: call void @bar(i8* bitcast ([2 x %U]* @H to i8*))
>>> ret void
>>> }
>>> define void @test8() {
>>> - %A = alloca %U, align 16
>>> - %a = bitcast %U* %A to i8*
>>> +; 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 @bar(i8* nonnull [[A]]) #2
>>> +; CHECK-NEXT: ret void
>>> +;
>>> + %al = alloca %U, align 16
>>> + %a = bitcast %U* %al to i8*
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4
>>> bitcast (%U* getelementptr ([2 x %U], [2 x %U]* @H, i64 0, i32 1) to
>>> i8*), i64 20, i1 false)
>>> call void @bar(i8* %a) readonly
>>> -; CHECK-LABEL: @test8(
>>> -; CHECK: llvm.memcpy
>>> -; CHECK: bar
>>> ret void
>>> }
>>> define void @test8_addrspacecast() {
>>> - %A = alloca %U, align 16
>>> - %a = bitcast %U* %A to i8*
>>> +; CHECK-LABEL: @test8_addrspacecast(
>>> +; CHECK-NEXT: [[AL:%.*]] = alloca [[U:%.*]], align 16
>>> +; CHECK-NEXT: [[A:%.*]] = bitcast %U* [[AL]] to i8*
>>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p1i8.i64(i8* nonnull
>>> align 16 dereferenceable(20) [[A]], i8 addrspace(1)* align 4
>>> dereferenceable(20) addrspacecast (i8* bitcast (%U* getelementptr
>>> inbounds ([2 x %U], [2 x %U]* @H, i64 0, i64 1) to i8*) to i8
>>> addrspace(1)*), i64 20, i1 false)
>>> +; CHECK-NEXT: call void @bar(i8* nonnull [[A]]) #2
>>> +; CHECK-NEXT: ret void
>>> +;
>>> + %Al = alloca %U, align 16
>>> + %a = bitcast %U* %Al to i8*
>>> call void @llvm.memcpy.p0i8.p1i8.i64(i8* align 4 %a, i8
>>> addrspace(1)* align 4 addrspacecast (%U* getelementptr ([2 x %U], [2
>>> x %U]* @H, i64 0, i32 1) to i8 addrspace(1)*), i64 20, i1 false)
>>> call void @bar(i8* %a) readonly
>>> -; CHECK-LABEL: @test8_addrspacecast(
>>> -; CHECK: llvm.memcpy
>>> -; CHECK: bar
>>> ret void
>>> }
>>> define void @test9() {
>>> +; CHECK-LABEL: @test9(
>>> +; CHECK-NEXT: call void @bar(i8* bitcast (%U* getelementptr
>>> inbounds ([2 x %U], [2 x %U]* @H, i64 0, i64 1) to i8*)) #2
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %U, align 4
>>> %a = bitcast %U* %A to i8*
>>> call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4
>>> bitcast (%U* getelementptr ([2 x %U], [2 x %U]* @H, i64 0, i32 1) to
>>> i8*), i64 20, i1 false)
>>> call void @bar(i8* %a) readonly
>>> -; CHECK-LABEL: @test9(
>>> -; CHECK-NEXT: call void @bar(i8* bitcast (%U* getelementptr
>>> inbounds ([2 x %U], [2 x %U]* @H, i64 0, i64 1) to i8*))
>>> ret void
>>> }
>>> define void @test9_addrspacecast() {
>>> +; CHECK-LABEL: @test9_addrspacecast(
>>> +; CHECK-NEXT: call void @bar(i8* bitcast (%U* getelementptr
>>> inbounds ([2 x %U], [2 x %U]* @H, i64 0, i64 1) to i8*)) #2
>>> +; CHECK-NEXT: ret void
>>> +;
>>> %A = alloca %U, align 4
>>> %a = bitcast %U* %A to i8*
>>> call void @llvm.memcpy.p0i8.p1i8.i64(i8* align 4 %a, i8
>>> addrspace(1)* align 4 addrspacecast (%U* getelementptr ([2 x %U], [2
>>> x %U]* @H, i64 0, i32 1) to i8 addrspace(1)*), i64 20, i1 false)
>>> call void @bar(i8* %a) readonly
>>> -; CHECK-LABEL: @test9_addrspacecast(
>>> -; CHECK-NEXT: call void @bar(i8* bitcast (%U* getelementptr
>>> inbounds ([2 x %U], [2 x %U]* @H, i64 0, i64 1) to i8*))
>>> ret void
>>> }
>>> @@ -231,8 +291,13 @@ define void @test9_addrspacecast() {
>>> ; Should not replace alloca with global because of size mismatch.
>>> define void @test9_small_global() {
>>> ; CHECK-LABEL: @test9_small_global(
>>> -; CHECK-NOT: call void
>>> @llvm.memcpy.p0i8.p0i8.i64({{.*}}@bbb,{{.*}}@_ZL3KKK,
>>> -; CHECK: alloca [1000000 x i8]
>>> +; 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: ret void
>>> +;
>>> entry:
>>> %cc = alloca [1000000 x i8], align 16
>>> %cc.0..sroa_idx = getelementptr inbounds [1000000 x i8], [1000000
>>> x i8]* %cc, i64 0, i64 0
>>> @@ -245,8 +310,10 @@ entry:
>>> ; Should replace alloca with global as they have exactly the same size.
>>> define void @test10_same_global() {
>>> ; CHECK-LABEL: @test10_same_global(
>>> -; CHECK-NOT: alloca
>>> -; CHECK: call void
>>> @llvm.memcpy.p0i8.p0i8.i64({{.*}}@bbb,{{.*}}@_ZL3KKK,{{.*}}, i64 3,
>>> +; 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: ret void
>>> +;
>>> entry:
>>> %cc = alloca [3 x i8], align 1
>>> %cc.0..sroa_idx = getelementptr inbounds [3 x i8], [3 x i8]* %cc,
>>> i64 0, i64 0
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll Tue Aug
>>> 13 02:11:49 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
>>> [[D:%.*]], i8* align 1 [[S:%.*]], i32 3, i1 false)
>>> +; 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: 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
>>> [[D:%.*]], i8* align 1 [[S:%.*]], i32 5, i1 false)
>>> +; 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: 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
>>> [[D:%.*]], i8* align 1 [[S:%.*]], i32 16, i1 false)
>>> +; 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: 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/memcpy.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/memcpy.ll Tue Aug 13
>>> 02:11:49 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 [[D:%.*]], i8* align 4 [[S:%.*]], i64 17179869184, i1 false)
>>> +; 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: 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll Tue Aug
>>> 13 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test lib call simplification of __memcpy_chk calls with various
>>> values
>>> ; for dstlen and len.
>>> ;
>>> @@ -17,22 +18,22 @@ 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: ret i8* bitcast (%struct.T1* @t1 to i8*)
>>> +;
>>> %dst = bitcast %struct.T1* @t1 to i8*
>>> %src = bitcast %struct.T2* @t2 to i8*
>>> -
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4
>>> bitcast (%struct.T1* @t1 to i8*), i8* align 4 bitcast (%struct.T2*
>>> @t2 to i8*), i64 1824, i1 false)
>>> -; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
>>> %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
>>> ret i8* %ret
>>> }
>>> 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: ret i8* bitcast (%struct.T1* @t1 to i8*)
>>> +;
>>> %dst = bitcast %struct.T1* @t1 to i8*
>>> %src = bitcast %struct.T3* @t3 to i8*
>>> -
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4
>>> bitcast (%struct.T1* @t1 to i8*), i8* align 4 bitcast (%struct.T3*
>>> @t3 to i8*), i64 1824, i1 false)
>>> -; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
>>> %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
>>> ret i8* %ret
>>> }
>>> @@ -41,36 +42,35 @@ define i8* @test_simplify2() {
>>> define i8* @test_no_simplify1() {
>>> ; CHECK-LABEL: @test_no_simplify1(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__memcpy_chk(i8* bitcast
>>> (%struct.T3* @t3 to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64
>>> 2848, i64 1824)
>>> +; CHECK-NEXT: ret i8* [[RET]]
>>> +;
>>> %dst = bitcast %struct.T3* @t3 to i8*
>>> %src = bitcast %struct.T1* @t1 to i8*
>>> -
>>> -; CHECK-NEXT: %ret = call i8* @__memcpy_chk(i8* bitcast
>>> (%struct.T3* @t3 to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64
>>> 2848, i64 1824)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
>>> ret i8* %ret
>>> }
>>> define i8* @test_no_simplify2() {
>>> ; CHECK-LABEL: @test_no_simplify2(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__memcpy_chk(i8* bitcast
>>> (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64
>>> 1024, i64 0)
>>> +; CHECK-NEXT: ret i8* [[RET]]
>>> +;
>>> %dst = bitcast %struct.T1* @t1 to i8*
>>> %src = bitcast %struct.T2* @t2 to i8*
>>> -
>>> -; CHECK-NEXT: %ret = call i8* @__memcpy_chk(i8* bitcast
>>> (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64
>>> 1024, i64 0)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1024, i64 0)
>>> ret i8* %ret
>>> }
>>> 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: ret i8* [[DST]]
>>> +;
>>> %src = bitcast %struct.T2* @t2 to i8*
>>> -
>>> -; CHECK-NEXT: %dst = call i8* %alloc()
>>> %dst = call i8* %alloc()
>>> -
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64
>>> %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
>>> -; CHECK-NEXT: ret i8* %dst
>>> ret i8* %ret
>>> }
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll Tue Aug
>>> 13 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test lib call simplification of __memmove_chk calls with various
>>> values
>>> ; for dstlen and len.
>>> ;
>>> @@ -17,22 +18,24 @@ 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: ret i8* bitcast (%struct.T1* @t1 to i8*)
>>> +;
>>> %dst = bitcast %struct.T1* @t1 to i8*
>>> %src = bitcast %struct.T2* @t2 to i8*
>>> -; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* align 4
>>> bitcast (%struct.T1* @t1 to i8*), i8* align 4 bitcast (%struct.T2*
>>> @t2 to i8*), i64 1824, i1 false)
>>> -; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
>>> %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64
>>> 1824)
>>> ret i8* %ret
>>> }
>>> 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: ret i8* bitcast (%struct.T1* @t1 to i8*)
>>> +;
>>> %dst = bitcast %struct.T1* @t1 to i8*
>>> %src = bitcast %struct.T3* @t3 to i8*
>>> -; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* align 4
>>> bitcast (%struct.T1* @t1 to i8*), i8* align 4 bitcast (%struct.T3*
>>> @t3 to i8*), i64 1824, i1 false)
>>> -; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
>>> %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64
>>> 2848)
>>> ret i8* %ret
>>> }
>>> @@ -41,22 +44,24 @@ define i8* @test_simplify2() {
>>> define i8* @test_no_simplify1() {
>>> ; CHECK-LABEL: @test_no_simplify1(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__memmove_chk(i8* bitcast
>>> (%struct.T3* @t3 to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64
>>> 2848, i64 1824)
>>> +; CHECK-NEXT: ret i8* [[RET]]
>>> +;
>>> %dst = bitcast %struct.T3* @t3 to i8*
>>> %src = bitcast %struct.T1* @t1 to i8*
>>> -; CHECK-NEXT: %ret = call i8* @__memmove_chk(i8* bitcast
>>> (%struct.T3* @t3 to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64
>>> 2848, i64 1824)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 2848, i64
>>> 1824)
>>> ret i8* %ret
>>> }
>>> define i8* @test_no_simplify2() {
>>> ; CHECK-LABEL: @test_no_simplify2(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__memmove_chk(i8* bitcast
>>> (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64
>>> 1024, i64 0)
>>> +; CHECK-NEXT: ret i8* [[RET]]
>>> +;
>>> %dst = bitcast %struct.T1* @t1 to i8*
>>> %src = bitcast %struct.T2* @t2 to i8*
>>> -; CHECK-NEXT: %ret = call i8* @__memmove_chk(i8* bitcast
>>> (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64
>>> 1024, i64 0)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1024, i64 0)
>>> ret i8* %ret
>>> }
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll Tue Aug
>>> 13 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test lib call simplification of __memset_chk calls with various
>>> values
>>> ; for dstlen and len.
>>> ;
>>> @@ -13,30 +14,33 @@ 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: ret i8* bitcast (%struct.T* @t to i8*)
>>> +;
>>> %dst = bitcast %struct.T* @t to i8*
>>> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 bitcast
>>> (%struct.T* @t to i8*), i8 0, i64 1824, i1 false)
>>> -; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
>>> %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824)
>>> ret i8* %ret
>>> }
>>> 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: ret i8* bitcast (%struct.T* @t to i8*)
>>> +;
>>> %dst = bitcast %struct.T* @t to i8*
>>> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 bitcast
>>> (%struct.T* @t to i8*), i8 0, i64 1824, i1 false)
>>> -; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
>>> %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 3648)
>>> ret i8* %ret
>>> }
>>> 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: ret i8* bitcast (%struct.T* @t to i8*)
>>> +;
>>> %dst = bitcast %struct.T* @t to i8*
>>> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 bitcast
>>> (%struct.T* @t to i8*), i8 0, i64 1824, i1 false)
>>> -; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
>>> %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 -1)
>>> ret i8* %ret
>>> }
>>> @@ -45,41 +49,55 @@ define i8* @test_simplify3() {
>>> define i8* @test_no_simplify1() {
>>> ; CHECK-LABEL: @test_no_simplify1(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__memset_chk(i8* bitcast
>>> (%struct.T* @t to i8*), i32 0, i64 1824, i64 400)
>>> +; CHECK-NEXT: ret i8* [[RET]]
>>> +;
>>> %dst = bitcast %struct.T* @t to i8*
>>> -; CHECK-NEXT: %ret = call i8* @__memset_chk(i8* bitcast
>>> (%struct.T* @t to i8*), i32 0, i64 1824, i64 400)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 400)
>>> ret i8* %ret
>>> }
>>> define i8* @test_no_simplify2() {
>>> ; CHECK-LABEL: @test_no_simplify2(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__memset_chk(i8* bitcast
>>> (%struct.T* @t to i8*), i32 0, i64 1824, i64 0)
>>> +; CHECK-NEXT: ret i8* [[RET]]
>>> +;
>>> %dst = bitcast %struct.T* @t to i8*
>>> -; CHECK-NEXT: %ret = call i8* @__memset_chk(i8* bitcast
>>> (%struct.T* @t to i8*), i32 0, i64 1824, i64 0)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 0)
>>> ret i8* %ret
>>> }
>>> ; Test that RAUW in SimplifyLibCalls for __memset_chk generates
>>> valid IR
>>> define i32 @test_rauw(i8* %a, i8* %b, i8** %c) {
>>> -; CHECK-LABEL: test_rauw
>>> +; CHECK-LABEL: @test_rauw(
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[CALL49:%.*]] = call i64 @strlen(i8* [[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: [[STRCHR2:%.*]] = getelementptr i8, i8* [[B]], i64
>>> [[STRLEN]]
>>> +; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8** [[C:%.*]] to i64*
>>> +; CHECK-NEXT: [[D1:%.*]] = load i64, i64* [[TMP0]], align 8
>>> +; CHECK-NEXT: [[SUB183:%.*]] = ptrtoint i8* [[B]] to i64
>>> +; CHECK-NEXT: [[SUB184:%.*]] = sub i64 [[D1]], [[SUB183]]
>>> +; CHECK-NEXT: [[ADD52_I_I:%.*]] = add nsw i64 [[SUB184]], 1
>>> +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1
>>> [[STRCHR2]], i8 0, i64 [[ADD52_I_I]], i1 false)
>>> +; CHECK-NEXT: ret i32 4
>>> +;
>>> entry:
>>> %call49 = call i64 @strlen(i8* %a)
>>> %add180 = add i64 %call49, 1
>>> %yo107 = call i64 @llvm.objectsize.i64.p0i8(i8* %b, i1 false, i1
>>> false, i1 false)
>>> %call50 = call i8* @__memmove_chk(i8* %b, i8* %a, i64 %add180,
>>> i64 %yo107)
>>> -; CHECK: %strlen = call i64 @strlen(i8* %b)
>>> -; CHECK-NEXT: %strchr2 = getelementptr i8, i8* %b, i64 %strlen
>>> %call51i = call i8* @strrchr(i8* %b, i32 0)
>>> %d = load i8*, i8** %c, align 8
>>> %sub182 = ptrtoint i8* %d to i64
>>> %sub183 = ptrtoint i8* %b to i64
>>> %sub184 = sub i64 %sub182, %sub183
>>> %add52.i.i = add nsw i64 %sub184, 1
>>> -; CHECK: call void @llvm.memset.p0i8.i64(i8* align 1 %strchr2
>>> %call185 = call i8* @__memset_chk(i8* %call51i, i32 0, i64
>>> %add52.i.i, i64 -1)
>>> ret i32 4
>>> }
>>> @@ -94,6 +112,20 @@ declare i8* @__memset_chk(i8*, i32, i64,
>>> ; FIXME: memset(malloc(x), 0, x) -> calloc(1, x)
>>> define float* @pr25892(i64 %size) #0 {
>>> +; CHECK-LABEL: @pr25892(
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @malloc(i64
>>> [[SIZE:%.*]]) #3
>>> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[CALL]], null
>>> +; CHECK-NEXT: br i1 [[CMP]], label [[CLEANUP:%.*]], label
>>> [[IF_END:%.*]]
>>> +; CHECK: if.end:
>>> +; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[CALL]] to float*
>>> +; CHECK-NEXT: [[CALL2:%.*]] = tail call i64
>>> @llvm.objectsize.i64.p0i8(i8* nonnull [[CALL]], i1 false, i1 false,
>>> i1 false)
>>> +; CHECK-NEXT: [[CALL3:%.*]] = tail call i8* @__memset_chk(i8*
>>> nonnull [[CALL]], i32 0, i64 [[SIZE]], i64 [[CALL2]]) #3
>>> +; CHECK-NEXT: br label [[CLEANUP]]
>>> +; CHECK: cleanup:
>>> +; CHECK-NEXT: [[RETVAL_0:%.*]] = phi float* [ [[BC]], [[IF_END]]
>>> ], [ null, [[ENTRY:%.*]] ]
>>> +; CHECK-NEXT: ret float* [[RETVAL_0]]
>>> +;
>>> entry:
>>> %call = tail call i8* @malloc(i64 %size) #1
>>> %cmp = icmp eq i8* %call, null
>>> @@ -107,19 +139,6 @@ cleanup:
>>> %retval.0 = phi float* [ %bc, %if.end ], [ null, %entry ]
>>> ret float* %retval.0
>>> -; CHECK-LABEL: @pr25892(
>>> -; CHECK: entry:
>>> -; CHECK-NEXT: %call = tail call i8* @malloc(i64 %size)
>>> -; CHECK-NEXT: %cmp = icmp eq i8* %call, null
>>> -; CHECK-NEXT: br i1 %cmp, label %cleanup, label %if.end
>>> -; CHECK: if.end:
>>> -; CHECK-NEXT: %bc = bitcast i8* %call to float*
>>> -; CHECK-NEXT: %call2 = tail call i64
>>> @llvm.objectsize.i64.p0i8(i8* nonnull %call, i1 false, i1 false, i1
>>> false)
>>> -; CHECK-NEXT: %call3 = tail call i8* @__memset_chk(i8* nonnull
>>> %call, i32 0, i64 %size, i64 %call2)
>>> -; CHECK-NEXT: br label %cleanup
>>> -; CHECK: cleanup:
>>> -; CHECK-NEXT: %retval.0 = phi float* [ %bc, %if.end ], [ null,
>>> %entry ]
>>> -; CHECK-NEXT: ret float* %retval.0
>>> }
>>> declare noalias i8* @malloc(i64) #1
>>>
>>> Modified: llvm/trunk/test/Transforms/InstCombine/objsize.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/objsize.ll?rev=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/objsize.ll Tue Aug 13
>>> 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test a pile of objectsize bounds checking.
>>> ; RUN: opt < %s -instcombine -S | FileCheck %s
>>> ; We need target data to get the sizes of the arrays and structures.
>>> @@ -7,18 +8,27 @@ target datalayout = "e-p:32:32:32-i1:8:8
>>> @.str = private constant [8 x i8] c"abcdefg\00" ; <[8 x i8]*>
>>> define i32 @foo() nounwind {
>>> ; CHECK-LABEL: @foo(
>>> -; CHECK-NEXT: ret i32 60
>>> +; CHECK-NEXT: ret i32 60
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1
>>> false, i1 false)
>>> ret i32 %1
>>> }
>>> define i8* @bar() nounwind {
>>> ; CHECK-LABEL: @bar(
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[RETVAL:%.*]] = alloca i8*, align 4
>>> +; CHECK-NEXT: br i1 true, label [[COND_TRUE:%.*]], label
>>> [[COND_FALSE:%.*]]
>>> +; CHECK: cond.true:
>>> +; CHECK-NEXT: [[TMP0:%.*]] = load i8*, i8** [[RETVAL]], align 4
>>> +; CHECK-NEXT: ret i8* [[TMP0]]
>>> +; CHECK: cond.false:
>>> +; CHECK-NEXT: ret i8* undef
>>> +;
>>> entry:
>>> %retval = alloca i8*
>>> %0 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1
>>> false, i1 false)
>>> %cmp = icmp ne i32 %0, -1
>>> -; CHECK: br i1 true
>>> br i1 %cmp, label %cond.true, label %cond.false
>>> cond.true:
>>> @@ -32,7 +42,8 @@ cond.false:
>>> define i32 @f() nounwind {
>>> ; CHECK-LABEL: @f(
>>> -; CHECK-NEXT: ret i32 0
>>> +; CHECK-NEXT: ret i32 0
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr ([60 x
>>> i8], [60 x i8]* @a, i32 1, i32 0), i1 false, i1 false, i1 false)
>>> ret i32 %1
>>> }
>>> @@ -41,7 +52,10 @@ define i32 @f() nounwind {
>>> define i1 @baz() nounwind {
>>> ; CHECK-LABEL: @baz(
>>> -; CHECK-NEXT: objectsize
>>> +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32
>>> @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8], [0 x
>>> i8]* @window, i32 0, i32 0), i1 false, i1 false, i1 false)
>>> +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -1
>>> +; CHECK-NEXT: ret i1 [[TMP2]]
>>> +;
>>> %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr
>>> inbounds ([0 x i8], [0 x i8]* @window, i32 0, i32 0), i1 false, i1
>>> false, i1 false)
>>> %2 = icmp eq i32 %1, -1
>>> ret i1 %2
>>> @@ -49,7 +63,15 @@ define i1 @baz() nounwind {
>>> define void @test1(i8* %q, i32 %x) nounwind noinline {
>>> ; CHECK-LABEL: @test1(
>>> -; CHECK: objectsize.i32.p0i8
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[TMP0:%.*]] = call i32
>>> @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([0 x i8], [0 x
>>> i8]* @window, i32 0, i32 10), i1 false, i1 false, i1 false)
>>> +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], -1
>>> +; CHECK-NEXT: br i1 [[TMP1]], label %"47", label %"46"
>>> +; CHECK: "46":
>>> +; CHECK-NEXT: unreachable
>>> +; CHECK: "47":
>>> +; CHECK-NEXT: unreachable
>>> +;
>>> entry:
>>> %0 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr
>>> inbounds ([0 x i8], [0 x i8]* @window, i32 0, i32 10), i1 false, i1
>>> false, i1 false) ; <i64> [#uses=1]
>>> %1 = icmp eq i32 %0, -1 ; <i1> [#uses=1]
>>> @@ -66,7 +88,8 @@ entry:
>>> 101, i32 102, i32 103, i32 0], align 4
>>> define i32 @test2() nounwind {
>>> ; CHECK-LABEL: @test2(
>>> -; CHECK-NEXT: ret i32 34
>>> +; CHECK-NEXT: ret i32 34
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr (i8,
>>> i8* bitcast ([9 x i32]* @.str5 to i8*), i32 2), i1 false, i1 false,
>>> i1 false)
>>> ret i32 %1
>>> }
>>> @@ -84,6 +107,14 @@ declare i8* @__inline_memcpy_chk(i8*, i8
>>> define void @test3() nounwind {
>>> ; CHECK-LABEL: @test3(
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: br i1 undef, label [[BB11:%.*]], label [[BB12:%.*]]
>>> +; CHECK: bb11:
>>> +; CHECK-NEXT: unreachable
>>> +; CHECK: bb12:
>>> +; CHECK-NEXT: [[TMP0:%.*]] = call i8* @__inline_memcpy_chk(i8*
>>> bitcast (float* getelementptr inbounds ([480 x float], [480 x
>>> float]* @array, i32 0, i32 1) to i8*), i8* undef, i32 512) #3
>>> +; CHECK-NEXT: unreachable
>>> +;
>>> entry:
>>> br i1 undef, label %bb11, label %bb12
>>> @@ -92,14 +123,12 @@ bb11:
>>> %1 = bitcast float* %0 to i8* ; <i8*> [#uses=1]
>>> %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1
>>> false, i1 false) ; <i32> [#uses=1]
>>> %3 = call i8* @__memcpy_chk(i8* undef, i8* undef, i32 512, i32
>>> %2) nounwind ; <i8*> [#uses=0]
>>> -; CHECK: unreachable
>>> unreachable
>>> bb12:
>>> %4 = getelementptr inbounds float, float* getelementptr inbounds
>>> ([480 x float], [480 x float]* @array, i32 0, i32 128), i32 -127 ;
>>> <float*> [#uses=1]
>>> %5 = bitcast float* %4 to i8* ; <i8*> [#uses=1]
>>> %6 = call i8* @__inline_memcpy_chk(i8* %5, i8* undef, i32 512)
>>> nounwind inlinehint ; <i8*> [#uses=0]
>>> -; CHECK: @__inline_memcpy_chk
>>> unreachable
>>> }
>>> @@ -109,12 +138,18 @@ bb12:
>>> define i32 @test4(i8** %esc) nounwind ssp {
>>> ; CHECK-LABEL: @test4(
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[TMP0:%.*]] = alloca [[STRUCT_DATA:%.*]], align 8
>>> +; CHECK-NEXT: [[TMP1:%.*]] = bitcast %struct.data* [[TMP0]] to i8*
>>> +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align
>>> 8 dereferenceable(1824) [[TMP1]], i8 0, i32 1824, i1 false)
>>> +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8** [[ESC:%.*]] to
>>> %struct.data**
>>> +; CHECK-NEXT: store %struct.data* [[TMP0]], %struct.data**
>>> [[TMP2]], align 4
>>> +; CHECK-NEXT: ret i32 0
>>> +;
>>> entry:
>>> %0 = alloca %struct.data, align 8
>>> %1 = bitcast %struct.data* %0 to i8*
>>> %2 = call i32 @llvm.objectsize.i32.p0i8(i8* %1, i1 false, i1
>>> false, i1 false) nounwind
>>> -; CHECK-NOT: @llvm.objectsize
>>> -; CHECK: @llvm.memset.p0i8.i32(i8* nonnull align 8 %1, i8 0, i32
>>> 1824, i1 false)
>>> %3 = call i8* @__memset_chk(i8* %1, i32 0, i32 1824, i32 %2) nounwind
>>> store i8* %1, i8** %esc
>>> ret i32 0
>>> @@ -125,24 +160,32 @@ entry:
>>> define i8* @test5(i32 %n) nounwind ssp {
>>> ; CHECK-LABEL: @test5(
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[TMP0:%.*]] = tail call noalias 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: ret i8* [[TMP0]]
>>> +;
>>> entry:
>>> %0 = tail call noalias i8* @malloc(i32 20) nounwind
>>> %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1
>>> false, i1 false)
>>> %2 = load i8*, i8** @s, align 8
>>> -; CHECK-NOT: @llvm.objectsize
>>> -; CHECK: @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %0, i8* align 1 %1,
>>> i32 10, i1 false)
>>> %3 = tail call i8* @__memcpy_chk(i8* %0, i8* %2, i32 10, i32 %1)
>>> nounwind
>>> ret i8* %0
>>> }
>>> define void @test6(i32 %n) nounwind ssp {
>>> ; CHECK-LABEL: @test6(
>>> +; CHECK-NEXT: entry:
>>> +; CHECK-NEXT: [[TMP0:%.*]] = tail call noalias i8* @malloc(i32
>>> 20) #0
>>> +; CHECK-NEXT: [[TMP1:%.*]] = load i8*, i8** @s, align 8
>>> +; CHECK-NEXT: [[TMP2:%.*]] = tail call i8* @__memcpy_chk(i8*
>>> [[TMP0]], i8* [[TMP1]], i32 30, i32 20) #0
>>> +; CHECK-NEXT: ret void
>>> +;
>>> entry:
>>> %0 = tail call noalias i8* @malloc(i32 20) nounwind
>>> %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %0, i1 false, i1
>>> false, i1 false)
>>> %2 = load i8*, i8** @s, align 8
>>> -; CHECK-NOT: @llvm.objectsize
>>> -; CHECK: @__memcpy_chk(i8* %0, i8* %1, i32 30, i32 20)
>>> %3 = tail call i8* @__memcpy_chk(i8* %0, i8* %2, i32 30, i32 %1)
>>> nounwind
>>> ret void
>>> }
>>> @@ -153,11 +196,14 @@ declare noalias i8* @malloc(i32) nounwin
>>> define i32 @test7(i8** %esc) {
>>> ; CHECK-LABEL: @test7(
>>> +; CHECK-NEXT: [[ALLOC:%.*]] = call noalias i8* @malloc(i32 48) #0
>>> +; CHECK-NEXT: store i8* [[ALLOC]], i8** [[ESC:%.*]], align 4
>>> +; CHECK-NEXT: ret i32 32
>>> +;
>>> %alloc = call noalias i8* @malloc(i32 48) nounwind
>>> store i8* %alloc, i8** %esc
>>> %gep = getelementptr inbounds i8, i8* %alloc, i32 16
>>> %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false,
>>> i1 false, i1 false) nounwind readonly
>>> -; CHECK: ret i32 32
>>> ret i32 %objsize
>>> }
>>> @@ -165,67 +211,86 @@ declare noalias i8* @calloc(i32, i32) no
>>> define i32 @test8(i8** %esc) {
>>> ; CHECK-LABEL: @test8(
>>> +; CHECK-NEXT: [[ALLOC:%.*]] = call noalias i8* @calloc(i32 5,
>>> i32 7) #0
>>> +; CHECK-NEXT: store i8* [[ALLOC]], i8** [[ESC:%.*]], align 4
>>> +; CHECK-NEXT: ret i32 30
>>> +;
>>> %alloc = call noalias i8* @calloc(i32 5, i32 7) nounwind
>>> store i8* %alloc, i8** %esc
>>> %gep = getelementptr inbounds i8, i8* %alloc, i32 5
>>> %objsize = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 false,
>>> i1 false, i1 false) nounwind readonly
>>> -; CHECK: ret i32 30
>>> ret i32 %objsize
>>> }
>>> declare noalias i8* @strdup(i8* nocapture) nounwind
>>> declare noalias i8* @strndup(i8* nocapture, i32) nounwind
>>> -; CHECK-LABEL: @test9(
>>> define i32 @test9(i8** %esc) {
>>> +; CHECK-LABEL: @test9(
>>> +; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strdup(i8*
>>> getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0)) #0
>>> +; CHECK-NEXT: store i8* [[CALL]], i8** [[ESC:%.*]], align 8
>>> +; CHECK-NEXT: ret i32 8
>>> +;
>>> %call = tail call i8* @strdup(i8* getelementptr inbounds ([8 x
>>> i8], [8 x i8]* @.str, i64 0, i64 0)) nounwind
>>> store i8* %call, i8** %esc, align 8
>>> %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true,
>>> i1 false, i1 false)
>>> -; CHECK: ret i32 8
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test10(
>>> define i32 @test10(i8** %esc) {
>>> +; CHECK-LABEL: @test10(
>>> +; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strndup(i8*
>>> getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0),
>>> i32 3) #0
>>> +; CHECK-NEXT: store i8* [[CALL]], i8** [[ESC:%.*]], align 8
>>> +; CHECK-NEXT: ret i32 4
>>> +;
>>> %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x
>>> i8], [8 x i8]* @.str, i64 0, i64 0), i32 3) nounwind
>>> store i8* %call, i8** %esc, align 8
>>> %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true,
>>> i1 false, i1 false)
>>> -; CHECK: ret i32 4
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test11(
>>> define i32 @test11(i8** %esc) {
>>> +; CHECK-LABEL: @test11(
>>> +; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strndup(i8*
>>> getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0),
>>> i32 7) #0
>>> +; CHECK-NEXT: store i8* [[CALL]], i8** [[ESC:%.*]], align 8
>>> +; CHECK-NEXT: ret i32 8
>>> +;
>>> %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x
>>> i8], [8 x i8]* @.str, i64 0, i64 0), i32 7) nounwind
>>> store i8* %call, i8** %esc, align 8
>>> %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true,
>>> i1 false, i1 false)
>>> -; CHECK: ret i32 8
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test12(
>>> define i32 @test12(i8** %esc) {
>>> +; CHECK-LABEL: @test12(
>>> +; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strndup(i8*
>>> getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0),
>>> i32 8) #0
>>> +; CHECK-NEXT: store i8* [[CALL]], i8** [[ESC:%.*]], align 8
>>> +; CHECK-NEXT: ret i32 8
>>> +;
>>> %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x
>>> i8], [8 x i8]* @.str, i64 0, i64 0), i32 8) nounwind
>>> store i8* %call, i8** %esc, align 8
>>> %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true,
>>> i1 false, i1 false)
>>> -; CHECK: ret i32 8
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test13(
>>> define i32 @test13(i8** %esc) {
>>> +; CHECK-LABEL: @test13(
>>> +; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strndup(i8*
>>> getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0),
>>> i32 57) #0
>>> +; CHECK-NEXT: store i8* [[CALL]], i8** [[ESC:%.*]], align 8
>>> +; CHECK-NEXT: ret i32 8
>>> +;
>>> %call = tail call i8* @strndup(i8* getelementptr inbounds ([8 x
>>> i8], [8 x i8]* @.str, i64 0, i64 0), i32 57) nounwind
>>> store i8* %call, i8** %esc, align 8
>>> %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %call, i1 true,
>>> i1 false, i1 false)
>>> -; CHECK: ret i32 8
>>> ret i32 %1
>>> }
>>> @globalalias = internal alias [60 x i8], [60 x i8]* @a
>>> -; CHECK-LABEL: @test18(
>>> -; CHECK-NEXT: ret i32 60
>>> define i32 @test18() {
>>> +; CHECK-LABEL: @test18(
>>> +; CHECK-NEXT: ret i32 60
>>> +;
>>> %bc = bitcast [60 x i8]* @globalalias to i8*
>>> %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1
>>> false, i1 false)
>>> ret i32 %1
>>> @@ -233,71 +298,87 @@ define i32 @test18() {
>>> @globalalias2 = weak alias [60 x i8], [60 x i8]* @a
>>> -; CHECK-LABEL: @test19(
>>> -; CHECK: llvm.objectsize
>>> define i32 @test19() {
>>> +; CHECK-LABEL: @test19(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = call i32
>>> @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60
>>> x i8]* @globalalias2, i32 0, i32 0), i1 false, i1 false, i1 false)
>>> +; CHECK-NEXT: ret i32 [[TMP1]]
>>> +;
>>> %bc = bitcast [60 x i8]* @globalalias2 to i8*
>>> %1 = call i32 @llvm.objectsize.i32.p0i8(i8* %bc, i1 false, i1
>>> false, i1 false)
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test20(
>>> -; CHECK: ret i32 0
>>> define i32 @test20() {
>>> +; CHECK-LABEL: @test20(
>>> +; CHECK-NEXT: ret i32 0
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1
>>> false, i1 false)
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test21(
>>> -; CHECK: ret i32 0
>>> define i32 @test21() {
>>> +; CHECK-LABEL: @test21(
>>> +; CHECK-NEXT: ret i32 0
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1
>>> false, i1 false)
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test22(
>>> -; CHECK: llvm.objectsize
>>> define i32 @test22() {
>>> +; CHECK-LABEL: @test22(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = call i32
>>> @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1 true, i1 false)
>>> +; CHECK-NEXT: ret i32 [[TMP1]]
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 false, i1
>>> true, i1 false)
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test23(
>>> -; CHECK: llvm.objectsize
>>> define i32 @test23() {
>>> +; CHECK-LABEL: @test23(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = call i32
>>> @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1 true, i1 false)
>>> +; CHECK-NEXT: ret i32 [[TMP1]]
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p0i8(i8* null, i1 true, i1
>>> true, i1 false)
>>> ret i32 %1
>>> }
>>> ; 1 is an arbitrary non-zero address space.
>>> -; CHECK-LABEL: @test24(
>>> -; CHECK: llvm.objectsize
>>> define i32 @test24() {
>>> +; CHECK-LABEL: @test24(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = call i32
>>> @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 false, i1 false,
>>> i1 false)
>>> +; CHECK-NEXT: ret i32 [[TMP1]]
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1
>>> false,
>>> - i1 false, i1 false)
>>> + i1 false, i1 false)
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test25(
>>> -; CHECK: llvm.objectsize
>>> define i32 @test25() {
>>> +; CHECK-LABEL: @test25(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = call i32
>>> @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 true, i1 false,
>>> i1 false)
>>> +; CHECK-NEXT: ret i32 [[TMP1]]
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1
>>> true,
>>> - i1 false, i1 false)
>>> + i1 false, i1 false)
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test26(
>>> -; CHECK: llvm.objectsize
>>> define i32 @test26() {
>>> +; CHECK-LABEL: @test26(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = call i32
>>> @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 false, i1 true,
>>> i1 false)
>>> +; CHECK-NEXT: ret i32 [[TMP1]]
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1
>>> false,
>>> - i1 true, i1 false)
>>> + i1 true, i1 false)
>>> ret i32 %1
>>> }
>>> -; CHECK-LABEL: @test27(
>>> -; CHECK: llvm.objectsize
>>> define i32 @test27() {
>>> +; CHECK-LABEL: @test27(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = call i32
>>> @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 true, i1 true,
>>> i1 false)
>>> +; CHECK-NEXT: ret i32 [[TMP1]]
>>> +;
>>> %1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1
>>> true,
>>> - i1 true, i1 false)
>>> + i1 true, i1 false)
>>> ret i32 %1
>>> }
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/sprintf-1.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/sprintf-1.ll Tue Aug 13
>>> 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test that the sprintf library call simplifier works correctly.
>>> ;
>>> ; RUN: opt < %s -instcombine -S | FileCheck %s
>>> @@ -20,81 +21,125 @@ 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: 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: ret void
>>> +;
>>> %fmt = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0
>>> call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt)
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1
>>> %dst, i8* align 1 getelementptr inbounds ([13 x i8], [13 x i8]*
>>> @hello_world, i32 0, i32 0), i32 13, i1 false)
>>> ret void
>>> -; CHECK-NEXT: ret void
>>> }
>>> define void @test_simplify2(i8* %dst) {
>>> ; CHECK-LABEL: @test_simplify2(
>>> +; CHECK-NEXT: store i8 0, i8* [[DST:%.*]], align 1
>>> +; CHECK-NEXT: ret void
>>> +;
>>> +; CHECK-IPRINTF-LABEL: @test_simplify2(
>>> +; CHECK-IPRINTF-NEXT: store i8 0, i8* [[DST:%.*]], align 1
>>> +; CHECK-IPRINTF-NEXT: ret void
>>> +;
>>> %fmt = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
>>> call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt)
>>> -; CHECK-NEXT: store i8 0, i8* %dst, align 1
>>> ret void
>>> -; CHECK-NEXT: ret void
>>> }
>>> define void @test_simplify3(i8* %dst) {
>>> ; CHECK-LABEL: @test_simplify3(
>>> +; CHECK-NEXT: store i8 0, i8* [[DST:%.*]], align 1
>>> +; CHECK-NEXT: ret void
>>> +;
>>> +; CHECK-IPRINTF-LABEL: @test_simplify3(
>>> +; CHECK-IPRINTF-NEXT: store i8 0, i8* [[DST:%.*]], align 1
>>> +; CHECK-IPRINTF-NEXT: ret void
>>> +;
>>> %fmt = getelementptr [7 x i8], [7 x i8]* @null_hello, i32 0, i32 0
>>> call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt)
>>> -; CHECK-NEXT: store i8 0, i8* %dst, align 1
>>> ret void
>>> -; CHECK-NEXT: ret void
>>> }
>>> ; Check sprintf(dst, "%c", chr) -> *(i8*)dst = chr; *((i8*)dst +
>>> 1) = 0.
>>> define void @test_simplify4(i8* %dst) {
>>> ; CHECK-LABEL: @test_simplify4(
>>> +; CHECK-NEXT: store i8 104, i8* [[DST:%.*]], align 1
>>> +; CHECK-NEXT: [[NUL:%.*]] = getelementptr i8, i8* [[DST]], i32 1
>>> +; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1
>>> +; CHECK-NEXT: ret void
>>> +;
>>> +; CHECK-IPRINTF-LABEL: @test_simplify4(
>>> +; CHECK-IPRINTF-NEXT: store i8 104, i8* [[DST:%.*]], align 1
>>> +; CHECK-IPRINTF-NEXT: [[NUL:%.*]] = getelementptr i8, i8*
>>> [[DST]], i32 1
>>> +; CHECK-IPRINTF-NEXT: store i8 0, i8* [[NUL]], align 1
>>> +; CHECK-IPRINTF-NEXT: ret void
>>> +;
>>> %fmt = getelementptr [3 x i8], [3 x i8]* @percent_c, i32 0, i32 0
>>> call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8 104)
>>> -; CHECK-NEXT: store i8 104, i8* %dst, align 1
>>> -; CHECK-NEXT: [[NUL:%[a-z0-9]+]] = getelementptr i8, i8* %dst, i32 1
>>> -; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1
>>> ret void
>>> -; CHECK-NEXT: ret void
>>> }
>>> ; Check sprintf(dst, "%s", str) -> llvm.memcpy(dest, str,
>>> strlen(str) + 1, 1).
>>> define void @test_simplify5(i8* %dst, i8* %str) {
>>> ; CHECK-LABEL: @test_simplify5(
>>> +; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* [[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: [[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
>>> +;
>>> %fmt = getelementptr [3 x i8], [3 x i8]* @percent_s, i32 0, i32 0
>>> call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i8* %str)
>>> -; CHECK-NEXT: [[STRLEN:%[a-z0-9]+]] = call i32 @strlen(i8* %str)
>>> -; CHECK-NEXT: [[LENINC:%[a-z0-9]+]] = 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)
>>> ret void
>>> -; CHECK-NEXT: ret void
>>> }
>>> ; Check sprintf(dst, format, ...) -> siprintf(str, format, ...)
>>> if no floating.
>>> 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: ret void
>>> +;
>>> ; CHECK-IPRINTF-LABEL: @test_simplify6(
>>> +; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...)
>>> @siprintf(i8* [[DST:%.*]], i8* getelementptr inbounds ([3 x i8], [3
>>> x i8]* @percent_d, i32 0, i32 0), i32 187)
>>> +; CHECK-IPRINTF-NEXT: ret void
>>> +;
>>> %fmt = getelementptr [3 x i8], [3 x i8]* @percent_d, i32 0, i32 0
>>> call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, i32 187)
>>> -; CHECK-IPRINTF-NEXT: call i32 (i8*, i8*, ...) @siprintf(i8* %dst,
>>> 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(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: 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: ret void
>>> +;
>>> %fmt = getelementptr [3 x i8], [3 x i8]* @percent_f, i32 0, i32 0
>>> call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, double 1.87)
>>> -; CHECK-IPRINTF-NEXT: 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)
>>> ret void
>>> -; CHECK-IPRINTF-NEXT: ret void
>>> }
>>> 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: 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: ret void
>>> +;
>>> call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt, double %d)
>>> -; CHECK-NEXT: call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt,
>>> double %d)
>>> ret void
>>> -; CHECK-NEXT: ret void
>>> }
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll Tue Aug
>>> 13 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test lib call simplification of __stpcpy_chk calls with various
>>> values
>>> ; for src, dst, and slen.
>>> ;
>>> @@ -13,33 +14,36 @@ 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: 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
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> align 1 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)
>>> %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 60)
>>> ret i8* %ret
>>> }
>>> 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: 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
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> align 1 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)
>>> %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 12)
>>> ret i8* %ret
>>> }
>>> 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: 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
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> align 1 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)
>>> %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
>>> ret i8* %ret
>>> }
>>> @@ -48,11 +52,12 @@ define i8* @test_simplify3() {
>>> define i8* @test_simplify4() {
>>> ; CHECK-LABEL: @test_simplify4(
>>> +; CHECK-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(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: ret i8* [[STPCPY]]
>>> +;
>>> %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
>>> -; CHECK-NEXT: %stpcpy = call i8* @stpcpy(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: ret i8* %stpcpy
>>> %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
>>> ret i8* %ret
>>> }
>>> @@ -61,12 +66,13 @@ define i8* @test_simplify4() {
>>> define i8* @test_simplify5() {
>>> ; CHECK-LABEL: @test_simplify5(
>>> +; CHECK-NEXT: [[LEN:%.*]] = call i32
>>> @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60
>>> x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
>>> +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @__memcpy_chk(i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0),
>>> i32 12, i32 [[LEN]])
>>> +; CHECK-NEXT: 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
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1
>>> false, i1 false, i1 false)
>>> -; CHECK-NEXT: %1 = call i8* @__memcpy_chk(i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr
>>> inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i32 %len)
>>> -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]*
>>> @a, i32 0, i32 11)
>>> %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1
>>> false, i1 false)
>>> %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 %len)
>>> ret i8* %ret
>>> @@ -76,11 +82,12 @@ 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: [[TMP1:%.*]] = getelementptr inbounds [60 x i8],
>>> [60 x i8]* @a, i32 0, i32 [[STRLEN]]
>>> +; CHECK-NEXT: ret i8* [[TMP1]]
>>> +;
>>> %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
>>> -; CHECK-NEXT: %strlen = call i32 @strlen(i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0))
>>> -; CHECK-NEXT: %1 = getelementptr inbounds [60 x i8], [60 x i8]* @a,
>>> i32 0, i32 %strlen
>>> -; CHECK-NEXT: ret i8* %1
>>> %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1
>>> false, i1 false)
>>> %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %dst, i32 %len)
>>> ret i8* %ret
>>> @@ -90,11 +97,12 @@ define i8* @test_simplify6() {
>>> define i8* @test_no_simplify1() {
>>> ; CHECK-LABEL: @test_no_simplify1(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__stpcpy_chk(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 8)
>>> +; 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
>>> -; CHECK-NEXT: %ret = call i8* @__stpcpy_chk(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 8)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 8)
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/strcmp-1.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/strcmp-1.ll Tue Aug 13
>>> 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test that the strcmp library call simplifier works correctly.
>>> ; RUN: opt < %s -instcombine -S | FileCheck %s --check-prefix=NOBCMP
>>> ; RUN: opt < %s -instcombine -mtriple=unknown-unknown-linux-gnu -S
>>> | FileCheck %s --check-prefix=BCMP
>>> @@ -18,7 +19,18 @@ define i32 @test1(i8* %str2) {
>>> ; CHECK: %1 = zext i8 %strcmpload to i32
>>> ; CHECK: %2 = sub nsw i32 0, %1
>>> ; CHECK: ret i32 %2
>>> -
>>> +; NOBCMP-LABEL: @test1(
>>> +; NOBCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR2:%.*]],
>>> align 1
>>> +; NOBCMP-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32
>>> +; NOBCMP-NEXT: [[TMP2:%.*]] = sub nsw i32 0, [[TMP1]]
>>> +; NOBCMP-NEXT: ret i32 [[TMP2]]
>>> +;
>>> +; BCMP-LABEL: @test1(
>>> +; BCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR2:%.*]], align 1
>>> +; BCMP-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32
>>> +; BCMP-NEXT: [[TMP2:%.*]] = sub nsw i32 0, [[TMP1]]
>>> +; BCMP-NEXT: ret i32 [[TMP2]]
>>> +;
>>> %str1 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0,
>>> i32 0
>>> %temp1 = call i32 @strcmp(i8* %str1, i8* %str2)
>>> ret i32 %temp1
>>> @@ -31,7 +43,16 @@ define i32 @test2(i8* %str1) {
>>> ; CHECK: %strcmpload = load i8, i8* %str
>>> ; CHECK: %1 = zext i8 %strcmpload to i32
>>> ; CHECK: ret i32 %1
>>> -
>>> +; NOBCMP-LABEL: @test2(
>>> +; NOBCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR1:%.*]],
>>> align 1
>>> +; NOBCMP-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32
>>> +; NOBCMP-NEXT: ret i32 [[TMP1]]
>>> +;
>>> +; BCMP-LABEL: @test2(
>>> +; BCMP-NEXT: [[STRCMPLOAD:%.*]] = load i8, i8* [[STR1:%.*]], align 1
>>> +; BCMP-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32
>>> +; BCMP-NEXT: ret i32 [[TMP1]]
>>> +;
>>> %str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0,
>>> i32 0
>>> %temp1 = call i32 @strcmp(i8* %str1, i8* %str2)
>>> ret i32 %temp1
>>> @@ -41,7 +62,12 @@ define i32 @test2(i8* %str1) {
>>> define i32 @test3() {
>>> ; CHECK-LABEL: @test3(
>>> ; CHECK: ret i32 -1
>>> -
>>> +; NOBCMP-LABEL: @test3(
>>> +; NOBCMP-NEXT: ret i32 -1
>>> +;
>>> +; BCMP-LABEL: @test3(
>>> +; BCMP-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
>>> %temp1 = call i32 @strcmp(i8* %str1, i8* %str2)
>>> @@ -51,7 +77,12 @@ define i32 @test3() {
>>> define i32 @test4() {
>>> ; CHECK-LABEL: @test4(
>>> ; CHECK: ret i32 1
>>> -
>>> +; NOBCMP-LABEL: @test4(
>>> +; NOBCMP-NEXT: ret i32 1
>>> +;
>>> +; BCMP-LABEL: @test4(
>>> +; BCMP-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
>>> %temp1 = call i32 @strcmp(i8* %str1, i8* %str2)
>>> @@ -64,7 +95,16 @@ define i32 @test5(i1 %b) {
>>> ; CHECK-LABEL: @test5(
>>> ; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6
>>> x i8], [6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5)
>>> ; CHECK: 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: 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: ret i32 [[MEMCMP]]
>>> +;
>>> %str1 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0,
>>> i32 0
>>> %temp1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0,
>>> i32 0
>>> %temp2 = getelementptr inbounds [5 x i8], [5 x i8]* @bell, i32 0,
>>> i32 0
>>> @@ -77,22 +117,31 @@ define i32 @test5(i1 %b) {
>>> define i32 @test6(i8* %str) {
>>> ; CHECK-LABEL: @test6(
>>> ; CHECK: ret i32 0
>>> -
>>> +; NOBCMP-LABEL: @test6(
>>> +; NOBCMP-NEXT: ret i32 0
>>> +;
>>> +; BCMP-LABEL: @test6(
>>> +; BCMP-NEXT: ret i32 0
>>> +;
>>> %temp1 = call i32 @strcmp(i8* %str, i8* %str)
>>> ret i32 %temp1
>>> }
>>> ; strcmp(x, y) == 0 -> bcmp(x, y, <known length>)
>>> 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: [[RES:%.*]] = icmp eq i32 [[MEMCMP]], 0
>>> +; NOBCMP-NEXT: ret i1 [[RES]]
>>> +;
>>> ; BCMP-LABEL: @test7(
>>> -; BCMP: %bcmp = call i32 @bcmp(i8* getelementptr inbounds ([6 x
>>> i8], [6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5)
>>> -; BCMP: %res = icmp eq i32 %bcmp, 0
>>> -; BCMP: ret i1 %res
>>> +; 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: [[RES:%.*]] = icmp eq i32 [[BCMP]], 0
>>> +; BCMP-NEXT: ret i1 [[RES]]
>>> +;
>>> -; NOBCMP-LABEL: @test7(
>>> -; NOBCMP: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6
>>> x i8], [6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5)
>>> -; NOBCMP: %res = icmp eq i32 %memcmp, 0
>>> -; NOBCMP: ret i1 %res
>>> %str1 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32
>>> 0, i32 0
>>> %temp1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0,
>>> i32 0
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/strcmp-memcmp.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/strcmp-memcmp.ll Tue Aug
>>> 13 02:11:49 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
>>> [[STRING]], i8* 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* 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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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: [[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
>>> [[STRING]], i8* 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* 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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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: [[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
>>> [[STRING]], i8* 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* 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
>>> [[STRING]], i8* 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* 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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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_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
>>> [[STRING]], i8* 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* 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
>>> [[STRING]], i8* 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* 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
>>> [[STRING]], i8* 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* 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
>>> [[STRING]], i8* 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* 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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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: [[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
>>> [[STRING]], i8* 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* 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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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: [[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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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: [[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
>>> [[STRING]], i8* 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* 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
>>> [[STRING]], i8* 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* 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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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: [[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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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_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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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: [[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*
>>> getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8*
>>> nonnull [[STRING]], i64 4)
>>> +; 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: [[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
>>> [[STRING]], i8* 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* 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
>>> [[STRING]], i8* 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* 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]]
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll Tue Aug
>>> 13 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test lib call simplification of __strcpy_chk calls with various
>>> values
>>> ; for src, dst, and slen.
>>> ;
>>> @@ -13,33 +14,36 @@ 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: ret i8* getelementptr inbounds ([60 x i8], [60 x
>>> i8]* @a, i32 0, i32 0)
>>> +;
>>> %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> align 1 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)
>>> %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60)
>>> ret i8* %ret
>>> }
>>> 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: ret i8* getelementptr inbounds ([60 x i8], [60 x
>>> i8]* @a, i32 0, i32 0)
>>> +;
>>> %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> align 1 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)
>>> %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 12)
>>> ret i8* %ret
>>> }
>>> 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: ret i8* getelementptr inbounds ([60 x i8], [60 x
>>> i8]* @a, i32 0, i32 0)
>>> +;
>>> %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> align 1 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)
>>> %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
>>> ret i8* %ret
>>> }
>>> @@ -48,11 +52,12 @@ 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: ret i8* [[STRCPY]]
>>> +;
>>> %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
>>> -; 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: ret i8* %strcpy
>>> %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
>>> ret i8* %ret
>>> }
>>> @@ -61,12 +66,13 @@ define i8* @test_simplify4() {
>>> define i8* @test_simplify5() {
>>> ; CHECK-LABEL: @test_simplify5(
>>> +; CHECK-NEXT: [[LEN:%.*]] = call i32
>>> @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60
>>> x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
>>> +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @__memcpy_chk(i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0),
>>> i32 12, i32 [[LEN]])
>>> +; CHECK-NEXT: ret i8* [[TMP1]]
>>> +;
>>> %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1
>>> false, i1 false, i1 false)
>>> -; CHECK-NEXT: %1 = call i8* @__memcpy_chk(i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr
>>> inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i32 %len)
>>> -; CHECK-NEXT: ret i8* %1
>>> %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1
>>> false, i1 false)
>>> %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len)
>>> ret i8* %ret
>>> @@ -76,11 +82,12 @@ define i8* @test_simplify5() {
>>> define i8* @test_simplify6() {
>>> ; CHECK-LABEL: @test_simplify6(
>>> +; CHECK-NEXT: [[LEN:%.*]] = call i32
>>> @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60
>>> x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__strcpy_chk(i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i32
>>> [[LEN]])
>>> +; CHECK-NEXT: ret i8* [[RET]]
>>> +;
>>> %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
>>> -; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1
>>> false, i1 false, i1 false)
>>> -; CHECK-NEXT: %ret = call i8* @__strcpy_chk(i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i32 %len)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1
>>> false, i1 false)
>>> %ret = call i8* @__strcpy_chk(i8* %dst, i8* %dst, i32 %len)
>>> ret i8* %ret
>>> @@ -90,11 +97,12 @@ define i8* @test_simplify6() {
>>> define i8* @test_no_simplify1() {
>>> ; CHECK-LABEL: @test_no_simplify1(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__strcpy_chk(i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 8)
>>> +; 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
>>> -; CHECK-NEXT: %ret = call i8* @__strcpy_chk(i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 8)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 8)
>>> ret i8* %ret
>>> }
>>>
>>> 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=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll Tue Aug
>>> 13 02:11:49 2019
>>> @@ -1,3 +1,4 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; Test lib call simplification of __strncpy_chk calls with various
>>> values
>>> ; for len and dstlen.
>>> ;
>>> @@ -13,33 +14,36 @@ 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: ret i8* getelementptr inbounds ([60 x i8], [60 x
>>> i8]* @a, i32 0, i32 0)
>>> +;
>>> %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> align 1 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)
>>> %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
>>> ret i8* %ret
>>> }
>>> 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: ret i8* getelementptr inbounds ([60 x i8], [60 x
>>> i8]* @a, i32 0, i32 0)
>>> +;
>>> %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> align 1 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)
>>> %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 12)
>>> ret i8* %ret
>>> }
>>> 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: ret i8* [[STRNCPY]]
>>> +;
>>> %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
>>> -; 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: ret i8* %strncpy
>>> %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
>>> ret i8* %ret
>>> }
>>> @@ -48,22 +52,24 @@ define i8* @test_simplify3() {
>>> define i8* @test_no_simplify1() {
>>> ; CHECK-LABEL: @test_no_simplify1(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__strncpy_chk(i8*
>>> getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8*
>>> getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0),
>>> i32 8, i32 4)
>>> +; CHECK-NEXT: ret i8* [[RET]]
>>> +;
>>> %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
>>> %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0,
>>> i32 0
>>> -; CHECK-NEXT: %ret = call i8* @__strncpy_chk(i8* getelementptr
>>> inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr
>>> inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 8, i32 4)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 4)
>>> ret i8* %ret
>>> }
>>> define i8* @test_no_simplify2() {
>>> ; CHECK-LABEL: @test_no_simplify2(
>>> +; CHECK-NEXT: [[RET:%.*]] = call i8* @__strncpy_chk(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
>>> 8, i32 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
>>> -; CHECK-NEXT: %ret = call i8* @__strncpy_chk(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 8, i32 0)
>>> -; CHECK-NEXT: ret i8* %ret
>>> %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 0)
>>> ret i8* %ret
>>> }
>>>
>>> Modified:
>>> llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset-with-lifetimes.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset-with-lifetimes.ll?rev=368657&r1=368656&r2=368657&view=diff
>>> ==============================================================================
>>> ---
>>> llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset-with-lifetimes.ll
>>> (original)
>>> +++
>>> llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset-with-lifetimes.ll
>>> Tue Aug 13 02:11:49 2019
>>> @@ -1,9 +1,16 @@
>>> +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> ; RUN: opt -basicaa -memcpyopt -instcombine -S < %s | FileCheck %s
>>> target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
>>> target triple = "x86_64-unknown-linux-gnu"
>>> define void @foo([8 x i64]* noalias nocapture sret
>>> dereferenceable(64) %sret) {
>>> +; CHECK-LABEL: @foo(
>>> +; CHECK-NEXT: entry-block:
>>> +; CHECK-NEXT: [[SRET1:%.*]] = bitcast [8 x i64]* [[SRET:%.*]] to i8*
>>> +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align
>>> 8 dereferenceable(64) [[SRET1]], i8 0, i64 64, i1 false)
>>> +; CHECK-NEXT: ret void
>>> +;
>>> entry-block:
>>> %a = alloca [8 x i64], align 8
>>> %a.cast = bitcast [8 x i64]* %a to i8*
>>> @@ -14,14 +21,23 @@ entry-block:
>>> call void @llvm.lifetime.end.p0i8(i64 64, i8* %a.cast)
>>> ret void
>>> -; CHECK-LABEL: @foo(
>>> -; CHECK: %[[sret_cast:[^=]+]] = bitcast [8 x i64]* %sret to i8*
>>> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align
>>> 8 %[[sret_cast]], i8 0, i64 64
>>> -; CHECK-NOT: call void @llvm.memcpy
>>> -; CHECK: ret void
>>> }
>>> define void @bar([8 x i64]* noalias nocapture sret
>>> dereferenceable(64) %sret, [8 x i64]* noalias nocapture
>>> dereferenceable(64) %out) {
>>> +; CHECK-LABEL: @bar(
>>> +; CHECK-NEXT: entry-block:
>>> +; CHECK-NEXT: [[A:%.*]] = alloca [8 x i64], align 8
>>> +; CHECK-NEXT: [[A_CAST:%.*]] = bitcast [8 x i64]* [[A]] to i8*
>>> +; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 64, i8*
>>> nonnull [[A_CAST]])
>>> +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align
>>> 8 dereferenceable(64) [[A_CAST]], i8 0, i64 64, i1 false)
>>> +; CHECK-NEXT: [[SRET_CAST:%.*]] = bitcast [8 x i64]*
>>> [[SRET:%.*]] to i8*
>>> +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align
>>> 8 dereferenceable(64) [[SRET_CAST]], i8 0, i64 64, i1 false)
>>> +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align
>>> 8 dereferenceable(32) [[A_CAST]], i8 42, i64 32, i1 false)
>>> +; CHECK-NEXT: [[OUT_CAST:%.*]] = bitcast [8 x i64]* [[OUT:%.*]]
>>> to i8*
>>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull
>>> align 8 dereferenceable(64) [[OUT_CAST]], i8* nonnull align 8
>>> dereferenceable(64) [[A_CAST]], i64 64, i1 false)
>>> +; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 64, i8*
>>> nonnull [[A_CAST]])
>>> +; CHECK-NEXT: ret void
>>> +;
>>> entry-block:
>>> %a = alloca [8 x i64], align 8
>>> %a.cast = bitcast [8 x i64]* %a to i8*
>>> @@ -35,17 +51,6 @@ entry-block:
>>> call void @llvm.lifetime.end.p0i8(i64 64, i8* %a.cast)
>>> ret void
>>> -; CHECK-LABEL: @bar(
>>> -; CHECK: %[[a:[^=]+]] = alloca [8 x i64]
>>> -; CHECK: %[[a_cast:[^=]+]] = bitcast [8 x i64]* %[[a]] to i8*
>>> -; CHECK: call void @llvm.memset.p0i8.i64(i8* nonnull align
>>> 8 %[[a_cast]], i8 0, i64 64
>>> -; CHECK: %[[sret_cast:[^=]+]] = bitcast [8 x i64]* %sret to i8*
>>> -; CHECK: call void @llvm.memset.p0i8.i64(i8* nonnull align
>>> 8 %[[sret_cast]], i8 0, i64 64
>>> -; CHECK: call void @llvm.memset.p0i8.i64(i8* nonnull align
>>> 8 %[[a_cast]], i8 42, i64 32
>>> -; CHECK: %[[out_cast:[^=]+]] = bitcast [8 x i64]* %out to i8*
>>> -; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull
>>> align 8 %[[out_cast]], i8* nonnull align 8 %[[a_cast]], i64 64
>>> -; CHECK-NOT: call void @llvm.memcpy
>>> -; CHECK: ret void
>>> }
>>> declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190813/3a7dad83/attachment-0001.html>
More information about the llvm-commits
mailing list