<div dir="ltr">Seems it causes crash. See;<div><a href="http://lab.llvm.org:8011/builders/clang-ppc64-elf-linux2/builds/20202">http://lab.llvm.org:8011/builders/clang-ppc64-elf-linux2/builds/20202</a><br></div><div><a href="http://bb.pgr.jp/builders/clang-3stage-i686-linux/builds/3787">http://bb.pgr.jp/builders/clang-3stage-i686-linux/builds/3787</a><br></div><div><br></div><div>I can reproduce crash with selfhosting on x86-64.</div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Nov 19, 2015 at 7:20 AM Pete Cooper via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: pete<br>
Date: Wed Nov 18 16:17:24 2015<br>
New Revision: 253511<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=253511&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=253511&view=rev</a><br>
Log:<br>
Change memcpy/memset/memmove to have dest and source alignments.<br>
<br>
Note, this was reviewed (and more details are in) <a href="http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312083.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312083.html</a><br>
<br>
These intrinsics currently have an explicit alignment argument which is<br>
required to be a constant integer.  It represents the alignment of the<br>
source and dest, and so must be the minimum of those.<br>
<br>
This change allows source and dest to each have their own alignments<br>
by using the alignment attribute on their arguments.  The alignment<br>
argument itself is removed.<br>
<br>
There are a few places in the code for which the code needs to be<br>
checked by an expert as to whether using only src/dest alignment is<br>
safe.  For those places, they currently take the minimum of src/dest<br>
alignments which matches the current behaviour.<br>
<br>
For example, code which used to read:<br>
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false)<br>
will now read:<br>
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %dest, i8* align 8 %src, i32 500, i1 false)<br>
<br>
For out of tree owners, I was able to strip alignment from calls using sed by replacing:<br>
  (call.*llvm\.memset.*)i32\ [0-9]*\,\ i1 false\)<br>
with:<br>
  $1i1 false)<br>
<br>
and similarly for memmove and memcpy.<br>
<br>
I then added back in alignment to test cases which needed it.<br>
<br>
A similar commit will be made to clang which actually has many differences in alignment as now<br>
IRBuilder can generate different source/dest alignments on calls.<br>
<br>
In IRBuilder itself, a new argument was added.  Instead of calling:<br>
  CreateMemCpy(Dst, Src, getInt64(Size), DstAlign, /* isVolatile */ false)<br>
you now call<br>
  CreateMemCpy(Dst, Src, getInt64(Size), DstAlign, SrcAlign, /* isVolatile */ false)<br>
<br>
There is a temporary class (IntegerAlignment) which takes the source alignment and rejects<br>
implicit conversion from bool.  This is to prevent isVolatile here from passing its default<br>
parameter to the source alignment.<br>
<br>
Note, changes in future can now be made to codegen.  I didn't change anything here, but this<br>
change should enable better memcpy code sequences.<br>
<br>
Reviewed by Hal Finkel.<br>
<br>
Added:<br>
    llvm/trunk/test/Bitcode/memintrinsics.3.7.ll<br>
    llvm/trunk/test/Bitcode/memintrinsics.3.7.ll.bc<br>
