xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/sink-cb-diff-attrs.ll (revision e343af777ef51c4496e7fb2689735866bc617897)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2; RUN: opt < %s -passes='simplifycfg<sink-common-insts>' -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3
4declare ptr @foo0()
5declare ptr @foo(ptr %p, i64 %x)
6declare ptr @foo2(ptr %p, ptr %p2, i64 %x)
7declare void @side.effect()
8
9define ptr @test_sink_no_args_oneside(i1 %c) {
10; CHECK-LABEL: define {{[^@]+}}@test_sink_no_args_oneside
11; CHECK-SAME: (i1 [[C:%.*]]) {
12; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[END:%.*]]
13; CHECK:       if:
14; CHECK-NEXT:    call void @side.effect()
15; CHECK-NEXT:    br label [[END]]
16; CHECK:       end:
17; CHECK-NEXT:    [[R2:%.*]] = call ptr @foo0()
18; CHECK-NEXT:    ret ptr [[R2]]
19;
20  br i1 %c, label %if, label %else
21if:
22  call void @side.effect()
23  %r = call ptr @foo0()
24  br label %end
25
26else:
27  %r2 = call ptr @foo0() readonly
28  br label %end
29end:
30  %pr = phi ptr [ %r, %if], [%r2, %else]
31  ret ptr %pr
32}
33
34define ptr @test_sink_no_args_oneside_fail(i1 %c) {
35; CHECK-LABEL: define {{[^@]+}}@test_sink_no_args_oneside_fail
36; CHECK-SAME: (i1 [[C:%.*]]) {
37; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
38; CHECK:       if:
39; CHECK-NEXT:    call void @side.effect()
40; CHECK-NEXT:    [[R:%.*]] = call ptr @foo0()
41; CHECK-NEXT:    br label [[END:%.*]]
42; CHECK:       else:
43; CHECK-NEXT:    [[R2:%.*]] = call ptr @foo0() #[[ATTR0:[0-9]+]]
44; CHECK-NEXT:    br label [[END]]
45; CHECK:       end:
46; CHECK-NEXT:    [[PR:%.*]] = phi ptr [ [[R]], [[IF]] ], [ [[R2]], [[ELSE]] ]
47; CHECK-NEXT:    ret ptr [[PR]]
48;
49  br i1 %c, label %if, label %else
50if:
51  call void @side.effect()
52  %r = call ptr @foo0()
53  br label %end
54
55else:
56  %r2 = call ptr @foo0() readonly alwaysinline
57  br label %end
58end:
59  %pr = phi ptr [ %r, %if], [%r2, %else]
60  ret ptr %pr
61}
62
63define ptr @test_sink_int_attrs(i1 %c, ptr %p, ptr %p2, i64 %x) {
64; CHECK-LABEL: define {{[^@]+}}@test_sink_int_attrs
65; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P2:%.*]], i64 [[X:%.*]]) {
66; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[END:%.*]]
67; CHECK:       if:
68; CHECK-NEXT:    call void @side.effect()
69; CHECK-NEXT:    br label [[END]]
70; CHECK:       end:
71; CHECK-NEXT:    [[R2:%.*]] = call ptr @foo2(ptr align 32 dereferenceable_or_null(100) [[P]], ptr align 32 dereferenceable(50) [[P2]], i64 range(i64 10, 100000) [[X]]) #[[ATTR1:[0-9]+]]
72; CHECK-NEXT:    ret ptr [[R2]]
73;
74  br i1 %c, label %if, label %else
75if:
76  call void @side.effect()
77  %r = call ptr @foo2(ptr align 64 dereferenceable_or_null(100) %p, ptr dereferenceable(50) align 64 %p2, i64 range(i64 10, 1000) %x) memory(read)
78  br label %end
79
80else:
81  %r2 = call ptr @foo2(ptr align 32 dereferenceable_or_null(200) %p, ptr dereferenceable(100) align 32 %p2, i64 range(i64 10000, 100000) %x) memory(write)
82  br label %end
83end:
84  %pr = phi ptr [ %r, %if], [%r2, %else]
85  ret ptr %pr
86}
87
88define ptr @test_sink_int_attrs2(i1 %c, ptr %p, i64 %x) {
89; CHECK-LABEL: define {{[^@]+}}@test_sink_int_attrs2
90; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) {
91; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[END:%.*]]
92; CHECK:       if:
93; CHECK-NEXT:    call void @side.effect()
94; CHECK-NEXT:    br label [[END]]
95; CHECK:       end:
96; CHECK-NEXT:    [[R2:%.*]] = call ptr @foo(ptr dereferenceable(50) [[P]], i64 range(i64 10, 1000) [[X]]) #[[ATTR2:[0-9]+]]
97; CHECK-NEXT:    ret ptr [[R2]]
98;
99  br i1 %c, label %if, label %else
100if:
101  call void @side.effect()
102  %r = call ptr @foo(ptr dereferenceable(50) %p, i64 range(i64 10, 1000) %x) memory(read)
103  br label %end
104
105else:
106  %r2 = call ptr @foo(ptr dereferenceable(100) align 32 dereferenceable_or_null(200) %p, i64 range(i64 11, 100) %x) memory(none)
107  br label %end
108end:
109  %pr = phi ptr [ %r, %if], [%r2, %else]
110  ret ptr %pr
111}
112
113define ptr @test_sink_bool_attrs2(i1 %c, ptr %p, i64 %x) {
114; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs2
115; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) {
116; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[END:%.*]]
117; CHECK:       if:
118; CHECK-NEXT:    call void @side.effect()
119; CHECK-NEXT:    br label [[END]]
120; CHECK:       end:
121; CHECK-NEXT:    [[R2:%.*]] = call noundef ptr @foo(ptr nonnull [[P]], i64 noundef [[X]]) #[[ATTR3:[0-9]+]]
122; CHECK-NEXT:    ret ptr [[R2]]
123;
124  br i1 %c, label %if, label %else
125if:
126  call void @side.effect()
127  %r = call noundef ptr @foo(ptr readnone nonnull noundef %p, i64 noundef %x) cold mustprogress nocallback nofree nosync willreturn
128  br label %end
129
130else:
131  %r2 = call noundef nonnull ptr @foo(ptr readonly nonnull %p, i64 noundef %x) mustprogress nocallback nofree willreturn
132  br label %end
133end:
134  %pr = phi ptr [ %r, %if], [%r2, %else]
135  ret ptr %pr
136}
137
138define ptr @test_sink_bool_attrs3(i1 %c, ptr %p, i64 %x) {
139; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs3
140; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) {
141; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[END:%.*]]
142; CHECK:       if:
143; CHECK-NEXT:    call void @side.effect()
144; CHECK-NEXT:    br label [[END]]
145; CHECK:       end:
146; CHECK-NEXT:    [[R2:%.*]] = call nonnull ptr @foo(ptr [[P]], i64 noundef [[X]]) #[[ATTR4:[0-9]+]]
147; CHECK-NEXT:    ret ptr [[R2]]
148;
149  br i1 %c, label %if, label %else
150if:
151  call void @side.effect()
152  %r = call nonnull ptr @foo(ptr readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn alwaysinline
153  br label %end
154
155else:
156  %r2 = call noundef nonnull ptr @foo(ptr writeonly nonnull %p, i64 noundef %x) nosync willreturn alwaysinline
157  br label %end
158end:
159  %pr = phi ptr [ %r, %if], [%r2, %else]
160  ret ptr %pr
161}
162
163define ptr @test_sink_bool_attrs_fail_non_droppable(i1 %c, ptr %p, i64 %x) {
164; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs_fail_non_droppable
165; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) {
166; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
167; CHECK:       if:
168; CHECK-NEXT:    call void @side.effect()
169; CHECK-NEXT:    [[R:%.*]] = call nonnull ptr @foo(ptr noundef readonly [[P]], i64 noundef [[X]]) #[[ATTR5:[0-9]+]]
170; CHECK-NEXT:    br label [[END:%.*]]
171; CHECK:       else:
172; CHECK-NEXT:    [[R2:%.*]] = call noundef nonnull ptr @foo(ptr nonnull writeonly [[P]], i64 noundef [[X]]) #[[ATTR6:[0-9]+]]
173; CHECK-NEXT:    br label [[END]]
174; CHECK:       end:
175; CHECK-NEXT:    [[PR:%.*]] = phi ptr [ [[R]], [[IF]] ], [ [[R2]], [[ELSE]] ]
176; CHECK-NEXT:    ret ptr [[PR]]
177;
178  br i1 %c, label %if, label %else
179if:
180  call void @side.effect()
181  %r = call nonnull ptr @foo(ptr readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn alwaysinline
182  br label %end
183
184else:
185  %r2 = call noundef nonnull ptr @foo(ptr writeonly nonnull %p, i64 noundef %x) nosync willreturn
186  br label %end
187end:
188  %pr = phi ptr [ %r, %if], [%r2, %else]
189  ret ptr %pr
190}
191
192define ptr @test_sink_bool_attrs_fail_non_droppable2(i1 %c, ptr %p, i64 %x) {
193; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs_fail_non_droppable2
194; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) {
195; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
196; CHECK:       if:
197; CHECK-NEXT:    call void @side.effect()
198; CHECK-NEXT:    [[R:%.*]] = call nonnull ptr @foo(ptr noundef readonly [[P]], i64 noundef [[X]]) #[[ATTR7:[0-9]+]]
199; CHECK-NEXT:    br label [[END:%.*]]
200; CHECK:       else:
201; CHECK-NEXT:    [[R2:%.*]] = call noundef nonnull ptr @foo(ptr nonnull writeonly byval(i64) [[P]], i64 noundef [[X]]) #[[ATTR6]]
202; CHECK-NEXT:    br label [[END]]
203; CHECK:       end:
204; CHECK-NEXT:    [[PR:%.*]] = phi ptr [ [[R]], [[IF]] ], [ [[R2]], [[ELSE]] ]
205; CHECK-NEXT:    ret ptr [[PR]]
206;
207  br i1 %c, label %if, label %else
208if:
209  call void @side.effect()
210  %r = call nonnull ptr @foo(ptr readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn
211  br label %end
212
213else:
214  %r2 = call noundef nonnull ptr @foo(ptr byval(i64) writeonly nonnull %p, i64 noundef %x) nosync willreturn
215  br label %end
216end:
217  %pr = phi ptr [ %r, %if], [%r2, %else]
218  ret ptr %pr
219}
220
221define ptr @test_sink_bool_attrs_fail_non_droppable3(i1 %c, ptr %p, i64 %x) {
222; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs_fail_non_droppable3
223; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) {
224; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
225; CHECK:       if:
226; CHECK-NEXT:    call void @side.effect()
227; CHECK-NEXT:    [[R:%.*]] = call nonnull ptr @foo(ptr noundef readonly byval(i32) [[P]], i64 noundef [[X]]) #[[ATTR7]]
228; CHECK-NEXT:    br label [[END:%.*]]
229; CHECK:       else:
230; CHECK-NEXT:    [[R2:%.*]] = call noundef nonnull ptr @foo(ptr nonnull writeonly byval(i64) [[P]], i64 noundef [[X]]) #[[ATTR8:[0-9]+]]
231; CHECK-NEXT:    br label [[END]]
232; CHECK:       end:
233; CHECK-NEXT:    [[PR:%.*]] = phi ptr [ [[R]], [[IF]] ], [ [[R2]], [[ELSE]] ]
234; CHECK-NEXT:    ret ptr [[PR]]
235;
236  br i1 %c, label %if, label %else
237if:
238  call void @side.effect()
239  %r = call nonnull ptr @foo(ptr byval(i32) readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn
240  br label %end
241
242else:
243  %r2 = call noundef nonnull ptr @foo(ptr byval(i64) writeonly nonnull %p, i64 noundef %x) nosync
244  br label %end
245end:
246  %pr = phi ptr [ %r, %if], [%r2, %else]
247  ret ptr %pr
248}
249
250define ptr @test_sink_bool_attrs4(i1 %c, ptr %p, i64 %x) {
251; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs4
252; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) {
253; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[END:%.*]]
254; CHECK:       if:
255; CHECK-NEXT:    call void @side.effect()
256; CHECK-NEXT:    br label [[END]]
257; CHECK:       end:
258; CHECK-NEXT:    [[R2:%.*]] = call nonnull ptr @foo(ptr byval(i64) [[P]], i64 noundef [[X]]) #[[ATTR8]]
259; CHECK-NEXT:    ret ptr [[R2]]
260;
261  br i1 %c, label %if, label %else
262if:
263  call void @side.effect()
264  %r = call nonnull ptr @foo(ptr byval(i64) readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn
265  br label %end
266
267else:
268  %r2 = call noundef nonnull ptr @foo(ptr byval(i64) writeonly nonnull %p, i64 noundef %x) nosync
269  br label %end
270end:
271  %pr = phi ptr [ %r, %if], [%r2, %else]
272  ret ptr %pr
273}
274
275;.
276; CHECK: attributes #[[ATTR0]] = { alwaysinline memory(read) }
277; CHECK: attributes #[[ATTR1]] = { memory(readwrite) }
278; CHECK: attributes #[[ATTR2]] = { memory(read) }
279; CHECK: attributes #[[ATTR3]] = { mustprogress nocallback nofree willreturn }
280; CHECK: attributes #[[ATTR4]] = { alwaysinline nosync willreturn }
281; CHECK: attributes #[[ATTR5]] = { alwaysinline cold nocallback nofree nosync willreturn }
282; CHECK: attributes #[[ATTR6]] = { nosync willreturn }
283; CHECK: attributes #[[ATTR7]] = { cold nocallback nofree nosync willreturn }
284; CHECK: attributes #[[ATTR8]] = { nosync }
285;.
286