xref: /llvm-project/llvm/test/Transforms/Attributor/cb_range_enabled.ll (revision e31724f1a6e928951a86c9dbe725533a91f3c7da)
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
3
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
5
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
7
8define 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]]
14;
15  %1 = icmp sgt i32 %unknown, 100
16  %2 = select i1 %1, i32 100, i32 0
17  ret i32 %2
18}
19
20define 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]]
26;
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]]
32;
33  %1 = call i32 @test_range(i32 %unknown)
34  %2 = sub nsw i32 %1, %b
35  ret i32 %2
36}
37
38define 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]]
44;
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]]
50;
51  %1 = call i32 @test_range(i32 %unknown)
52  %2 = add nsw i32 %1, %b
53  ret i32 %2
54}
55
56; Positive checks
57
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).
62define 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]]
69;
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]]
76;
77  %1 = call i32 @test1(i32 %unknown, i32 20)
78  %2 = icmp sle i32 %1, 90
79  %3 = zext i1 %2 to i32
80  ret i32 %3
81}
82
83define 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]]
90;
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]]
97;
98  %1 = call i32 @test2(i32 %unknown, i32 20)
99  %2 = icmp sge i32 %1, 20
100  %3 = zext i1 %2 to i32
101  ret i32 %3
102}
103
104; Negative checks
105
106define 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]]
113;
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]]
120;
121  %1 = call i32 @test1(i32 %unknown, i32 20)
122  %2 = icmp sle i32 %1, 10
123  %3 = zext i1 %2 to i32
124  ret i32 %3
125}
126
127define 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]]
134;
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]]
141;
142  %1 = call i32 @test2(i32 %unknown, i32 20)
143  %2 = icmp sge i32 %1, 30
144  %3 = zext i1 %2 to i32
145  ret i32 %3
146}
147;.
148; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
149; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn memory(none) }
150;.
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 }
154;.
155