diff options
Diffstat (limited to 'llvm/test/Transforms/DeadStoreElimination')
| -rw-r--r-- | llvm/test/Transforms/DeadStoreElimination/simple.ll | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/llvm/test/Transforms/DeadStoreElimination/simple.ll b/llvm/test/Transforms/DeadStoreElimination/simple.ll index 6130fbbf807..604621130e0 100644 --- a/llvm/test/Transforms/DeadStoreElimination/simple.ll +++ b/llvm/test/Transforms/DeadStoreElimination/simple.ll @@ -252,6 +252,9 @@ define void @test17v(i8* %P, i8* %Q) nounwind ssp { ; Do not delete instruction where possible situation is: ; A = B ; A = A +; +; NB! See PR11763 - currently LLVM allows memcpy's source and destination to be +; equal (but not inequal and overlapping). define void @test18(i8* %P, i8* %Q, i8* %R) nounwind ssp { tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) @@ -521,3 +524,51 @@ define void @test35(i32* noalias %p) { store i32 0, i32* %p ret void } + +; We cannot optimize away the first memmove since %P could overlap with %Q. +define void @test36(i8* %P, i8* %Q) { +; CHECK-LABEL: @test36( +; CHECK-NEXT: tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) +; CHECK-NEXT: tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) +; CHECK-NEXT: ret + + tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) + tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) + ret void +} + +define void @test37(i8* %P, i8* %Q, i8* %R) { +; CHECK-LABEL: @test37( +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) +; CHECK-NEXT: tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) +; CHECK-NEXT: ret + + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) + tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) + ret void +} + +; Same caveat about memcpy as in @test18 applies here. +define void @test38(i8* %P, i8* %Q, i8* %R) { +; CHECK-LABEL: @test38( +; CHECK-NEXT: tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) +; CHECK-NEXT: ret + + tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) + ret void +} + +define void @test39(i8* %P, i8* %Q, i8* %R) { +; CHECK-LABEL: @test39( +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 8, i1 false) +; CHECK-NEXT: ret + + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 8, i1 false) + ret void +} + +declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1) |

