• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -S -early-cse -earlycse-debug-hash | FileCheck %s --check-prefix=CHECK-NOMEMSSA
2; RUN: opt < %s -S -basic-aa -early-cse-memssa | FileCheck %s
3; RUN: opt < %s -S -passes='early-cse' | FileCheck %s --check-prefix=CHECK-NOMEMSSA
4; RUN: opt < %s -S -aa-pipeline=basic-aa -passes='early-cse-memssa' | FileCheck %s
5
6@G1 = global i32 zeroinitializer
7@G2 = global i32 zeroinitializer
8@G3 = global i32 zeroinitializer
9
10;; Simple load value numbering across non-clobbering store.
11; CHECK-LABEL: @test1(
12; CHECK-NOMEMSSA-LABEL: @test1(
13define i32 @test1() {
14  %V1 = load i32, i32* @G1
15  store i32 0, i32* @G2
16  %V2 = load i32, i32* @G1
17  ; CHECK-NOMEMSSA: sub i32 %V1, %V2
18  %Diff = sub i32 %V1, %V2
19  ret i32 %Diff
20  ; CHECK: ret i32 0
21}
22
23;; Simple dead store elimination across non-clobbering store.
24; CHECK-LABEL: @test2(
25; CHECK-NOMEMSSA-LABEL: @test2(
26define void @test2() {
27entry:
28  %V1 = load i32, i32* @G1
29  ; CHECK: store i32 0, i32* @G2
30  store i32 0, i32* @G2
31  ; CHECK-NOT: store
32  ; CHECK-NOMEMSSA: store i32 %V1, i32* @G1
33  store i32 %V1, i32* @G1
34  ret void
35}
36
37;; Check that memoryphi optimization happens during EarlyCSE, enabling
38;; more load CSE opportunities.
39; CHECK-LABEL: @test_memphiopt(
40; CHECK-NOMEMSSA-LABEL: @test_memphiopt(
41define void @test_memphiopt(i1 %c, i32* %p) {
42; CHECK-LABEL: entry:
43; CHECK-NOMEMSSA-LABEL: entry:
44entry:
45; CHECK: load
46; CHECK-NOMEMSSA: load
47  %v1 = load i32, i32* @G1
48  br i1 %c, label %then, label %end
49
50; CHECK-LABEL: then:
51; CHECK-NOMEMSSA-LABEL: then:
52then:
53; CHECK: load
54; CHECK-NOMEMSSA: load
55  %pv = load i32, i32* %p
56; CHECK-NOT: store
57; CHECK-NOMEMSSA-NOT: store
58  store i32 %pv, i32* %p
59  br label %end
60
61; CHECK-LABEL: end:
62; CHECK-NOMEMSSA-LABEL: end:
63end:
64; CHECK-NOT: load
65; CHECK-NOMEMSSA: load
66  %v2 = load i32, i32* @G1
67  %sum = add i32 %v1, %v2
68  store i32 %sum, i32* @G2
69  ret void
70}
71
72
73;; Check that MemoryPhi optimization and MemoryUse re-optimization
74;; happens during EarlyCSE, enabling more load CSE opportunities.
75; CHECK-LABEL: @test_memphiopt2(
76; CHECK-NOMEMSSA-LABEL: @test_memphiopt2(
77define void @test_memphiopt2(i1 %c, i32* %p) {
78; CHECK-LABEL: entry:
79; CHECK-NOMEMSSA-LABEL: entry:
80entry:
81; CHECK: load
82; CHECK-NOMEMSSA: load
83  %v1 = load i32, i32* @G1
84; CHECK: store
85; CHECK-NOMEMSSA: store
86  store i32 %v1, i32* @G2
87  br i1 %c, label %then, label %end
88
89; CHECK-LABEL: then:
90; CHECK-NOMEMSSA-LABEL: then:
91then:
92; CHECK: load
93; CHECK-NOMEMSSA: load
94  %pv = load i32, i32* %p
95; CHECK-NOT: store
96; CHECK-NOMEMSSA-NOT: store
97  store i32 %pv, i32* %p
98  br label %end
99
100; CHECK-LABEL: end:
101; CHECK-NOMEMSSA-LABEL: end:
102end:
103; CHECK-NOT: load
104; CHECK-NOMEMSSA: load
105  %v2 = load i32, i32* @G1
106  store i32 %v2, i32* @G3
107  ret void
108}
109
110;; Check that we respect lifetime.start/lifetime.end intrinsics when deleting
111;; stores that, without the lifetime calls, would be writebacks.
112; CHECK-LABEL: @test_writeback_lifetimes(
113; CHECK-NOMEMSSA-LABEL: @test_writeback_lifetimes(
114define void @test_writeback_lifetimes(i32* %p) {
115entry:
116  %q = getelementptr i32, i32* %p, i64 1
117  %pv = load i32, i32* %p
118  %qv = load i32, i32* %q
119  call void @llvm.lifetime.end.p0i8(i64 8, i32* %p)
120  call void @llvm.lifetime.start.p0i8(i64 8, i32* %p)
121  ; CHECK: store i32 %pv
122  ; CHECK-NOMEMSSA-LABEL: store i32 %pv
123  store i32 %pv, i32* %p
124  ; CHECK: store i32 %qv, i32* %q
125  ; CHECK-NOMEMSSA-LABEL: store i32 %qv, i32* %q
126  store i32 %qv, i32* %q
127  ret void
128}
129
130;; Check that we respect lifetime.start/lifetime.end intrinsics when deleting
131;; stores that, without the lifetime calls, would be writebacks.
132; CHECK-LABEL: @test_writeback_lifetimes_multi_arg(
133; CHECK-NOMEMSSA-LABEL: @test_writeback_lifetimes_multi_arg(
134define void @test_writeback_lifetimes_multi_arg(i32* %p, i32* %q) {
135entry:
136  %pv = load i32, i32* %p
137  %qv = load i32, i32* %q
138  call void @llvm.lifetime.end.p0i8(i64 8, i32* %p)
139  call void @llvm.lifetime.start.p0i8(i64 8, i32* %p)
140  ; CHECK: store i32 %pv
141  ; CHECK-NOMEMSSA-LABEL: store i32 %pv
142  store i32 %pv, i32* %p
143  ; CHECK: store i32 %qv, i32* %q
144  ; CHECK-NOMEMSSA-LABEL: store i32 %qv, i32* %q
145  store i32 %qv, i32* %q
146  ret void
147}
148
149declare void @llvm.lifetime.end.p0i8(i64, i32*)
150declare void @llvm.lifetime.start.p0i8(i64, i32*)
151