xref: /llvm-project/llvm/test/Transforms/EarlyCSE/replace-calls-def-attrs.ll (revision b98c405f954f9ef6150c655f6ffc68e377d2ac84)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5
2; RUN: opt -S -passes=early-cse  < %s | FileCheck %s
3
4declare i8 @baz(i8, i8)
5declare i8 @baz_side_effects(i8, i8)
6declare i8 @buz(i8, i8)
7
8declare ptr @baz.ptr(i8, i8)
9declare i8 @buz.ptr(ptr, ptr)
10
11declare float @baz.fp(float, float)
12declare i8 @buz.fp(float, float)
13define i8 @same_parent_combine_diff_attrs(i8 %x, i8 %y) {
14; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs(
15; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
16; CHECK-NEXT:    [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0:[0-9]+]]
17; CHECK-NEXT:    [[R:%.*]] = call i8 @buz(i8 [[C1]], i8 [[C1]])
18; CHECK-NEXT:    ret i8 [[R]]
19;
20  %c1 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone
21  %c0 = call i8 @baz(i8 %x, i8 noundef %y) readnone
22  %r = call i8 @buz(i8 %c0, i8 %c1)
23  ret i8 %r
24
25}
26
27define i8 @same_parent_combine_diff_attrs_needs_intersect(i8 %x, i8 %y) {
28; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_needs_intersect(
29; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
30; CHECK-NEXT:    [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]]
31; CHECK-NEXT:    [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr [[C1]])
32; CHECK-NEXT:    ret i8 [[R]]
33;
34  %c1 = call nonnull ptr @baz.ptr(i8 noundef %x, i8 noundef %y) readnone
35  %c0 = call ptr @baz.ptr(i8 %x, i8 noundef %y) readnone
36  %r = call i8 @buz.ptr(ptr %c0, ptr %c1)
37  ret i8 %r
38
39}
40
41define i8 @same_parent_combine_diff_attrs_fmf(float %x, float %y) {
42; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fmf(
43; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
44; CHECK-NEXT:    [[C1:%.*]] = call nnan float @baz.fp(float [[X]], float noundef [[Y]]) #[[ATTR1:[0-9]+]]
45; CHECK-NEXT:    [[R:%.*]] = call i8 @buz.fp(float [[C1]], float [[C1]])
46; CHECK-NEXT:    ret i8 [[R]]
47;
48  %c1 = call nnan nsz float @baz.fp(float noundef %x, float noundef %y) readonly
49  %c0 = call nnan float @baz.fp(float %x, float noundef %y) readonly
50  %r = call i8 @buz.fp(float %c0, float %c1)
51  ret i8 %r
52
53}
54
55define i8 @same_parent_combine_diff_attrs_fmf2(float %x, float %y) {
56; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fmf2(
57; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
58; CHECK-NEXT:    [[C1:%.*]] = call nnan float @baz.fp(float [[X]], float noundef [[Y]]) #[[ATTR0]]
59; CHECK-NEXT:    [[R:%.*]] = call i8 @buz.fp(float [[C1]], float [[C1]])
60; CHECK-NEXT:    ret i8 [[R]]
61;
62  %c1 = call nnan float @baz.fp(float noundef %x, float noundef %y) readnone
63  %c0 = call nnan nsz float @baz.fp(float %x, float noundef %y) readnone
64  %r = call i8 @buz.fp(float %c0, float %c1)
65  ret i8 %r
66
67}
68
69define i8 @same_parent_combine_diff_attrs_needs_intersect2(i8 %x, i8 %y) {
70; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_needs_intersect2(
71; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
72; CHECK-NEXT:    [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]]
73; CHECK-NEXT:    [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr [[C1]])
74; CHECK-NEXT:    ret i8 [[R]]
75;
76  %c1 = call nonnull ptr @baz.ptr(i8 noundef %x, i8 noundef %y) readonly
77  %c0 = call ptr @baz.ptr(i8 %x, i8 noundef %y) readonly
78  %r = call i8 @buz.ptr(ptr %c0, ptr %c1)
79  ret i8 %r
80
81}
82
83define i8 @same_parent_combine_diff_attrs_really_needs_intersect(i8 %x, i8 %y) {
84; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_really_needs_intersect(
85; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
86; CHECK-NEXT:    [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]]
87; CHECK-NEXT:    [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr noundef [[C1]])
88; CHECK-NEXT:    ret i8 [[R]]
89;
90  %c1 = call nonnull ptr @baz.ptr(i8 noundef %x, i8 noundef %y) readonly
91  %c0 = call ptr @baz.ptr(i8 %x, i8 noundef %y) readonly
92  %r = call i8 @buz.ptr(ptr %c0, ptr noundef %c1)
93  ret i8 %r
94
95}
96
97define i8 @same_parent_combine_diff_attrs_fail_side_effects(i8 %x, i8 %y) {
98; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fail_side_effects(
99; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
100; CHECK-NEXT:    [[C1:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]])
101; CHECK-NEXT:    [[C0:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]])
102; CHECK-NEXT:    [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
103; CHECK-NEXT:    ret i8 [[R]]
104;
105  %c1 = call i8 @baz(i8 noundef %x, i8 noundef %y)
106  %c0 = call i8 @baz(i8 %x, i8 noundef %y)
107  %r = call i8 @buz(i8 %c0, i8 %c1)
108  ret i8 %r
109
110}
111
112define i8 @same_parent_combine_diff_attrs_quasi_side_effects2(i8 %x, i8 %y) {
113; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_quasi_side_effects2(
114; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
115; CHECK-NEXT:    [[C1:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR0]]
116; CHECK-NEXT:    [[C0:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]])
117; CHECK-NEXT:    [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
118; CHECK-NEXT:    ret i8 [[R]]
119;
120  %c1 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone
121  %c0 = call i8 @baz(i8 %x, i8 noundef %y)
122  %r = call i8 @buz(i8 %c0, i8 %c1)
123  ret i8 %r
124
125}
126
127define i8 @diff_parent_combine_diff_attrs(i1 %c, i8 %x, i8 %y) {
128; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs(
129; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {
130; CHECK-NEXT:    [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]]
131; CHECK-NEXT:    br i1 [[C]], label %[[T:.*]], label %[[F:.*]]
132; CHECK:       [[T]]:
133; CHECK-NEXT:    [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR1]]
134; CHECK-NEXT:    [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
135; CHECK-NEXT:    ret i8 [[R]]
136; CHECK:       [[F]]:
137; CHECK-NEXT:    [[R2:%.*]] = add i8 [[C1]], 4
138; CHECK-NEXT:    ret i8 [[R2]]
139;
140  %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone
141  br i1 %c, label %T, label %F
142T:
143  %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readonly
144  %r = call i8 @buz(i8 %c0, i8 %c1)
145  ret i8 %r
146F:
147  %r2 = add i8 %c1, 4
148  ret i8 %r2
149}
150
151define i8 @diff_parent_combine_diff_attrs_preserves_return_attrs(i1 %c, i8 %x, i8 %y) {
152; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs_preserves_return_attrs(
153; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {
154; CHECK-NEXT:    [[C1:%.*]] = call nonnull ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]]
155; CHECK-NEXT:    br i1 [[C]], label %[[T:.*]], label %[[F:.*]]
156; CHECK:       [[T]]:
157; CHECK-NEXT:    [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr noundef [[C1]])
158; CHECK-NEXT:    ret i8 [[R]]
159; CHECK:       [[F]]:
160; CHECK-NEXT:    ret i8 9
161;
162  %c1 = call nonnull ptr @baz.ptr(i8 %x, i8 noundef %y) readonly
163  br i1 %c, label %T, label %F
164T:
165  %c0 = call nonnull ptr @baz.ptr(i8 noundef %x, i8 noundef %y) readonly
166  %r = call i8 @buz.ptr(ptr %c0, ptr noundef %c1)
167  ret i8 %r
168F:
169  ret i8 9
170}
171
172define i8 @same_parent_combine_diff_attrs_todo(i8 %x, i8 %y) {
173; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_todo(
174; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
175; CHECK-NEXT:    [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]]
176; CHECK-NEXT:    [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR2:[0-9]+]]
177; CHECK-NEXT:    [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
178; CHECK-NEXT:    ret i8 [[R]]
179;
180  %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone
181  %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone alwaysinline
182  %r = call i8 @buz(i8 %c0, i8 %c1)
183  ret i8 %r
184
185}
186
187define i8 @same_parent_combine_diff_attrs_fail(i8 %x, i8 %y) {
188; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fail(
189; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
190; CHECK-NEXT:    [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]]
191; CHECK-NEXT:    [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR3:[0-9]+]]
192; CHECK-NEXT:    [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
193; CHECK-NEXT:    ret i8 [[R]]
194;
195  %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone
196  %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone strictfp
197  %r = call i8 @buz(i8 %c0, i8 %c1)
198  ret i8 %r
199
200}
201
202define i8 @diff_parent_combine_diff_attrs_todo(i1 %c, i8 %x, i8 %y) {
203; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs_todo(
204; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {
205; CHECK-NEXT:    [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]]
206; CHECK-NEXT:    br i1 [[C]], label %[[T:.*]], label %[[F:.*]]
207; CHECK:       [[T]]:
208; CHECK-NEXT:    [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR4:[0-9]+]]
209; CHECK-NEXT:    [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
210; CHECK-NEXT:    ret i8 [[R]]
211; CHECK:       [[F]]:
212; CHECK-NEXT:    [[R2:%.*]] = add i8 [[C1]], 4
213; CHECK-NEXT:    ret i8 [[R2]]
214;
215  %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone
216  br i1 %c, label %T, label %F
217T:
218  %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone optnone noinline
219  %r = call i8 @buz(i8 %c0, i8 %c1)
220  ret i8 %r
221F:
222  %r2 = add i8 %c1, 4
223  ret i8 %r2
224}
225
226define i8 @diff_parent_combine_diff_attrs_fail(i1 %c, i8 %x, i8 %y) {
227; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs_fail(
228; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {
229; CHECK-NEXT:    [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]]
230; CHECK-NEXT:    br i1 [[C]], label %[[T:.*]], label %[[F:.*]]
231; CHECK:       [[T]]:
232; CHECK-NEXT:    [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR3]]
233; CHECK-NEXT:    [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]])
234; CHECK-NEXT:    ret i8 [[R]]
235; CHECK:       [[F]]:
236; CHECK-NEXT:    [[R2:%.*]] = add i8 [[C1]], 4
237; CHECK-NEXT:    ret i8 [[R2]]
238;
239  %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone
240  br i1 %c, label %T, label %F
241T:
242  %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone strictfp
243  %r = call i8 @buz(i8 %c0, i8 %c1)
244  ret i8 %r
245F:
246  %r2 = add i8 %c1, 4
247  ret i8 %r2
248}
249
250;.
251; CHECK: attributes #[[ATTR0]] = { memory(none) }
252; CHECK: attributes #[[ATTR1]] = { memory(read) }
253; CHECK: attributes #[[ATTR2]] = { alwaysinline memory(none) }
254; CHECK: attributes #[[ATTR3]] = { strictfp memory(none) }
255; CHECK: attributes #[[ATTR4]] = { noinline optnone memory(none) }
256;.
257