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

NAKAMURA Takumi via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 18 21:25:52 PST 2015


Seems it causes crash. See;
http://lab.llvm.org:8011/builders/clang-ppc64-elf-linux2/builds/20202
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> 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
> 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
>
> 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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
>
> ==============================================================================
> --- 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/20151119/8229903a/attachment.html>


More information about the llvm-commits mailing list