diff options
author | Chris Lattner <sabre@nondot.org> | 2008-01-13 22:30:28 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-01-13 22:30:28 +0000 |
commit | 88b39744ecb383074175a65a92d193f0444a8497 (patch) | |
tree | 54a897d98c9a036b4f1c1e1a42a22a40cd511642 | |
parent | 6d0339d451aeee14f8b1d0f4c74591903580b5cd (diff) |
simplify some code. If we can infer alignment for source and dest that are
greater than memcpy alignment, and if we lower to load/store, use the best
alignment info we have.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45943 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 82df3fc7a4..fcca06dd12 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -7854,34 +7854,35 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // If we can determine a pointer alignment that is bigger than currently // set, update the alignment. if (isa<MemCpyInst>(MI) || isa<MemMoveInst>(MI)) { - unsigned Alignment1 = GetOrEnforceKnownAlignment(MI->getOperand(1), TD); - unsigned Alignment2 = GetOrEnforceKnownAlignment(MI->getOperand(2), TD); - unsigned Align = std::min(Alignment1, Alignment2); - if (MI->getAlignment()->getZExtValue() < Align) { - MI->setAlignment(ConstantInt::get(Type::Int32Ty, Align)); + unsigned DstAlign = GetOrEnforceKnownAlignment(MI->getOperand(1), TD); + unsigned SrcAlign = GetOrEnforceKnownAlignment(MI->getOperand(2), TD); + unsigned MinAlign = std::min(DstAlign, SrcAlign); + unsigned CopyAlign = MI->getAlignment()->getZExtValue(); + if (CopyAlign < MinAlign) { + MI->setAlignment(ConstantInt::get(Type::Int32Ty, MinAlign)); Changed = true; } - + // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with // load/store. - ConstantInt *MemOpLength = dyn_cast<ConstantInt>(CI.getOperand(3)); - if (MemOpLength) { + if (ConstantInt *MemOpLength = dyn_cast<ConstantInt>(CI.getOperand(3))) { + // Source and destination pointer types are always "i8*" for intrinsic. + // If Size is 8 then use Int64Ty + // If Size is 4 then use Int32Ty + // If Size is 2 then use Int16Ty + // If Size is 1 then use Int8Ty unsigned Size = MemOpLength->getZExtValue(); - unsigned Align = cast<ConstantInt>(CI.getOperand(4))->getZExtValue(); - PointerType *NewPtrTy = NULL; - // Destination pointer type is always i8 * - // If Size is 8 then use Int64Ty - // If Size is 4 then use Int32Ty - // If Size is 2 then use Int16Ty - // If Size is 1 then use Int8Ty - if (Size && Size <=8 && !(Size&(Size-1))) - NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3)); - - if (NewPtrTy) { + if (Size && Size <= 8 && !(Size&(Size-1))) { + Type *NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3)); + // If the memcpy/memmove provides better alignment info than we can + // infer, use it. + SrcAlign = std::max(SrcAlign, CopyAlign); + DstAlign = std::max(DstAlign, CopyAlign); + Value *Src = InsertBitCastBefore(CI.getOperand(2), NewPtrTy, CI); Value *Dest = InsertBitCastBefore(CI.getOperand(1), NewPtrTy, CI); - Value *L = new LoadInst(Src, "tmp", false, Align, &CI); - Value *NS = new StoreInst(L, Dest, false, Align, &CI); + Value *L = new LoadInst(Src, "tmp", false, SrcAlign, &CI); + Value *NS = new StoreInst(L, Dest, false, DstAlign, &CI); CI.replaceAllUsesWith(NS); Changed = true; return EraseInstFromFunction(CI); |