Removed:<br>
    llvm/trunk/test/Verifier/2008-08-22-MemCpyAlignment.ll<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/IRBuilder.h<br>
    llvm/trunk/include/llvm/IR/Instructions.h<br>
    llvm/trunk/include/llvm/IR/IntrinsicInst.h<br>
    llvm/trunk/include/llvm/IR/Intrinsics.td<br>
    llvm/trunk/lib/Analysis/Lint.cpp<br>
    llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp<br>
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp<br>
    llvm/trunk/lib/IR/Attributes.cpp<br>
    llvm/trunk/lib/IR/AutoUpgrade.cpp<br>
    llvm/trunk/lib/IR/IRBuilder.cpp<br>
    llvm/trunk/lib/IR/Verifier.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp<br>
    llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp<br>
    llvm/trunk/lib/Target/ARM/ARMFastISel.cpp<br>
    llvm/trunk/lib/Target/Mips/MipsFastISel.cpp<br>
    llvm/trunk/lib/Target/X86/X86FastISel.cpp<br>
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
    llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h<br>
    llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp<br>
    llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp<br>
    llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp<br>
    llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp<br>
    llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp<br>
    llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp<br>
    llvm/trunk/lib/Transforms/Scalar/SROA.cpp<br>
    llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp<br>
    llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp<br>
    llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp<br>
    llvm/trunk/test/Analysis/BasicAA/assume.ll<br>
    llvm/trunk/test/Analysis/BasicAA/cs-cs.ll<br>
    llvm/trunk/test/Analysis/BasicAA/getmodrefinfo-cs-cs.ll<br>
    llvm/trunk/test/Analysis/BasicAA/modref.ll<br>
    llvm/trunk/test/Analysis/CallGraph/no-intrinsics.ll<br>
    llvm/trunk/test/Analysis/DependenceAnalysis/Preliminary.ll<br>
    llvm/trunk/test/Analysis/GlobalsModRef/pr12351.ll<br>
    llvm/trunk/test/Analysis/GlobalsModRef/volatile-instrs.ll<br>
    llvm/trunk/test/Analysis/ScalarEvolution/avoid-smax-1.ll<br>
    llvm/trunk/test/Analysis/ScalarEvolution/trip-count.ll<br>
    llvm/trunk/test/Analysis/ScalarEvolution/trip-count3.ll<br>
    llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll<br>
    llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/memcpyopt.ll<br>
    llvm/trunk/test/Bitcode/standardCIntrinsic.3.2.ll<br>
    llvm/trunk/test/CodeGen/AArch64/PBQP-csr.ll<br>
    llvm/trunk/test/CodeGen/AArch64/aarch64-deferred-spilling.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-2012-05-07-MemcpyAlignBug.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-abi-varargs.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-abi_align.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-memcpy-inline.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-memset-inline.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-memset-to-bzero.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-misaligned-memcpy-inline.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-misched-basic-A53.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-misched-basic-A57.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-stur.ll<br>
    llvm/trunk/test/CodeGen/AArch64/arm64-virtual_base.ll<br>
    llvm/trunk/test/CodeGen/AArch64/fast-isel-memcpy.ll<br>
    llvm/trunk/test/CodeGen/AArch64/func-argpassing.ll<br>
    llvm/trunk/test/CodeGen/AArch64/memcpy-f128.ll<br>
    llvm/trunk/test/CodeGen/AArch64/tailcall-mem-intrinsics.ll<br>
    llvm/trunk/test/CodeGen/AMDGPU/llvm.memcpy.ll<br>
    llvm/trunk/test/CodeGen/ARM/2009-03-07-SpillerBug.ll<br>
    llvm/trunk/test/CodeGen/ARM/2011-03-10-DAGCombineCrash.ll<br>
    llvm/trunk/test/CodeGen/ARM/2011-10-26-memset-inline.ll<br>
    llvm/trunk/test/CodeGen/ARM/2011-10-26-memset-with-neon.ll<br>
    llvm/trunk/test/CodeGen/ARM/2012-04-24-SplitEHCriticalEdge.ll<br>
    llvm/trunk/test/CodeGen/ARM/Windows/memset.ll<br>
    llvm/trunk/test/CodeGen/ARM/Windows/no-aeabi.ll<br>
    llvm/trunk/test/CodeGen/ARM/crash-O0.ll<br>
    llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll<br>
    llvm/trunk/test/CodeGen/ARM/dyn-stackalloc.ll<br>
    llvm/trunk/test/CodeGen/ARM/fast-isel-intrinsic.ll<br>
    llvm/trunk/test/CodeGen/ARM/machine-cse-cmp.ll<br>
    llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll<br>
    llvm/trunk/test/CodeGen/ARM/memfunc.ll<br>
    llvm/trunk/test/CodeGen/ARM/memset-inline.ll<br>
    llvm/trunk/test/CodeGen/ARM/stack-protector-bmovpcb_call.ll<br>
    llvm/trunk/test/CodeGen/ARM/struct-byval-frame-index.ll<br>
    llvm/trunk/test/CodeGen/BPF/byval.ll<br>
    llvm/trunk/test/CodeGen/BPF/ex1.ll<br>
    llvm/trunk/test/CodeGen/BPF/sanity.ll<br>
    llvm/trunk/test/CodeGen/Generic/ForceStackAlign.ll<br>
    llvm/trunk/test/CodeGen/Generic/invalid-memcpy.ll<br>
    llvm/trunk/test/CodeGen/Hexagon/mem-fi-add.ll<br>
    llvm/trunk/test/CodeGen/Hexagon/tail-call-mem-intrinsics.ll<br>
    llvm/trunk/test/CodeGen/MSP430/memset.ll<br>
    llvm/trunk/test/CodeGen/Mips/2012-12-12-ExpandMemcpy.ll<br>
    llvm/trunk/test/CodeGen/Mips/Fast-ISel/memtest1.ll<br>
    llvm/trunk/test/CodeGen/Mips/biggot.ll<br>
    llvm/trunk/test/CodeGen/Mips/cconv/arguments-small-structures-bigger-than-32bits.ll<br>
    llvm/trunk/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-byte.ll<br>
    llvm/trunk/test/CodeGen/Mips/cconv/arguments-varargs-small-structs-combinations.ll<br>
    llvm/trunk/test/CodeGen/Mips/cconv/return-struct.ll<br>
    llvm/trunk/test/CodeGen/Mips/largeimmprinting.ll<br>
    llvm/trunk/test/CodeGen/Mips/memcpy.ll<br>
    llvm/trunk/test/CodeGen/Mips/tailcall.ll<br>
    llvm/trunk/test/CodeGen/NVPTX/lower-aggr-copies.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/2011-12-05-NoSpillDupCR.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/2011-12-06-SpillAndRestoreCR.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/ctrloop-reg.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/emptystruct.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/fsl-e500mc.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/fsl-e5500.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/glob-comp-aa-crash.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/isel-rc-nox0.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/memcpy-vec.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/memset-nc-le.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/memset-nc.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/ppc-empty-fs.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/resolvefi-basereg.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/resolvefi-disp.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/structsinmem.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/structsinregs.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/stwu8.ll<br>
    llvm/trunk/test/CodeGen/PowerPC/toc-load-sched-bug.ll<br>
    llvm/trunk/test/CodeGen/SystemZ/memcpy-01.ll<br>
    llvm/trunk/test/CodeGen/SystemZ/memset-01.ll<br>
    llvm/trunk/test/CodeGen/SystemZ/memset-02.ll<br>
    llvm/trunk/test/CodeGen/SystemZ/memset-03.ll<br>
    llvm/trunk/test/CodeGen/SystemZ/memset-04.ll<br>
    llvm/trunk/test/CodeGen/SystemZ/tail-call-mem-intrinsics.ll<br>
    llvm/trunk/test/CodeGen/Thumb/2011-05-11-DAGLegalizer.ll<br>
    llvm/trunk/test/CodeGen/Thumb/dyn-stackalloc.ll<br>
    llvm/trunk/test/CodeGen/Thumb/ldm-stm-base-materialization.ll<br>
    llvm/trunk/test/CodeGen/Thumb/stack-coloring-without-frame-ptr.ll<br>
    llvm/trunk/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll<br>
    llvm/trunk/test/CodeGen/Thumb2/2012-01-13-CBNZBug.ll<br>
    llvm/trunk/test/CodeGen/X86/2009-01-25-NoSSE.ll<br>
    llvm/trunk/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll<br>
    llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll<br>
    llvm/trunk/test/CodeGen/X86/2010-04-21-CoalescerBug.ll<br>
    llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll<br>
    llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll<br>
    llvm/trunk/test/CodeGen/X86/2012-01-10-UndefExceptionEdge.ll<br>
    llvm/trunk/test/CodeGen/X86/alignment-2.ll<br>
    llvm/trunk/test/CodeGen/X86/darwin-bzero.ll<br>
    llvm/trunk/test/CodeGen/X86/fast-isel-call.ll<br>
    llvm/trunk/test/CodeGen/X86/fast-isel-x86-64.ll<br>
    llvm/trunk/test/CodeGen/X86/force-align-stack-alloca.ll<br>
    llvm/trunk/test/CodeGen/X86/immediate_merging.ll<br>
    llvm/trunk/test/CodeGen/X86/load-slice.ll<br>
    llvm/trunk/test/CodeGen/X86/lsr-normalization.ll<br>
    llvm/trunk/test/CodeGen/X86/mem-intrin-base-reg.ll<br>
    llvm/trunk/test/CodeGen/X86/memcpy-2.ll<br>
    llvm/trunk/test/CodeGen/X86/memcpy.ll<br>
    llvm/trunk/test/CodeGen/X86/memset-2.ll<br>
    llvm/trunk/test/CodeGen/X86/memset-3.ll<br>
    llvm/trunk/test/CodeGen/X86/memset-sse-stack-realignment.ll<br>
    llvm/trunk/test/CodeGen/X86/memset.ll<br>
    llvm/trunk/test/CodeGen/X86/memset64-on-x86-32.ll<br>
    llvm/trunk/test/CodeGen/X86/misaligned-memset.ll<br>
    llvm/trunk/test/CodeGen/X86/misched-new.ll<br>
    llvm/trunk/test/CodeGen/X86/optimize-max-0.ll<br>
    llvm/trunk/test/CodeGen/X86/pr11985.ll<br>
    llvm/trunk/test/CodeGen/X86/pr14333.ll<br>
    llvm/trunk/test/CodeGen/X86/ragreedy-hoist-spill.ll<br>
    llvm/trunk/test/CodeGen/X86/remat-fold-load.ll<br>
    llvm/trunk/test/CodeGen/X86/small-byval-memcpy.ll<br>
    llvm/trunk/test/CodeGen/X86/stack-protector.ll<br>
    llvm/trunk/test/CodeGen/X86/tailcall-mem-intrinsics.ll<br>
    llvm/trunk/test/CodeGen/X86/tlv-1.ll<br>
    llvm/trunk/test/CodeGen/X86/unaligned-load.ll<br>
    llvm/trunk/test/CodeGen/X86/unwindraise.ll<br>
    llvm/trunk/test/CodeGen/X86/variable-sized-darwin-bzero.ll<br>
    llvm/trunk/test/CodeGen/X86/x86-64-static-relo-movl.ll<br>
    llvm/trunk/test/CodeGen/XCore/memcpy.ll<br>
    llvm/trunk/test/DebugInfo/AArch64/frameindices.ll<br>
    llvm/trunk/test/DebugInfo/X86/array.ll<br>
    llvm/trunk/test/DebugInfo/X86/array2.ll<br>
    llvm/trunk/test/DebugInfo/X86/debug-ranges-offset.ll<br>
    llvm/trunk/test/DebugInfo/X86/pieces-2.ll<br>
    llvm/trunk/test/DebugInfo/X86/pieces-3.ll<br>
    llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll<br>
    llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll<br>
    llvm/trunk/test/DebugInfo/X86/sroasplit-4.ll<br>
    llvm/trunk/test/DebugInfo/X86/sroasplit-5.ll<br>
    llvm/trunk/test/Instrumentation/AddressSanitizer/basic.ll<br>
    llvm/trunk/test/Instrumentation/DataFlowSanitizer/memset.ll<br>
    llvm/trunk/test/Instrumentation/MemorySanitizer/byval-alignment.ll<br>
    llvm/trunk/test/Instrumentation/MemorySanitizer/check_access_address.ll<br>
    llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll<br>
    llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll<br>
    llvm/trunk/test/Linker/type-unique-simple2-a.ll<br>
    llvm/trunk/test/Linker/type-unique-type-array-a.ll<br>
    llvm/trunk/test/Linker/type-unique-type-array-b.ll<br>
    llvm/trunk/test/Object/mangle-ir.ll<br>
    llvm/trunk/test/Other/lint.ll<br>
    llvm/trunk/test/Transforms/AlignmentFromAssumptions/simple.ll<br>
    llvm/trunk/test/Transforms/AlignmentFromAssumptions/simple32.ll<br>
    llvm/trunk/test/Transforms/BBVectorize/X86/wr-aliases.ll<br>
    llvm/trunk/test/Transforms/CodeGenPrepare/X86/memset_chk-simplify-nobuiltin.ll<br>
    llvm/trunk/test/Transforms/CorrelatedValuePropagation/non-null.ll<br>
    llvm/trunk/test/Transforms/DeadStoreElimination/2011-09-06-MemCpy.ll<br>
    llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll<br>
    llvm/trunk/test/Transforms/DeadStoreElimination/crash.ll<br>
    llvm/trunk/test/Transforms/DeadStoreElimination/cs-cs-aliasing.ll<br>
    llvm/trunk/test/Transforms/DeadStoreElimination/lifetime.ll<br>
    llvm/trunk/test/Transforms/DeadStoreElimination/memintrinsics.ll<br>
    llvm/trunk/test/Transforms/DeadStoreElimination/no-targetdata.ll<br>
    llvm/trunk/test/Transforms/DeadStoreElimination/pr11390.ll<br>
    llvm/trunk/test/Transforms/DeadStoreElimination/simple.ll<br>
    llvm/trunk/test/Transforms/GVN/nonescaping-malloc.ll<br>
    llvm/trunk/test/Transforms/GVN/pr17732.ll<br>
    llvm/trunk/test/Transforms/GVN/rle.ll<br>
    llvm/trunk/test/Transforms/GlobalOpt/crash.ll<br>
    llvm/trunk/test/Transforms/GlobalOpt/memcpy.ll<br>
    llvm/trunk/test/Transforms/GlobalOpt/memset-null.ll<br>
    llvm/trunk/test/Transforms/GlobalOpt/memset.ll<br>
    llvm/trunk/test/Transforms/Inline/alloca-dbgdeclare.ll<br>
    llvm/trunk/test/Transforms/Inline/inline-invoke-tail.ll<br>
    llvm/trunk/test/Transforms/Inline/inline-vla.ll<br>
    llvm/trunk/test/Transforms/Inline/noalias-calls.ll<br>
    llvm/trunk/test/Transforms/InstCombine/2007-10-10-EliminateMemCpy.ll<br>
    llvm/trunk/test/Transforms/InstCombine/2009-02-20-InstCombine-SROA.ll<br>
    llvm/trunk/test/Transforms/InstCombine/addrspacecast.ll<br>
    llvm/trunk/test/Transforms/InstCombine/align-addr.ll<br>
    llvm/trunk/test/Transforms/InstCombine/alloca.ll<br>
    llvm/trunk/test/Transforms/InstCombine/call-intrinsics.ll<br>
    llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll<br>
    llvm/trunk/test/Transforms/InstCombine/memcpy-from-global.ll<br>
    llvm/trunk/test/Transforms/InstCombine/memcpy-to-load.ll<br>
    llvm/trunk/test/Transforms/InstCombine/memcpy.ll<br>
    llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll<br>
    llvm/trunk/test/Transforms/InstCombine/memmove.ll<br>
    llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll<br>
    llvm/trunk/test/Transforms/InstCombine/memset.ll<br>
    llvm/trunk/test/Transforms/InstCombine/memset2.ll<br>
    llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll<br>
    llvm/trunk/test/Transforms/InstCombine/objsize.ll<br>
    llvm/trunk/test/Transforms/InstCombine/simplify-libcalls.ll<br>
    llvm/trunk/test/Transforms/InstCombine/sprintf-1.ll<br>
    llvm/trunk/test/Transforms/InstCombine/stack-overalign.ll<br>
    llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll<br>
    llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll<br>
    llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll<br>
    llvm/trunk/test/Transforms/InstCombine/struct-assign-tbaa.ll<br>
    llvm/trunk/test/Transforms/LoopIdiom/basic-address-space.ll<br>
    llvm/trunk/test/Transforms/LoopIdiom/basic.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/2008-02-24-MultipleUseofSRet.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/align.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/atomic.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/callslot_aa.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/callslot_deref.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/capturing-func.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset-with-lifetimes.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/memcpy-to-memset.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/memcpy-undef.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/memcpy.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/memmove.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/memset-memcpy-to-2x-memset.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/smaller.ll<br>
    llvm/trunk/test/Transforms/MemCpyOpt/sret.ll<br>
    llvm/trunk/test/Transforms/MergeFunc/vector.ll<br>
    llvm/trunk/test/Transforms/MetaRenamer/metarenamer.ll<br>
    llvm/trunk/test/Transforms/ObjCARC/nested.ll<br>
    llvm/trunk/test/Transforms/PlaceSafepoints/memset.ll<br>
    llvm/trunk/test/Transforms/SROA/address-spaces.ll<br>
    llvm/trunk/test/Transforms/SROA/alignment.ll<br>
    llvm/trunk/test/Transforms/SROA/basictest.ll<br>
    llvm/trunk/test/Transforms/SROA/big-endian.ll<br>
    llvm/trunk/test/Transforms/SROA/slice-order-independence.ll<br>
    llvm/trunk/test/Transforms/SROA/slice-width.ll<br>
    llvm/trunk/test/Transforms/SROA/vector-promotion.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2007-05-29-MemcpyPreserve.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2008-06-22-LargeArray.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2008-08-22-out-of-range-array-promote.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2008-09-22-vector-gep.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2009-03-04-MemCpyAlign.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2009-12-11-NeonTypes.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2011-05-06-CapturedAlloca.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2011-06-17-VectorPartialMemset.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2011-10-11-VectorMemset.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/2011-11-11-EmptyStruct.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/address-space.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/badarray.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/copy-aggregate.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/crash.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/inline-vector.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/memcpy-align.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/memset-aggregate-byte-leader.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/memset-aggregate.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/negative-memset.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/only-memcpy-uses.ll<br>
    llvm/trunk/test/Transforms/ScalarRepl/vector_memcpy.ll<br>
    llvm/trunk/test/Transforms/Util/combine-alias-scope-metadata.ll<br>
    llvm/trunk/test/Verifier/2006-12-12-IntrinsicDefine.ll<br>
    llvm/trunk/test/Verifier/memcpy.ll<br>
