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