• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -S -basicaa -licm | FileCheck %s
2; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
3
4; Check that we can hoist unordered loads
5define i32 @test1(i32* nocapture %y) nounwind uwtable ssp {
6entry:
7  br label %loop
8
9loop:
10  %i = phi i32 [ %inc, %loop ], [ 0, %entry ]
11  %val = load atomic i32, i32* %y unordered, align 4
12  %inc = add nsw i32 %i, 1
13  %exitcond = icmp eq i32 %inc, %val
14  br i1 %exitcond, label %end, label %loop
15
16end:
17  ret i32 %val
18; CHECK-LABEL: define i32 @test1(
19; CHECK: load atomic
20; CHECK-NEXT: br label %loop
21}
22
23; Check that we don't sink/hoist monotonic loads
24; (Strictly speaking, it's not forbidden, but it's supposed to be possible to
25; use monotonic for spinlock-like constructs.)
26define i32 @test2(i32* nocapture %y) nounwind uwtable ssp {
27entry:
28  br label %loop
29
30loop:
31  %val = load atomic i32, i32* %y monotonic, align 4
32  %exitcond = icmp ne i32 %val, 0
33  br i1 %exitcond, label %end, label %loop
34
35end:
36  ret i32 %val
37; CHECK-LABEL: define i32 @test2(
38; CHECK: load atomic
39; CHECK-NEXT: %exitcond = icmp ne
40; CHECK-NEXT: br i1 %exitcond, label %end, label %loop
41}
42
43; Check that we hoist unordered around monotonic.
44; (The noalias shouldn't be necessary in theory, but LICM isn't quite that
45; smart yet.)
46define i32 @test3(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
47entry:
48  br label %loop
49
50loop:
51  %vala = load atomic i32, i32* %y monotonic, align 4
52  %valb = load atomic i32, i32* %x unordered, align 4
53  %exitcond = icmp ne i32 %vala, %valb
54  br i1 %exitcond, label %end, label %loop
55
56end:
57  ret i32 %vala
58; CHECK-LABEL: define i32 @test3(
59; CHECK: load atomic i32, i32* %x unordered
60; CHECK-NEXT: br label %loop
61}
62
63; We can sink an unordered store
64define i32 @test4(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
65entry:
66  br label %loop
67
68loop:
69  %vala = load atomic i32, i32* %y monotonic, align 4
70  store atomic i32 %vala, i32* %x unordered, align 4
71  %exitcond = icmp ne i32 %vala, 0
72  br i1 %exitcond, label %end, label %loop
73
74end:
75  ret i32 %vala
76; CHECK-LABEL: define i32 @test4(
77; CHECK-LABEL: loop:
78; CHECK: load atomic i32, i32* %y monotonic
79; CHECK-NOT: store
80; CHECK-LABEL: end:
81; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %vala
82; CHECK:   store atomic i32 %[[LCSSAPHI]], i32* %x unordered, align 4
83}
84
85; We currently don't handle ordered atomics.
86define i32 @test5(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
87entry:
88  br label %loop
89
90loop:
91  %vala = load atomic i32, i32* %y monotonic, align 4
92  store atomic i32 %vala, i32* %x release, align 4
93  %exitcond = icmp ne i32 %vala, 0
94  br i1 %exitcond, label %end, label %loop
95
96end:
97  ret i32 %vala
98; CHECK-LABEL: define i32 @test5(
99; CHECK: load atomic i32, i32* %y monotonic
100; CHECK-NEXT: store atomic
101}
102
103; We currently don't touch volatiles
104define i32 @test6(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
105entry:
106  br label %loop
107
108loop:
109  %vala = load atomic i32, i32* %y monotonic, align 4
110  store volatile i32 %vala, i32* %x, align 4
111  %exitcond = icmp ne i32 %vala, 0
112  br i1 %exitcond, label %end, label %loop
113
114end:
115  ret i32 %vala
116; CHECK-LABEL: define i32 @test6(
117; CHECK: load atomic i32, i32* %y monotonic
118; CHECK-NEXT: store volatile
119}
120
121; We currently don't touch volatiles
122define i32 @test6b(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
123entry:
124  br label %loop
125
126loop:
127  %vala = load atomic i32, i32* %y monotonic, align 4
128  store atomic volatile i32 %vala, i32* %x unordered, align 4
129  %exitcond = icmp ne i32 %vala, 0
130  br i1 %exitcond, label %end, label %loop
131
132end:
133  ret i32 %vala
134; CHECK-LABEL: define i32 @test6b(
135; CHECK: load atomic i32, i32* %y monotonic
136; CHECK-NEXT: store atomic volatile
137}
138
139; Mixing unorder atomics and normal loads/stores is
140; current unimplemented
141define i32 @test7(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
142entry:
143  br label %loop
144
145loop:
146  store i32 5, i32* %x
147  %vala = load atomic i32, i32* %y monotonic, align 4
148  store atomic i32 %vala, i32* %x unordered, align 4
149  %exitcond = icmp ne i32 %vala, 0
150  br i1 %exitcond, label %end, label %loop
151
152end:
153  ret i32 %vala
154; CHECK-LABEL: define i32 @test7(
155; CHECK: store i32 5, i32* %x
156; CHECK-NEXT: load atomic i32, i32* %y
157; CHECK-NEXT: store atomic i32
158}
159
160; Three provably noalias locations - we can sink normal and unordered, but
161;  not monotonic
162define i32 @test7b(i32* nocapture noalias %x, i32* nocapture %y, i32* noalias nocapture %z) nounwind uwtable ssp {
163entry:
164  br label %loop
165
166loop:
167  store i32 5, i32* %x
168  %vala = load atomic i32, i32* %y monotonic, align 4
169  store atomic i32 %vala, i32* %z unordered, align 4
170  %exitcond = icmp ne i32 %vala, 0
171  br i1 %exitcond, label %end, label %loop
172
173end:
174  ret i32 %vala
175; CHECK-LABEL: define i32 @test7b(
176; CHECK: load atomic i32, i32* %y monotonic
177
178; CHECK-LABEL: end:
179; CHECK: store i32 5, i32* %x
180; CHECK: store atomic i32 %{{.+}}, i32* %z unordered, align 4
181}
182
183
184define i32 @test8(i32* nocapture noalias %x, i32* nocapture %y) {
185entry:
186  br label %loop
187
188loop:
189  %vala = load atomic i32, i32* %y monotonic, align 4
190  store atomic i32 %vala, i32* %x unordered, align 4
191  fence release
192  %exitcond = icmp ne i32 %vala, 0
193  br i1 %exitcond, label %end, label %loop
194
195end:
196  ret i32 %vala
197; CHECK-LABEL: define i32 @test8(
198; CHECK-LABEL: loop:
199; CHECK: load atomic i32, i32* %y monotonic
200; CHECK-NEXT: store atomic
201; CHECK-NEXT: fence
202}
203
204; Exact semantics of monotonic accesses are a bit vague in the C++ spec,
205; for the moment, be conservative and don't touch them.
206define i32 @test9(i32* nocapture noalias %x, i32* nocapture %y) {
207entry:
208  br label %loop
209
210loop:
211  %vala = load atomic i32, i32* %y monotonic, align 4
212  store atomic i32 %vala, i32* %x monotonic, align 4
213  %exitcond = icmp ne i32 %vala, 0
214  br i1 %exitcond, label %end, label %loop
215
216end:
217  ret i32 %vala
218; CHECK-LABEL: define i32 @test9(
219; CHECK-LABEL: loop:
220; CHECK: load atomic i32, i32* %y monotonic
221; CHECK-NEXT:   store atomic i32 %vala, i32* %x monotonic, align 4
222}
223