<br>
Modified: llvm/trunk/include/llvm/IR/IRBuilder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IRBuilder.h?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IRBuilder.h?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/IRBuilder.h (original)<br>
+++ llvm/trunk/include/llvm/IR/IRBuilder.h Wed Nov 18 16:17:24 2015<br>
@@ -362,34 +362,56 @@ public:<br>
   /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is<br>
   /// specified, it will be added to the instruction. Likewise with alias.scope<br>
   /// and noalias tags.<br>
-  CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,<br>
+  CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size,<br>
+                         unsigned DstAlign,<br>
                          bool isVolatile = false, MDNode *TBAATag = nullptr,<br>
                          MDNode *ScopeTag = nullptr,<br>
                          MDNode *NoAliasTag = nullptr) {<br>
-    return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile,<br>
+    return CreateMemSet(Ptr, Val, getInt64(Size), DstAlign, isVolatile,<br>
                         TBAATag, ScopeTag, NoAliasTag);<br>
   }<br>
<br>
-  CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,<br>
+  CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned DstAlign,<br>
                          bool isVolatile = false, MDNode *TBAATag = nullptr,<br>
                          MDNode *ScopeTag = nullptr,<br>
                          MDNode *NoAliasTag = nullptr);<br>
<br>
-  /// \brief Create and insert a memcpy between the specified pointers.<br>
+  /// Create and insert a memcpy between the specified pointers.<br>
   ///<br>
   /// If the pointers aren't i8*, they will be converted.  If a TBAA tag is<br>
   /// specified, it will be added to the instruction. Likewise with alias.scope<br>
   /// and noalias tags.<br>
-  CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,<br>
+  ///<br>
+  /// Note!  This is very temporary.  It is only intended to catch calls to<br>
+  /// CreateMemCpy in out of tree code which would otherwise silently pass the<br>
+  /// volatile flag to source alignment.<br>
+  class IntegerAlignment {<br>
+  private:<br>
+    uint64_t Align;<br>
+<br>
+    IntegerAlignment() = delete;<br>
+    IntegerAlignment(bool) = delete;<br>
+  public:<br>
+    IntegerAlignment(int Align) : Align(Align) { }<br>
+    IntegerAlignment(long long Align) : Align(Align) { }<br>
+    IntegerAlignment(unsigned Align) : Align(Align) { }<br>
+    IntegerAlignment(uint64_t Align) : Align(Align) { }<br>
+<br>
+    operator unsigned() { return Align; }<br>
+  };<br>
+  CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size,<br>
+                         unsigned DstAlign, IntegerAlignment SrcAlign,<br>
                          bool isVolatile = false, MDNode *TBAATag = nullptr,<br>
                          MDNode *TBAAStructTag = nullptr,<br>
                          MDNode *ScopeTag = nullptr,<br>
                          MDNode *NoAliasTag = nullptr) {<br>
-    return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag,<br>
+    return CreateMemCpy(Dst, Src, getInt64(Size), DstAlign, SrcAlign,<br>
+                        isVolatile, TBAATag,<br>
                         TBAAStructTag, ScopeTag, NoAliasTag);<br>
   }<br>
<br>
-  CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,<br>
+  CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size,<br>
+                         unsigned DstAlign, IntegerAlignment SrcAlign,<br>
                          bool isVolatile = false, MDNode *TBAATag = nullptr,<br>
                          MDNode *TBAAStructTag = nullptr,<br>
                          MDNode *ScopeTag = nullptr,<br>
@@ -401,15 +423,18 @@ public:<br>
   /// If the pointers aren't i8*, they will be converted.  If a TBAA tag is<br>
   /// specified, it will be added to the instruction. Likewise with alias.scope<br>
   /// and noalias tags.<br>
