diff options
| author | Daniel Neilson <dneilson@azul.com> | 2018-02-12 23:06:55 +0000 |
|---|---|---|
| committer | Daniel Neilson <dneilson@azul.com> | 2018-02-12 23:06:55 +0000 |
| commit | 2363da92364eb611c39e9a6238b3060728b4c9ce (patch) | |
| tree | 5c2b107b53edd2a717efb56a109b11e0a46ebfee /llvm | |
| parent | 6b1ae9b854bd186c8dab4784d287f38ce61459d2 (diff) | |
| download | bcm5719-llvm-2363da92364eb611c39e9a6238b3060728b4c9ce.tar.gz bcm5719-llvm-2363da92364eb611c39e9a6238b3060728b4c9ce.zip | |
[InstCombine] Simplify MemTransferInst's source and dest alignments separately
Summary:
This change is part of step five in the series of changes to remove alignment argument from
memcpy/memmove/memset in favour of alignment attributes. In particular, this changes the
InstCombine pass to cease using the deprecated MemoryIntrinsic::getAlignment() method, and
instead we use the separate getSourceAlignment and getDestAlignment APIs to simplify
the source and destination alignment attributes separately.
Steps:
Step 1) Remove alignment parameter and create alignment parameter attributes for
memcpy/memmove/memset. ( rL322965, rC322964, rL322963 )
Step 2) Expand the IRBuilder API to allow creation of memcpy/memmove with differing
source and dest alignments. ( rL323597 )
Step 3) Update Clang to use the new IRBuilder API. ( rC323617 )
Step 4) Update Polly to use the new IRBuilder API. ( rL323618 )
Step 5) Update LLVM passes that create memcpy/memmove calls to use the new IRBuilder API,
and those that use use MemIntrinsicInst::[get|set]Alignment() to use [get|set]DestAlignment()
and [get|set]SourceAlignment() instead. ( rL323886, rL323891, rL324148, rL324273, rL324278,
rL324384, rL324395, rL324402, rL324626, rL324642, rL324653, rL324654, rL324773, rL324774,
rL324781, rL324784, rL324955 )
Step 6) Remove the single-alignment IRBuilder API for memcpy/memmove, and the
MemIntrinsicInst::[get|set]Alignment() methods.
Reference
http://lists.llvm.org/pipermail/llvm-dev/2015-August/089384.html
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312083.html
Reviewers: majnemer, bollu, efriedma
Reviewed By: efriedma
Subscribers: efriedma, llvm-commits
Differential Revision: https://reviews.llvm.org/D42871
llvm-svn: 324960
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 31 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/memcpy-from-global.ll | 2 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/memmove.ll | 2 |
3 files changed, 18 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 2ad37c03376..e2a109cfa03 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -184,14 +184,18 @@ InstCombiner::SimplifyElementUnorderedAtomicMemCpy(AtomicMemCpyInst *AMI) { } Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *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(); - - // FIXME: Check & simplify source & dest alignments separately - if (CopyAlign < MinAlign) { - MI->setAlignment(MinAlign); + unsigned DstAlign = getKnownAlignment(MI->getRawDest(), DL, MI, &AC, &DT); + unsigned CopyDstAlign = MI->getDestAlignment(); + if (CopyDstAlign < DstAlign){ + MI->setDestAlignment(DstAlign); + return MI; + } + + auto* MTI = cast<MemTransferInst>(MI); + unsigned SrcAlign = getKnownAlignment(MTI->getRawSource(), DL, MI, &AC, &DT); + unsigned CopySrcAlign = MTI->getSourceAlignment(); + if (CopySrcAlign < SrcAlign) { + MTI->setSourceAlignment(SrcAlign); return MI; } @@ -235,15 +239,11 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { CopyMD = cast<MDNode>(M->getOperand(2)); } - // If the memcpy/memmove provides better alignment info than we can - // infer, use it. - SrcAlign = std::max(SrcAlign, CopyAlign); - DstAlign = std::max(DstAlign, CopyAlign); - Value *Src = Builder.CreateBitCast(MI->getArgOperand(1), NewSrcPtrTy); Value *Dest = Builder.CreateBitCast(MI->getArgOperand(0), NewDstPtrTy); LoadInst *L = Builder.CreateLoad(Src, MI->isVolatile()); - L->setAlignment(SrcAlign); + // Alignment from the mem intrinsic will be better, so use it. + L->setAlignment(CopySrcAlign); if (CopyMD) L->setMetadata(LLVMContext::MD_tbaa, CopyMD); MDNode *LoopMemParallelMD = @@ -252,7 +252,8 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { L->setMetadata(LLVMContext::MD_mem_parallel_loop_access, LoopMemParallelMD); StoreInst *S = Builder.CreateStore(L, Dest, MI->isVolatile()); - S->setAlignment(DstAlign); + // Alignment from the mem intrinsic will be better, so use it. + S->setAlignment(CopyDstAlign); if (CopyMD) S->setMetadata(LLVMContext::MD_tbaa, CopyMD); if (LoopMemParallelMD) diff --git a/llvm/test/Transforms/InstCombine/memcpy-from-global.ll b/llvm/test/Transforms/InstCombine/memcpy-from-global.ll index ce1aa2aba30..2aff969891b 100644 --- a/llvm/test/Transforms/InstCombine/memcpy-from-global.ll +++ b/llvm/test/Transforms/InstCombine/memcpy-from-global.ll @@ -60,7 +60,7 @@ define void @test2() { ; CHECK-NEXT: getelementptr inbounds [124 x i8], [124 x i8]* ; use @G instead of %A -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 %{{.*}}, i8* align 8 getelementptr inbounds (%T, %T* @G, i64 0, i32 0) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 %{{.*}}, i8* align 16 getelementptr inbounds (%T, %T* @G, i64 0, i32 0) call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %a, i8* align 4 bitcast (%T* @G to i8*), i64 124, i1 false) call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %b, i8* align 4 %a, i64 124, i1 false) call void @bar(i8* %b) diff --git a/llvm/test/Transforms/InstCombine/memmove.ll b/llvm/test/Transforms/InstCombine/memmove.ll index 2df88f64410..18e0c634636 100644 --- a/llvm/test/Transforms/InstCombine/memmove.ll +++ b/llvm/test/Transforms/InstCombine/memmove.ll @@ -17,7 +17,7 @@ define void @test1(i8* %A, i8* %B, i32 %N) { define void @test2(i8* %A, i32 %N) { ;; dest can't alias source since we can't write to source! ;; CHECK-LABEL: test2 - ;; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %A, i8* align 1 getelementptr inbounds ([33 x i8], [33 x i8]* @S, i{{32|64}} 0, i{{32|64}} 0), i32 %N, i1 false) + ;; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %A, i8* align 16 getelementptr inbounds ([33 x i8], [33 x i8]* @S, i{{32|64}} 0, i{{32|64}} 0), i32 %N, i1 false) ;; CHECK-NEXT: ret void call void @llvm.memmove.p0i8.p0i8.i32(i8* %A, i8* getelementptr inbounds ([33 x i8], [33 x i8]* @S, i32 0, i32 0), i32 %N, i1 false) ret void |

