[llvm] r253511 - Change memcpy/memset/memmove to have dest and source alignments.

Pete Cooper via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 18 22:05:17 PST 2015


Thanks for letting me know.  I’ve reverted the LLVM and clang changes in r253541-3.

Seems to be breaking stage 2 on a number of bots, but unfortunately none of them are the green dragon ones which were able to pass without any issues.

My guess right now is that the green dragon bots, being Mac OS based, are using a different stdlib from the linux bots and so some different code sequences are reaching the backend.  No idea if this is exposing a bug in my code, a bug in the backends (unlikely given it fails on x86 and ppc), or a bug in the stdlib itself to do with alignment (perhaps unlikely if UB was able to catch this before now).

I don’t have access to an environment on which this crashes right now.  If you or anyone else has time to help me track this down i’d really appreciate it.  Otherwise I might have to wait a little while until I can get something set up which can report it.

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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151118/ba6b0e14/attachment.html>


More information about the llvm-commits mailing list