-  CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,<br>
+  CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size,<br>
+                          unsigned DstAlign, IntegerAlignment SrcAlign,<br>
                           bool isVolatile = false, MDNode *TBAATag = nullptr,<br>
                           MDNode *ScopeTag = nullptr,<br>
                           MDNode *NoAliasTag = nullptr) {<br>
-    return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile,<br>
+    return CreateMemMove(Dst, Src, getInt64(Size), DstAlign, SrcAlign,<br>
+                         isVolatile,<br>
                          TBAATag, ScopeTag, NoAliasTag);<br>
   }<br>
<br>
-  CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,<br>
+  CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size,<br>
+                          unsigned DstAlign, IntegerAlignment SrcAlign,<br>
                           bool isVolatile = false, MDNode *TBAATag = nullptr,<br>
                           MDNode *ScopeTag = nullptr,<br>
                           MDNode *NoAliasTag = nullptr);<br>
<br>
Modified: llvm/trunk/include/llvm/IR/Instructions.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instructions.h?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instructions.h?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/Instructions.h (original)<br>
+++ llvm/trunk/include/llvm/IR/Instructions.h Wed Nov 18 16:17:24 2015<br>
@@ -1638,6 +1638,23 @@ public:<br>
     return AttributeList.getParamAlignment(i);<br>
   }<br>
<br>
+  /// Set the alignment for a call or parameter (0=unknown).<br>
+  void setParamAlignment(unsigned Index, unsigned Align) {<br>
+    // Its not valid to change the parameter alignment.  Instead we have to<br>
+    // remove the old one if its there, and add a new one.<br>
+    if (AttributeList.hasAttribute(Index, Attribute::Alignment))<br>
+      AttributeList = AttributeList.removeAttribute(getContext(),<br>
+                                                    Index,<br>
+                                                    Attribute::Alignment);<br>
+<br>
+    // Now add the new alignment.<br>
+    llvm::AttrBuilder B;<br>
+    B.addAlignmentAttr(Align);<br>
+    AttributeList = AttributeList.addAttributes(getContext(), Index,<br>
+                                                AttributeSet::get(getContext(),<br>
+                                                                  Index, B));<br>
+  }<br>
+<br>
   /// \brief Extract the number of dereferenceable bytes for a call or<br>
   /// parameter (0=unknown).<br>
   uint64_t getDereferenceableBytes(unsigned i) const {<br>
<br>
Modified: llvm/trunk/include/llvm/IR/IntrinsicInst.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicInst.h?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicInst.h?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/IntrinsicInst.h (original)<br>
+++ llvm/trunk/include/llvm/IR/IntrinsicInst.h Wed Nov 18 16:17:24 2015<br>
@@ -150,16 +150,13 @@ namespace llvm {<br>
     const Use &getLengthUse() const { return getArgOperandUse(2); }<br>
     Use &getLengthUse() { return getArgOperandUse(2); }<br>
<br>
-    ConstantInt *getAlignmentCst() const {<br>
-      return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3)));<br>
-    }<br>
-<br>
-    unsigned getAlignment() const {<br>
-      return getAlignmentCst()->getZExtValue();<br>
+    unsigned getDestAlignment() const {<br>
+      // Note, param attributes start at 1, so offset dest index from 0 to 1.<br>
+      return getParamAlignment(1);<br>
     }<br>
<br>
     ConstantInt *getVolatileCst() const {<br>
-      return cast<ConstantInt>(const_cast<Value*>(getArgOperand(4)));<br>
+      return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3)));<br>
     }<br>
     bool isVolatile() const {<br>
       return !getVolatileCst()->isZero();<br>
@@ -188,16 +185,13 @@ namespace llvm {<br>
       setArgOperand(2, L);<br>
     }<br>
<br>
-    void setAlignment(Constant* A) {<br>
-      setArgOperand(3, A);<br>
+    void setDestAlignment(unsigned Align) {<br>
+      // Note, param attributes start at 1, so offset dest index from 0 to 1.<br>
+      setParamAlignment(1, Align);<br>
     }<br>
<br>
     void setVolatile(Constant* V) {<br>
-      setArgOperand(4, V);<br>
-    }<br>
-<br>
-    Type *getAlignmentType() const {<br>
-      return getArgOperand(3)->getType();<br>
+      setArgOperand(3, V);<br>
     }<br>
<br>
     // Methods for support type inquiry through isa, cast, and dyn_cast:<br>
@@ -259,12 +253,22 @@ namespace llvm {<br>
       return cast<PointerType>(getRawSource()->getType())->getAddressSpace();<br>
     }<br>
<br>
+    unsigned getSrcAlignment() const {<br>
+      // Note, param attributes start at 1, so offset src index from 1 to 2.<br>
+      return getParamAlignment(2);<br>
+    }<br>
+<br>
     void setSource(Value *Ptr) {<br>
       assert(getRawSource()->getType() == Ptr->getType() &&<br>
              "setSource called with pointer of wrong type!");<br>
       setArgOperand(1, Ptr);<br>
     }<br>
<br>
+    void setSrcAlignment(unsigned Align) {<br>
+      // Note, param attributes start at 1, so offset src index from 1 to 2.<br>
+      setParamAlignment(2, Align);<br>
+    }<br>
+<br>
     // Methods for support type inquiry through isa, cast, and dyn_cast:<br>
     static inline bool classof(const IntrinsicInst *I) {<br>
       return I->getIntrinsicID() == Intrinsic::memcpy ||<br>
<br>
Modified: llvm/trunk/include/llvm/IR/Intrinsics.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)<br>
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Wed Nov 18 16:17:24 2015<br>
@@ -333,17 +333,17 @@ def int_instrprof_value_profile : Intrin<br>
<br>
 def int_memcpy  : Intrinsic<[],<br>
                              [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,<br>
-                              llvm_i32_ty, llvm_i1_ty],<br>
+                              llvm_i1_ty],<br>
                             [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>,<br>
                              ReadOnly<1>]>;<br>
 def int_memmove : Intrinsic<[],<br>
                             [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,<br>
-                             llvm_i32_ty, llvm_i1_ty],<br>
+                             llvm_i1_ty],<br>
                             [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>,<br>
                              ReadOnly<1>]>;<br>
 def int_memset  : Intrinsic<[],<br>
                             [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,<br>
-                             llvm_i32_ty, llvm_i1_ty],<br>
+                             llvm_i1_ty],<br>
                             [IntrReadWriteArgMem, NoCapture<0>]>;<br>
<br>
 let Properties = [IntrNoMem] in {<br>
<br>
Modified: llvm/trunk/lib/Analysis/Lint.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Analysis/Lint.cpp (original)<br>
+++ llvm/trunk/lib/Analysis/Lint.cpp Wed Nov 18 16:17:24 2015<br>
@@ -284,9 +284,9 @@ void Lint::visitCallSite(CallSite CS) {<br>
       MemCpyInst *MCI = cast<MemCpyInst>(&I);<br>
       // TODO: If the size is known, use it.<br>
       visitMemoryReference(I, MCI->getDest(), MemoryLocation::UnknownSize,<br>
-                           MCI->getAlignment(), nullptr, MemRef::Write);<br>
+                           MCI->getDestAlignment(), nullptr, MemRef::Write);<br>
       visitMemoryReference(I, MCI->getSource(), MemoryLocation::UnknownSize,<br>
-                           MCI->getAlignment(), nullptr, MemRef::Read);<br>
+                           MCI->getSrcAlignment(), nullptr, MemRef::Read);<br>
<br>
       // Check that the memcpy arguments don't overlap. The AliasAnalysis API<br>
       // isn't expressive enough for what we really want to do. Known partial<br>
@@ -306,16 +306,16 @@ void Lint::visitCallSite(CallSite CS) {<br>
       MemMoveInst *MMI = cast<MemMoveInst>(&I);<br>
       // TODO: If the size is known, use it.<br>
       visitMemoryReference(I, MMI->getDest(), MemoryLocation::UnknownSize,<br>
-                           MMI->getAlignment(), nullptr, MemRef::Write);<br>
+                           MMI->getDestAlignment(), nullptr, MemRef::Write);<br>
       visitMemoryReference(I, MMI->getSource(), MemoryLocation::UnknownSize,<br>
-                           MMI->getAlignment(), nullptr, MemRef::Read);<br>
+                           MMI->getSrcAlignment(), nullptr, MemRef::Read);<br>
       break;<br>
     }<br>
     case Intrinsic::memset: {<br>
       MemSetInst *MSI = cast<MemSetInst>(&I);<br>
       // TODO: If the size is known, use it.<br>
       visitMemoryReference(I, MSI->getDest(), MemoryLocation::UnknownSize,<br>
-                           MSI->getAlignment(), nullptr, MemRef::Write);<br>
+                           MSI->getDestAlignment(), nullptr, MemRef::Write);<br>
       break;<br>
     }<br>
