blob: c8a126848b0687e11e8aa6933481d1388333be39 [file] [log] [blame]
Amaury Secheta0c242c2016-01-05 20:17:48 +00001; RUN: opt -memcpyopt -S < %s | FileCheck %s
2
3target datalayout = "e-i64:64-f80:128-n8:16:32:64"
4target triple = "x86_64-unknown-linux-gnu"
5
Amaury Sechet3235c082016-01-06 19:47:24 +00006%S = type { i8*, i8, i32 }
Amaury Secheta0c242c2016-01-05 20:17:48 +00007
8define void @copy(%S* %src, %S* %dst) {
9; CHECK-LABEL: copy
Amaury Sechetd3b2c0f2016-01-06 09:30:39 +000010; CHECK-NOT: load
Amaury Secheta0c242c2016-01-05 20:17:48 +000011; CHECK: call void @llvm.memmove.p0i8.p0i8.i64
12; CHECK-NEXT: ret void
13 %1 = load %S, %S* %src
14 store %S %1, %S* %dst
15 ret void
16}
17
18define void @noaliassrc(%S* noalias %src, %S* %dst) {
19; CHECK-LABEL: noaliassrc
Amaury Sechetd3b2c0f2016-01-06 09:30:39 +000020; CHECK-NOT: load
Amaury Secheta0c242c2016-01-05 20:17:48 +000021; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
22; CHECK-NEXT: ret void
23 %1 = load %S, %S* %src
24 store %S %1, %S* %dst
25 ret void
26}
27
28define void @noaliasdst(%S* %src, %S* noalias %dst) {
29; CHECK-LABEL: noaliasdst
Amaury Sechetd3b2c0f2016-01-06 09:30:39 +000030; CHECK-NOT: load
Amaury Secheta0c242c2016-01-05 20:17:48 +000031; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
32; CHECK-NEXT: ret void
33 %1 = load %S, %S* %src
34 store %S %1, %S* %dst
35 ret void
36}
37
Amaury Sechetd3b2c0f2016-01-06 09:30:39 +000038define void @destroysrc(%S* %src, %S* %dst) {
39; CHECK-LABEL: destroysrc
Amaury Sechet3235c082016-01-06 19:47:24 +000040; CHECK: load %S, %S* %src
41; CHECK: call void @llvm.memset.p0i8.i64
42; CHECK-NEXT: store %S %1, %S* %dst
43; CHECK-NEXT: ret void
Amaury Sechetd3b2c0f2016-01-06 09:30:39 +000044 %1 = load %S, %S* %src
45 store %S zeroinitializer, %S* %src
46 store %S %1, %S* %dst
47 ret void
48}
49
50define void @destroynoaliassrc(%S* noalias %src, %S* %dst) {
51; CHECK-LABEL: destroynoaliassrc
52; CHECK-NOT: load
53; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
Amaury Sechet3235c082016-01-06 19:47:24 +000054; CHECK-NEXT: call void @llvm.memset.p0i8.i64
Amaury Sechetd3b2c0f2016-01-06 09:30:39 +000055; CHECK-NEXT: ret void
56 %1 = load %S, %S* %src
57 store %S zeroinitializer, %S* %src
58 store %S %1, %S* %dst
59 ret void
60}
61
Amaury Secheta0c242c2016-01-05 20:17:48 +000062define void @copyalias(%S* %src, %S* %dst) {
63; CHECK-LABEL: copyalias
64; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %S, %S* %src
65; CHECK-NOT: load
66; CHECK: call void @llvm.memmove.p0i8.p0i8.i64
67; CHECK-NEXT: store %S [[LOAD]], %S* %dst
68; CHECK-NEXT: ret void
69 %1 = load %S, %S* %src
70 %2 = load %S, %S* %src
71 store %S %1, %S* %dst
72 store %S %2, %S* %dst
73 ret void
74}
Mehdi Amini05350032016-01-06 23:50:22 +000075
76
77; The GEP is present after the aliasing store, preventing to move the memcpy before
78; (without further analysis/transformation)
79define void @copyaliaswithproducerinbetween(%S* %src, %S* %dst) {
80; CHECK-LABEL: copyalias
81; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %S, %S* %src
82; CHECK-NOT: call
83 %1 = load %S, %S* %src
84 store %S undef, %S* %dst
85 %dst2 = getelementptr %S , %S* %dst, i64 1
86 store %S %1, %S* %dst2
87 ret void
88}