1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

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
This commit is contained in:
Teresa Johnson 2017-06-28 13:07:37 +00:00
parent 0276bd1729
commit 3be58ceecd
2 changed files with 16 additions and 5 deletions

View File

@ -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,

View File

@ -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]]