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
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