<br>
<br>
Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Wed Nov 18 16:17:24 2015<br>
@@ -1665,8 +1665,8 @@ bool CodeGenPrepare::optimizeCallInst(Ca<br>
       unsigned Align = getKnownAlignment(MI->getDest(), *DL);<br>
       if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI))<br>
         Align = std::min(Align, getKnownAlignment(MTI->getSource(), *DL));<br>
-      if (Align > MI->getAlignment())<br>
-        MI->setAlignment(ConstantInt::get(MI->getAlignmentType(), Align));<br>
+      if (Align > MI->getDestAlignment())<br>
+        MI->setDestAlignment(Align);<br>
     }<br>
   }<br>
<br>
<br>
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Nov 18 16:17:24 2015<br>
@@ -4365,69 +4365,73 @@ SelectionDAGBuilder::visitIntrinsicCall(<br>
   case Intrinsic::longjmp:<br>
     return &"_longjmp"[!TLI.usesUnderscoreLongJmp()];<br>
   case Intrinsic::memcpy: {<br>
+    const MemCpyInst &MemCpyI = cast<MemCpyInst>(I);<br>
     // FIXME: this definition of "user defined address space" is x86-specific<br>
     // Assert for address < 256 since we support only user defined address<br>
     // spaces.<br>
-    assert(cast<PointerType>(I.getArgOperand(0)->getType())->getAddressSpace()<br>
-           < 256 &&<br>
-           cast<PointerType>(I.getArgOperand(1)->getType())->getAddressSpace()<br>
-           < 256 &&<br>
+    assert(MemCpyI.getDestAddressSpace() < 256 &&<br>
+           MemCpyI.getSourceAddressSpace() < 256 &&<br>
            "Unknown address space");<br>
-    SDValue Op1 = getValue(I.getArgOperand(0));<br>
-    SDValue Op2 = getValue(I.getArgOperand(1));<br>
-    SDValue Op3 = getValue(I.getArgOperand(2));<br>
-    unsigned Align = cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();<br>
+    SDValue Op1 = getValue(MemCpyI.getDest());<br>
+    SDValue Op2 = getValue(MemCpyI.getSource());<br>
+    SDValue Op3 = getValue(MemCpyI.getLength());<br>
+    // FIXME: Support passing different dest/src alignments to the memcpy<br>
+    // DAG node.<br>
+    unsigned Align = std::min(MemCpyI.getDestAlignment(),<br>
+                              MemCpyI.getSrcAlignment());<br>
     if (!Align)<br>
       Align = 1; // @llvm.memcpy defines 0 and 1 to both mean no alignment.<br>
-    bool isVol = cast<ConstantInt>(I.getArgOperand(4))->getZExtValue();<br>
+    bool isVol = MemCpyI.isVolatile();<br>
     bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());<br>
     SDValue MC = DAG.getMemcpy(getRoot(), sdl, Op1, Op2, Op3, Align, isVol,<br>
                                false, isTC,<br>
-                               MachinePointerInfo(I.getArgOperand(0)),<br>
-                               MachinePointerInfo(I.getArgOperand(1)));<br>
+                               MachinePointerInfo(MemCpyI.getDest()),<br>
+                               MachinePointerInfo(MemCpyI.getSource()));<br>
     updateDAGForMaybeTailCall(MC);<br>
     return nullptr;<br>
   }<br>
   case Intrinsic::memset: {<br>
+    const MemSetInst &MemSetI = cast<MemSetInst>(I);<br>
     // FIXME: this definition of "user defined address space" is x86-specific<br>
     // Assert for address < 256 since we support only user defined address<br>
     // spaces.<br>
-    assert(cast<PointerType>(I.getArgOperand(0)->getType())->getAddressSpace()<br>
-           < 256 &&<br>
+    assert(MemSetI.getDestAddressSpace() < 256 &&<br>
            "Unknown address space");<br>
-    SDValue Op1 = getValue(I.getArgOperand(0));<br>
-    SDValue Op2 = getValue(I.getArgOperand(1));<br>
-    SDValue Op3 = getValue(I.getArgOperand(2));<br>
-    unsigned Align = cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();<br>
+    SDValue Op1 = getValue(MemSetI.getDest());<br>
+    SDValue Op2 = getValue(MemSetI.getValue());<br>
+    SDValue Op3 = getValue(MemSetI.getLength());<br>
+    unsigned Align = MemSetI.getDestAlignment();<br>
     if (!Align)<br>
       Align = 1; // @llvm.memset defines 0 and 1 to both mean no alignment.<br>
-    bool isVol = cast<ConstantInt>(I.getArgOperand(4))->getZExtValue();<br>
+    bool isVol = MemSetI.isVolatile();<br>
     bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());<br>
     SDValue MS = DAG.getMemset(getRoot(), sdl, Op1, Op2, Op3, Align, isVol,<br>
-                               isTC, MachinePointerInfo(I.getArgOperand(0)));<br>
+                               isTC, MachinePointerInfo(MemSetI.getDest()));<br>
     updateDAGForMaybeTailCall(MS);<br>
     return nullptr;<br>
   }<br>
   case Intrinsic::memmove: {<br>
+    const MemMoveInst &MemMoveI = cast<MemMoveInst>(I);<br>
     // FIXME: this definition of "user defined address space" is x86-specific<br>
     // Assert for address < 256 since we support only user defined address<br>
     // spaces.<br>
-    assert(cast<PointerType>(I.getArgOperand(0)->getType())->getAddressSpace()<br>
-           < 256 &&<br>
-           cast<PointerType>(I.getArgOperand(1)->getType())->getAddressSpace()<br>
-           < 256 &&<br>
+    assert(MemMoveI.getDestAddressSpace() < 256 &&<br>
+           MemMoveI.getSourceAddressSpace() < 256 &&<br>
            "Unknown address space");<br>
-    SDValue Op1 = getValue(I.getArgOperand(0));<br>
-    SDValue Op2 = getValue(I.getArgOperand(1));<br>
-    SDValue Op3 = getValue(I.getArgOperand(2));<br>
-    unsigned Align = cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();<br>
+    SDValue Op1 = getValue(MemMoveI.getDest());<br>
+    SDValue Op2 = getValue(MemMoveI.getSource());<br>
+    SDValue Op3 = getValue(MemMoveI.getLength());<br>
+    // FIXME: Support passing different dest/src alignments to the memcpy<br>
+    // DAG node.<br>
+    unsigned Align = std::min(MemMoveI.getDestAlignment(),<br>
+                              MemMoveI.getSrcAlignment());<br>
     if (!Align)<br>
       Align = 1; // @llvm.memmove defines 0 and 1 to both mean no alignment.<br>
-    bool isVol = cast<ConstantInt>(I.getArgOperand(4))->getZExtValue();<br>
+    bool isVol = MemMoveI.isVolatile();<br>
     bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());<br>
     SDValue MM = DAG.getMemmove(getRoot(), sdl, Op1, Op2, Op3, Align, isVol,<br>
-                                isTC, MachinePointerInfo(I.getArgOperand(0)),<br>
-                                MachinePointerInfo(I.getArgOperand(1)));<br>
+                                isTC, MachinePointerInfo(MemMoveI.getDest()),<br>
+                                MachinePointerInfo(MemMoveI.getSource()));<br>
     updateDAGForMaybeTailCall(MM);<br>
     return nullptr;<br>
   }<br>
<br>
Modified: llvm/trunk/lib/IR/Attributes.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/Attributes.cpp (original)<br>
+++ llvm/trunk/lib/IR/Attributes.cpp Wed Nov 18 16:17:24 2015<br>
@@ -830,11 +830,6 @@ AttributeSet AttributeSet::removeAttribu<br>
   if (!pImpl) return AttributeSet();<br>
   if (!Attrs.pImpl) return *this;<br>
<br>
-  // FIXME it is not obvious how this should work for alignment.<br>
-  // For now, say we can't pass in alignment, which no current use does.<br>
-  assert(!Attrs.hasAttribute(Index, Attribute::Alignment) &&<br>
-         "Attempt to change alignment!");<br>
-<br>
   // Add the attribute slots before the one we're trying to add.<br>
   SmallVector<AttributeSet, 4> AttrSet;<br>
   uint64_t NumAttrs = pImpl->getNumAttributes();<br>
<br>
Modified: llvm/trunk/lib/IR/AutoUpgrade.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AutoUpgrade.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AutoUpgrade.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/AutoUpgrade.cpp (original)<br>
+++ llvm/trunk/lib/IR/AutoUpgrade.cpp Wed Nov 18 16:17:24 2015<br>
@@ -144,6 +144,36 @@ static bool UpgradeIntrinsicFunction1(Fu<br>
     }<br>
     break;<br>
   }<br>
