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 i32 @test_range(i32 %unknown) {
9 ; CHECK-LABEL: define {{[^@]+}}@test_range
10 ; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0:[0-9]+]] {
11 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[UNKNOWN]], 100
12 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 100, i32 0
13 ; CHECK-NEXT: ret i32 [[TMP2]]
15 %1 = icmp sgt i32 %unknown, 100
16 %2 = select i1 %1, i32 100, i32 0
20 define i32 @test1(i32 %unknown, i32 %b) {
21 ; TUNIT-LABEL: define {{[^@]+}}@test1
22 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
23 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]])
24 ; TUNIT-NEXT: [[TMP2:%.*]] = sub nsw i32 [[TMP1]], [[B]]
25 ; TUNIT-NEXT: ret i32 [[TMP2]]
27 ; CGSCC-LABEL: define {{[^@]+}}@test1
28 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] {
29 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]])
30 ; CGSCC-NEXT: [[TMP2:%.*]] = sub nsw i32 [[TMP1]], [[B]]
31 ; CGSCC-NEXT: ret i32 [[TMP2]]
33 %1 = call i32 @test_range(i32 %unknown)
34 %2 = sub nsw i32 %1, %b
38 define i32 @test2(i32 %unknown, i32 %b) {
39 ; TUNIT-LABEL: define {{[^@]+}}@test2
40 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
41 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]])
42 ; TUNIT-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[B]]
43 ; TUNIT-NEXT: ret i32 [[TMP2]]
45 ; CGSCC-LABEL: define {{[^@]+}}@test2
46 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR1]] {
47 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]])
48 ; CGSCC-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[B]]
49 ; CGSCC-NEXT: ret i32 [[TMP2]]
51 %1 = call i32 @test_range(i32 %unknown)
52 %2 = add nsw i32 %1, %b
58 ; FIXME: AAValueSimplify preserves the context but simplifies to a value in the other function, I think.
59 ; Either way, as we settle on the new AAValueSimplifyReturned scheme that replaces AAReturnedValues
60 ; we need to look into this again. For the purpose of making some progress we take this regression
61 ; for now, call site contexts are not on by default anyway (yet).
62 define i32 @test1_pcheck(i32 %unknown) {
63 ; TUNIT-LABEL: define {{[^@]+}}@test1_pcheck
64 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
65 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20)
66 ; TUNIT-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90
67 ; TUNIT-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
68 ; TUNIT-NEXT: ret i32 [[TMP3]]
70 ; CGSCC-LABEL: define {{[^@]+}}@test1_pcheck
71 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] {
72 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20)
73 ; CGSCC-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90
74 ; CGSCC-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
75 ; CGSCC-NEXT: ret i32 [[TMP3]]
77 %1 = call i32 @test1(i32 %unknown, i32 20)
78 %2 = icmp sle i32 %1, 90
79 %3 = zext i1 %2 to i32
83 define i32 @test2_pcheck(i32 %unknown) {
84 ; TUNIT-LABEL: define {{[^@]+}}@test2_pcheck
85 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
86 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20)
87 ; TUNIT-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20
88 ; TUNIT-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
89 ; TUNIT-NEXT: ret i32 [[TMP3]]
91 ; CGSCC-LABEL: define {{[^@]+}}@test2_pcheck
92 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] {
93 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20)
94 ; CGSCC-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20
95 ; CGSCC-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
96 ; CGSCC-NEXT: ret i32 [[TMP3]]
98 %1 = call i32 @test2(i32 %unknown, i32 20)
99 %2 = icmp sge i32 %1, 20
100 %3 = zext i1 %2 to i32
106 define i32 @test1_ncheck(i32 %unknown) {
107 ; TUNIT-LABEL: define {{[^@]+}}@test1_ncheck
108 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
109 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20)
110 ; TUNIT-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
111 ; TUNIT-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
112 ; TUNIT-NEXT: ret i32 [[TMP3]]
114 ; CGSCC-LABEL: define {{[^@]+}}@test1_ncheck
115 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] {
116 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20)
117 ; CGSCC-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
118 ; CGSCC-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
119 ; CGSCC-NEXT: ret i32 [[TMP3]]
121 %1 = call i32 @test1(i32 %unknown, i32 20)
122 %2 = icmp sle i32 %1, 10
123 %3 = zext i1 %2 to i32
127 define i32 @test2_ncheck(i32 %unknown) {
128 ; TUNIT-LABEL: define {{[^@]+}}@test2_ncheck
129 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
130 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20)
131 ; TUNIT-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
132 ; TUNIT-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
133 ; TUNIT-NEXT: ret i32 [[TMP3]]
135 ; CGSCC-LABEL: define {{[^@]+}}@test2_ncheck
136 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] {
137 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20)
138 ; CGSCC-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
139 ; CGSCC-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
140 ; CGSCC-NEXT: ret i32 [[TMP3]]
142 %1 = call i32 @test2(i32 %unknown, i32 20)
143 %2 = icmp sge i32 %1, 30
144 %3 = zext i1 %2 to i32
148 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
149 ; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn memory(none) }
151 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
152 ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
153 ; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nofree nosync willreturn }