llvm.org GIT mirror llvm / 8b170f7
Change memcpy/memset/memmove to have dest and source alignments. Note, this was reviewed (and more details are in) http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312083.html These intrinsics currently have an explicit alignment argument which is required to be a constant integer. It represents the alignment of the source and dest, and so must be the minimum of those. This change allows source and dest to each have their own alignments by using the alignment attribute on their arguments. The alignment argument itself is removed. There are a few places in the code for which the code needs to be checked by an expert as to whether using only src/dest alignment is safe. For those places, they currently take the minimum of src/dest alignments which matches the current behaviour. For example, code which used to read: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false) will now read: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %dest, i8* align 8 %src, i32 500, i1 false) For out of tree owners, I was able to strip alignment from calls using sed by replacing: (call.*llvm\.memset.*)i32\ [0-9]*\,\ i1 false\) with: $1i1 false) and similarly for memmove and memcpy. I then added back in alignment to test cases which needed it. A similar commit will be made to clang which actually has many differences in alignment as now IRBuilder can generate different source/dest alignments on calls. In IRBuilder itself, a new argument was added. Instead of calling: CreateMemCpy(Dst, Src, getInt64(Size), DstAlign, /* isVolatile */ false) you now call CreateMemCpy(Dst, Src, getInt64(Size), DstAlign, SrcAlign, /* isVolatile */ false) There is a temporary class (IntegerAlignment) which takes the source alignment and rejects implicit conversion from bool. This is to prevent isVolatile here from passing its default parameter to the source alignment. Note, changes in future can now be made to codegen. I didn't change anything here, but this change should enable better memcpy code sequences. Reviewed by Hal Finkel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253511 91177308-0d34-0410-b5e6-96231b3b80d8 Pete Cooper 3 years ago
294 changed file(s) with 1873 addition(s) and 1706 deletion(s). Raw diff Collapse all Expand all
361361 /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is
362362 /// specified, it will be added to the instruction. Likewise with alias.scope
363363 /// and noalias tags.
364 CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
364 CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size,
365 unsigned DstAlign,
365366 bool isVolatile = false, MDNode *TBAATag = nullptr,
366367 MDNode *ScopeTag = nullptr,
367368 MDNode *NoAliasTag = nullptr) {
368 return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile,
369 return CreateMemSet(Ptr, Val, getInt64(Size), DstAlign, isVolatile,
369370 TBAATag, ScopeTag, NoAliasTag);
370371 }
371372
372 CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
373 CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned DstAlign,
373374 bool isVolatile = false, MDNode *TBAATag = nullptr,
374375 MDNode *ScopeTag = nullptr,
375376 MDNode *NoAliasTag = nullptr);
376377
377 /// \brief Create and insert a memcpy between the specified pointers.
378 /// Create and insert a memcpy between the specified pointers.
378379 ///
379380 /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
380381 /// specified, it will be added to the instruction. Likewise with alias.scope
381382 /// and noalias tags.
382 CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
383 ///
384 /// Note! This is very temporary. It is only intended to catch calls to
385 /// CreateMemCpy in out of tree code which would otherwise silently pass the
386 /// volatile flag to source alignment.
387 class IntegerAlignment {
388 private:
389 uint64_t Align;
390
391 IntegerAlignment() = delete;
392 IntegerAlignment(bool) = delete;
393 public:
394 IntegerAlignment(int Align) : Align(Align) { }
395 IntegerAlignment(long long Align) : Align(Align) { }
396 IntegerAlignment(unsigned Align) : Align(Align) { }
397 IntegerAlignment(uint64_t Align) : Align(Align) { }
398
399 operator unsigned() { return Align; }
400 };
401 CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size,
402 unsigned DstAlign, IntegerAlignment SrcAlign,
383403 bool isVolatile = false, MDNode *TBAATag = nullptr,
384404 MDNode *TBAAStructTag = nullptr,
385405 MDNode *ScopeTag = nullptr,
386406 MDNode *NoAliasTag = nullptr) {
387 return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag,
407 return CreateMemCpy(Dst, Src, getInt64(Size), DstAlign, SrcAlign,
408 isVolatile, TBAATag,
388409 TBAAStructTag, ScopeTag, NoAliasTag);
389410 }
390411
391 CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
412 CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size,
413 unsigned DstAlign, IntegerAlignment SrcAlign,
392414 bool isVolatile = false, MDNode *TBAATag = nullptr,
393415 MDNode *TBAAStructTag = nullptr,
394416 MDNode *ScopeTag = nullptr,
400422 /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
401423 /// specified, it will be added to the instruction. Likewise with alias.scope
402424 /// and noalias tags.
403 CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
425 CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size,
426 unsigned DstAlign, IntegerAlignment SrcAlign,
404427 bool isVolatile = false, MDNode *TBAATag = nullptr,
405428 MDNode *ScopeTag = nullptr,
406429 MDNode *NoAliasTag = nullptr) {
407 return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile,
430 return CreateMemMove(Dst, Src, getInt64(Size), DstAlign, SrcAlign,
431 isVolatile,
408432 TBAATag, ScopeTag, NoAliasTag);
409433 }
410434
411 CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
435 CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size,
436 unsigned DstAlign, IntegerAlignment SrcAlign,
412437 bool isVolatile = false, MDNode *TBAATag = nullptr,
413438 MDNode *ScopeTag = nullptr,
414439 MDNode *NoAliasTag = nullptr);
16351635 /// \brief Extract the alignment for a call or parameter (0=unknown).
16361636 unsigned getParamAlignment(unsigned i) const {
16371637 return AttributeList.getParamAlignment(i);
1638 }
1639
1640 /// Set the alignment for a call or parameter (0=unknown).
1641 void setParamAlignment(unsigned Index, unsigned Align) {
1642 // Its not valid to change the parameter alignment. Instead we have to
1643 // remove the old one if its there, and add a new one.
1644 if (AttributeList.hasAttribute(Index, Attribute::Alignment))
1645 AttributeList = AttributeList.removeAttribute(getContext(),
1646 Index,
1647 Attribute::Alignment);
1648
1649 // Now add the new alignment.
1650 llvm::AttrBuilder B;
1651 B.addAlignmentAttr(Align);
1652 AttributeList = AttributeList.addAttributes(getContext(), Index,
1653 AttributeSet::get(getContext(),
1654 Index, B));
16381655 }
16391656
16401657 /// \brief Extract the number of dereferenceable bytes for a call or
149149 const Use &getLengthUse() const { return getArgOperandUse(2); }
150150 Use &getLengthUse() { return getArgOperandUse(2); }
151151
152 ConstantInt *getAlignmentCst() const {
152 unsigned getDestAlignment() const {
153 // Note, param attributes start at 1, so offset dest index from 0 to 1.
154 return getParamAlignment(1);
155 }
156
157 ConstantInt *getVolatileCst() const {
153158 return cast(const_cast(getArgOperand(3)));
154 }
155
156 unsigned getAlignment() const {
157 return getAlignmentCst()->getZExtValue();
158 }
159
160 ConstantInt *getVolatileCst() const {
161 return cast(const_cast(getArgOperand(4)));
162159 }
163160 bool isVolatile() const {
164161 return !getVolatileCst()->isZero();
187184 setArgOperand(2, L);
188185 }
189186
190 void setAlignment(Constant* A) {
191 setArgOperand(3, A);
187 void setDestAlignment(unsigned Align) {
188 // Note, param attributes start at 1, so offset dest index from 0 to 1.
189 setParamAlignment(1, Align);
192190 }
193191
194192 void setVolatile(Constant* V) {
195 setArgOperand(4, V);
196 }
197
198 Type *getAlignmentType() const {
199 return getArgOperand(3)->getType();
193 setArgOperand(3, V);
200194 }
201195
202196 // Methods for support type inquiry through isa, cast, and dyn_cast:
258252 return cast(getRawSource()->getType())->getAddressSpace();
259253 }
260254
255 unsigned getSrcAlignment() const {
256 // Note, param attributes start at 1, so offset src index from 1 to 2.
257 return getParamAlignment(2);
258 }
259
261260 void setSource(Value *Ptr) {
262261 assert(getRawSource()->getType() == Ptr->getType() &&
263262 "setSource called with pointer of wrong type!");
264263 setArgOperand(1, Ptr);
265264 }
266265
266 void setSrcAlignment(unsigned Align) {
267 // Note, param attributes start at 1, so offset src index from 1 to 2.
268 setParamAlignment(2, Align);
269 }
270
267271 // Methods for support type inquiry through isa, cast, and dyn_cast:
268272 static inline bool classof(const IntrinsicInst *I) {
269273 return I->getIntrinsicID() == Intrinsic::memcpy ||
332332
333333 def int_memcpy : Intrinsic<[],
334334 [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
335 llvm_i32_ty, llvm_i1_ty],
335 llvm_i1_ty],
336336 [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>,
337337 ReadOnly<1>]>;
338338 def int_memmove : Intrinsic<[],
339339 [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
340 llvm_i32_ty, llvm_i1_ty],
340 llvm_i1_ty],
341341 [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>,
342342 ReadOnly<1>]>;
343343 def int_memset : Intrinsic<[],
344344 [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
345 llvm_i32_ty, llvm_i1_ty],
345 llvm_i1_ty],
346346 [IntrReadWriteArgMem, NoCapture<0>]>;
347347
348348 let Properties = [IntrNoMem] in {
283283 MemCpyInst *MCI = cast(&I);
284284 // TODO: If the size is known, use it.
285285 visitMemoryReference(I, MCI->getDest(), MemoryLocation::UnknownSize,
286 MCI->getAlignment(), nullptr, MemRef::Write);
286 MCI->getDestAlignment(), nullptr, MemRef::Write);
287287 visitMemoryReference(I, MCI->getSource(), MemoryLocation::UnknownSize,
288 MCI->getAlignment(), nullptr, MemRef::Read);
288 MCI->getSrcAlignment(), nullptr, MemRef::Read);
289289
290290 // Check that the memcpy arguments don't overlap. The AliasAnalysis API
291291 // isn't expressive enough for what we really want to do. Known partial
305305 MemMoveInst *MMI = cast(&I);
306306 // TODO: If the size is known, use it.
307307 visitMemoryReference(I, MMI->getDest(), MemoryLocation::UnknownSize,
308 MMI->getAlignment(), nullptr, MemRef::Write);
308 MMI->getDestAlignment(), nullptr, MemRef::Write);
309309 visitMemoryReference(I, MMI->getSource(), MemoryLocation::UnknownSize,
310 MMI->getAlignment(), nullptr, MemRef::Read);
310 MMI->getSrcAlignment(), nullptr, MemRef::Read);
311311 break;
312312 }
313313 case Intrinsic::memset: {
314314 MemSetInst *MSI = cast(&I);
315315 // TODO: If the size is known, use it.
316316 visitMemoryReference(I, MSI->getDest(), MemoryLocation::UnknownSize,
317 MSI->getAlignment(), nullptr, MemRef::Write);
317 MSI->getDestAlignment(), nullptr, MemRef::Write);
318318 break;
319319 }
320320
16641664 unsigned Align = getKnownAlignment(MI->getDest(), *DL);
16651665 if (MemTransferInst *MTI = dyn_cast(MI))
16661666 Align = std::min(Align, getKnownAlignment(MTI->getSource(), *DL));
1667 if (Align > MI->getAlignment())
1668 MI->setAlignment(ConstantInt::get(MI->getAlignmentType(), Align));
1667 if (Align > MI->getDestAlignment())
1668 MI->setDestAlignment(Align);
16691669 }
16701670 }
16711671
43644364 case Intrinsic::longjmp:
43654365 return &"_longjmp"[!TLI.usesUnderscoreLongJmp()];
43664366 case Intrinsic::memcpy: {
4367 const MemCpyInst &MemCpyI = cast(I);
43674368 // FIXME: this definition of "user defined address space" is x86-specific
43684369 // Assert for address < 256 since we support only user defined address
43694370 // spaces.
4370 assert(cast(I.getArgOperand(0)->getType())->getAddressSpace()
4371 < 256 &&
4372 cast(I.getArgOperand(1)->getType())->getAddressSpace()
4373 < 256 &&
4371 assert(MemCpyI.getDestAddressSpace() < 256 &&
4372 MemCpyI.getSourceAddressSpace() < 256 &&
43744373 "Unknown address space");
4375 SDValue Op1 = getValue(I.getArgOperand(0));
4376 SDValue Op2 = getValue(I.getArgOperand(1));
4377 SDValue Op3 = getValue(I.getArgOperand(2));
4378 unsigned Align = cast(I.getArgOperand(3))->getZExtValue();
4374 SDValue Op1 = getValue(MemCpyI.getDest());
4375 SDValue Op2 = getValue(MemCpyI.getSource());
4376 SDValue Op3 = getValue(MemCpyI.getLength());
4377 // FIXME: Support passing different dest/src alignments to the memcpy
4378 // DAG node.
4379 unsigned Align = std::min(MemCpyI.getDestAlignment(),
4380 MemCpyI.getSrcAlignment());
43794381 if (!Align)
43804382 Align = 1; // @llvm.memcpy defines 0 and 1 to both mean no alignment.
4381 bool isVol = cast(I.getArgOperand(4))->getZExtValue();
4383 bool isVol = MemCpyI.isVolatile();
43824384 bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());
43834385 SDValue MC = DAG.getMemcpy(getRoot(), sdl, Op1, Op2, Op3, Align, isVol,
43844386 false, isTC,
4385 MachinePointerInfo(I.getArgOperand(0)),
4386 MachinePointerInfo(I.getArgOperand(1)));
4387 MachinePointerInfo(MemCpyI.getDest()),
4388 MachinePointerInfo(MemCpyI.getSource()));
43874389 updateDAGForMaybeTailCall(MC);
43884390 return nullptr;
43894391 }
43904392 case Intrinsic::memset: {
4393 const MemSetInst &MemSetI = cast(I);
43914394 // FIXME: this definition of "user defined address space" is x86-specific
43924395 // Assert for address < 256 since we support only user defined address
43934396 // spaces.
4394 assert(cast(I.getArgOperand(0)->getType())->getAddressSpace()
4395 < 256 &&
4397 assert(MemSetI.getDestAddressSpace() < 256 &&
43964398 "Unknown address space");
4397 SDValue Op1 = getValue(I.getArgOperand(0));
4398 SDValue Op2 = getValue(I.getArgOperand(1));
4399 SDValue Op3 = getValue(I.getArgOperand(2));
4400 unsigned Align = cast(I.getArgOperand(3))->getZExtValue();
4399 SDValue Op1 = getValue(MemSetI.getDest());
4400 SDValue Op2 = getValue(MemSetI.getValue());
4401 SDValue Op3 = getValue(MemSetI.getLength());
4402 unsigned Align = MemSetI.getDestAlignment();
44014403 if (!Align)
44024404 Align = 1; // @llvm.memset defines 0 and 1 to both mean no alignment.
4403 bool isVol = cast(I.getArgOperand(4))->getZExtValue();
4405 bool isVol = MemSetI.isVolatile();
44044406 bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());
44054407 SDValue MS = DAG.getMemset(getRoot(), sdl, Op1, Op2, Op3, Align, isVol,
4406 isTC, MachinePointerInfo(I.getArgOperand(0)));
4408 isTC, MachinePointerInfo(MemSetI.getDest()));
44074409 updateDAGForMaybeTailCall(MS);
44084410 return nullptr;
44094411 }
44104412 case Intrinsic::memmove: {
4413 const MemMoveInst &MemMoveI = cast(I);
44114414 // FIXME: this definition of "user defined address space" is x86-specific
44124415 // Assert for address < 256 since we support only user defined address
44134416 // spaces.
4414 assert(cast(I.getArgOperand(0)->getType())->getAddressSpace()
4415 < 256 &&
4416 cast(I.getArgOperand(1)->getType())->getAddressSpace()
4417 < 256 &&
4417 assert(MemMoveI.getDestAddressSpace() < 256 &&
4418 MemMoveI.getSourceAddressSpace() < 256 &&
44184419 "Unknown address space");
4419 SDValue Op1 = getValue(I.getArgOperand(0));
4420 SDValue Op2 = getValue(I.getArgOperand(1));
4421 SDValue Op3 = getValue(I.getArgOperand(2));
4422 unsigned Align = cast(I.getArgOperand(3))->getZExtValue();
4420 SDValue Op1 = getValue(MemMoveI.getDest());
4421 SDValue Op2 = getValue(MemMoveI.getSource());
4422 SDValue Op3 = getValue(MemMoveI.getLength());
4423 // FIXME: Support passing different dest/src alignments to the memcpy
4424 // DAG node.
4425 unsigned Align = std::min(MemMoveI.getDestAlignment(),
4426 MemMoveI.getSrcAlignment());
44234427 if (!Align)
44244428 Align = 1; // @llvm.memmove defines 0 and 1 to both mean no alignment.
4425 bool isVol = cast(I.getArgOperand(4))->getZExtValue();
4429 bool isVol = MemMoveI.isVolatile();
44264430 bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());
44274431 SDValue MM = DAG.getMemmove(getRoot(), sdl, Op1, Op2, Op3, Align, isVol,
4428 isTC, MachinePointerInfo(I.getArgOperand(0)),
4429 MachinePointerInfo(I.getArgOperand(1)));
4432 isTC, MachinePointerInfo(MemMoveI.getDest()),
4433 MachinePointerInfo(MemMoveI.getSource()));
44304434 updateDAGForMaybeTailCall(MM);
44314435 return nullptr;
44324436 }
829829 if (!pImpl) return AttributeSet();
830830 if (!Attrs.pImpl) return *this;
831831
832 // FIXME it is not obvious how this should work for alignment.
833 // For now, say we can't pass in alignment, which no current use does.
834 assert(!Attrs.hasAttribute(Index, Attribute::Alignment) &&
835 "Attempt to change alignment!");
836
837832 // Add the attribute slots before the one we're trying to add.
838833 SmallVector AttrSet;
839834 uint64_t NumAttrs = pImpl->getNumAttributes();
139139 F->setName(Name + ".old");
140140 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
141141 F->arg_begin()->getType());
142 return true;
143 }
144 break;
145 }
146 case 'm': {
147 if (Name.startswith("memcpy.") && F->arg_size() == 5) {
148 F->setName(Name + ".old");
149 // Get the types of dest, src, and len.
150 ArrayRef ParamTypes = F->getFunctionType()->params().slice(0, 3);
151 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memcpy,
152 ParamTypes);
153 return true;
154 }
155 if (Name.startswith("memmove.") && F->arg_size() == 5) {
156 F->setName(Name + ".old");
157 // Get the types of dest, src, and len.
158 ArrayRef ParamTypes = F->getFunctionType()->params().slice(0, 3);
159 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memmove,
160 ParamTypes);
161 return true;
162 }
163 if (Name.startswith("memset.") && F->arg_size() == 5) {
164 F->setName(Name + ".old");
165 // Get the types of dest and len.
166 Type *ParamTypes[2] = {
167 F->getFunctionType()->getParamType(0),
168 F->getFunctionType()->getParamType(2)
169 };
170 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memset,
171 ParamTypes);
142172 return true;
143173 }
144174 break;
726756 CI->eraseFromParent();
727757 return;
728758
759 case Intrinsic::memcpy:
760 case Intrinsic::memmove:
761 case Intrinsic::memset: {
762 // Remove alignment argument (3), and add alignment attributes to the
763 // dest/src pointers.
764 Value *Args[4] = {
765 CI->getArgOperand(0),
766 CI->getArgOperand(1),
767 CI->getArgOperand(2),
768 CI->getArgOperand(4)
769 };
770 auto *MemCI = cast(Builder.CreateCall(NewFn, Args, Name));
771
772 // All mem intrinsics support dest alignment.
773 const ConstantInt *Align = cast(CI->getArgOperand(3));
774 MemCI->setDestAlignment(Align->getZExtValue());
775
776 // Memcpy/Memmove also support source alignment.
777 if (auto *MemTransferI = dyn_cast(MemCI))
778 MemTransferI->setSrcAlignment(Align->getZExtValue());
779 CI->replaceAllUsesWith(MemCI);
780 CI->eraseFromParent();
781 return;
782 }
783
729784 case Intrinsic::objectsize:
730785 CI->replaceAllUsesWith(Builder.CreateCall(
731786 NewFn, {CI->getArgOperand(0), CI->getArgOperand(1)}, Name));
1414 #include "llvm/IR/Function.h"
1515 #include "llvm/IR/GlobalVariable.h"
1616 #include "llvm/IR/IRBuilder.h"
17 #include "llvm/IR/IntrinsicInst.h"
1718 #include "llvm/IR/Intrinsics.h"
1819 #include "llvm/IR/LLVMContext.h"
1920 #include "llvm/IR/Statepoint.h"
7879 }
7980
8081 CallInst *IRBuilderBase::
81 CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
82 CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned DstAlign,
8283 bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
8384 MDNode *NoAliasTag) {
8485 Ptr = getCastedInt8PtrValue(Ptr);
85 Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) };
86 Value *Ops[] = { Ptr, Val, Size, getInt1(isVolatile) };
8687 Type *Tys[] = { Ptr->getType(), Size->getType() };
8788 Module *M = BB->getParent()->getParent();
8889 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
9899
99100 if (NoAliasTag)
100101 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
102
103 cast(CI)->setDestAlignment(DstAlign);
101104
102105 return CI;
103106 }
104107
105108 CallInst *IRBuilderBase::
106 CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
109 CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned DstAlign,
110 IntegerAlignment SrcAlign,
107111 bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag,
108112 MDNode *ScopeTag, MDNode *NoAliasTag) {
109113 Dst = getCastedInt8PtrValue(Dst);
110114 Src = getCastedInt8PtrValue(Src);
111115
112 Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
116 Value *Ops[] = { Dst, Src, Size, getInt1(isVolatile) };
113117 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
114118 Module *M = BB->getParent()->getParent();
115119 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
129133
130134 if (NoAliasTag)
131135 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
136
137 auto *MCI = cast(CI);
138 MCI->setDestAlignment(DstAlign);
139 MCI->setSrcAlignment(SrcAlign);
132140
133141 return CI;
134142 }
135143
136144 CallInst *IRBuilderBase::
137 CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
145 CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned DstAlign,
146 IntegerAlignment SrcAlign,
138147 bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
139148 MDNode *NoAliasTag) {
140149 Dst = getCastedInt8PtrValue(Dst);
141150 Src = getCastedInt8PtrValue(Src);
142151
143 Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
152 Value *Ops[] = { Dst, Src, Size, getInt1(isVolatile) };
144153 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
145154 Module *M = BB->getParent()->getParent();
146155 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
156165
157166 if (NoAliasTag)
158167 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
168
169 auto *MMI = cast(CI);
170 MMI->setDestAlignment(DstAlign);
171 MMI->setSrcAlignment(SrcAlign);
159172
160173 return CI;
161174 }
35103510 const APInt &AlignVal = AlignCI->getValue();
35113511 Assert(AlignCI->isZero() || AlignVal.isPowerOf2(),
35123512 "alignment argument of memory intrinsics must be a power of 2", CS);
3513 Assert(isa(CS.getArgOperand(4)),
3513 Assert(isa(CS.getArgOperand(3)),
35143514 "isvolatile argument of memory intrinsics must be a constant int",
35153515 CS);
35163516 break;
33783378 // Small memcpy's are common enough that we want to do them without a call
33793379 // if possible.
33803380 uint64_t Len = cast(MTI->getLength())->getZExtValue();
3381 unsigned Alignment = MTI->getAlignment();
3381 unsigned Alignment = std::min(MTI->getDestAlignment(),
3382 MTI->getSrcAlignment());
33823383 if (isMemCpySmall(Len, Alignment)) {
33833384 Address Dest, Src;
33843385 if (!computeAddress(MTI->getRawDest(), Dest) ||
33983399 return false;
33993400
34003401 const char *IntrMemName = isa(II) ? "memcpy" : "memmove";
3401 return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 2);
3402 return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 1);
34023403 }
34033404 case Intrinsic::memset: {
34043405 const MemSetInst *MSI = cast(II);
34143415 // address spaces.
34153416 return false;
34163417
3417 return lowerCallTo(II, "memset", II->getNumArgOperands() - 2);
3418 return lowerCallTo(II, "memset", II->getNumArgOperands() - 1);
34183419 }
34193420 case Intrinsic::sin:
34203421 case Intrinsic::cos:
399399 case Intrinsic::memcpy: {
400400 MemCpyInst *MemCpy = cast(Intr);
401401 Builder.CreateMemCpy(MemCpy->getRawDest(), MemCpy->getRawSource(),
402 MemCpy->getLength(), MemCpy->getAlignment(),
403 MemCpy->isVolatile());
402 MemCpy->getLength(), MemCpy->getDestAlignment(),
403 MemCpy->getSrcAlignment(), MemCpy->isVolatile());
404404 Intr->eraseFromParent();
405405 continue;
406406 }
407407 case Intrinsic::memset: {
408408 MemSetInst *MemSet = cast(Intr);
409409 Builder.CreateMemSet(MemSet->getRawDest(), MemSet->getValue(),
410 MemSet->getLength(), MemSet->getAlignment(),
410 MemSet->getLength(), MemSet->getDestAlignment(),
411411 MemSet->isVolatile());
412412 Intr->eraseFromParent();
413413 continue;
23272327 for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
23282328 i != e; ++i) {
23292329 // If we're lowering a memory intrinsic instead of a regular call, skip the
2330 // last two arguments, which shouldn't be passed to the underlying function.
2331 if (IntrMemName && e-i <= 2)
2330 // last argument, which shouldn't be passed to the underlying function.
2331 if (IntrMemName && e-i <= 1)
23322332 break;
23332333
23342334 ISD::ArgFlagsTy Flags;
25262526 if (!ARMComputeAddress(MTI.getRawDest(), Dest) ||
25272527 !ARMComputeAddress(MTI.getRawSource(), Src))
25282528 return false;
2529 unsigned Alignment = MTI.getAlignment();
2529 unsigned Alignment = std::min(MTI.getDestAlignment(),
2530 MTI.getSrcAlignment());
25302531 if (ARMTryEmitSmallMemCpy(Dest, Src, Len, Alignment))
25312532 return true;
25322533 }
14021402 if (!MTI->getLength()->getType()->isIntegerTy(32))
14031403 return false;
14041404 const char *IntrMemName = isa(II) ? "memcpy" : "memmove";
1405 return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 2);
1405 return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 1);
14061406 }
14071407 case Intrinsic::memset: {
14081408 const MemSetInst *MSI = cast(II);
14111411 return false;
14121412 if (!MSI->getLength()->getType()->isIntegerTy(32))
14131413 return false;
1414 return lowerCallTo(II, "memset", II->getNumArgOperands() - 2);
1414 return lowerCallTo(II, "memset", II->getNumArgOperands() - 1);
14151415 }
14161416 }
14171417 return false;
24082408 if (MCI->getSourceAddressSpace() > 255 || MCI->getDestAddressSpace() > 255)
24092409 return false;
24102410
2411 return lowerCallTo(II, "memcpy", II->getNumArgOperands() - 2);
2411 return lowerCallTo(II, "memcpy", II->getNumArgOperands() - 1);
24122412 }
24132413 case Intrinsic::memset: {
24142414 const MemSetInst *MSI = cast(II);
24232423 if (MSI->getDestAddressSpace() > 255)
24242424 return false;
24252425
2426 return lowerCallTo(II, "memset", II->getNumArgOperands() - 2);
2426 return lowerCallTo(II, "memset", II->getNumArgOperands() - 1);
24272427 }
24282428 case Intrinsic::stackprotector: {
24292429 // Emit code to store the stack guard onto the stack.
5959 return T;
6060 }
6161
62 Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) {
62 Instruction *InstCombiner::SimplifyMemTransfer(MemTransferInst *MI) {
6363 unsigned DstAlign = getKnownAlignment(MI->getArgOperand(0), DL, MI, AC, DT);
6464 unsigned SrcAlign = getKnownAlignment(MI->getArgOperand(1), DL, MI, AC, DT);
65 unsigned MinAlign = std::min(DstAlign, SrcAlign);
66 unsigned CopyAlign = MI->getAlignment();
67
68 if (CopyAlign < MinAlign) {
69 MI->setAlignment(ConstantInt::get(MI->getAlignmentType(), MinAlign, false));
65 unsigned CopyDestAlign = MI->getDestAlignment();
66 unsigned CopySrcAlign = MI->getSrcAlignment();
67
68 if (CopyDestAlign < DstAlign) {
69 MI->setDestAlignment(DstAlign);
70 return MI;
71 }
72 if (CopySrcAlign < SrcAlign) {
73 MI->setSrcAlignment(SrcAlign);
7074 return MI;
7175 }
7276
134138
135139 // If the memcpy/memmove provides better alignment info than we can
136140 // infer, use it.
137 SrcAlign = std::max(SrcAlign, CopyAlign);
138 DstAlign = std::max(DstAlign, CopyAlign);
141 SrcAlign = std::max(SrcAlign, CopySrcAlign);
142 DstAlign = std::max(DstAlign, CopyDestAlign);
139143
140144 Value *Src = Builder->CreateBitCast(MI->getArgOperand(1), NewSrcPtrTy);
141145 Value *Dest = Builder->CreateBitCast(MI->getArgOperand(0), NewDstPtrTy);
155159
156160 Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) {
157161 unsigned Alignment = getKnownAlignment(MI->getDest(), DL, MI, AC, DT);
158 if (MI->getAlignment() < Alignment) {
159 MI->setAlignment(ConstantInt::get(MI->getAlignmentType(),
160 Alignment, false));
162 if (MI->getDestAlignment() < Alignment) {
163 MI->setDestAlignment(Alignment);
161164 return MI;
162165 }
163166
167170 if (!LenC || !FillC || !FillC->getType()->isIntegerTy(8))
168171 return nullptr;
169172 uint64_t Len = LenC->getLimitedValue();
170 Alignment = MI->getAlignment();
173 Alignment = MI->getDestAlignment();
171174 assert(Len && "0-sized memory setting should be removed already.");
172175
173176 // memset(s,c,n) -> store s, c (for n=1,2,4,8)
742745
743746 // If we can determine a pointer alignment that is bigger than currently
744747 // set, update the alignment.
745 if (isa(MI)) {
746 if (Instruction *I = SimplifyMemTransfer(MI))
748 if (auto *MTI = dyn_cast(MI)) {
749 if (Instruction *I = SimplifyMemTransfer(MTI))
747750 return I;
748751 } else if (MemSetInst *MSI = dyn_cast(MI)) {
749752 if (Instruction *I = SimplifyMemSet(MSI))
557557 Instruction *PromoteCastOfAllocation(BitCastInst &CI, AllocaInst &AI);
558558 Instruction *MatchBSwap(BinaryOperator &I);
559559 bool SimplifyStoreAtEndOfBlock(StoreInst &SI);
560 Instruction *SimplifyMemTransfer(MemIntrinsic *MI);
560 Instruction *SimplifyMemTransfer(MemTransferInst *MI);
561561 Instruction *SimplifyMemSet(MemSetInst *MI);
562562
563563 Value *EvaluateInDifferentType(Value *V, Type *Ty, bool isSigned);
13551355 Value *LenShadow = IRB.CreateMul(
13561356 I.getLength(),
13571357 ConstantInt::get(I.getLength()->getType(), DFSF.DFS.ShadowWidth / 8));
1358 Value *AlignShadow;
1359 if (ClPreserveAlignment) {
1360 AlignShadow = IRB.CreateMul(I.getAlignmentCst(),
1361 ConstantInt::get(I.getAlignmentCst()->getType(),
1362 DFSF.DFS.ShadowWidth / 8));
1363 } else {
1364 AlignShadow = ConstantInt::get(I.getAlignmentCst()->getType(),
1365 DFSF.DFS.ShadowWidth / 8);
1366 }
13671358 Type *Int8Ptr = Type::getInt8PtrTy(*DFSF.DFS.Ctx);
13681359 DestShadow = IRB.CreateBitCast(DestShadow, Int8Ptr);
13691360 SrcShadow = IRB.CreateBitCast(SrcShadow, Int8Ptr);
1370 IRB.CreateCall(I.getCalledValue(), {DestShadow, SrcShadow, LenShadow,
1371 AlignShadow, I.getVolatileCst()});
1361 auto *MTI = cast(IRB.CreateCall(I.getCalledValue(),
1362 { DestShadow, SrcShadow,
1363 LenShadow,
1364 I.getVolatileCst() }));
1365
1366 if (ClPreserveAlignment) {
1367 MTI->setDestAlignment(I.getDestAlignment() * (DFSF.DFS.ShadowWidth / 8));
1368 MTI->setSrcAlignment(I.getSrcAlignment() * (DFSF.DFS.ShadowWidth / 8));
1369 } else {
1370 MTI->setDestAlignment(DFSF.DFS.ShadowWidth / 8);
1371 MTI->setSrcAlignment(DFSF.DFS.ShadowWidth / 8);
1372 }
13721373 }
13731374
13741375 void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
11161116 unsigned CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
11171117 Value *Cpy = EntryIRB.CreateMemCpy(
11181118 getShadowPtr(V, EntryIRB.getInt8Ty(), EntryIRB), Base, Size,
1119 CopyAlign);
1119 CopyAlign, CopyAlign);
11201120 DEBUG(dbgs() << " ByValCpy: " << *Cpy << "\n");
11211121 (void)Cpy;
11221122 }
24812481 unsigned Alignment = std::min(ParamAlignment, kShadowTLSAlignment);
24822482 Store = IRB.CreateMemCpy(ArgShadowBase,
24832483 getShadowPtr(A, Type::getInt8Ty(*MS.C), IRB),
2484 Size, Alignment);
2484 Size, Alignment, Alignment);
24852485 } else {
24862486 Size = DL.getTypeAllocSize(A->getType());
24872487 if (ArgOffset + Size > kParamTLSSize) break;
28332833 Value *Base = getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset);
28342834 OverflowOffset += RoundUpToAlignment(ArgSize, 8);
28352835 IRB.CreateMemCpy(Base, MSV.getShadowPtr(A, IRB.getInt8Ty(), IRB),
2836 ArgSize, kShadowTLSAlignment);
2836 ArgSize, kShadowTLSAlignment, kShadowTLSAlignment);
28372837 } else {
28382838 ArgKind AK = classifyArgument(A);
28392839 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
29112911 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset),
29122912 VAArgOverflowSize);
29132913 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
2914 IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8);
2914 IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8, 8);
29152915 }
29162916
29172917 // Instrument va_start.
29302930 Value *RegSaveAreaShadowPtr =
29312931 MSV.getShadowPtr(RegSaveAreaPtr, IRB.getInt8Ty(), IRB);
29322932 IRB.CreateMemCpy(RegSaveAreaShadowPtr, VAArgTLSCopy,
2933 AMD64FpEndOffset, 16);
2933 AMD64FpEndOffset, 16, 16);
29342934
29352935 Value *OverflowArgAreaPtrPtr =
29362936 IRB.CreateIntToPtr(
29422942 MSV.getShadowPtr(OverflowArgAreaPtr, IRB.getInt8Ty(), IRB);
29432943 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
29442944 AMD64FpEndOffset);
2945 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize, 16);
2945 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize,
2946 16, 16);
29462947 }
29472948 }
29482949 };
30283029 // If there is a va_start in this function, make a backup copy of
30293030 // va_arg_tls somewhere in the function entry block.
30303031 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
3031 IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8);
3032 IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8, 8);
30323033 }
30333034
30343035 // Instrument va_start.
30433044 Value *RegSaveAreaPtr = IRB.CreateLoad(RegSaveAreaPtrPtr);
30443045 Value *RegSaveAreaShadowPtr =
30453046 MSV.getShadowPtr(RegSaveAreaPtr, IRB.getInt8Ty(), IRB);
3046 IRB.CreateMemCpy(RegSaveAreaShadowPtr, VAArgTLSCopy, CopySize, 8);
3047 IRB.CreateMemCpy(RegSaveAreaShadowPtr, VAArgTLSCopy, CopySize, 8, 8);
30473048 }
30483049 }
30493050 };
346346 // instruction, but only for one operand, save it. If we reach the
347347 // other operand through another assumption later, then we may
348348 // change the alignment at that point.
349 // FIXME: The above statement is no longer true. Fix the code below
350 // to be able to reason about different dest/src alignments.
349351 if (MemTransferInst *MTI = dyn_cast(MI)) {
350352 unsigned NewSrcAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV,
351353 MTI->getSource(), SE);
375377 if (AltSrcAlignment <= std::max(NewDestAlignment, AltDestAlignment))
376378 NewAlignment = std::max(NewAlignment, AltSrcAlignment);
377379
378 if (NewAlignment > MI->getAlignment()) {
379 MI->setAlignment(ConstantInt::get(Type::getInt32Ty(
380 MI->getParent()->getContext()), NewAlignment));
380 if (NewAlignment > MTI->getDestAlignment()) {
381 MTI->setDestAlignment(NewAlignment);
381382 ++NumMemIntAlignChanged;
382383 }
383384
385 if (NewAlignment > MTI->getSrcAlignment()) {
386 MTI->setSrcAlignment(NewAlignment);
387 ++NumMemIntAlignChanged;
388 }
389
384390 NewDestAlignments.insert(std::make_pair(MTI, NewDestAlignment));
385391 NewSrcAlignments.insert(std::make_pair(MTI, NewSrcAlignment));
386 } else if (NewDestAlignment > MI->getAlignment()) {
392 } else if (NewDestAlignment > MI->getDestAlignment()) {
387393 assert((!isa(MI) || isa(MI)) &&
388394 "Unknown memory intrinsic");
389395
390 MI->setAlignment(ConstantInt::get(Type::getInt32Ty(
391 MI->getParent()->getContext()), NewDestAlignment));
396 MI->setDestAlignment(NewDestAlignment);
392397 ++NumMemIntAlignChanged;
393398 }
394399 }
610610 // as any store/memset/memcpy is likely using vector instructions so
611611 // shortening it to not vector size is likely to be slower
612612 MemIntrinsic* DepIntrinsic = cast(DepWrite);
613 unsigned DepWriteAlign = DepIntrinsic->getAlignment();
613 unsigned DepWriteAlign = DepIntrinsic->getDestAlignment();
614614 if (llvm::isPowerOf2_64(InstWriteOffset) ||
615615 ((DepWriteAlign != 0) && InstWriteOffset % DepWriteAlign == 0)) {
616616
413413 return false;
414414
415415 return processLoopStridedStore(Pointer, (unsigned)SizeInBytes,
416 MSI->getAlignment(), MSI->getValue(), MSI, Ev,
417 BECount, /*NegStride=*/false);
416 MSI->getDestAlignment(), MSI->getValue(), MSI,
417 Ev, BECount, /*NegStride=*/false);
418418 }
419419
420420 /// mayLoopAccessLocation - Return true if the specified loop might access the
699699
700700 CallInst *NewCall =
701701 Builder.CreateMemCpy(StoreBasePtr, LoadBasePtr, NumBytes,
702 std::min(SI->getAlignment(), LI->getAlignment()));
702 SI->getAlignment(), LI->getAlignment());
703703 NewCall->setDebugLoc(SI->getDebugLoc());
704704
705705 DEBUG(dbgs() << " Formed memcpy: " << *NewCall << "\n"
228228
229229 void addMemSet(int64_t OffsetFromFirst, MemSetInst *MSI) {
230230 int64_t Size = cast(MSI->getLength())->getZExtValue();
231 addRange(OffsetFromFirst, Size, MSI->getDest(), MSI->getAlignment(), MSI);
231 addRange(OffsetFromFirst, Size, MSI->getDest(), MSI->getDestAlignment(),
232 MSI);
232233 }
233234
234235 void addRange(int64_t Start, int64_t Size, Value *Ptr,
818819
819820 // If all checks passed, then we can transform M.
820821
821 // Make sure to use the lesser of the alignment of the source and the dest
822 // since we're changing where we're reading from, but don't want to increase
823 // the alignment past what can be read from or written to.
824822 // TODO: Is this worth it if we're creating a less aligned memcpy? For
825823 // example we could be moving from movaps -> movq on x86.
826 unsigned Align = std::min(MDep->getAlignment(), M->getAlignment());
827
828824 IRBuilder<> Builder(M);
829825 if (UseMemMove)
830826 Builder.CreateMemMove(M->getRawDest(), MDep->getRawSource(), M->getLength(),
831 Align, M->isVolatile());
827 M->getDestAlignment(), MDep->getSrcAlignment(),
828 M->isVolatile());
832829 else
833830 Builder.CreateMemCpy(M->getRawDest(), MDep->getRawSource(), M->getLength(),
834 Align, M->isVolatile());
831 M->getDestAlignment(), MDep->getSrcAlignment(),
832 M->isVolatile());
835833
836834 // Remove the instruction we're replacing.
837835 MD->removeInstruction(M);
877875 // If Dest is aligned, and SrcSize is constant, use the minimum alignment
878876 // of the sum.
879877 const unsigned DestAlign =
880 std::max(MemSet->getAlignment(), MemCpy->getAlignment());
878 std::max(MemSet->getDestAlignment(), MemCpy->getDestAlignment());
881879 if (DestAlign > 1)
882880 if (ConstantInt *SrcSizeC = dyn_cast(SrcSize))
883881 Align = MinAlign(SrcSizeC->getZExtValue(), DestAlign);
934932
935933 IRBuilder<> Builder(MemCpy);
936934 Builder.CreateMemSet(MemCpy->getRawDest(), MemSet->getOperand(1),
937 CopySize, MemCpy->getAlignment());
935 CopySize, MemCpy->getDestAlignment());
938936 return true;
939937 }
940938
960958 if (Value *ByteVal = isBytewiseValue(GV->getInitializer())) {
961959 IRBuilder<> Builder(M);
962960 Builder.CreateMemSet(M->getRawDest(), ByteVal, M->getLength(),
963 M->getAlignment(), false);
961 M->getDestAlignment(), false);
964962 MD->removeInstruction(M);
965963 M->eraseFromParent();
966964 ++NumCpyToSet;
989987 // d) memcpy from a just-memset'd source can be turned into memset.
990988 if (DepInfo.isClobber()) {
991989 if (CallInst *C = dyn_cast(DepInfo.getInst())) {
990 // FIXME: Can we pass in either of dest/src alignment here instead of
991 // convervatively taking the minimum?
992 unsigned Align = std::min(M->getDestAlignment(), M->getSrcAlignment());
992993 if (performCallSlotOptzn(M, M->getDest(), M->getSource(),
993 CopySize->getZExtValue(), M->getAlignment(),
994 CopySize->getZExtValue(), Align,
994995 C)) {
995996 MD->removeInstruction(M);
996997 M->eraseFromParent();
11071108 getAnalysis().getAssumptionCache(
11081109 *CS->getParent()->getParent());
11091110 DominatorTree &DT = getAnalysis().getDomTree();
1110 if (MDep->getAlignment() < ByValAlign &&
1111 // FIXME: Can we use either of dest/src alignment here instead of
1112 // convervatively taking the minimum?
1113 unsigned MinAlign = std::min(MDep->getDestAlignment(),
1114 MDep->getSrcAlignment());
1115 if (MinAlign < ByValAlign &&
11111116 getOrEnforceKnownAlignment(MDep->getSource(), ByValAlign, DL,
11121117 CS.getInstruction(), &AC, &DT) < ByValAlign)
11131118 return false;
26172617 assert(!IsSplit);
26182618 assert(NewBeginOffset == BeginOffset);
26192619 II.setDest(getNewAllocaSlicePtr(IRB, OldPtr->getType()));
2620 Type *CstTy = II.getAlignmentCst()->getType();
2621 II.setAlignment(ConstantInt::get(CstTy, getSliceAlign()));
2620 II.setDestAlignment(getSliceAlign());
26222621
26232622 deleteIfTriviallyDead(OldPtr);
26242623 return false;
27342733 // update both source and dest of a single call.
27352734 if (!IsSplittable) {
27362735 Value *AdjustedPtr = getNewAllocaSlicePtr(IRB, OldPtr->getType());
2737 if (IsDest)
2736 if (IsDest) {
27382737 II.setDest(AdjustedPtr);
2739 else
2738
2739 if (II.getDestAlignment() > SliceAlign)
2740 II.setDestAlignment(MinAlign(II.getDestAlignment(), SliceAlign));
2741 } else {
27402742 II.setSource(AdjustedPtr);
27412743
2742 if (II.getAlignment() > SliceAlign) {
2743 Type *CstTy = II.getAlignmentCst()->getType();
2744 II.setAlignment(
2745 ConstantInt::get(CstTy, MinAlign(II.getAlignment(), SliceAlign)));
2744 if (II.getSrcAlignment() > SliceAlign)
2745 II.setSrcAlignment(MinAlign(II.getSrcAlignment(), SliceAlign));
27462746 }
27472747
27482748 DEBUG(dbgs() << " to: " << II << "\n");
27952795 // Compute the relative offset for the other pointer within the transfer.
27962796 unsigned IntPtrWidth = DL.getPointerSizeInBits(OtherAS);
27972797 APInt OtherOffset(IntPtrWidth, NewBeginOffset - BeginOffset);
2798 unsigned OtherAlign = MinAlign(II.getAlignment() ? II.getAlignment() : 1,
2799 OtherOffset.zextOrTrunc(64).getZExtValue());
2798 unsigned OtherDestAlign = MinAlign(II.getDestAlignment() ? II.getDestAlignment() : 1,
2799 OtherOffset.zextOrTrunc(64).getZExtValue());
2800 unsigned OtherSrcAlign = MinAlign(II.getSrcAlignment() ? II.getSrcAlignment() : 1,
2801 OtherOffset.zextOrTrunc(64).getZExtValue());
28002802
28012803 if (EmitMemCpy) {
28022804 // Compute the other pointer, folding as much as possible to produce
28082810 Type *SizeTy = II.getLength()->getType();
28092811 Constant *Size = ConstantInt::get(SizeTy, NewEndOffset - NewBeginOffset);
28102812
2811 CallInst *New = IRB.CreateMemCpy(
2812 IsDest ? OurPtr : OtherPtr, IsDest ? OtherPtr : OurPtr, Size,
2813 MinAlign(SliceAlign, OtherAlign), II.isVolatile());
2813 CallInst *New = IRB.CreateMemCpy(IsDest ? OurPtr : OtherPtr,
2814 IsDest ? OtherPtr : OurPtr, Size,
2815 MinAlign(SliceAlign, OtherDestAlign),
2816 MinAlign(SliceAlign, OtherSrcAlign),
2817 II.isVolatile());
28142818 (void)New;
28152819 DEBUG(dbgs() << " to: " << *New << "\n");
28162820 return false;
28422846
28432847 Value *SrcPtr = getAdjustedPtr(IRB, DL, OtherPtr, OtherOffset, OtherPtrTy,
28442848 OtherPtr->getName() + ".");
2845 unsigned SrcAlign = OtherAlign;
2849 unsigned SrcAlign = OtherSrcAlign;
28462850 Value *DstPtr = &NewAI;
28472851 unsigned DstAlign = SliceAlign;
28482852 if (!IsDest) {
715715 SrcPtr = Builder.CreateBitCast(SrcPtr, AIPTy);
716716
717717 LoadInst *SrcVal = Builder.CreateLoad(SrcPtr, "srcval");
718 SrcVal->setAlignment(MTI->getAlignment());
718 SrcVal->setAlignment(MTI->getSrcAlignment());
719719 Builder.CreateStore(SrcVal, NewAI);
720720 } else if (GetUnderlyingObject(MTI->getDest(), DL, 0) != OrigAI) {
721721 // Src must be OrigAI, change this to be a load from NewAI then a store
732732 Value *DstPtr = Builder.CreateBitCast(MTI->getDest(), AIPTy);
733733
734734 StoreInst *NewStore = Builder.CreateStore(SrcVal, DstPtr);
735 NewStore->setAlignment(MTI->getAlignment());
735 NewStore->setAlignment(MTI->getDestAlignment());
736736 } else {
737737 // Noop transfer. Src == Dst
738738 }
21812181 // that doesn't have anything to do with the alloca that we are promoting. For
21822182 // memset, this Value* stays null.
21832183 Value *OtherPtr = nullptr;
2184 unsigned MemAlignment = MI->getAlignment();
2184 unsigned DestMemAlignment = MI->getDestAlignment();
2185 unsigned SrcMemAlignment = 0;
21852186 if (MemTransferInst *MTI = dyn_cast(MI)) { // memmove/memcopy
21862187 if (Inst == MTI->getRawDest())
21872188 OtherPtr = MTI->getRawSource();
21892190 assert(Inst == MTI->getRawSource());
21902191 OtherPtr = MTI->getRawDest();
21912192 }
2193 SrcMemAlignment = MTI->getSrcAlignment();
21922194 }
21932195
21942196 // If there is an other pointer, we want to convert it to the same pointer
22342236 for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
22352237 // If this is a memcpy/memmove, emit a GEP of the other element address.
22362238 Value *OtherElt = nullptr;
2237 unsigned OtherEltAlign = MemAlignment;
2239 unsigned OtherDestEltAlign = DestMemAlignment;
2240 unsigned OtherSrcEltAlign = SrcMemAlignment;
22382241
22392242 if (OtherPtr) {
22402243 Value *Idx[2] = { Zero,
22572260 // mem intrinsic and the alignment of the element. If the alignment of
22582261 // the memcpy (f.e.) is 32 but the element is at a 4-byte offset, then the
22592262 // known alignment is just 4 bytes.
2260 OtherEltAlign = (unsigned)MinAlign(OtherEltAlign, EltOffset);
2263 OtherDestEltAlign = (unsigned)MinAlign(OtherDestEltAlign, EltOffset);
2264 OtherSrcEltAlign = (unsigned)MinAlign(OtherSrcEltAlign, EltOffset);
22612265 }
22622266
22632267 Value *EltPtr = NewElts[i];
22682272 if (isa(MI)) {
22692273 if (SROADest) {
22702274 // From Other to Alloca.
2271 Value *Elt = new LoadInst(OtherElt, "tmp", false, OtherEltAlign, MI);
2275 Value *Elt = new LoadInst(OtherElt, "tmp", false,
2276 OtherSrcEltAlign, MI);
22722277 new StoreInst(Elt, EltPtr, MI);
22732278 } else {
22742279 // From Alloca to Other.
22752280 Value *Elt = new LoadInst(EltPtr, "tmp", MI);
2276 new StoreInst(Elt, OtherElt, false, OtherEltAlign, MI);
2281 new StoreInst(Elt, OtherElt, false, OtherDestEltAlign, MI);
22772282 }
22782283 continue;
22792284 }
23362341 Value *Src = SROADest ? OtherElt : EltPtr; // Src ptr
23372342
23382343 if (isa(MI))
2339 Builder.CreateMemCpy(Dst, Src, EltSize, OtherEltAlign,MI->isVolatile());
2344 Builder.CreateMemCpy(Dst, Src, EltSize, OtherDestEltAlign,
2345 OtherSrcEltAlign, MI->isVolatile());
23402346 else
2341 Builder.CreateMemMove(Dst, Src, EltSize,OtherEltAlign,MI->isVolatile());
2347 Builder.CreateMemMove(Dst, Src, EltSize, OtherDestEltAlign,
2348 OtherSrcEltAlign, MI->isVolatile());
23422349 }
23432350 }
23442351 DeadInsts.push_back(MI);
850850 // Always generate a memcpy of alignment 1 here because we don't know
851851 // the alignment of the src pointer. Other optimizations can infer
852852 // better alignment.
853 Builder.CreateMemCpy(Dst, Src, Size, /*Align=*/1);
853 Builder.CreateMemCpy(Dst, Src, Size, /*DestAlign=*/1, /*SrcAlign=*/1);
854854 }
855855
856856 /// When inlining a call site that has a byval argument,
237237 // concatenation for us. Make a memcpy to copy the nul byte with align = 1.
238238 B.CreateMemCpy(CpyDst, Src,
239239 ConstantInt::get(DL.getIntPtrType(Src->getContext()), Len + 1),
240 1);
240 1, 1);
241241 return Dst;
242242 }
243243
470470 // We have enough information to now generate the memcpy call to do the
471471 // copy for us. Make a memcpy to copy the nul byte with align = 1.
472472 B.CreateMemCpy(Dst, Src,
473 ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len), 1);
473 ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len), 1,
474 1);
474475 return Dst;
475476 }
476477
497498
498499 // We have enough information to now generate the memcpy call to do the
499500 // copy for us. Make a memcpy to copy the nul byte with align = 1.
500 B.CreateMemCpy(Dst, Src, LenV, 1);
501 B.CreateMemCpy(Dst, Src, LenV, 1, 1);
501502 return DstEnd;
502503 }
503504
537538
538539 Type *PT = Callee->getFunctionType()->getParamType(0);
539540 // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant]
540 B.CreateMemCpy(Dst, Src, ConstantInt::get(DL.getIntPtrType(PT), Len), 1);
541 B.CreateMemCpy(Dst, Src, ConstantInt::get(DL.getIntPtrType(PT), Len), 1, 1);
541542
542543 return Dst;
543544 }
916917
917918 // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
918919 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
919 CI->getArgOperand(2), 1);
920 CI->getArgOperand(2), 1, 1);
920921 return CI->getArgOperand(0);
921922 }
922923
928929
929930 // memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
930931 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
931 CI->getArgOperand(2), 1);
932 CI->getArgOperand(2), 1, 1);
932933 return CI->getArgOperand(0);
933934 }
934935
17571758 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
17581759 ConstantInt::get(DL.getIntPtrType(CI->getContext()),
17591760 FormatStr.size() + 1),
1760 1); // Copy the null byte.
1761 1, 1); // Copy the null byte.
17611762 return ConstantInt::get(CI->getType(), FormatStr.size());
17621763 }
17631764
17911792 return nullptr;
17921793 Value *IncLen =
17931794 B.CreateAdd(Len, ConstantInt::get(Len->getType(), 1), "leninc");
1794 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1);
1795 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1, 1);
17951796
17961797 // The sprintf result is the unincremented number of bytes in the string.
17971798 return B.CreateIntCast(Len, CI->getType(), false);
23282329
23292330 if (isFortifiedCallFoldable(CI, 3, 2, false)) {
23302331 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
2331 CI->getArgOperand(2), 1);
2332 CI->getArgOperand(2), 1, 1);
23322333 return CI->getArgOperand(0);
23332334 }
23342335 return nullptr;
23422343
23432344 if (isFortifiedCallFoldable(CI, 3, 2, false)) {
23442345 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
2345 CI->getArgOperand(2), 1);
2346 CI->getArgOperand(2), 1, 1);
23462347 return CI->getArgOperand(0);
23472348 }
23482349 return nullptr;
0 ; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
11 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
22
3 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) #0
3 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) #0
44 declare void @llvm.assume(i1) #0
55
66 define void @test1(i8* %P, i8* %Q) nounwind ssp {
77 tail call void @llvm.assume(i1 true)
8 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
8 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
99 ret void
1010
1111 ; CHECK-LABEL: Function: test1:
1313 ; CHECK: MayAlias: i8* %P, i8* %Q
1414 ; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.assume(i1 true)
1515 ; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.assume(i1 true)
16 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
17 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
18 ; CHECK: NoModRef: tail call void @llvm.assume(i1 true) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
19 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.assume(i1 true)
16 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
17 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
18 ; CHECK: NoModRef: tail call void @llvm.assume(i1 true) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
19 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.assume(i1 true)
2020 }
2121
2222 attributes #0 = { nounwind }
44 declare <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8*, i32) nounwind readonly
55 declare void @llvm.arm.neon.vst1.p0i8.v8i16(i8*, <8 x i16>, i32) nounwind
66
7 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
8 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
7 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
8 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
99
1010 declare void @a_readonly_func(i8 *) noinline nounwind readonly
1111
3636 }
3737
3838 define void @test2(i8* %P, i8* %Q) nounwind ssp {
39 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
40 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
39 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
40 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
4141 ret void
4242
4343 ; CHECK-LABEL: Function: test2:
4444
4545 ; CHECK: MayAlias: i8* %P, i8* %Q
46 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
47 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
48 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
49 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
50 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
51 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
46 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
47 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
48 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
49 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
50 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
51 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
5252 }
5353
5454 define void @test2a(i8* noalias %P, i8* noalias %Q) nounwind ssp {
55 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
56 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
55 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
56 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
5757 ret void
5858
5959 ; CHECK-LABEL: Function: test2a:
6060
6161 ; CHECK: NoAlias: i8* %P, i8* %Q
62 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
63 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
64 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
65 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
66 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
67 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
62 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
63 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
64 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
65 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
66 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
67 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
6868 }
6969
7070 define void @test2b(i8* noalias %P, i8* noalias %Q) nounwind ssp {
71 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
71 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
7272 %R = getelementptr i8, i8* %P, i64 12
73 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
73 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
7474 ret void
7575
7676 ; CHECK-LABEL: Function: test2b:
7878 ; CHECK: NoAlias: i8* %P, i8* %Q
7979 ; CHECK: NoAlias: i8* %P, i8* %R
8080 ; CHECK: NoAlias: i8* %Q, i8* %R
81 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
82 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
83 ; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
84 ; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
85 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
86 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
87 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
88 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
81 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
82 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
83 ; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
84 ; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
85 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
86 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
87 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
88 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
8989 }
9090
9191 define void @test2c(i8* noalias %P, i8* noalias %Q) nounwind ssp {
92 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
92 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
9393 %R = getelementptr i8, i8* %P, i64 11
94 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
94 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
9595 ret void
9696
9797 ; CHECK-LABEL: Function: test2c:
9999 ; CHECK: NoAlias: i8* %P, i8* %Q
100100 ; CHECK: NoAlias: i8* %P, i8* %R
101101 ; CHECK: NoAlias: i8* %Q, i8* %R
102 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
103 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
104 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
105 ; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
106 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
107 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
108 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
109 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
102 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
103 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
104 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
105 ; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
106 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
107 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
108 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
109 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
110110 }
111111
112112 define void @test2d(i8* noalias %P, i8* noalias %Q) nounwind ssp {
113 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
113 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
114114 %R = getelementptr i8, i8* %P, i64 -12
115 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
115 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
116116 ret void
117117
118118 ; CHECK-LABEL: Function: test2d:
120120 ; CHECK: NoAlias: i8* %P, i8* %Q
121121 ; CHECK: NoAlias: i8* %P, i8* %R
122122 ; CHECK: NoAlias: i8* %Q, i8* %R
123 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
124 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
125 ; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
126 ; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
127 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
128 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
129 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
130 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
123 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
124 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
125 ; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
126 ; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
127 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
128 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
129 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
130 ; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
131131 }
132132
133133 define void @test2e(i8* noalias %P, i8* noalias %Q) nounwind ssp {
134 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
134 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
135135 %R = getelementptr i8, i8* %P, i64 -11
136 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
136 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
137137 ret void
138138
139139 ; CHECK-LABEL: Function: test2e:
141141 ; CHECK: NoAlias: i8* %P, i8* %Q
142142 ; CHECK: NoAlias: i8* %P, i8* %R
143143 ; CHECK: NoAlias: i8* %Q, i8* %R
144 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
145 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
146 ; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
147 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
148 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
149 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
150 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
151 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
144 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
145 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
146 ; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
147 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
148 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
149 ; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
150 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
151 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
152152 }
153153
154154 define void @test3(i8* %P, i8* %Q) nounwind ssp {
155 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
156 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
155 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
156 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
157157 ret void
158158
159159 ; CHECK-LABEL: Function: test3:
160160
161161 ; CHECK: MayAlias: i8* %P, i8* %Q
162 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
163 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
164 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
165 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
166 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
167 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
162 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
163 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
164 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
165 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
166 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
167 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
168168 }
169169
170170 define void @test3a(i8* noalias %P, i8* noalias %Q) nounwind ssp {
171 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
172 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
171 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
172 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
173173 ret void
174174
175175 ; CHECK-LABEL: Function: test3a:
176176
177177 ; CHECK: NoAlias: i8* %P, i8* %Q
178 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
179 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
180 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
181 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
182 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
183 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
178 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
179 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
180 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
181 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
182 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
183 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
184184 }
185185
186186 define void @test4(i8* %P, i8* noalias %Q) nounwind ssp {
187 tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false)
188 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
187 tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
188 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
189189 ret void
190190
191191 ; CHECK-LABEL: Function: test4:
192192
193193 ; CHECK: NoAlias: i8* %P, i8* %Q
194 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false)
195 ; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false)
196 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
197 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
198 ; CHECK: Just Mod: tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
199 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false)
194 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
195 ; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
196 ; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
197 ; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
198 ; CHECK: Just Mod: tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
199 ; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
200200 }
201201
202202 define void @test5(i8* %P, i8* %Q, i8* %R) nounwind ssp {
203 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
204 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
203 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
204 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
205205 ret void
206206
207207 ; CHECK-LABEL: Function: test5:
209209 ; CHECK: MayAlias: i8* %P, i8* %Q
210210 ; CHECK: MayAlias: i8* %P, i8* %R
211211 ; CHECK: MayAlias: i8* %Q, i8* %R
212 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
213 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
214 ; CHECK: Both ModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
215 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
216 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
217 ; CHECK: Both ModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
218 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
219 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
212 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
213 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
214 ; CHECK: Both ModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
215 ; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
216 ; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
217 ; CHECK: Both ModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
218 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
219 ; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
220220 }
221221
222222 define void @test6(i8* %P) nounwind ssp {
223 call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i32 8, i1 false)
223 call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i1 false)
224224 call void @a_readonly_func(i8* %P)
225225 ret void
226226
227227 ; CHECK-LABEL: Function: test6:
228228
229 ; CHECK: Just Mod: Ptr: i8* %P <-> call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i32 8, i1 false)
229 ; CHECK: Just Mod: Ptr: i8* %P <-> call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i1 false)
230230 ; CHECK: Just Ref: Ptr: i8* %P <-> call void @a_readonly_func(i8* %P)
231 ; CHECK: Just Mod: call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i32 8, i1 false) <-> call void @a_readonly_func(i8* %P)
232 ; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i32 8, i1 false)
231 ; CHECK: Just Mod: call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i1 false) <-> call void @a_readonly_func(i8* %P)
232 ; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i1 false)
233233 }
234234
235235 attributes #0 = { nounwind readonly argmemonly }
1111 ret void
1212 }
1313
14 ; CHECK: NoModRef: call void @llvm.memset.p0i8.i64(i8* @A, i8 0, i64 1, i32 1, i1 false) <-> call void @llvm.memset.p0i8.i64(i8* @B, i8 0, i64 1, i32 1, i1 false)
15 ; CHECK: NoModRef: call void @llvm.memset.p0i8.i64(i8* @B, i8 0, i64 1, i32 1, i1 false) <-> call void @llvm.memset.p0i8.i64(i8* @A, i8 0, i64 1, i32 1, i1 false)
14 ; CHECK: NoModRef: call void @llvm.memset.p0i8.i64(i8* @A, i8 0, i64 1, i1 false) <-> call void @llvm.memset.p0i8.i64(i8* @B, i8 0, i64 1, i1 false)
15 ; CHECK: NoModRef: call void @llvm.memset.p0i8.i64(i8* @B, i8 0, i64 1, i1 false) <-> call void @llvm.memset.p0i8.i64(i8* @A, i8 0, i64 1, i1 false)
1616
17 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
17 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
1818
1919 @A = external global i8
2020 @B = external global i8
2121 define void @test1() {
22 call void @llvm.memset.p0i8.i64(i8* @A, i8 0, i64 1, i32 1, i1 false)
23 call void @llvm.memset.p0i8.i64(i8* @B, i8 0, i64 1, i32 1, i1 false)
22 call void @llvm.memset.p0i8.i64(i8* @A, i8 0, i64 1, i1 false)
23 call void @llvm.memset.p0i8.i64(i8* @B, i8 0, i64 1, i1 false)
2424 ret void
2525 }
1010
1111 store i32 0, i32* %A
1212
13 call void @llvm.memset.p0i8.i32(i8* %P, i8 0, i32 42, i32 1, i1 false)
13 call void @llvm.memset.p0i8.i32(i8* %P, i8 0, i32 42, i1 false)
1414
1515 %B = load i32, i32* %A
1616 ret i32 %B
2626
2727 store i8 2, i8* %B ;; Not written to by memcpy
2828
29 call void @llvm.memcpy.p0i8.p0i8.i8(i8* %A, i8* %B, i8 -1, i32 0, i1 false)
29 call void @llvm.memcpy.p0i8.p0i8.i8(i8* %A, i8* %B, i8 -1, i1 false)
3030
3131 %C = load i8, i8* %B
3232 ret i8 %C
3737 ; CHECK-LABEL: @test2
3838 %P2 = getelementptr i8, i8* %P, i32 127
3939 store i8 1, i8* %P2 ;; Not dead across memset
40 call void @llvm.memset.p0i8.i8(i8* %P, i8 2, i8 127, i32 0, i1 false)
40 call void @llvm.memset.p0i8.i8(i8* %P, i8 2, i8 127, i1 false)
4141 %A = load i8, i8* %P2
4242 ret i8 %A
4343 ; CHECK: ret i8 1
5050 ;; FIXME: DSE isn't zapping this dead store.
5151 store i8 1, i8* %P2 ;; Dead, clobbered by memset.
5252
53 call void @llvm.memset.p0i8.i8(i8* %P, i8 2, i8 127, i32 0, i1 false)
53 call void @llvm.memset.p0i8.i8(i8* %P, i8 2, i8 127, i1 false)
5454 %A = load i8, i8* %P2
5555 ret i8 %A
5656 ; CHECK-NOT: load
9090
9191 define i32 @test4(i8* %P) {
9292 %tmp = load i32, i32* @G1
93 call void @llvm.memset.p0i8.i32(i8* bitcast ([4000 x i32]* @G2 to i8*), i8 0, i32 4000, i32 1, i1 false)
93 call void @llvm.memset.p0i8.i32(i8* bitcast ([4000 x i32]* @G2 to i8*), i8 0, i32 4000, i1 false)
9494 %tmp2 = load i32, i32* @G1
9595 %sub = sub i32 %tmp2, %tmp
9696 ret i32 %sub
105105 ; write to G1.
106106 define i32 @test5(i8* %P, i32 %Len) {
107107 %tmp = load i32, i32* @G1
108 call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([4000 x i32]* @G2 to i8*), i8* bitcast (i32* @G1 to i8*), i32 %Len, i32 1, i1 false)
108 call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([4000 x i32]* @G2 to i8*), i8* bitcast (i32* @G1 to i8*), i32 %Len, i1 false)
109109 %tmp2 = load i32, i32* @G1
110110 %sub = sub i32 %tmp2, %tmp
111111 ret i32 %sub
226226 ; CHECK: ret i32 0
227227 }
228228
229 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
230 declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i32, i1) nounwind
231 declare void @llvm.memcpy.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i32, i1) nounwind
232 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
229 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) nounwind
230 declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i1) nounwind
231 declare void @llvm.memcpy.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i1) nounwind
232 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
11
22 ; Check that intrinsics aren't added to the call graph
33
4 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
4 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
55
66 define void @f(i8* %out, i8* %in) {
7 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %out, i8* %in, i32 100, i32 4, i1 false)
7 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %out, i8* %in, i32 100, i1 false)
88 ret void
99 }
1010
695695 ret void
696696 }
697697
698 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
698 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
0 ; RUN: opt < %s -basicaa -globals-aa -gvn -S | FileCheck %s
11
2 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
2 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
33 define void @foo(i8* %x, i8* %y) {
4 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x, i8* %y, i32 1, i32 1, i1 false);
4 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x, i8* %y, i32 1, i1 false);
55 ret void
66 }
77
99 @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
1010
1111 declare i32 @printf(i8* nocapture, ...) nounwind
12 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
12 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
1313
1414
1515 ; Make sure that the initial memcpy call does not go away
2020
2121 define i32 @main() nounwind uwtable ssp {
2222 main_entry:
23 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.anon* @b to i8*), i8* bitcast (%struct.anon* @a to i8*), i64 12, i32 4, i1 false)
23 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.anon* @b to i8*), i8* bitcast (%struct.anon* @a to i8*), i64 12, i1 false)
2424 %0 = load volatile i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @b, i64 0, i32 0), align 4
2525 store i32 %0, i32* @c, align 4
26 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.anon* @b to i8*), i8* bitcast (%struct.anon* @a to i8*), i64 12, i32 4, i1 false) nounwind
26 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.anon* @b to i8*), i8* bitcast (%struct.anon* @a to i8*), i64 12, i1 false) nounwind
2727 %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %0) nounwind
2828 ret i32 0
2929 }
171171 %55 = mul i32 %y.21, %w ; [#uses=1]
172172 %.sum5 = add i32 %55, %.sum3 ; [#uses=1]
173173 %56 = getelementptr i8, i8* %j, i32 %.sum5 ; [#uses=1]
174 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %56, i8* %54, i32 %w, i32 1, i1 false)
174 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %56, i8* %54, i32 %w, i1 false)
175175 %57 = add i32 %y.21, 1 ; [#uses=2]
176176 br label %bb24
177177
188188 %60 = getelementptr i8, i8* %j, i32 %.sum4 ; [#uses=1]
189189 %61 = mul i32 %x, %w ; [#uses=1]
190190 %62 = sdiv i32 %61, 2 ; [#uses=1]
191 tail call void @llvm.memset.p0i8.i32(i8* %60, i8 -128, i32 %62, i32 1, i1 false)
191 tail call void @llvm.memset.p0i8.i32(i8* %60, i8 -128, i32 %62, i1 false)
192192 ret void
193193
194194 bb29: ; preds = %bb20, %entry
206206 %67 = getelementptr i8, i8* %r, i32 %66 ; [#uses=1]
207207 %68 = mul i32 %y.310, %w ; [#uses=1]
208208 %69 = getelementptr i8, i8* %j, i32 %68 ; [#uses=1]
209 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %69, i8* %67, i32 %w, i32 1, i1 false)
209 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %69, i8* %67, i32 %w, i1 false)
210210 %70 = add i32 %y.310, 1 ; [#uses=2]
211211 br label %bb31
212212
222222 %73 = getelementptr i8, i8* %j, i32 %72 ; [#uses=1]
223223 %74 = mul i32 %x, %w ; [#uses=1]
224224 %75 = sdiv i32 %74, 2 ; [#uses=1]
225 tail call void @llvm.memset.p0i8.i32(i8* %73, i8 -128, i32 %75, i32 1, i1 false)
225 tail call void @llvm.memset.p0i8.i32(i8* %73, i8 -128, i32 %75, i1 false)
226226 ret void
227227
228228 return: ; preds = %bb20
229229 ret void
230230 }
231231
232 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
233 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
232 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
233 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) nounwind
4040 entry:
4141 %bins = alloca [16 x i64], align 16
4242 %0 = bitcast [16 x i64]* %bins to i8*
43 call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 128, i32 16, i1 false)
43 call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 128, i1 false)
4444 br label %preheader
4545
4646 preheader: ; preds = %for.inc.1, %entry
8787 }
8888
8989 ; Function Attrs: nounwind
90 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #0
90 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) #0
4949 bb2.i: ; preds = %bb3.i
5050 %1 = getelementptr %struct.SHA_INFO, %struct.SHA_INFO* %sha_info, i64 0, i32 3
5151 %2 = bitcast [16 x i32]* %1 to i8*
52 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %buffer_addr.0.i, i64 64, i32 1, i1 false)
52 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %buffer_addr.0.i, i64 64, i1 false)
5353 %3 = getelementptr %struct.SHA_INFO, %struct.SHA_INFO* %sha_info, i64 0, i32 3, i64 0
5454 %4 = bitcast i32* %3 to i8*
5555 br label %codeRepl
7373
7474 declare void @sha_stream_bb3_2E_i_bb1_2E_i_2E_i(i8*) nounwind
7575
76 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
76 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
7777
78 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
78 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
7979
4444
4545 ; CHECK: define void @test2_yes(i8* nocapture %p, i8* nocapture %q, i64 %n) #0 {
4646 define void @test2_yes(i8* %p, i8* %q, i64 %n) nounwind {
47 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 %n, i32 1, i1 false), !tbaa !1
47 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 %n, i1 false), !tbaa !1
4848 ret void
4949 }
5050
5151 ; CHECK: define void @test2_no(i8* nocapture %p, i8* nocapture readonly %q, i64 %n) #1 {
5252 define void @test2_no(i8* %p, i8* %q, i64 %n) nounwind {
53 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 %n, i32 1, i1 false), !tbaa !2
53 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 %n, i1 false), !tbaa !2
5454 ret void
5555 }
5656
6969 }
7070
7171 declare void @callee(i32* %p) nounwind
72 declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1) nounwind
72 declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1) nounwind
7373
7474 ; CHECK: attributes #0 = { norecurse nounwind readnone }
7575 ; CHECK: attributes #1 = { norecurse nounwind }
55 ; it has a TBAA tag which declares that it is unrelated.
66
77 ; CHECK: @foo
8 ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 16, i32 1, i1 false), !tbaa !0
8 ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %p, i8* align 1 %q, i64 16, i1 false), !tbaa !0
99 ; CHECK-NEXT: store i8 2, i8* %s, align 1, !tbaa [[TAGA:!.*]]
1010 ; CHECK-NEXT: ret void
1111 define void @foo(i8* nocapture %p, i8* nocapture %q, i8* nocapture %s) nounwind {
12 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 16, i32 1, i1 false), !tbaa !2
12 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 16, i1 false), !tbaa !2
1313 store i8 2, i8* %s, align 1, !tbaa !1
14 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %q, i8* %p, i64 16, i32 1, i1 false), !tbaa !2
14 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %q, i8* %p, i64 16, i1 false), !tbaa !2
1515 ret void
1616 }
1717
18 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
18 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
1919
2020 ; CHECK: [[TAGA]] = !{[[TYPEA:!.*]], [[TYPEA]], i64 0}
2121 ; CHECK: [[TYPEA]] = !{!"A", !{{.*}}}
0 ; RUN: llvm-dis < %s.bc| FileCheck %s
1
2 ; memintrinsics.3.7.ll.bc was generated by passing this file to llvm-as-3.7.
3 ; The test checks that LLVM does not misread memcpy/memmove/memset intrinsic functions
4 ; of older bitcode files.
5
6 define void @memcpyintrinsic(i8* %dest, i8* %src, i32 %len) {
7 entry:
8
9 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %dest, i8* align 4 %src, i32 %len, i1 true)
10 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i32 4, i1 true)
11 ret void
12 }
13
14 define void @memmoveintrinsic(i8* %dest, i8* %src, i32 %len) {
15 entry:
16
17 ; CHECK: call void @llvm.memmove.p0i8.p0i8.i32(i8* align 8 %dest, i8* align 8 %src, i32 %len, i1 true)
18 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i32 8, i1 true)
19 ret void
20 }
21
22 define void @memsetintrinsic(i8* %dest, i8* %src, i32 %len) {
23 entry:
24
25 ; CHECK: call void @llvm.memset.p0i8.i32(i8* align 16 %dest, i8 0, i32 %len, i1 true)
26 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 %len, i32 16, i1 true)
27 ret void
28 }
29
30 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i32 %align, i1 %isvolatile)
31 declare void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i32 %align, i1 %isvolatile)
32 declare void @llvm.memset.p0i8.i32(i8* %dest, i8 %src, i32 %len, i32 %align, i1 %isvolatile)
66 define void @memcpyintrinsic(i8* %dest, i8* %src, i32 %len) {
77 entry:
88
9 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i32 1, i1 true)
10 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i32 1, i1 true)
11
9 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %dest, i8* align 1 %src, i32 %len, i1 true)
10 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 true)
1211 ret void
1312 }
1413
15 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i32 %align, i1 %isvolatile)
14 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
2121 %z.i60 = getelementptr inbounds %rs, %rs* %r, i64 0, i32 9, i32 2
2222 %na = getelementptr inbounds %rs, %rs* %r, i64 0, i32 0
2323 %0 = bitcast double* %x.i to i8*
24 call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 72, i32 8, i1 false)
24 call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 72, i1 false)
2525 %1 = load i32, i32* %na, align 4
2626 %cmp70 = icmp sgt i32 %1, 0
2727 br i1 %cmp70, label %for.body.lr.ph, label %for.end
8686 }
8787
8888 ; Function Attrs: nounwind
89 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
89 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1)
9090
4040
4141 declare void @bar(i32)
4242
43 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
43 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1)
4444
4545 define i32 @foo(%struct.DState* %s) {
4646 entry:
7070 %save_zvec = getelementptr inbounds %struct.DState, %struct.DState* %s, i64 0, i32 57
7171 %save_zj = getelementptr inbounds %struct.DState, %struct.DState* %s, i64 0, i32 58
7272 %tmp1 = bitcast i32* %save_i to i8*
73 call void @llvm.memset.p0i8.i64(i8* %tmp1, i8 0, i64 108, i32 4, i1 false)
73 call void @llvm.memset.p0i8.i64(i8* %tmp1, i8 0, i64 108, i1 false)
7474 br label %sw.default
7575
7676 if.end: ; preds = %entry
1313 ; CHECK-NEXT: str [[VAL2]], [x0]
1414
1515 define void @foo(i8* %a) {
16 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* bitcast ([3 x i32]* @b to i8*), i64 12, i32 4, i1 false)
16 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* bitcast ([3 x i32]* @b to i8*), i64 12, i1 false)
1717 ret void
1818 }
1919
20 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
20 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
167167 %4 = bitcast i8* %ap.align to %struct.s41*
168168 %5 = bitcast %struct.s41* %vs to i8*
169169 %6 = bitcast %struct.s41* %4 to i8*
170 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %5, i8* %6, i64 16, i32 16, i1 false)
170 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %5, i8* %6, i64 16, i1 false)
171171 ret void
172172 }
173 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
173 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
174174
175175 define void @bar2(i32 %x, i128 %s41.coerce) nounwind {
176176 entry:
300300 %tmp = alloca %struct.s42, align 4
301301 %tmp1 = alloca %struct.s42, align 4
302302 %0 = bitcast %struct.s42* %tmp to i8*
303 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.s42* @g42 to i8*), i64 24, i32 4, i1 false), !tbaa.struct !4
303 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 bitcast (%struct.s42* @g42 to i8*), i64 24, i1 false), !tbaa.struct !4
304304 %1 = bitcast %struct.s42* %tmp1 to i8*
305 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast (%struct.s42* @g42_2 to i8*), i64 24, i32 4, i1 false), !tbaa.struct !4
305 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 bitcast (%struct.s42* @g42_2 to i8*), i64 24, i1 false), !tbaa.struct !4
306306 %call = call i32 @f42(i32 3, %struct.s42* %tmp, %struct.s42* %tmp1) #5
307307 ret i32 %call
308308 }
309309
310 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) #4
310 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) #4
311311
312312 declare i32 @f42_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
313313 i32 %i7, i32 %i8, i32 %i9, %struct.s42* nocapture %s1,
346346 %tmp = alloca %struct.s42, align 4
347347 %tmp1 = alloca %struct.s42, align 4
348348 %0 = bitcast %struct.s42* %tmp to i8*
349 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.s42* @g42 to i8*), i64 24, i32 4, i1 false), !tbaa.struct !4
349 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 bitcast (%struct.s42* @g42 to i8*), i64 24, i1 false), !tbaa.struct !4
350350 %1 = bitcast %struct.s42* %tmp1 to i8*
351 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast (%struct.s42* @g42_2 to i8*), i64 24, i32 4, i1 false), !tbaa.struct !4
351 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 bitcast (%struct.s42* @g42_2 to i8*), i64 24, i1 false), !tbaa.struct !4
352352 %call = call i32 @f42_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
353353 i32 8, i32 9, %struct.s42* %tmp, %struct.s42* %tmp1) #5
354354 ret i32 %call
414414 %tmp = alloca %struct.s43, align 16
415415 %tmp1 = alloca %struct.s43, align 16
416416 %0 = bitcast %struct.s43* %tmp to i8*
417 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.s43* @g43 to i8*), i64 32, i32 16, i1 false), !tbaa.struct !4
417 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.s43* @g43 to i8*), i64 32, i1 false), !tbaa.struct !4
418418 %1 = bitcast %struct.s43* %tmp1 to i8*
419 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast (%struct.s43* @g43_2 to i8*), i64 32, i32 16, i1 false), !tbaa.struct !4
419 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %1, i8* align 16 bitcast (%struct.s43* @g43_2 to i8*), i64 32, i1 false), !tbaa.struct !4
420420 %call = call i32 @f43(i32 3, %struct.s43* %tmp, %struct.s43* %tmp1) #5
421421 ret i32 %call
422422 }
465465 %tmp = alloca %struct.s43, align 16
466466 %tmp1 = alloca %struct.s43, align 16
467467 %0 = bitcast %struct.s43* %tmp to i8*
468 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.s43* @g43 to i8*), i64 32, i32 16, i1 false), !tbaa.struct !4
468 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.s43* @g43 to i8*), i64 32, i1 false), !tbaa.struct !4
469469 %1 = bitcast %struct.s43* %tmp1 to i8*
470 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast (%struct.s43* @g43_2 to i8*), i64 32, i32 16, i1 false), !tbaa.struct !4
470 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %1, i8* align 16 bitcast (%struct.s43* @g43_2 to i8*), i64 32, i1 false), !tbaa.struct !4
471471 %call = call i32 @f43_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
472472 i32 8, i32 9, %struct.s43* %tmp, %struct.s43* %tmp1) #5
473473 ret i32 %call
1010 ; ARM64: movz x2, #0x50
1111 ; ARM64: uxtb w1, w9
1212 ; ARM64: bl _memset
13 call void @llvm.memset.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i8 0, i64 80, i32 16, i1 false)
13 call void @llvm.memset.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i8 0, i64 80, i1 false)
1414 ret void
1515 }
1616
17 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
17 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1)
1818
1919 define void @t2() {
2020 ; ARM64-LABEL: t2
2424 ; ARM64: add x1, x8, _message@PAGEOFF
2525 ; ARM64: movz x2, #0x50
2626 ; ARM64: bl _memcpy
27 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 80, i32 16, i1 false)
27 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 80, i1 false)
2828 ret void
2929 }
3030
31 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1)
31 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
3232
3333 define void @t3() {
3434 ; ARM64-LABEL: t3
3838 ; ARM64: add x1, x8, _message@PAGEOFF
3939 ; ARM64: movz x2, #0x14
4040 ; ARM64: bl _memmove
41 call void @llvm.memmove.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 20, i32 16, i1 false)
41 call void @llvm.memmove.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 20, i1 false)
4242 ret void
4343 }
4444
45 declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1)
45 declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
4646
4747 define void @t4() {
4848 ; ARM64-LABEL: t4
5757 ; ARM64: ldrb w11, [x9, #16]
5858 ; ARM64: strb w11, [x8, #16]
5959 ; ARM64: ret
60 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 17, i32 16, i1 false)
60 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 17, i1 false)
6161 ret void
6262 }
6363
7474 ; ARM64: ldrb w11, [x9, #16]
7575 ; ARM64: strb w11, [x8, #16]
7676 ; ARM64: ret
77 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 17, i32 8, i1 false)
77 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 17, i1 false)
7878 ret void
7979 }
8080
9191 ; ARM64: ldrb w10, [x9, #8]
9292 ; ARM64: strb w10, [x8, #8]
9393 ; ARM64: ret
94 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 9, i32 4, i1 false)
94 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* align 4 getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 9, i1 false)
9595 ret void
9696 }
9797
110110 ; ARM64: ldrb w10, [x9, #6]
111111 ; ARM64: strb w10, [x8, #6]
112112 ; ARM64: ret
113 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 7, i32 2, i1 false)
113 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 2 getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* align 2 getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 7, i1 false)
114114 ret void
115115 }
116116
129129 ; ARM64: ldrb w10, [x9, #3]
130130 ; ARM64: strb w10, [x8, #3]
131131 ; ARM64: ret
132 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 4, i32 1, i1 false)
132 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([80 x i8], [80 x i8]* @temp, i32 0, i32 0), i8* align 1 getelementptr inbounds ([80 x i8], [80 x i8]* @message, i32 0, i32 0), i64 4, i1 false)
133133 ret void
134134 }
135135
142142 ; ARM64: strb [[BYTE]], [x0]
143143 %array = alloca i8, i32 8192
144144 %elem = getelementptr i8, i8* %array, i32 8000
145 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %elem, i64 1, i32 1, i1 false)
145 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %elem, i64 1, i1 false)
146146 ret void
147147 }
2121 ; CHECK: strh [[REG1]], [x[[BASEREG2]], #8]
2222 ; CHECK: ldr [[REG2:x[0-9]+]],
2323 ; CHECK: str [[REG2]],
24 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds (%struct.x, %struct.x* @dst, i32 0, i32 0), i8* getelementptr inbounds (%struct.x, %struct.x* @src, i32 0, i32 0), i32 11, i32 8, i1 false)
24 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds (%struct.x, %struct.x* @dst, i32 0, i32 0), i8* getelementptr inbounds (%struct.x, %struct.x* @src, i32 0, i32 0), i32 11, i1 false)
2525 ret i32 0
2626 }
2727
3232 ; CHECK: stur [[DEST]], [x0, #15]
3333 ; CHECK: ldr [[DEST:q[0-9]+]], [x[[BASEREG]]]
3434 ; CHECK: str [[DEST]], [x0]
35 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str1, i64 0, i64 0), i64 31, i32 1, i1 false)
35 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str1, i64 0, i64 0), i64 31, i1 false)
3636 ret void
3737 }
3838
4444 ; CHECK: str [[REG3]], [x0, #32]
4545 ; CHECK: ldp [[DEST1:q[0-9]+]], [[DEST2:q[0-9]+]], [x{{[0-9]+}}]
4646 ; CHECK: stp [[DEST1]], [[DEST2]], [x0]
47 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str2, i64 0, i64 0), i64 36, i32 1, i1 false)
47 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str2, i64 0, i64 0), i64 36, i1 false)
4848 ret void
4949 }
5050
5555 ; CHECK: str [[REG4]], [x0, #16]
5656 ; CHECK: ldr [[DEST:q[0-9]+]], [x[[BASEREG]]]
5757 ; CHECK: str [[DEST]], [x0]
58 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str3, i64 0, i64 0), i64 24, i32 1, i1 false)
58 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str3, i64 0, i64 0), i64 24, i1 false)
5959 ret void
6060 }
6161
6666 ; CHECK: strh [[REG5]], [x0, #16]
6767 ; CHECK: ldr [[REG6:q[0-9]+]], [x{{[0-9]+}}]
6868 ; CHECK: str [[REG6]], [x0]
69 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str4, i64 0, i64 0), i64 18, i32 1, i1 false)
69 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str4, i64 0, i64 0), i64 18, i1 false)
7070 ret void
7171 }
7272
7979 ; CHECK: movz [[REG8:w[0-9]+]],
8080 ; CHECK: movk [[REG8]],
8181 ; CHECK: str [[REG8]], [x0]
82 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str5, i64 0, i64 0), i64 7, i32 1, i1 false)
82 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str5, i64 0, i64 0), i64 7, i1 false)
8383 ret void
8484 }
8585
9090 ; CHECK: stur [[REG9]], [x{{[0-9]+}}, #6]
9191 ; CHECK: ldr
9292 ; CHECK: str
93 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([512 x i8], [512 x i8]* @spool.splbuf, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str6, i64 0, i64 0), i64 14, i32 1, i1 false)
93 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([512 x i8], [512 x i8]* @spool.splbuf, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str6, i64 0, i64 0), i64 14, i1 false)
9494 ret void
9595 }
9696
103103 ; CHECK: str [[REG10]], [x0]
104104 %0 = bitcast %struct.Foo* %a to i8*
105105 %1 = bitcast %struct.Foo* %b to i8*
106 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 16, i32 4, i1 false)
106 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 16, i1 false)
107107 ret void
108108 }
109109
110 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
111 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
110 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
111 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
44 ; CHECK-LABEL: t1:
55 ; CHECK: str wzr, [x0, #8]
66 ; CHECK: str xzr, [x0]
7 call void @llvm.memset.p0i8.i64(i8* %c, i8 0, i64 12, i32 8, i1 false)
7 call void @llvm.memset.p0i8.i64(i8* %c, i8 0, i64 12, i1 false)
88 ret void
99 }
1010
1616 ; CHECK: str xzr, [sp, #8]
1717 %buf = alloca [26 x i8], align 1
1818 %0 = getelementptr inbounds [26 x i8], [26 x i8]* %buf, i32 0, i32 0
19 call void @llvm.memset.p0i8.i32(i8* %0, i8 0, i32 26, i32 1, i1 false)
19 call void @llvm.memset.p0i8.i32(i8* %0, i8 0, i32 26, i1 false)
2020 call void @something(i8* %0) nounwind
2121 ret void
2222 }
2323
2424 declare void @something(i8*) nounwind
25 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
26 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
25 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) nounwind
26 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
88 ; CHECK: memset
99 define void @fct1(i8* nocapture %ptr) {
1010 entry:
11 tail call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 256, i32 1, i1 false)
11 tail call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 256, i1 false)
1212 ret void
1313 }
1414
15 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
15 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1)
1616
1717 ; CHECK: @fct2
1818 ; When the size is bigger than 256, change into bzero.
2020 ; CHECK-LINUX: memset
2121 define void @fct2(i8* nocapture %ptr) {
2222 entry:
23 tail call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 257, i32 1, i1 false)
23 tail call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 257, i1 false)
2424 ret void
2525 }
2626
3131 define void @fct3(i8* nocapture %ptr, i32 %unknown) {
3232 entry:
3333 %conv = sext i32 %unknown to i64
34 tail call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 %conv, i32 1, i1 false)
34 tail call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 %conv, i1 false)
3535 ret void
3636 }
3737
66 ; CHECK: orr w2, wzr, #0x10
77 ; CHECK-NEXT: bl _memcpy
88 entry:
9 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %out, i8* %in, i64 16, i32 1, i1 false)
9 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %out, i8* %in, i64 16, i1 false)
1010 ret void
1111 }
1212
13 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
13 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1)
2424 %yy = alloca i32, align 4
2525 store i32 0, i32* %retval
2626 %0 = bitcast [8 x i32]* %x to i8*
27 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast ([8 x i32]* @main.x to i8*), i64 32, i32 4, i1 false)
27 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast ([8 x i32]* @main.x to i8*), i64 32, i1 false)
2828 %1 = bitcast [8 x i32]* %y to i8*
29 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast ([8 x i32]* @main.y to i8*), i64 32, i32 4, i1 false)
29 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast ([8 x i32]* @main.y to i8*), i64 32, i1 false)
3030 store i32 0, i32* %xx, align 4
3131 store i32 0, i32* %yy, align 4
3232 store i32 0, i32* %i, align 4
103103 }
104104
105105 ; Function Attrs: nounwind
106 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #1
106 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1) #1
107107
108108 attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
109109 attributes #1 = { nounwind }
3131 %yy = alloca i32, align 4
3232 store i32 0, i32* %retval
3333 %0 = bitcast [8 x i32]* %x to i8*
34 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast ([8 x i32]* @main.x to i8*), i64 32, i32 4, i1 false)
34 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast ([8 x i32]* @main.x to i8*), i64 32, i1 false)
3535 %1 = bitcast [8 x i32]* %y to i8*
36 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast ([8 x i32]* @main.y to i8*), i64 32, i32 4, i1 false)
36 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast ([8 x i32]* @main.y to i8*), i64 32, i1 false)
3737 store i32 0, i32* %xx, align 4
3838 store i32 0, i32* %yy, align 4
3939 store i32 0, i32* %i, align 4
105105
106106
107107 ; Function Attrs: nounwind
108 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #1
108 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1) #1
109109
110110 attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
111111 attributes #1 = { nounwind }
5454 ; CHECK-NEXT: ret
5555 %B = getelementptr inbounds %struct.X, %struct.X* %p, i64 0, i32 1
5656 %val = bitcast i64* %B to i8*
57 call void @llvm.memset.p0i8.i64(i8* %val, i8 0, i64 16, i32 1, i1 false)
57 call void @llvm.memset.p0i8.i64(i8* %val, i8 0, i64 16, i1 false)
5858 ret void
5959 }
6060
61 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
61 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
6262
6363 ; Unaligned 16b stores are split into 8b stores for performance.
6464 ; radar://15424193
4242 %tmp14 = bitcast double* %arraydecay5.3.1 to i8*
4343 %arraydecay11.3.1 = getelementptr inbounds %struct.Bicubic_Patch_Struct, %struct.Bicubic_Patch_Struct* %Shape, i64 0, i32 12, i64 1, i64 3, i64 0
4444 %tmp15 = bitcast double* %arraydecay11.3.1 to i8*
45 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp14, i8* %tmp15, i64 24, i32 1, i1 false)
45 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp14, i8* %tmp15, i64 24, i1 false)
4646 ret void
4747 }
4848
4949 ; Function Attrs: nounwind
50 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1)
50 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
77 define void @test(i64 %a, i8* %b) {
88 %1 = and i64 %a, 9223372036854775807
99 %2 = inttoptr i64 %1 to i8*
10 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %b, i64 8, i32 8, i1 false)
10 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %b, i64 8, i1 false)
1111 ret void
1212 }
1313
14 declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1)
14 declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
185185 ret void
186186 }
187187
188 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
188 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
189189
190190 define i32 @test_extern() {
191191 ; CHECK-LABEL: test_extern:
192 call void @llvm.memcpy.p0i8.p0i8.i32(i8* undef, i8* undef, i32 undef, i32 4, i1 0)
192 call void @llvm.memcpy.p0i8.p0i8.i32(i8* undef, i8* undef, i32 undef, i1 0)
193193 ; CHECK: bl memcpy
194194 ret i32 0
195195 }
1111 ; CHECK: str q0
1212 ; CHECK: ret
1313 entry:
14 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* undef, i8* bitcast (%structA* @stubA to i8*), i64 48, i32 8, i1 false)
14 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* undef, i8* bitcast (%structA* @stubA to i8*), i64 48, i1 false)
1515 ret void
1616 }
1717
18 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
18 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1)
33 ; CHECK: b memcpy
44 define void @tail_memcpy(i8* nocapture %p, i8* nocapture readonly %q, i32 %n) #0 {
55 entry:
6 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i32 1, i1 false)
6 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i1 false)
77 ret void
88 }
99
1111 ; CHECK: b memmove
1212 define void @tail_memmove(i8* nocapture %p, i8* nocapture readonly %q, i32 %n) #0 {
1313 entry:
14 tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i32 1, i1 false)
14 tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i1 false)
1515 ret void
1616 }
1717
1919 ; CHECK: b memset
2020 define void @tail_memset(i8* nocapture %p, i8 %c, i32 %n) #0 {
2121 entry:
22 tail call void @llvm.memset.p0i8.i32(i8* %p, i8 %c, i32 %n, i32 1, i1 false)
22 tail call void @llvm.memset.p0i8.i32(i8* %p, i8 %c, i32 %n, i1 false)
2323 ret void
2424 }
2525
26 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #0
27 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #0
28 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0
26 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i1) #0
27 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i1) #0
28 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) #0
2929
3030 attributes #0 = { nounwind }
0 ; RUN: llc -march=amdgcn -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
11 ; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
22
3 declare void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* nocapture, i8 addrspace(3)* nocapture, i32, i32, i1) nounwind
4 declare void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* nocapture, i8 addrspace(1)* nocapture, i64, i32, i1) nounwind
3 declare void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* nocapture, i8 addrspace(3)* nocapture, i32, i1) nounwind
4 declare void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* nocapture, i8 addrspace(1)* nocapture, i64, i1) nounwind
55
66
77 ; FUNC-LABEL: {{^}}test_small_memcpy_i64_lds_to_lds_align1:
8181 define void @test_small_memcpy_i64_lds_to_lds_align1(i64 addrspace(3)* noalias %out, i64 addrspace(3)* noalias %in) nounwind {
8282 %bcin = bitcast i64 addrspace(3)* %in to i8 addrspace(3)*
8383 %bcout = bitcast i64 addrspace(3)* %out to i8 addrspace(3)*
84 call void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* %bcout, i8 addrspace(3)* %bcin, i32 32, i32 1, i1 false) nounwind
84 call void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* align 1 %bcout, i8 addrspace(3)* align 1 %bcin, i32 32, i1 false) nounwind
8585 ret void
8686 }
8787
126126 define void @test_small_memcpy_i64_lds_to_lds_align2(i64 addrspace(3)* noalias %out, i64 addrspace(3)* noalias %in) nounwind {
127127 %bcin = bitcast i64 addrspace(3)* %in to i8 addrspace(3)*
128128 %bcout = bitcast i64 addrspace(3)* %out to i8 addrspace(3)*
129 call void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* %bcout, i8 addrspace(3)* %bcin, i32 32, i32 2, i1 false) nounwind
129 call void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* align 2 %bcout, i8 addrspace(3)* align 2 %bcin, i32 32, i1 false) nounwind
130130 ret void
131131 }
132132
162162 define void @test_small_memcpy_i64_lds_to_lds_align4(i64 addrspace(3)* noalias %out, i64 addrspace(3)* noalias %in) nounwind {
163163 %bcin = bitcast i64 addrspace(3)* %in to i8 addrspace(3)*
164164 %bcout = bitcast i64 addrspace(3)* %out to i8 addrspace(3)*
165 call void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* %bcout, i8 addrspace(3)* %bcin, i32 32, i32 4, i1 false) nounwind
165 call void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* align 4 %bcout, i8 addrspace(3)* align 4 %bcin, i32 32, i1 false) nounwind
166166 ret void
167167 }
168168
200200 define void @test_small_memcpy_i64_lds_to_lds_align8(i64 addrspace(3)* noalias %out, i64 addrspace(3)* noalias %in) nounwind {
201201 %bcin = bitcast i64 addrspace(3)* %in to i8 addrspace(3)*
202202 %bcout = bitcast i64 addrspace(3)* %out to i8 addrspace(3)*
203 call void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* %bcout, i8 addrspace(3)* %bcin, i32 32, i32 8, i1 false) nounwind
203 call void @llvm.memcpy.p3i8.p3i8.i32(i8 addrspace(3)* align 8 %bcout, i8 addrspace(3)* align 8 %bcin, i32 32, i1 false) nounwind
204204 ret void
205205 }
206206
277277 define void @test_small_memcpy_i64_global_to_global_align1(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in) nounwind {
278278 %bcin = bitcast i64 addrspace(1)* %in to i8 addrspace(1)*
279279 %bcout = bitcast i64 addrspace(1)* %out to i8 addrspace(1)*
280 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %bcout, i8 addrspace(1)* %bcin, i64 32, i32 1, i1 false) nounwind
280 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* align 1 %bcout, i8 addrspace(1)* align 1 %bcin, i64 32, i1 false) nounwind
281281 ret void
282282 }
283283
320320 define void @test_small_memcpy_i64_global_to_global_align2(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in) nounwind {
321321 %bcin = bitcast i64 addrspace(1)* %in to i8 addrspace(1)*
322322 %bcout = bitcast i64 addrspace(1)* %out to i8 addrspace(1)*
323 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %bcout, i8 addrspace(1)* %bcin, i64 32, i32 2, i1 false) nounwind
323 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* align 2 %bcout, i8 addrspace(1)* align 2 %bcin, i64 32, i1 false) nounwind
324324 ret void
325325 }
326326
333333 define void @test_small_memcpy_i64_global_to_global_align4(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in) nounwind {
334334 %bcin = bitcast i64 addrspace(1)* %in to i8 addrspace(1)*
335335 %bcout = bitcast i64 addrspace(1)* %out to i8 addrspace(1)*
336 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %bcout, i8 addrspace(1)* %bcin, i64 32, i32 4, i1 false) nounwind
336 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* align 4 %bcout, i8 addrspace(1)* align 4 %bcin, i64 32, i1 false) nounwind
337337 ret void
338338 }
339339
346346 define void @test_small_memcpy_i64_global_to_global_align8(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in) nounwind {
347347 %bcin = bitcast i64 addrspace(1)* %in to i8 addrspace(1)*
348348 %bcout = bitcast i64 addrspace(1)* %out to i8 addrspace(1)*
349 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %bcout, i8 addrspace(1)* %bcin, i64 32, i32 8, i1 false) nounwind
349 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* align 8 %bcout, i8 addrspace(1)* align 8 %bcin, i64 32, i1 false) nounwind
350350 ret void
351351 }
352352
359359 define void @test_small_memcpy_i64_global_to_global_align16(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in) nounwind {
360360 %bcin = bitcast i64 addrspace(1)* %in to i8 addrspace(1)*
361361 %bcout = bitcast i64 addrspace(1)* %out to i8 addrspace(1)*
362 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %bcout, i8 addrspace(1)* %bcin, i64 32, i32 16, i1 false) nounwind
363 ret void
364 }
362 call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* align 16 %bcout, i8 addrspace(1)* align 16 %bcin, i64 32, i1 false) nounwind
363 ret void
364 }
5858 %34 = fadd double %31, 0.000000e+00
5959 %35 = fadd double %32, 0.000000e+00
6060 %36 = bitcast %struct.ggPoint3* %x to i8*
61 call void @llvm.memcpy.p0i8.p0i8.i32(i8* null, i8* %36, i32 24, i32 4, i1 false)
61 call void @llvm.memcpy.p0i8.p0i8.i32(i8* null, i8* %36, i32 24, i1 false)
6262 store double %33, double* null, align 8
6363 br i1 false, label %_Z20ggRaySphereIntersectRK6ggRay3RK8ggSphereddRd.exit, label %bb5.i.i.i
6464
7575 ret i32 0
7676 }
7777
78 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
78 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
1515
1616 bb1: ; preds = %entry
1717 %0 = call %struct.ui* @vn_pp_to_ui(i32* undef) nounwind
18 call void @llvm.memset.p0i8.i32(i8* undef, i8 0, i32 40, i32 4, i1 false)
18 call void @llvm.memset.p0i8.i32(i8* undef, i8 0, i32 40, i1 false)
1919 %1 = getelementptr inbounds %struct.ui, %struct.ui* %0, i32 0, i32 0
2020 store %struct.mo* undef, %struct.mo** %1, align 4
2121 %2 = getelementptr inbounds %struct.ui, %struct.ui* %0, i32 0, i32 5
3939
4040 declare %struct.ui* @vn_pp_to_ui(i32*)
4141
42 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
42 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) nounwind
4343
4444 declare i32 @mo_create_nnm(%struct.mo*, i64, i32**)
4545
1313 ; CHECK-UNALIGNED: str
1414 define void @foo(i8* nocapture %c) nounwind optsize {
1515 entry:
16 call void @llvm.memset.p0i8.i64(i8* %c, i8 -1, i64 5, i32 1, i1 false)
16 call void @llvm.memset.p0i8.i64(i8* %c, i8 -1, i64 5, i1 false)
1717 ret void
1818 }
1919
20 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
20 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
44 ; CHECK: vst1.64
55 define void @f_0_40(i8* nocapture %c) nounwind optsize {
66 entry:
7 call void @llvm.memset.p0i8.i64(i8* %c, i8 0, i64 40, i32 16, i1 false)
7 call void @llvm.memset.p0i8.i64(i8* align 16 %c, i8 0, i64 40, i1 false)
88 ret void
99 }
1010
11 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
11 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
1818
1919 declare i8* @__cxa_begin_catch(i8*)
2020
21 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
21 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
2222
2323 declare void @__cxa_end_catch()
2424
11
22 @source = common global [512 x i8] zeroinitializer, align 4
33
4 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
4 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) nounwind
55
66 define void @function() {
77 entry:
8 call void @llvm.memset.p0i8.i32(i8* bitcast ([512 x i8]* @source to i8*), i8 0, i32 512, i32 0, i1 false)
8 call void @llvm.memset.p0i8.i32(i8* bitcast ([512 x i8]* @source to i8*), i8 0, i32 512, i1 false)
99 unreachable
1010 }
1111
0 ; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s
11
2 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
3 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
2 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
3 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
44
55 @source = common global [512 x i8] zeroinitializer, align 4
66 @target = common global [512 x i8] zeroinitializer, align 4
77
88 define void @move() nounwind {
99 entry:
10 call void @llvm.memmove.p0i8.p0i8.i32(i8* bitcast ([512 x i8]* @target to i8*), i8* bitcast ([512 x i8]* @source to i8*), i32 512, i32 0, i1 false)
10 call void @llvm.memmove.p0i8.p0i8.i32(i8* bitcast ([512 x i8]* @target to i8*), i8* bitcast ([512 x i8]* @source to i8*), i32 512, i1 false)
1111 unreachable
1212 }
1313
1515
1616 define void @copy() nounwind {
1717 entry:
18 call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([512 x i8]* @target to i8*), i8* bitcast ([512 x i8]* @source to i8*), i32 512, i32 0, i1 false)
18 call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([512 x i8]* @target to i8*), i8* bitcast ([512 x i8]* @source to i8*), i32 512, i1 false)
1919 unreachable
2020 }
2121
1111 }
1212
1313 @.str523 = private constant [256 x i8] c"\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4 ; <[256 x i8]*> [#uses=1]
14 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
14 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
1515
1616 ; This function uses the scavenger for an ADDri instruction.
1717 ; ARMBaseRegisterInfo::estimateRSStackSizeLimit must return a 255 limit.
2020 %letter = alloca i8 ; [#uses=0]
2121 %prodvers = alloca [256 x i8] ; <[256 x i8]*> [#uses=1]
2222 %buildver = alloca [256 x i8] ; <[256 x i8]*> [#uses=0]
23 call void @llvm.memcpy.p0i8.p0i8.i32(i8* undef, i8* getelementptr inbounds ([256 x i8], [256 x i8]* @.str523, i32 0, i32 0), i32 256, i32 1, i1 false)
23 call void @llvm.memcpy.p0i8.p0i8.i32(i8* undef, i8* getelementptr inbounds ([256 x i8], [256 x i8]* @.str523, i32 0, i32 0), i32 256, i1 false)
2424 %prodvers2 = bitcast [256 x i8]* %prodvers to i8* ; [#uses=1]
25 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %prodvers2, i8* getelementptr inbounds ([256 x i8], [256 x i8]* @.str523, i32 0, i32 0), i32 256, i32 1, i1 false)
25 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %prodvers2, i8* getelementptr inbounds ([256 x i8], [256 x i8]* @.str523, i32 0, i32 0), i32 256, i1 false)
2626 unreachable
2727 }
2424
2525 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone
2626
27 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
27 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
2828
2929 define hidden void @foobar_func_block_invoke_0(i8* %.block_descriptor, %0* %loadedMydata, [4 x i32] %bounds.coerce0, [4 x i32] %data.coerce0) ssp !dbg !23 {
3030 %1 = alloca %0*, align 4
6666 %24 = bitcast i8* %23 to %struct.CR*, !dbg !143
6767 %25 = bitcast %struct.CR* %24 to i8*, !dbg !143
6868 %26 = bitcast %struct.CR* %data to i8*, !dbg !143
69 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %25, i8* %26, i32 16, i32 4, i1 false), !dbg !143
69 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %25, i8* %26, i32 16, i1 false), !dbg !143
7070 %27 = getelementptr inbounds %2, %2* %6, i32 0, i32 6, !dbg !144
7171 %28 = load %3*, %3** %27, align 4, !dbg !144
7272 %29 = load i32, i32* @"OBJC_IVAR_$_MyWork._bounds", !dbg !144
7575 %32 = bitcast i8* %31 to %struct.CR*, !dbg !144
7676 %33 = bitcast %struct.CR* %32 to i8*, !dbg !144
7777 %34 = bitcast %struct.CR* %bounds to i8*, !dbg !144
78 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %33, i8* %34, i32 16, i32 4, i1 false), !dbg !144
78 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %33, i8* %34, i32 16, i1 false), !dbg !144
7979 %35 = getelementptr inbounds %2, %2* %6, i32 0, i32 6, !dbg !145
8080 %36 = load %3*, %3** %35, align 4, !dbg !145
8181 %37 = getelementptr inbounds %2, %2* %6, i32 0, i32 5, !dbg !145
5050 %tmp9 = call i8* @strcpy(i8* %tmp6, i8* %tag)
5151 %tmp6.len = call i32 @strlen(i8* %tmp6)
5252 %tmp6.indexed = getelementptr i8, i8* %tmp6, i32 %tmp6.len
53 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %tmp6.indexed, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @str215, i32 0, i32 0), i32 2, i32 1, i1 false)
53 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %tmp6.indexed, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @str215, i32 0, i32 0), i32 2, i1 false)
5454 %tmp15 = call i8* @strcat(i8* %tmp6, i8* %contents)
5555 call fastcc void @comment_add(%struct.comment* %vc, i8* %tmp6)
5656 ret void
6464
6565 declare i8* @strcpy(i8*, i8*)
6666
67 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
67 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
3838 ; THUMB-LONG: movt r3, :upper16:L_memset$non_lazy_ptr
3939 ; THUMB-LONG: ldr r3, [r3]
4040 ; THUMB-LONG: blx r3
41 call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @message1, i32 0, i32 5), i8 64, i32 10, i32 4, i1 false)
42 ret void
43 }
44
45 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
41 call void @llvm.memset.p0i8.i32(i8* align 4 getelementptr inbounds ([60 x i8], [60 x i8]* @message1, i32 0, i32 5), i8 64, i32 10, i1 false)
42 ret void
43 }
44
45 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) nounwind
4646
4747 define void @t2() nounwind ssp {
4848 ; ARM-LABEL: t2:
7777 ; THUMB-LONG: movt r3, :upper16:L_memcpy$non_lazy_ptr
7878 ; THUMB-LONG: ldr r3, [r3]
7979 ; THUMB-LONG: blx r3
80 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 17, i32 4, i1 false)
81 ret void
82 }
83
84 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
80 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* align 4 getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 17, i1 false)
81 ret void
82 }
83
84 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
8585
8686 define void @t3() nounwind ssp {
8787 ; ARM-LABEL: t3:
114114 ; THUMB-LONG: movt r3, :upper16:L_memmove$non_lazy_ptr
115115 ; THUMB-LONG: ldr r3, [r3]
116116 ; THUMB-LONG: blx r3
117 call void @llvm.memmove.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 1, i1 false)
117 call void @llvm.memmove.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i1 false)
118118 ret void
119119 }
120120
141141 ; THUMB: ldrh r1, [r0, #24]
142142 ; THUMB: strh r1, [r0, #12]
143143 ; THUMB: bx lr
144 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 4, i1 false)
145 ret void
146 }
147
148 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
144 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i1 false)
145 ret void
146 }
147
148 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
149149
150150 define void @t5() nounwind ssp {
151151 ; ARM-LABEL: t5:
178178 ; THUMB: ldrh r1, [r0, #24]
179179 ; THUMB: strh r1, [r0, #12]
180180 ; THUMB: bx lr
181 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 2, i1 false)
181 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* align 2 getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i1 false)
182182 ret void
183183 }
184184
233233 ; THUMB: ldrb r1, [r0, #25]
234234 ; THUMB: strb r1, [r0, #13]
235235 ; THUMB: bx lr
236 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 1, i1 false)
236 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* align 1 getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i1 false)
237237 ret void
238238 }
239239
240240 ; rdar://13202135
241241 define void @t7() nounwind ssp {
242242 ; Just make sure this doesn't assert when we have an odd length and an alignment of 2.
243 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 3, i32 2, i1 false)
243 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 3, i1 false)
244244 ret void
245245 }
246246
3636 for.body.lr.ph: ; preds = %entry
3737 %1 = icmp sgt i32 %0, 1
3838 %smax = select i1 %1, i32 %0, i32 1
39 call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([250 x i8], [250 x i8]* @bar, i32 0, i32 0), i8 0, i32 %smax, i32 1, i1 false)
39 call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([250 x i8], [250 x i8]* @bar, i32 0, i32 0), i8 0, i32 %smax, i1 false)
4040 unreachable
4141
4242 for.cond1.preheader: ; preds = %entry
4343 ret void
4444 }
4545
46 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
46 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) nounwind
4747
4848 ; rdar://12462006
4949 define i8* @f3(i8* %base, i32* nocapture %offset, i32 %size) nounwind {
2222 ; CHECK-T1: strb [[TREG1]],
2323 ; CHECK-T1: ldrh [[TREG2:r[0-9]]],
2424 ; CHECK-T1: strh [[TREG2]]
25 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds (%struct.x, %struct.x* @dst, i32 0, i32 0), i8* getelementptr inbounds (%struct.x, %struct.x* @src, i32 0, i32 0), i32 11, i32 8, i1 false)
25 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 getelementptr inbounds (%struct.x, %struct.x* @dst, i32 0, i32 0), i8* align 8 getelementptr inbounds (%struct.x, %struct.x* @src, i32 0, i32 0), i32 11, i1 false)
2626 ret i32 0
2727 }
2828
3535 ; CHECK: adds r1, #15
3636 ; CHECK: vld1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r1]
3737 ; CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0]
38 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str1, i64 0, i64 0), i64 31, i32 1, i1 false)
38 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str1, i64 0, i64 0), i64 31, i1 false)
3939 ret void
4040 }
4141
4949 ; CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0]!
5050 ; CHECK: vld1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r1]
5151 ; CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0]
52 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str2, i64 0, i64 0), i64 36, i32 1, i1 false)
52 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str2, i64 0, i64 0), i64 36, i1 false)
5353 ret void
5454 }
5555
6060 ; CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r0]!
6161 ; CHECK: vldr d{{[0-9]+}}, [r1]
6262 ; CHECK: vst1.8 {d{{[0-9]+}}}, [r0]
63 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str3, i64 0, i64 0), i64 24, i32 1, i1 false)
63 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str3, i64 0, i64 0), i64 24, i1 false)
6464 ret void
6565 }
6666
7070 ; CHECK: vld1.64 {[[REG3:d[0-9]+]], [[REG4:d[0-9]+]]}, [r1]
7171 ; CHECK: vst1.8 {[[REG3]], [[REG4]]}, [r0]!
7272 ; CHECK: strh [[REG5:r[0-9]+]], [r0]
73 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str4, i64 0, i64 0), i64 18, i32 1, i1 false)
73 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str4, i64 0, i64 0), i64 18, i1 false)
7474 ret void
7575 }
7676
8989 ; CHECK-T1: strb [[TREG3]],
9090 ; CHECK-T1: movs [[TREG4:r[0-9]]],
9191 ; CHECK-T1: strb [[TREG4]],
92 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str5, i64 0, i64 0), i64 7, i32 1, i1 false)
92 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str5, i64 0, i64 0), i64 7, i1 false)
9393 ret void
9494 }
9595
107107 ; CHECK-T1: strh [[TREG5]],
108108 ; CHECK-T1: ldr [[TREG6:r[0-9]]],
109109 ; CHECK-T1: str [[TREG6]]
110 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([512 x i8], [512 x i8]* @spool.splbuf, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str6, i64 0, i64 0), i64 14, i32 1, i1 false)
110 call void @llvm.memcpy.p0i8.p0i8.i64(i8* getelementptr inbounds ([512 x i8], [512 x i8]* @spool.splbuf, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str6, i64 0, i64 0), i64 14, i1 false)
111111 ret void
112112 }
113113
123123 ; CHECK-T1: str
124124 %0 = bitcast %struct.Foo* %a to i8*
125125 %1 = bitcast %struct.Foo* %b to i8*
126 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 16, i32 4, i1 false)
126 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 %1, i32 16, i1 false)
127127 ret void
128128 }
129129
130 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
131 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
130 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind
131 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
1313 ; CHECK-DARWIN: bl _memmove
1414 ; CHECK-EABI: bl __aeabi_memmove
1515 ; CHECK-GNUEABI: bl memmove
16 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false)
17
18 ; CHECK-IOS: bl _memcpy
19 ; CHECK-DARWIN: bl _memcpy
20 ; CHECK-EABI: bl __aeabi_memcpy
21 ; CHECK-GNUEABI: bl memcpy
22 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false)
16 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i1 false)
17
18 ; CHECK-IOS: bl _memcpy
19 ; CHECK-DARWIN: bl _memcpy
20 ; CHECK-EABI: bl __aeabi_memcpy
21 ; CHECK-GNUEABI: bl memcpy
22 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i1 false)
2323
2424 ; EABI memset swaps arguments
2525 ; CHECK-IOS: mov r1, #1
3030 ; CHECK-EABI: bl __aeabi_memset
3131 ; CHECK-GNUEABI: mov r1, #1
3232 ; CHECK-GNUEABI: bl memset
33 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 0, i1 false)
33 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i1 false)
3434
3535 ; EABI uses memclr if value set to 0
3636 ; CHECK-IOS: mov r1, #0
3939 ; CHECK-DARWIN: bl _memset
4040 ; CHECK-EABI: bl __aeabi_memclr
4141 ; CHECK-GNUEABI: bl memset
42 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 0, i1 false)
42 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i1 false)
4343
4444 ; EABI uses aligned function variants if possible
4545
4747 ; CHECK-DARWIN: bl _memmove
4848 ; CHECK-EABI: bl __aeabi_memmove4
4949 ; CHECK-GNUEABI: bl memmove
50 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false)
50 call void @llvm.memmove.p0i8.p0i8.i32(i8* align 4 %dest, i8* align 4 %src, i32 500, i1 false)
5151
5252 ; CHECK-IOS: bl _memcpy
5353 ; CHECK-DARWIN: bl _memcpy
5454 ; CHECK-EABI: bl __aeabi_memcpy4
5555 ; CHECK-GNUEABI: bl memcpy
56 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false)
56 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %dest, i8* align 4 %src, i32 500, i1 false)
5757
5858 ; CHECK-IOS: bl _memset
5959 ; CHECK-DARWIN: bl _memset
6060 ; CHECK-EABI: bl __aeabi_memset4
6161 ; CHECK-GNUEABI: bl memset
62 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 4, i1 false)
62 call void @llvm.memset.p0i8.i32(i8* align 4 %dest, i8 1, i32 500, i1 false)
6363
6464 ; CHECK-IOS: bl _memset
6565 ; CHECK-DARWIN: bl _memset
6666 ; CHECK-EABI: bl __aeabi_memclr4
6767 ; CHECK-GNUEABI: bl memset
68 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 4, i1 false)
68 call void @llvm.memset.p0i8.i32(i8* align 4 %dest, i8 0, i32 500, i1 false)
6969
7070 ; CHECK-IOS: bl _memmove
7171 ; CHECK-DARWIN: bl _memmove
7272 ; CHECK-EABI: bl __aeabi_memmove8
7373 ; CHECK-GNUEABI: bl memmove
74 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false)
74 call void @llvm.memmove.p0i8.p0i8.i32(i8* align 8 %dest, i8* align 8 %src, i32 500, i1 false)
7575
7676 ; CHECK-IOS: bl _memcpy
7777 ; CHECK-DARWIN: bl _memcpy
7878 ; CHECK-EABI: bl __aeabi_memcpy8
7979 ; CHECK-GNUEABI: bl memcpy
80 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false)
80 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %dest, i8* align 8 %src, i32 500, i1 false)
8181
8282 ; CHECK-IOS: bl _memset
8383 ; CHECK-DARWIN: bl _memset
8484 ; CHECK-EABI: bl __aeabi_memset8
8585 ; CHECK-GNUEABI: bl memset
86 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 8, i1 false)
86 call void @llvm.memset.p0i8.i32(i8* align 8 %dest, i8 1, i32 500, i1 false)
8787
8888 ; CHECK-IOS: bl _memset
8989 ; CHECK-DARWIN: bl _memset
9090 ; CHECK-EABI: bl __aeabi_memclr8
9191 ; CHECK-GNUEABI: bl memset
92 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 8, i1 false)
92 call void @llvm.memset.p0i8.i32(i8* align 8 %dest, i8 0, i32 500, i1 false)
9393
9494 unreachable
9595 }
110110 ; CHECK-GNUEABI: bl memmove
111111 %arr0 = alloca [9 x i8], align 1
112112 %0 = bitcast [9 x i8]* %arr0 to i8*
113 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
113 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i1 false)
114114
115115 ; CHECK: add r1, sp, #16
116116 ; CHECK-IOS: bl _memcpy
119119 ; CHECK-GNUEABI: bl memcpy
120120 %arr1 = alloca [9 x i8], align 1
121121 %1 = bitcast [9 x i8]* %arr1 to i8*
122 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
122 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i1 false)
123123
124124 ; CHECK-IOS: mov r0, sp
125125 ; CHECK-IOS: mov r1, #1
135135 ; CHECK-GNUEABI: bl memset
136136 %arr2 = alloca [9 x i8], align 1
137137 %2 = bitcast [9 x i8]* %arr2 to i8*
138 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
138 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i1 false)
139139
140140 unreachable
141141 }
152152 ; CHECK-GNUEABI: bl memmove
153153 %arr0 = alloca [7 x i8], align 1
154154 %0 = bitcast [7 x i8]* %arr0 to i8*
155 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
155 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i1 false)
156156
157157 ; CHECK: {{add(.w)? r1, sp, #10}}
158158 ; CHECK-IOS: bl _memcpy
161161 ; CHECK-GNUEABI: bl memcpy
162162 %arr1 = alloca [7 x i8], align 1
163163 %1 = bitcast [7 x i8]* %arr1 to i8*
164 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
164 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i1 false)
165165
166166 ; CHECK: {{add(.w)? r0, sp, #3}}
167167 ; CHECK-IOS: mov r1, #1
174174 ; CHECK-GNUEABI: bl memset
175175 %arr2 = alloca [7 x i8], align 1
176176 %2 = bitcast [7 x i8]* %arr2 to i8*
177 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
177 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i1 false)
178178
179179 unreachable
180180 }
191191 ; CHECK-GNUEABI: bl memmove
192192 %arr0 = alloca [9 x i8], align 1
193193 %0 = getelementptr inbounds [9 x i8], [9 x i8]* %arr0, i32 0, i32 4
194 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
194 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i1 false)
195195
196196 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
197197 ; CHECK-IOS: bl _memcpy
200200 ; CHECK-GNUEABI: bl memcpy
201201 %arr1 = alloca [9 x i8], align 1
202202 %1 = getelementptr inbounds [9 x i8], [9 x i8]* %arr1, i32 0, i32 4
203 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
203 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i1 false)
204204
205205 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
206206 ; CHECK-IOS: mov r1, #1
213213 ; CHECK-GNUEABI: bl memset
214214 %arr2 = alloca [9 x i8], align 1
215215 %2 = getelementptr inbounds [9 x i8], [9 x i8]* %arr2, i32 0, i32 4
216 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
216 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i1 false)
217217
218218 unreachable
219219 }
230230 ; CHECK-GNUEABI: bl memmove
231231 %arr0 = alloca [13 x i8], align 1
232232 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 1
233 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
233 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i1 false)
234234
235235 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
236236 ; CHECK-IOS: bl _memcpy
239239 ; CHECK-GNUEABI: bl memcpy
240240 %arr1 = alloca [13 x i8], align 1
241241 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 1
242 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
242 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i1 false)
243243
244244 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
245245 ; CHECK-IOS: mov r1, #1
252252 ; CHECK-GNUEABI: bl memset
253253 %arr2 = alloca [13 x i8], align 1
254254 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 1
255 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
255 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i1 false)
256256
257257 unreachable
258258 }
269269 ; CHECK-GNUEABI: bl memmove
270270 %arr0 = alloca [13 x i8], align 1
271271 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 %i
272 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
272 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i1 false)
273273
274274 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
275275 ; CHECK-IOS: bl _memcpy
278278 ; CHECK-GNUEABI: bl memcpy
279279 %arr1 = alloca [13 x i8], align 1
280280 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 %i
281 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
281 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i1 false)
282282
283283 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
284284 ; CHECK-IOS: mov r1, #1
291291 ; CHECK-GNUEABI: bl memset
292292 %arr2 = alloca [13 x i8], align 1
293293 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 %i
294 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
294 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i1 false)
295295
296296 unreachable
297297