blob: 0215431ac3503f947577ba91d364b7cdea1bf600 [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
Amaury Sechetbdb261b2016-03-14 22:52:27 +000076; If the store address is computed ina complex manner, make
77; sure we lift the computation as well if needed and possible.
78define void @addrproducer(%S* %src, %S* %dst) {
79; CHECK-LABEL: addrproducer
80; CHECK: %dst2 = getelementptr %S, %S* %dst, i64 1
81; CHECK: call void @llvm.memmove.p0i8.p0i8.i64
82; CHECK-NEXT: store %S undef, %S* %dst
83; CHECK-NEXT: ret void
Mehdi Amini05350032016-01-06 23:50:22 +000084 %1 = load %S, %S* %src
85 store %S undef, %S* %dst
86 %dst2 = getelementptr %S , %S* %dst, i64 1
87 store %S %1, %S* %dst2
88 ret void
89}
Amaury Sechetbdb261b2016-03-14 22:52:27 +000090
91define void @aliasaddrproducer(%S* %src, %S* %dst, i32* %dstidptr) {
92; CHECK-LABEL: aliasaddrproducer
93 %1 = load %S, %S* %src
94 store %S undef, %S* %dst
95 %dstindex = load i32, i32* %dstidptr
96 %dst2 = getelementptr %S , %S* %dst, i32 %dstindex
97 store %S %1, %S* %dst2
98 ret void
99}
100
101define void @noaliasaddrproducer(%S* %src, %S* noalias %dst, i32* noalias %dstidptr) {
102; CHECK-LABEL: noaliasaddrproducer
103 %1 = load %S, %S* %src
104 store %S undef, %S* %src
105 %2 = load i32, i32* %dstidptr
106 %dstindex = or i32 %2, 1
107 %dst2 = getelementptr %S , %S* %dst, i32 %dstindex
108 store %S %1, %S* %dst2
109 ret void
110}