1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4 ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
6 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7 target triple = "x86_64-unknown-linux-gnu"
9 define void @fn2(i32* %P, i1 %C) {
11 ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind
12 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2
13 ; IS__TUNIT_OPM-SAME: (i32* nocapture nofree [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
14 ; IS__TUNIT_OPM-NEXT: entry:
15 ; IS__TUNIT_OPM-NEXT: br label [[IF_END:%.*]]
16 ; IS__TUNIT_OPM: for.cond1:
17 ; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
18 ; IS__TUNIT_OPM: if.end:
19 ; IS__TUNIT_OPM-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
20 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
21 ; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]]) #[[ATTR3:[0-9]+]]
22 ; IS__TUNIT_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
23 ; IS__TUNIT_OPM-NEXT: br label [[FOR_COND1]]
24 ; IS__TUNIT_OPM: exit:
25 ; IS__TUNIT_OPM-NEXT: ret void
27 ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind
28 ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2
29 ; IS__TUNIT_NPM-SAME: (i32* nocapture nofree [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
30 ; IS__TUNIT_NPM-NEXT: entry:
31 ; IS__TUNIT_NPM-NEXT: br label [[IF_END:%.*]]
32 ; IS__TUNIT_NPM: for.cond1:
33 ; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
34 ; IS__TUNIT_NPM: if.end:
35 ; IS__TUNIT_NPM-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
36 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
37 ; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
38 ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND1]]
39 ; IS__TUNIT_NPM: exit:
40 ; IS__TUNIT_NPM-NEXT: ret void
42 ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind
43 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn2
44 ; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
45 ; IS__CGSCC_OPM-NEXT: entry:
46 ; IS__CGSCC_OPM-NEXT: br label [[IF_END:%.*]]
47 ; IS__CGSCC_OPM: for.cond1:
48 ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
49 ; IS__CGSCC_OPM: if.end:
50 ; IS__CGSCC_OPM-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
51 ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
52 ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]])
53 ; IS__CGSCC_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
54 ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND1]]
55 ; IS__CGSCC_OPM: exit:
56 ; IS__CGSCC_OPM-NEXT: ret void
58 ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind
59 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn2
60 ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
61 ; IS__CGSCC_NPM-NEXT: entry:
62 ; IS__CGSCC_NPM-NEXT: br label [[IF_END:%.*]]
63 ; IS__CGSCC_NPM: for.cond1:
64 ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
65 ; IS__CGSCC_NPM: if.end:
66 ; IS__CGSCC_NPM-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
67 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
68 ; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
69 ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND1]]
70 ; IS__CGSCC_NPM: exit:
71 ; IS__CGSCC_NPM-NEXT: ret void
76 for.cond1: ; preds = %if.end
77 br i1 %C, label %if.end, label %exit
79 if.end: ; preds = %entry, %for.cond1
80 %e.2 = phi i32* [ %P, %entry ], [ null, %for.cond1 ]
81 %0 = load i32, i32* %e.2, align 4
82 %call = call i32 @fn1(i32 %0)
83 store i32 %call, i32* %P
89 define internal i32 @fn1(i32 %p1) {
90 ; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
91 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn1
92 ; IS__TUNIT_OPM-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
93 ; IS__TUNIT_OPM-NEXT: entry:
94 ; IS__TUNIT_OPM-NEXT: ret i32 [[P1]]
96 ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
97 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn1
98 ; IS__CGSCC_OPM-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
99 ; IS__CGSCC_OPM-NEXT: entry:
100 ; IS__CGSCC_OPM-NEXT: ret i32 [[P1]]
102 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
103 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn1
104 ; IS__CGSCC_NPM-SAME: (i32 [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
105 ; IS__CGSCC_NPM-NEXT: entry:
106 ; IS__CGSCC_NPM-NEXT: ret i32 undef
109 %tobool = icmp ne i32 %p1, 0
110 %cond = select i1 %tobool, i32 %p1, i32 %p1
114 define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid {
116 ; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind null_pointer_is_valid
117 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn_no_null_opt
118 ; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
119 ; IS__TUNIT_OPM-NEXT: entry:
120 ; IS__TUNIT_OPM-NEXT: br label [[IF_END:%.*]]
121 ; IS__TUNIT_OPM: for.cond1:
122 ; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
123 ; IS__TUNIT_OPM: if.end:
124 ; IS__TUNIT_OPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
125 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
126 ; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) #[[ATTR3]]
127 ; IS__TUNIT_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
128 ; IS__TUNIT_OPM-NEXT: br label [[FOR_COND1]]
129 ; IS__TUNIT_OPM: exit:
130 ; IS__TUNIT_OPM-NEXT: ret void
132 ; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind null_pointer_is_valid
133 ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn_no_null_opt
134 ; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
135 ; IS__TUNIT_NPM-NEXT: entry:
136 ; IS__TUNIT_NPM-NEXT: br label [[IF_END:%.*]]
137 ; IS__TUNIT_NPM: for.cond1:
138 ; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
139 ; IS__TUNIT_NPM: if.end:
140 ; IS__TUNIT_NPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
141 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
142 ; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
143 ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND1]]
144 ; IS__TUNIT_NPM: exit:
145 ; IS__TUNIT_NPM-NEXT: ret void
147 ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid
148 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn_no_null_opt
149 ; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
150 ; IS__CGSCC_OPM-NEXT: entry:
151 ; IS__CGSCC_OPM-NEXT: br label [[IF_END:%.*]]
152 ; IS__CGSCC_OPM: for.cond1:
153 ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
154 ; IS__CGSCC_OPM: if.end:
155 ; IS__CGSCC_OPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
156 ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 536870912
157 ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
158 ; IS__CGSCC_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
159 ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND1]]
160 ; IS__CGSCC_OPM: exit:
161 ; IS__CGSCC_OPM-NEXT: ret void
163 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid
164 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn_no_null_opt
165 ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
166 ; IS__CGSCC_NPM-NEXT: entry:
167 ; IS__CGSCC_NPM-NEXT: br label [[IF_END:%.*]]
168 ; IS__CGSCC_NPM: for.cond1:
169 ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
170 ; IS__CGSCC_NPM: if.end:
171 ; IS__CGSCC_NPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
172 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 536870912
173 ; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
174 ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND1]]
175 ; IS__CGSCC_NPM: exit:
176 ; IS__CGSCC_NPM-NEXT: ret void
181 for.cond1: ; preds = %if.end
182 br i1 %C, label %if.end, label %exit
184 if.end: ; preds = %entry, %for.cond1
185 %e.2 = phi i32* [ undef, %entry ], [ null, %for.cond1 ]
186 %0 = load i32, i32* %e.2, align 4
187 %call = call i32 @fn0(i32 %0)
188 store i32 %call, i32* %P
194 define internal i32 @fn0(i32 %p1) {
195 ; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
196 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn0
197 ; IS__TUNIT_OPM-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
198 ; IS__TUNIT_OPM-NEXT: entry:
199 ; IS__TUNIT_OPM-NEXT: ret i32 [[P1]]
201 ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
202 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn0
203 ; IS__CGSCC_OPM-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
204 ; IS__CGSCC_OPM-NEXT: entry:
205 ; IS__CGSCC_OPM-NEXT: ret i32 [[P1]]
207 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
208 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn0
209 ; IS__CGSCC_NPM-SAME: (i32 [[P1:%.*]]) #[[ATTR1]] {
210 ; IS__CGSCC_NPM-NEXT: entry:
211 ; IS__CGSCC_NPM-NEXT: ret i32 undef
214 %tobool = icmp ne i32 %p1, 0
215 %cond = select i1 %tobool, i32 %p1, i32 %p1
219 ; IS__TUNIT_OPM: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind }
220 ; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
221 ; IS__TUNIT_OPM: attributes #[[ATTR2]] = { nofree nosync nounwind null_pointer_is_valid }
222 ; IS__TUNIT_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone }
224 ; IS__TUNIT_NPM: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind }
225 ; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree nosync nounwind null_pointer_is_valid }
227 ; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind }
228 ; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
229 ; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nofree norecurse nosync nounwind null_pointer_is_valid }