+  case 'm': {<br>
+    if (Name.startswith("memcpy.") && F->arg_size() == 5) {<br>
+      F->setName(Name + ".old");<br>
+      // Get the types of dest, src, and len.<br>
+      ArrayRef<Type *> ParamTypes = F->getFunctionType()->params().slice(0, 3);<br>
+      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memcpy,<br>
+                                        ParamTypes);<br>
+      return true;<br>
+    }<br>
+    if (Name.startswith("memmove.") && F->arg_size() == 5) {<br>
+      F->setName(Name + ".old");<br>
+      // Get the types of dest, src, and len.<br>
+      ArrayRef<Type *> ParamTypes = F->getFunctionType()->params().slice(0, 3);<br>
+      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memmove,<br>
+                                        ParamTypes);<br>
+      return true;<br>
+    }<br>
+    if (Name.startswith("memset.") && F->arg_size() == 5) {<br>
+      F->setName(Name + ".old");<br>
+      // Get the types of dest and len.<br>
+      Type *ParamTypes[2] = {<br>
+        F->getFunctionType()->getParamType(0),<br>
+        F->getFunctionType()->getParamType(2)<br>
+      };<br>
+      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memset,<br>
+                                        ParamTypes);<br>
+      return true;<br>
+    }<br>
+    break;<br>
+  }<br>
<br>
   case 'o':<br>
     // We only need to change the name to match the mangling including the<br>
@@ -727,6 +757,31 @@ void llvm::UpgradeIntrinsicCall(CallInst<br>
     CI->eraseFromParent();<br>
     return;<br>
<br>
+  case Intrinsic::memcpy:<br>
+  case Intrinsic::memmove:<br>
+  case Intrinsic::memset: {<br>
+    // Remove alignment argument (3), and add alignment attributes to the<br>
+    // dest/src pointers.<br>
+    Value *Args[4] = {<br>
+      CI->getArgOperand(0),<br>
+      CI->getArgOperand(1),<br>
+      CI->getArgOperand(2),<br>
+      CI->getArgOperand(4)<br>
+    };<br>
+    auto *MemCI = cast<MemIntrinsic>(Builder.CreateCall(NewFn, Args, Name));<br>
+<br>
+    // All mem intrinsics support dest alignment.<br>
+    const ConstantInt *Align = cast<ConstantInt>(CI->getArgOperand(3));<br>
+    MemCI->setDestAlignment(Align->getZExtValue());<br>
+<br>
+    // Memcpy/Memmove also support source alignment.<br>
+    if (auto *MemTransferI = dyn_cast<MemTransferInst>(MemCI))<br>
+      MemTransferI->setSrcAlignment(Align->getZExtValue());<br>
+    CI->replaceAllUsesWith(MemCI);<br>
+    CI->eraseFromParent();<br>
+    return;<br>
+  }<br>
+<br>
   case Intrinsic::objectsize:<br>
     CI->replaceAllUsesWith(Builder.CreateCall(<br>
         NewFn, {CI->getArgOperand(0), CI->getArgOperand(1)}, Name));<br>
<br>
Modified: llvm/trunk/lib/IR/IRBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/IRBuilder.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/IRBuilder.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/IRBuilder.cpp (original)<br>
+++ llvm/trunk/lib/IR/IRBuilder.cpp Wed Nov 18 16:17:24 2015<br>
@@ -15,6 +15,7 @@<br>
 #include "llvm/IR/Function.h"<br>
 #include "llvm/IR/GlobalVariable.h"<br>
 #include "llvm/IR/IRBuilder.h"<br>
+#include "llvm/IR/IntrinsicInst.h"<br>
 #include "llvm/IR/Intrinsics.h"<br>
 #include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/IR/Statepoint.h"<br>
@@ -79,11 +80,11 @@ static InvokeInst *createInvokeHelper(Va<br>
 }<br>
<br>
 CallInst *IRBuilderBase::<br>
-CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,<br>
+CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned DstAlign,<br>
              bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,<br>
              MDNode *NoAliasTag) {<br>
   Ptr = getCastedInt8PtrValue(Ptr);<br>
-  Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) };<br>
+  Value *Ops[] = { Ptr, Val, Size, getInt1(isVolatile) };<br>
   Type *Tys[] = { Ptr->getType(), Size->getType() };<br>
   Module *M = BB->getParent()->getParent();<br>
   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);<br>
@@ -99,18 +100,21 @@ CreateMemSet(Value *Ptr, Value *Val, Val<br>
<br>
   if (NoAliasTag)<br>
     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);<br>
+<br>
+  cast<MemSetInst>(CI)->setDestAlignment(DstAlign);<br>
<br>
   return CI;<br>
 }<br>
<br>
 CallInst *IRBuilderBase::<br>
-CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,<br>
+CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned DstAlign,<br>
+             IntegerAlignment SrcAlign,<br>
              bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag,<br>
              MDNode *ScopeTag, MDNode *NoAliasTag) {<br>
   Dst = getCastedInt8PtrValue(Dst);<br>
   Src = getCastedInt8PtrValue(Src);<br>
<br>
-  Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };<br>
+  Value *Ops[] = { Dst, Src, Size, getInt1(isVolatile) };<br>
   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };<br>
   Module *M = BB->getParent()->getParent();<br>
   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);<br>
@@ -130,18 +134,23 @@ CreateMemCpy(Value *Dst, Value *Src, Val<br>
<br>
   if (NoAliasTag)<br>
     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);<br>
+<br>
+  auto *MCI = cast<MemCpyInst>(CI);<br>
+  MCI->setDestAlignment(DstAlign);<br>
+  MCI->setSrcAlignment(SrcAlign);<br>
<br>
   return CI;<br>
 }<br>
<br>
 CallInst *IRBuilderBase::<br>
-CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,<br>
+CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned DstAlign,<br>
+              IntegerAlignment SrcAlign,<br>
               bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,<br>
               MDNode *NoAliasTag) {<br>
   Dst = getCastedInt8PtrValue(Dst);<br>
   Src = getCastedInt8PtrValue(Src);<br>
<br>
-  Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };<br>
+  Value *Ops[] = { Dst, Src, Size, getInt1(isVolatile) };<br>
   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };<br>
   Module *M = BB->getParent()->getParent();<br>
   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);<br>
@@ -157,6 +166,10 @@ CreateMemMove(Value *Dst, Value *Src, Va<br>
<br>
   if (NoAliasTag)<br>
     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);<br>
+<br>
+  auto *MMI = cast<MemMoveInst>(CI);<br>
+  MMI->setDestAlignment(DstAlign);<br>
+  MMI->setSrcAlignment(SrcAlign);<br>
<br>
   return CI;<br>
 }<br>
