1 ; RUN: opt < %s -S -early-cse | FileCheck %s --check-prefix=CHECK-NOMEMSSA
2 ; RUN: opt < %s -S -basicaa -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
6 @G1 = global i32 zeroinitializer
7 @G2 = global i32 zeroinitializer
8 @G3 = global i32 zeroinitializer
10 ;; Simple load value numbering across non-clobbering store.
11 ; CHECK-LABEL: @test1(
12 ; CHECK-NOMEMSSA-LABEL: @test1(
14 %V1 = load i32, i32* @G1
16 %V2 = load i32, i32* @G1
17 ; CHECK-NOMEMSSA: sub i32 %V1, %V2
18 %Diff = sub i32 %V1, %V2
23 ;; Simple dead store elimination across non-clobbering store.
24 ; CHECK-LABEL: @test2(
25 ; CHECK-NOMEMSSA-LABEL: @test2(
26 define void @test2() {
28 %V1 = load i32, i32* @G1
29 ; CHECK: store i32 0, i32* @G2
32 ; CHECK-NOMEMSSA: store i32 %V1, i32* @G1
33 store i32 %V1, i32* @G1
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(
41 define void @test_memphiopt(i1 %c, i32* %p) {
43 ; CHECK-NOMEMSSA-LABEL: entry:
46 ; CHECK-NOMEMSSA: load
47 %v1 = load i32, i32* @G1
48 br i1 %c, label %then, label %end
51 ; CHECK-NOMEMSSA-LABEL: then:
54 ; CHECK-NOMEMSSA: load
55 %pv = load i32, i32* %p
57 ; CHECK-NOMEMSSA-NOT: store
58 store i32 %pv, i32* %p
62 ; CHECK-NOMEMSSA-LABEL: end:
65 ; CHECK-NOMEMSSA: load
66 %v2 = load i32, i32* @G1
67 %sum = add i32 %v1, %v2
68 store i32 %sum, i32* @G2
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(
77 define void @test_memphiopt2(i1 %c, i32* %p) {
79 ; CHECK-NOMEMSSA-LABEL: entry:
82 ; CHECK-NOMEMSSA: load
83 %v1 = load i32, i32* @G1
85 ; CHECK-NOMEMSSA: store
86 store i32 %v1, i32* @G2
87 br i1 %c, label %then, label %end
90 ; CHECK-NOMEMSSA-LABEL: then:
93 ; CHECK-NOMEMSSA: load
94 %pv = load i32, i32* %p
96 ; CHECK-NOMEMSSA-NOT: store
97 store i32 %pv, i32* %p
101 ; CHECK-NOMEMSSA-LABEL: end:
104 ; CHECK-NOMEMSSA: load
105 %v2 = load i32, i32* @G1
106 store i32 %v2, i32* @G3
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(
114 define void @test_writeback_lifetimes(i32* %p) {
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
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(
134 define void @test_writeback_lifetimes_multi_arg(i32* %p, i32* %q) {
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
149 declare void @llvm.lifetime.end.p0i8(i64, i32*)
150 declare void @llvm.lifetime.start.p0i8(i64, i32*)