• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; 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
6%S = type { i8*, i8, i32 }
7
8define void @copy(%S* %src, %S* %dst) {
9; CHECK-LABEL: copy
10; CHECK-NOT: load
11; 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
20; CHECK-NOT: load
21; 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
30; CHECK-NOT: load
31; 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
38define void @destroysrc(%S* %src, %S* %dst) {
39; CHECK-LABEL: destroysrc
40; 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
44  %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
54; CHECK-NEXT: call void @llvm.memset.p0i8.i64
55; 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
62define 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}
75
76; 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
84  %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}
90
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}
111