1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-globals
2 ; call site specific analysis is enabled
4 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-enable-call-site-specific-deduction=true -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
6 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-enable-call-site-specific-deduction=true -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
8 define dso_local i32 @test_range1(i32 %0) #0 {
9 ; CHECK-LABEL: define {{[^@]+}}@test_range1
10 ; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
11 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0]], 0
12 ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
14 ; CHECK-NEXT: br label [[TMP5:%.*]]
16 ; CHECK-NEXT: br label [[TMP5]]
18 ; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ 100, [[TMP3]] ], [ 0, [[TMP4]] ]
19 ; CHECK-NEXT: ret i32 [[DOT0]]
21 %2 = icmp ne i32 %0, 0
22 br i1 %2, label %3, label %4
31 %.0 = phi i32 [ 100, %3 ], [ 0, %4 ]
35 define i32 @test_range2(i32 %0) #0 {
36 ; CHECK-LABEL: define {{[^@]+}}@test_range2
37 ; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
38 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0]], 0
39 ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
41 ; CHECK-NEXT: br label [[TMP5:%.*]]
43 ; CHECK-NEXT: br label [[TMP5]]
45 ; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ 100, [[TMP3]] ], [ 200, [[TMP4]] ]
46 ; CHECK-NEXT: ret i32 [[DOT0]]
48 %2 = icmp ne i32 %0, 0
49 br i1 %2, label %3, label %4
58 %.0 = phi i32 [ 100, %3 ], [ 200, %4 ]
61 define i32 @test(i32 %0, i32 %1) #0 {
62 ; TUNIT-LABEL: define {{[^@]+}}@test
63 ; TUNIT-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0]] {
64 ; TUNIT-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
65 ; TUNIT-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
67 ; TUNIT-NEXT: [[TMP5:%.*]] = call i32 @test_range1(i32 [[TMP0]])
68 ; TUNIT-NEXT: br label [[TMP8:%.*]]
70 ; TUNIT-NEXT: [[TMP7:%.*]] = call i32 @test_range2(i32 [[TMP0]])
71 ; TUNIT-NEXT: br label [[TMP8]]
73 ; TUNIT-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ]
74 ; TUNIT-NEXT: ret i32 [[DOT0]]
76 ; CGSCC-LABEL: define {{[^@]+}}@test
77 ; CGSCC-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR1:[0-9]+]] {
78 ; CGSCC-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
79 ; CGSCC-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
81 ; CGSCC-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]])
82 ; CGSCC-NEXT: br label [[TMP8:%.*]]
84 ; CGSCC-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]])
85 ; CGSCC-NEXT: br label [[TMP8]]
87 ; CGSCC-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ]
88 ; CGSCC-NEXT: ret i32 [[DOT0]]
90 %3 = icmp ne i32 %1, 0
91 br i1 %3, label %4, label %6
94 %5 = call i32 @test_range1(i32 %0)
98 %7 = call i32 @test_range2(i32 %0)
102 %.0 = phi i32 [ %5, %4 ], [ %7, %6 ]
106 define i32 @test_pcheck1(i32 %0) #0 {
107 ; TUNIT-LABEL: define {{[^@]+}}@test_pcheck1
108 ; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
109 ; TUNIT-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1)
110 ; TUNIT-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101
111 ; TUNIT-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
112 ; TUNIT-NEXT: ret i32 [[TMP4]]
114 ; CGSCC-LABEL: define {{[^@]+}}@test_pcheck1
115 ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
116 ; CGSCC-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1)
117 ; CGSCC-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101
118 ; CGSCC-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
119 ; CGSCC-NEXT: ret i32 [[TMP4]]
121 ; TUNIT_ENABLED-LABEL: define {{[^@]+}}@test_pcheck1
122 ; TUNIT_ENABLED-SAME: (i32 [[TMP0:%.*]])
123 ; TUNIT_ENABLED-NEXT: ret i32 1
124 %2 = call i32 @test(i32 %0, i32 1)
125 %3 = icmp slt i32 %2, 101
126 %4 = zext i1 %3 to i32
130 define i32 @test_pcheck2(i32 %0) #0 {
131 ; TUNIT-LABEL: define {{[^@]+}}@test_pcheck2
132 ; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
133 ; TUNIT-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0)
134 ; TUNIT-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99
135 ; TUNIT-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
136 ; TUNIT-NEXT: ret i32 [[TMP4]]
138 ; CGSCC-LABEL: define {{[^@]+}}@test_pcheck2
139 ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
140 ; CGSCC-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0)
141 ; CGSCC-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99
142 ; CGSCC-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
143 ; CGSCC-NEXT: ret i32 [[TMP4]]
145 %2 = call i32 @test(i32 %0, i32 0)
146 %3 = icmp sgt i32 %2, 99
147 %4 = zext i1 %3 to i32
151 define i32 @test_ncheck1(i32 %0) #0 {
152 ; TUNIT-LABEL: define {{[^@]+}}@test_ncheck1
153 ; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
154 ; TUNIT-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1)
155 ; TUNIT-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50
156 ; TUNIT-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
157 ; TUNIT-NEXT: ret i32 [[TMP4]]
159 ; CGSCC-LABEL: define {{[^@]+}}@test_ncheck1
160 ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
161 ; CGSCC-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1)
162 ; CGSCC-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50
163 ; CGSCC-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
164 ; CGSCC-NEXT: ret i32 [[TMP4]]
166 %2 = call i32 @test(i32 %0, i32 1)
167 %3 = icmp sgt i32 %2, 50
168 %4 = zext i1 %3 to i32
172 define i32 @test_ncheck2(i32 %0) #0 {
173 ; TUNIT-LABEL: define {{[^@]+}}@test_ncheck2
174 ; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
175 ; TUNIT-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0)
176 ; TUNIT-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150
177 ; TUNIT-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
178 ; TUNIT-NEXT: ret i32 [[TMP4]]
180 ; CGSCC-LABEL: define {{[^@]+}}@test_ncheck2
181 ; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
182 ; CGSCC-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0)
183 ; CGSCC-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150
184 ; CGSCC-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
185 ; CGSCC-NEXT: ret i32 [[TMP4]]
187 %2 = call i32 @test(i32 %0, i32 0)
188 %3 = icmp sgt i32 %2, 150
189 %4 = zext i1 %3 to i32
193 attributes #0 = { noinline nounwind sspstrong uwtable}
195 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) uwtable }
196 ; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn memory(none) }
198 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind sspstrong willreturn memory(none) uwtable }
199 ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree noinline nosync nounwind sspstrong willreturn memory(none) uwtable }
200 ; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nofree nosync willreturn }