diff options
author | Teresa Johnson <tejohnson@google.com> | 2017-06-28 13:07:37 +0000 |
---|---|---|
committer | Teresa Johnson <tejohnson@google.com> | 2017-06-28 13:07:37 +0000 |
commit | 538b8d25f03a55e6169247e45b3f43d0c87feaf6 (patch) | |
tree | 960fe5828b1f64123790667d08de016a2c001a60 /llvm | |
parent | b738ffa845493d8af0d08acaa7c8b2b91dd295b2 (diff) | |
download | bcm5719-llvm-538b8d25f03a55e6169247e45b3f43d0c87feaf6.tar.gz bcm5719-llvm-538b8d25f03a55e6169247e45b3f43d0c87feaf6.zip |
Add zero-length check to memcpy/memset load store loop expansion
Summary:
I was testing using this expansion logic in other cases besides
NVPTX, and found some runtime failures due to the lack of a check
for a zero length memcpy/memset before the loop. There is already
such a check in the memmove expansion code though.
Reviewers: hfinkel
Subscribers: jholewinski, wdng, llvm-commits
Differential Revision: https://reviews.llvm.org/D34707
llvm-svn: 306541
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Transforms/Utils/LowerMemIntrinsics.cpp | 17 | ||||
-rw-r--r-- | llvm/test/CodeGen/NVPTX/lower-aggr-copies.ll | 4 |
2 files changed, 16 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Utils/LowerMemIntrinsics.cpp b/llvm/lib/Transforms/Utils/LowerMemIntrinsics.cpp index 0a51f9a0e4a..ef829d43b7d 100644 --- a/llvm/lib/Transforms/Utils/LowerMemIntrinsics.cpp +++ b/llvm/lib/Transforms/Utils/LowerMemIntrinsics.cpp @@ -27,8 +27,11 @@ void llvm::createMemCpyLoop(Instruction *InsertBefore, BasicBlock *LoopBB = BasicBlock::Create(F->getContext(), "loadstoreloop", F, NewBB); - OrigBB->getTerminator()->setSuccessor(0, LoopBB); IRBuilder<> Builder(OrigBB->getTerminator()); + Builder.CreateCondBr( + Builder.CreateICmpEQ(ConstantInt::get(TypeOfCopyLen, 0), CopyLen), NewBB, + LoopBB); + OrigBB->getTerminator()->eraseFromParent(); // SrcAddr and DstAddr are expected to be pointer types, // so no check is made here. @@ -167,6 +170,7 @@ static void createMemMoveLoop(Instruction *InsertBefore, static void createMemSetLoop(Instruction *InsertBefore, Value *DstAddr, Value *CopyLen, Value *SetValue, unsigned Align, bool IsVolatile) { + Type *TypeOfCopyLen = CopyLen->getType(); BasicBlock *OrigBB = InsertBefore->getParent(); Function *F = OrigBB->getParent(); BasicBlock *NewBB = @@ -174,8 +178,11 @@ static void createMemSetLoop(Instruction *InsertBefore, BasicBlock *LoopBB = BasicBlock::Create(F->getContext(), "loadstoreloop", F, NewBB); - OrigBB->getTerminator()->setSuccessor(0, LoopBB); IRBuilder<> Builder(OrigBB->getTerminator()); + Builder.CreateCondBr( + Builder.CreateICmpEQ(ConstantInt::get(TypeOfCopyLen, 0), CopyLen), NewBB, + LoopBB); + OrigBB->getTerminator()->eraseFromParent(); // Cast pointer to the type of value getting stored unsigned dstAS = cast<PointerType>(DstAddr->getType())->getAddressSpace(); @@ -183,8 +190,8 @@ static void createMemSetLoop(Instruction *InsertBefore, PointerType::get(SetValue->getType(), dstAS)); IRBuilder<> LoopBuilder(LoopBB); - PHINode *LoopIndex = LoopBuilder.CreatePHI(CopyLen->getType(), 0); - LoopIndex->addIncoming(ConstantInt::get(CopyLen->getType(), 0), OrigBB); + PHINode *LoopIndex = LoopBuilder.CreatePHI(TypeOfCopyLen, 0); + LoopIndex->addIncoming(ConstantInt::get(TypeOfCopyLen, 0), OrigBB); LoopBuilder.CreateStore( SetValue, @@ -192,7 +199,7 @@ static void createMemSetLoop(Instruction *InsertBefore, IsVolatile); Value *NewIndex = - LoopBuilder.CreateAdd(LoopIndex, ConstantInt::get(CopyLen->getType(), 1)); + LoopBuilder.CreateAdd(LoopIndex, ConstantInt::get(TypeOfCopyLen, 1)); LoopIndex->addIncoming(NewIndex, LoopBB); LoopBuilder.CreateCondBr(LoopBuilder.CreateICmpULT(NewIndex, CopyLen), LoopBB, diff --git a/llvm/test/CodeGen/NVPTX/lower-aggr-copies.ll b/llvm/test/CodeGen/NVPTX/lower-aggr-copies.ll index 192d4becb05..f522c6722ee 100644 --- a/llvm/test/CodeGen/NVPTX/lower-aggr-copies.ll +++ b/llvm/test/CodeGen/NVPTX/lower-aggr-copies.ll @@ -17,6 +17,8 @@ entry: ret i8* %dst ; IR-LABEL: @memcpy_caller +; IR: [[CMPREG:%[0-9]+]] = icmp eq i64 0, %n +; IR: br i1 [[CMPREG]], label %split, label %loadstoreloop ; IR: loadstoreloop: ; IR: [[LOADPTR:%[0-9]+]] = getelementptr inbounds i8, i8* %src, i64 ; IR-NEXT: [[VAL:%[0-9]+]] = load i8, i8* [[LOADPTR]] @@ -73,6 +75,8 @@ entry: ; IR-LABEL: @memset_caller ; IR: [[VAL:%[0-9]+]] = trunc i32 %c to i8 +; IR: [[CMPREG:%[0-9]+]] = icmp eq i64 0, %n +; IR: br i1 [[CMPREG]], label %split, label %loadstoreloop ; IR: loadstoreloop: ; IR: [[STOREPTR:%[0-9]+]] = getelementptr inbounds i8, i8* %dst, i64 ; IR-NEXT: store i8 [[VAL]], i8* [[STOREPTR]] |