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 disabled
4 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -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-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 define i32 @test1_pcheck(i32 %unknown) {
59 ; TUNIT-LABEL: define {{[^@]+}}@test1_pcheck
60 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
61 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20)
62 ; TUNIT-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90
63 ; TUNIT-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
64 ; TUNIT-NEXT: ret i32 [[TMP3]]
66 ; CGSCC-LABEL: define {{[^@]+}}@test1_pcheck
67 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] {
68 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20)
69 ; CGSCC-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90
70 ; CGSCC-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
71 ; CGSCC-NEXT: ret i32 [[TMP3]]
73 %1 = call i32 @test1(i32 %unknown, i32 20)
74 %2 = icmp sle i32 %1, 90
75 %3 = zext i1 %2 to i32
79 define i32 @test2_pcheck(i32 %unknown) {
80 ; TUNIT-LABEL: define {{[^@]+}}@test2_pcheck
81 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
82 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20)
83 ; TUNIT-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20
84 ; TUNIT-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
85 ; TUNIT-NEXT: ret i32 [[TMP3]]
87 ; CGSCC-LABEL: define {{[^@]+}}@test2_pcheck
88 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] {
89 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20)
90 ; CGSCC-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20
91 ; CGSCC-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
92 ; CGSCC-NEXT: ret i32 [[TMP3]]
94 %1 = call i32 @test2(i32 %unknown, i32 20)
95 %2 = icmp sge i32 %1, 20
96 %3 = zext i1 %2 to i32
102 define i32 @test1_ncheck(i32 %unknown) {
103 ; TUNIT-LABEL: define {{[^@]+}}@test1_ncheck
104 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
105 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20)
106 ; TUNIT-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
107 ; TUNIT-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
108 ; TUNIT-NEXT: ret i32 [[TMP3]]
110 ; CGSCC-LABEL: define {{[^@]+}}@test1_ncheck
111 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] {
112 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20)
113 ; CGSCC-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
114 ; CGSCC-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
115 ; CGSCC-NEXT: ret i32 [[TMP3]]
117 %1 = call i32 @test1(i32 %unknown, i32 20)
118 %2 = icmp sle i32 %1, 10
119 %3 = zext i1 %2 to i32
123 define i32 @test2_ncheck(i32 %unknown) {
124 ; TUNIT-LABEL: define {{[^@]+}}@test2_ncheck
125 ; TUNIT-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
126 ; TUNIT-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20)
127 ; TUNIT-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
128 ; TUNIT-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
129 ; TUNIT-NEXT: ret i32 [[TMP3]]
131 ; CGSCC-LABEL: define {{[^@]+}}@test2_ncheck
132 ; CGSCC-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] {
133 ; CGSCC-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20)
134 ; CGSCC-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
135 ; CGSCC-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
136 ; CGSCC-NEXT: ret i32 [[TMP3]]
138 %1 = call i32 @test2(i32 %unknown, i32 20)
139 %2 = icmp sge i32 %1, 30
140 %3 = zext i1 %2 to i32
144 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
145 ; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn memory(none) }
147 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
148 ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
149 ; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nofree nosync willreturn }