<br>
Modified: llvm/trunk/lib/IR/Verifier.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/Verifier.cpp (original)<br>
+++ llvm/trunk/lib/IR/Verifier.cpp Wed Nov 18 16:17:24 2015<br>
@@ -3511,7 +3511,7 @@ void Verifier::visitIntrinsicCallSite(In<br>
     const APInt &AlignVal = AlignCI->getValue();<br>
     Assert(AlignCI->isZero() || AlignVal.isPowerOf2(),<br>
            "alignment argument of memory intrinsics must be a power of 2", CS);<br>
-    Assert(isa<ConstantInt>(CS.getArgOperand(4)),<br>
+    Assert(isa<ConstantInt>(CS.getArgOperand(3)),<br>
            "isvolatile argument of memory intrinsics must be a constant int",<br>
            CS);<br>
     break;<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Wed Nov 18 16:17:24 2015<br>
@@ -3379,7 +3379,8 @@ bool AArch64FastISel::fastLowerIntrinsic<br>
       // Small memcpy's are common enough that we want to do them without a call<br>
       // if possible.<br>
       uint64_t Len = cast<ConstantInt>(MTI->getLength())->getZExtValue();<br>
-      unsigned Alignment = MTI->getAlignment();<br>
+      unsigned Alignment = std::min(MTI->getDestAlignment(),<br>
+                                    MTI->getSrcAlignment());<br>
       if (isMemCpySmall(Len, Alignment)) {<br>
         Address Dest, Src;<br>
         if (!computeAddress(MTI->getRawDest(), Dest) ||<br>
@@ -3399,7 +3400,7 @@ bool AArch64FastISel::fastLowerIntrinsic<br>
       return false;<br>
<br>
     const char *IntrMemName = isa<MemCpyInst>(II) ? "memcpy" : "memmove";<br>
-    return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 2);<br>
+    return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 1);<br>
   }<br>
   case Intrinsic::memset: {<br>
     const MemSetInst *MSI = cast<MemSetInst>(II);<br>
@@ -3415,7 +3416,7 @@ bool AArch64FastISel::fastLowerIntrinsic<br>
       // address spaces.<br>
       return false;<br>
<br>
-    return lowerCallTo(II, "memset", II->getNumArgOperands() - 2);<br>
+    return lowerCallTo(II, "memset", II->getNumArgOperands() - 1);<br>
   }<br>
   case Intrinsic::sin:<br>
   case Intrinsic::cos:<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp Wed Nov 18 16:17:24 2015<br>
@@ -400,15 +400,15 @@ void AMDGPUPromoteAlloca::visitAlloca(Al<br>
     case Intrinsic::memcpy: {<br>
       MemCpyInst *MemCpy = cast<MemCpyInst>(Intr);<br>
       Builder.CreateMemCpy(MemCpy->getRawDest(), MemCpy->getRawSource(),<br>
-                           MemCpy->getLength(), MemCpy->getAlignment(),<br>
-                           MemCpy->isVolatile());<br>
+                           MemCpy->getLength(), MemCpy->getDestAlignment(),<br>
+                           MemCpy->getSrcAlignment(), MemCpy->isVolatile());<br>
       Intr->eraseFromParent();<br>
       continue;<br>
     }<br>
     case Intrinsic::memset: {<br>
       MemSetInst *MemSet = cast<MemSetInst>(Intr);<br>
       Builder.CreateMemSet(MemSet->getRawDest(), MemSet->getValue(),<br>
-                           MemSet->getLength(), MemSet->getAlignment(),<br>
+                           MemSet->getLength(), MemSet->getDestAlignment(),<br>
                            MemSet->isVolatile());<br>
       Intr->eraseFromParent();<br>
       continue;<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Wed Nov 18 16:17:24 2015<br>
@@ -2328,8 +2328,8 @@ bool ARMFastISel::SelectCall(const Instr<br>
   for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();<br>
        i != e; ++i) {<br>
     // If we're lowering a memory intrinsic instead of a regular call, skip the<br>
-    // last two arguments, which shouldn't be passed to the underlying function.<br>
-    if (IntrMemName && e-i <= 2)<br>
+    // last argument, which shouldn't be passed to the underlying function.<br>
+    if (IntrMemName && e-i <= 1)<br>
       break;<br>
<br>
     ISD::ArgFlagsTy Flags;<br>
@@ -2527,7 +2527,8 @@ bool ARMFastISel::SelectIntrinsicCall(co<br>
         if (!ARMComputeAddress(MTI.getRawDest(), Dest) ||<br>
             !ARMComputeAddress(MTI.getRawSource(), Src))<br>
           return false;<br>
-        unsigned Alignment = MTI.getAlignment();<br>
+        unsigned Alignment = std::min(MTI.getDestAlignment(),<br>
+                                      MTI.getSrcAlignment());<br>
         if (ARMTryEmitSmallMemCpy(Dest, Src, Len, Alignment))<br>
           return true;<br>
       }<br>
<br>
Modified: llvm/trunk/lib/Target/Mips/MipsFastISel.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsFastISel.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsFastISel.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Mips/MipsFastISel.cpp (original)<br>
+++ llvm/trunk/lib/Target/Mips/MipsFastISel.cpp Wed Nov 18 16:17:24 2015<br>
@@ -1403,7 +1403,7 @@ bool MipsFastISel::fastLowerIntrinsicCal<br>
     if (!MTI->getLength()->getType()->isIntegerTy(32))<br>
       return false;<br>
     const char *IntrMemName = isa<MemCpyInst>(II) ? "memcpy" : "memmove";<br>
-    return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 2);<br>
+    return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 1);<br>
   }<br>
   case Intrinsic::memset: {<br>
     const MemSetInst *MSI = cast<MemSetInst>(II);<br>
@@ -1412,7 +1412,7 @@ bool MipsFastISel::fastLowerIntrinsicCal<br>
       return false;<br>
     if (!MSI->getLength()->getType()->isIntegerTy(32))<br>
       return false;<br>
-    return lowerCallTo(II, "memset", II->getNumArgOperands() - 2);<br>
+    return lowerCallTo(II, "memset", II->getNumArgOperands() - 1);<br>
   }<br>
   }<br>
   return false;<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Wed Nov 18 16:17:24 2015<br>
@@ -2409,7 +2409,7 @@ bool X86FastISel::fastLowerIntrinsicCall<br>
     if (MCI->getSourceAddressSpace() > 255 || MCI->getDestAddressSpace() > 255)<br>
       return false;<br>
<br>
-    return lowerCallTo(II, "memcpy", II->getNumArgOperands() - 2);<br>
+    return lowerCallTo(II, "memcpy", II->getNumArgOperands() - 1);<br>
   }<br>
   case Intrinsic::memset: {<br>
     const MemSetInst *MSI = cast<MemSetInst>(II);<br>
@@ -2424,7 +2424,7 @@ bool X86FastISel::fastLowerIntrinsicCall<br>
     if (MSI->getDestAddressSpace() > 255)<br>
       return false;<br>
<br>
-    return lowerCallTo(II, "memset", II->getNumArgOperands() - 2);<br>
+    return lowerCallTo(II, "memset", II->getNumArgOperands() - 1);<br>
   }<br>
   case Intrinsic::stackprotector: {<br>
     // Emit code to store the stack guard onto the stack.<br>
<br>
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Wed Nov 18 16:17:24 2015<br>
@@ -60,14 +60,18 @@ static Type *reduceToSingleValueType(Typ<br>
   return T;<br>
 }<br>
<br>
-Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) {<br>
+Instruction *InstCombiner::SimplifyMemTransfer(MemTransferInst *MI) {<br>
   unsigned DstAlign = getKnownAlignment(MI->getArgOperand(0), DL, MI, AC, DT);<br>
   unsigned SrcAlign = getKnownAlignment(MI->getArgOperand(1), DL, MI, AC, DT);<br>
-  unsigned MinAlign = std::min(DstAlign, SrcAlign);<br>
-  unsigned CopyAlign = MI->getAlignment();<br>
+  unsigned CopyDestAlign = MI->getDestAlignment();<br>
+  unsigned CopySrcAlign = MI->getSrcAlignment();<br>
<br>
-  if (CopyAlign < MinAlign) {<br>
-    MI->setAlignment(ConstantInt::get(MI->getAlignmentType(), MinAlign, false));<br>
+  if (CopyDestAlign < DstAlign) {<br>
+    MI->setDestAlignment(DstAlign);<br>
+    return MI;<br>
+  }<br>
+  if (CopySrcAlign < SrcAlign) {<br>
+    MI->setSrcAlignment(SrcAlign);<br>
     return MI;<br>
   }<br>
<br>
@@ -135,8 +139,8 @@ Instruction *InstCombiner::SimplifyMemTr<br>
<br>
   // If the memcpy/memmove provides better alignment info than we can<br>
   // infer, use it.<br>
-  SrcAlign = std::max(SrcAlign, CopyAlign);<br>
-  DstAlign = std::max(DstAlign, CopyAlign);<br>
+  SrcAlign = std::max(SrcAlign, CopySrcAlign);<br>
+  DstAlign = std::max(DstAlign, CopyDestAlign);<br>
<br>
   Value *Src = Builder->CreateBitCast(MI->getArgOperand(1), NewSrcPtrTy);<br>
   Value *Dest = Builder->CreateBitCast(MI->getArgOperand(0), NewDstPtrTy);<br>
@@ -156,9 +160,8 @@ Instruction *InstCombiner::SimplifyMemTr<br>
<br>
 Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) {<br>
   unsigned Alignment = getKnownAlignment(MI->getDest(), DL, MI, AC, DT);<br>
-  if (MI->getAlignment() < Alignment) {<br>
-    MI->setAlignment(ConstantInt::get(MI->getAlignmentType(),<br>
-                                             Alignment, false));<br>
+  if (MI->getDestAlignment() < Alignment) {<br>
+    MI->setDestAlignment(Alignment);<br>
     return MI;<br>
   }<br>
<br>
@@ -168,7 +171,7 @@ Instruction *InstCombiner::SimplifyMemSe<br>
   if (!LenC || !FillC || !FillC->getType()->isIntegerTy(8))<br>
     return nullptr;<br>
   uint64_t Len = LenC->getLimitedValue();<br>
-  Alignment = MI->getAlignment();<br>
+  Alignment = MI->getDestAlignment();<br>
   assert(Len && "0-sized memory setting should be removed already.");<br>
<br>
   // memset(s,c,n) -> store s, c (for n=1,2,4,8)<br>
@@ -743,8 +746,8 @@ Instruction *InstCombiner::visitCallInst<br>
<br>
     // If we can determine a pointer alignment that is bigger than currently<br>
     // set, update the alignment.<br>
-    if (isa<MemTransferInst>(MI)) {<br>
-      if (Instruction *I = SimplifyMemTransfer(MI))<br>
+    if (auto *MTI = dyn_cast<MemTransferInst>(MI)) {<br>
+      if (Instruction *I = SimplifyMemTransfer(MTI))<br>
         return I;<br>
     } else if (MemSetInst *MSI = dyn_cast<MemSetInst>(MI)) {<br>
       if (Instruction *I = SimplifyMemSet(MSI))<br>
<br>
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h (original)<br>
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h Wed Nov 18 16:17:24 2015<br>
@@ -558,7 +558,7 @@ private:<br>
   Instruction *PromoteCastOfAllocation(BitCastInst &CI, AllocaInst &AI);<br>
   Instruction *MatchBSwap(BinaryOperator &I);<br>
   bool SimplifyStoreAtEndOfBlock(StoreInst &SI);<br>
-  Instruction *SimplifyMemTransfer(MemIntrinsic *MI);<br>
+  Instruction *SimplifyMemTransfer(MemTransferInst *MI);<br>
   Instruction *SimplifyMemSet(MemSetInst *MI);<br>
<br>
   Value *EvaluateInDifferentType(Value *V, Type *Ty, bool isSigned);<br>
<br>
Modified: llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp Wed Nov 18 16:17:24 2015<br>
@@ -1356,20 +1356,21 @@ void DFSanVisitor::visitMemTransferInst(<br>
   Value *LenShadow = IRB.CreateMul(<br>
       I.getLength(),<br>
       ConstantInt::get(I.getLength()->getType(), DFSF.DFS.ShadowWidth / 8));<br>
-  Value *AlignShadow;<br>
-  if (ClPreserveAlignment) {<br>
-    AlignShadow = IRB.CreateMul(I.getAlignmentCst(),<br>
-                                ConstantInt::get(I.getAlignmentCst()->getType(),<br>
-                                                 DFSF.DFS.ShadowWidth / 8));<br>
-  } else {<br>
-    AlignShadow = ConstantInt::get(I.getAlignmentCst()->getType(),<br>
-                                   DFSF.DFS.ShadowWidth / 8);<br>
-  }<br>
   Type *Int8Ptr = Type::getInt8PtrTy(*DFSF.DFS.Ctx);<br>
   DestShadow = IRB.CreateBitCast(DestShadow, Int8Ptr);<br>
   SrcShadow = IRB.CreateBitCast(SrcShadow, Int8Ptr);<br>
-  IRB.CreateCall(I.getCalledValue(), {DestShadow, SrcShadow, LenShadow,<br>
-                                      AlignShadow, I.getVolatileCst()});<br>
+  auto *MTI = cast<MemTransferInst>(IRB.CreateCall(I.getCalledValue(),<br>
+                                                   { DestShadow, SrcShadow,<br>
+                                                     LenShadow,<br>
+                                                     I.getVolatileCst() }));<br>
+<br>
+  if (ClPreserveAlignment) {<br>
+    MTI->setDestAlignment(I.getDestAlignment() * (DFSF.DFS.ShadowWidth / 8));<br>
+    MTI->setSrcAlignment(I.getSrcAlignment() * (DFSF.DFS.ShadowWidth / 8));<br>
+  } else {<br>
+    MTI->setDestAlignment(DFSF.DFS.ShadowWidth / 8);<br>
+    MTI->setSrcAlignment(DFSF.DFS.ShadowWidth / 8);<br>
+  }<br>
 }<br>
<br>
 void DFSanVisitor::visitReturnInst(ReturnInst &RI) {<br>
<br>
Modified: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp Wed Nov 18 16:17:24 2015<br>
@@ -1117,7 +1117,7 @@ struct MemorySanitizerVisitor : public I<br>
               unsigned CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);<br>
               Value *Cpy = EntryIRB.CreateMemCpy(<br>
                   getShadowPtr(V, EntryIRB.getInt8Ty(), EntryIRB), Base, Size,<br>
-                  CopyAlign);<br>
+                  CopyAlign, CopyAlign);<br>
               DEBUG(dbgs() << "  ByValCpy: " << *Cpy << "\n");<br>
               (void)Cpy;<br>
             }<br>
@@ -2482,7 +2482,7 @@ struct MemorySanitizerVisitor : public I<br>
         unsigned Alignment = std::min(ParamAlignment, kShadowTLSAlignment);<br>
         Store = IRB.CreateMemCpy(ArgShadowBase,<br>
                                  getShadowPtr(A, Type::getInt8Ty(*MS.C), IRB),<br>
-                                 Size, Alignment);<br>
+                                 Size, Alignment, Alignment);<br>
       } else {<br>
         Size = DL.getTypeAllocSize(A->getType());<br>
         if (ArgOffset + Size > kParamTLSSize) break;<br>
@@ -2834,7 +2834,7 @@ struct VarArgAMD64Helper : public VarArg<br>
         Value *Base = getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset);<br>
         OverflowOffset += RoundUpToAlignment(ArgSize, 8);<br>
         IRB.CreateMemCpy(Base, MSV.getShadowPtr(A, IRB.getInt8Ty(), IRB),<br>
-                         ArgSize, kShadowTLSAlignment);<br>
+                         ArgSize, kShadowTLSAlignment, kShadowTLSAlignment);<br>
       } else {<br>
         ArgKind AK = classifyArgument(A);<br>
         if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)<br>
@@ -2912,7 +2912,7 @@ struct VarArgAMD64Helper : public VarArg<br>
         IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset),<br>
                       VAArgOverflowSize);<br>
       VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);<br>
-      IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8);<br>
+      IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8, 8);<br>
     }<br>
<br>
     // Instrument va_start.<br>
@@ -2931,7 +2931,7 @@ struct VarArgAMD64Helper : public VarArg<br>
       Value *RegSaveAreaShadowPtr =<br>
         MSV.getShadowPtr(RegSaveAreaPtr, IRB.getInt8Ty(), IRB);<br>
       IRB.CreateMemCpy(RegSaveAreaShadowPtr, VAArgTLSCopy,<br>
-                       AMD64FpEndOffset, 16);<br>
+                       AMD64FpEndOffset, 16, 16);<br>
<br>
       Value *OverflowArgAreaPtrPtr =<br>
         IRB.CreateIntToPtr(<br>
@@ -2943,7 +2943,8 @@ struct VarArgAMD64Helper : public VarArg<br>
         MSV.getShadowPtr(OverflowArgAreaPtr, IRB.getInt8Ty(), IRB);<br>
       Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,<br>
                                              AMD64FpEndOffset);<br>
-      IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize, 16);<br>
+      IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize,<br>
+                       16, 16);<br>
     }<br>
   }<br>
 };<br>
@@ -3029,7 +3030,7 @@ struct VarArgMIPS64Helper : public VarAr<br>
       // If there is a va_start in this function, make a backup copy of<br>
       // va_arg_tls somewhere in the function entry block.<br>
       VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);<br>
-      IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8);<br>
+      IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8, 8);<br>
     }<br>
<br>
     // Instrument va_start.<br>
@@ -3044,7 +3045,7 @@ struct VarArgMIPS64Helper : public VarAr<br>
       Value *RegSaveAreaPtr = IRB.CreateLoad(RegSaveAreaPtrPtr);<br>
       Value *RegSaveAreaShadowPtr =<br>
       MSV.getShadowPtr(RegSaveAreaPtr, IRB.getInt8Ty(), IRB);<br>
-      IRB.CreateMemCpy(RegSaveAreaShadowPtr, VAArgTLSCopy, CopySize, 8);<br>
+      IRB.CreateMemCpy(RegSaveAreaShadowPtr, VAArgTLSCopy, CopySize, 8, 8);<br>
     }<br>
   }<br>
 };<br>
<br>
Modified: llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp?rev=253511&r1=253510&r2=253511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp?rev=253511&r1=253510&r2=253511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp Wed Nov 18 16:17:24 2015<br>
@@ -347,6 +347,8 @@ bool AlignmentFromAssumptions::processAs<br>
       // instruction, but only for one operand, save it. If we reach the<br>
       // other operand through another assumption later, then we may<br>
       // change the alignment at that point.<br>
+      // FIXME: The above statement is no longer true.  Fix the code below<br>
+      // to be able to reason about different dest/src alignments.<br>
       if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) {<br>
         unsigned NewSrcAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV,<br>
           MTI->getSource(), SE);<br>
@@ -376,20 +378,23 @@ bool AlignmentFromAssumptions::processAs<br>
         if (AltSrcAlignment <= std::max(NewDestAlignment, AltDestAlignment))<br>
           NewAlignment = std::max(NewAlignment, AltSrcAlignment);<br>
<br>
-        if (NewAlignment > MI->getAlign</blockquote></div>