[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / Attributor / range.ll
blob48040fec772dc0859541a6730818618189af8545
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 ; FIXME: CGSCC is not looking at callees and calleers even though it could be allowed.
7 define i32 @test0(ptr %p) {
8 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
9 ; CHECK-LABEL: define {{[^@]+}}@test0
10 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
11 ; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]]
12 ; CHECK-NEXT:    ret i32 [[A]]
14   %a = load i32, ptr %p, !range !0
15   ret i32 %a
18 define i32 @test0-range-check(ptr %p) {
19 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
20 ; TUNIT-LABEL: define {{[^@]+}}@test0-range-check
21 ; TUNIT-SAME: (ptr nocapture nofree readonly align 4 [[P:%.*]]) #[[ATTR0]] {
22 ; TUNIT-NEXT:    [[A:%.*]] = tail call i32 @test0(ptr nocapture nofree noundef readonly align 4 [[P]]) #[[ATTR3:[0-9]+]], !range [[RNG0]]
23 ; TUNIT-NEXT:    ret i32 [[A]]
25 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
26 ; CGSCC-LABEL: define {{[^@]+}}@test0-range-check
27 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1:[0-9]+]] {
28 ; CGSCC-NEXT:    [[A:%.*]] = tail call i32 @test0(ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5:[0-9]+]]
29 ; CGSCC-NEXT:    ret i32 [[A]]
31   %a = tail call i32 @test0(ptr %p)
32   ret i32 %a
35 declare void @use3-dummy(i1, i1, i1)
36 define void @use3(i1, i1, i1) {
37 ; CHECK-LABEL: define {{[^@]+}}@use3
38 ; CHECK-SAME: (i1 [[TMP0:%.*]], i1 [[TMP1:%.*]], i1 [[TMP2:%.*]]) {
39 ; CHECK-NEXT:    tail call void @use3-dummy(i1 [[TMP0]], i1 [[TMP1]], i1 [[TMP2]])
40 ; CHECK-NEXT:    ret void
42   tail call void @use3-dummy(i1 %0, i1 %1, i1 %2)
43   ret void
46 ; TEST0 icmp test
47 define void @test0-icmp-check(ptr %p){
48   ; ret = [0, 10)
49 ; TUNIT-LABEL: define {{[^@]+}}@test0-icmp-check
50 ; TUNIT-SAME: (ptr nocapture nofree readonly align 4 [[P:%.*]]) {
51 ; TUNIT-NEXT:    [[RET:%.*]] = tail call i32 @test0(ptr nocapture nofree noundef readonly align 4 [[P]]) #[[ATTR3]]
52 ; TUNIT-NEXT:    [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
53 ; TUNIT-NEXT:    [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
54 ; TUNIT-NEXT:    [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
55 ; TUNIT-NEXT:    [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
56 ; TUNIT-NEXT:    [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
57 ; TUNIT-NEXT:    [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1
58 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
59 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]])
60 ; TUNIT-NEXT:    [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10
61 ; TUNIT-NEXT:    [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
62 ; TUNIT-NEXT:    [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
63 ; TUNIT-NEXT:    [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
64 ; TUNIT-NEXT:    [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
65 ; TUNIT-NEXT:    [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1
66 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
67 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]])
68 ; TUNIT-NEXT:    [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10
69 ; TUNIT-NEXT:    [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9
70 ; TUNIT-NEXT:    [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
71 ; TUNIT-NEXT:    [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
72 ; TUNIT-NEXT:    [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
73 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]])
74 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false)
75 ; TUNIT-NEXT:    [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10
76 ; TUNIT-NEXT:    [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
77 ; TUNIT-NEXT:    [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
78 ; TUNIT-NEXT:    [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
79 ; TUNIT-NEXT:    [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1
80 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
81 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]])
82 ; TUNIT-NEXT:    [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10
83 ; TUNIT-NEXT:    [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9
84 ; TUNIT-NEXT:    [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
85 ; TUNIT-NEXT:    [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
86 ; TUNIT-NEXT:    [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
87 ; TUNIT-NEXT:    [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1
88 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]])
89 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]])
90 ; TUNIT-NEXT:    [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10
91 ; TUNIT-NEXT:    [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
92 ; TUNIT-NEXT:    [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
93 ; TUNIT-NEXT:    [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
94 ; TUNIT-NEXT:    [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0
95 ; TUNIT-NEXT:    [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1
96 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
97 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]])
98 ; TUNIT-NEXT:    [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10
99 ; TUNIT-NEXT:    [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
100 ; TUNIT-NEXT:    [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
101 ; TUNIT-NEXT:    [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
102 ; TUNIT-NEXT:    [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0
103 ; TUNIT-NEXT:    [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1
104 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
105 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]])
106 ; TUNIT-NEXT:    [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10
107 ; TUNIT-NEXT:    [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9
108 ; TUNIT-NEXT:    [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
109 ; TUNIT-NEXT:    [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
110 ; TUNIT-NEXT:    [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
111 ; TUNIT-NEXT:    [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1
112 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]])
113 ; TUNIT-NEXT:    tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]])
114 ; TUNIT-NEXT:    ret void
116 ; CGSCC-LABEL: define {{[^@]+}}@test0-icmp-check
117 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) {
118 ; CGSCC-NEXT:    [[RET:%.*]] = tail call i32 @test0(ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5]]
119 ; CGSCC-NEXT:    [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
120 ; CGSCC-NEXT:    [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
121 ; CGSCC-NEXT:    [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
122 ; CGSCC-NEXT:    [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
123 ; CGSCC-NEXT:    [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
124 ; CGSCC-NEXT:    [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1
125 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
126 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]])
127 ; CGSCC-NEXT:    [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10
128 ; CGSCC-NEXT:    [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
129 ; CGSCC-NEXT:    [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
130 ; CGSCC-NEXT:    [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
131 ; CGSCC-NEXT:    [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
132 ; CGSCC-NEXT:    [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1
133 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
134 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]])
135 ; CGSCC-NEXT:    [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10
136 ; CGSCC-NEXT:    [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9
137 ; CGSCC-NEXT:    [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
138 ; CGSCC-NEXT:    [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
139 ; CGSCC-NEXT:    [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
140 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]])
141 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false)
142 ; CGSCC-NEXT:    [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10
143 ; CGSCC-NEXT:    [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
144 ; CGSCC-NEXT:    [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
145 ; CGSCC-NEXT:    [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
146 ; CGSCC-NEXT:    [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1
147 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
148 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]])
149 ; CGSCC-NEXT:    [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10
150 ; CGSCC-NEXT:    [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9
151 ; CGSCC-NEXT:    [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
152 ; CGSCC-NEXT:    [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
153 ; CGSCC-NEXT:    [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
154 ; CGSCC-NEXT:    [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1
155 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]])
156 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]])
157 ; CGSCC-NEXT:    [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10
158 ; CGSCC-NEXT:    [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
159 ; CGSCC-NEXT:    [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
160 ; CGSCC-NEXT:    [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
161 ; CGSCC-NEXT:    [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0
162 ; CGSCC-NEXT:    [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1
163 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
164 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]])
165 ; CGSCC-NEXT:    [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10
166 ; CGSCC-NEXT:    [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
167 ; CGSCC-NEXT:    [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
168 ; CGSCC-NEXT:    [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
169 ; CGSCC-NEXT:    [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0
170 ; CGSCC-NEXT:    [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1
171 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
172 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]])
173 ; CGSCC-NEXT:    [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10
174 ; CGSCC-NEXT:    [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9
175 ; CGSCC-NEXT:    [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
176 ; CGSCC-NEXT:    [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
177 ; CGSCC-NEXT:    [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
178 ; CGSCC-NEXT:    [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1
179 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]])
180 ; CGSCC-NEXT:    tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]])
181 ; CGSCC-NEXT:    ret void
183   %ret = tail call i32 @test0(ptr %p)
185   ; ret = [0, 10), eq
186   %cmp-eq-1 = icmp eq i32 %ret, 10
187   %cmp-eq-2 = icmp eq i32 %ret, 9
188   %cmp-eq-3 = icmp eq i32 %ret, 8
189   %cmp-eq-4 = icmp eq i32 %ret, 1
190   %cmp-eq-5 = icmp eq i32 %ret, 0
191   %cmp-eq-6 = icmp eq i32 %ret, -1
192   tail call void @use3(i1 %cmp-eq-1, i1 %cmp-eq-2, i1 %cmp-eq-3)
193   tail call void @use3(i1 %cmp-eq-4, i1 %cmp-eq-5, i1 %cmp-eq-6)
195   ; ret = [0, 10), ne
196   %cmp-ne-1 = icmp ne i32 %ret, 10
197   %cmp-ne-2 = icmp ne i32 %ret, 9
198   %cmp-ne-3 = icmp ne i32 %ret, 8
199   %cmp-ne-4 = icmp ne i32 %ret, 1
200   %cmp-ne-5 = icmp ne i32 %ret, 0
201   %cmp-ne-6 = icmp ne i32 %ret, -1
202   tail call void @use3(i1 %cmp-ne-1, i1 %cmp-ne-2, i1 %cmp-ne-3)
203   tail call void @use3(i1 %cmp-ne-4, i1 %cmp-ne-5, i1 %cmp-ne-6)
205   ; ret = [0, 10), ugt
206   %cmp-ugt-1 = icmp ugt i32 %ret, 10
207   %cmp-ugt-2 = icmp ugt i32 %ret, 9
208   %cmp-ugt-3 = icmp ugt i32 %ret, 8
209   %cmp-ugt-4 = icmp ugt i32 %ret, 1
210   %cmp-ugt-5 = icmp ugt i32 %ret, 0
211   %cmp-ugt-6 = icmp ugt i32 %ret, -1
212   tail call void @use3(i1 %cmp-ugt-1, i1 %cmp-ugt-2, i1 %cmp-ugt-3)
213   tail call void @use3(i1 %cmp-ugt-4, i1 %cmp-ugt-5, i1 %cmp-ugt-6)
215   ; ret = [0, 10), uge
216   %cmp-uge-1 = icmp uge i32 %ret, 10
217   %cmp-uge-2 = icmp uge i32 %ret, 9
218   %cmp-uge-3 = icmp uge i32 %ret, 8
219   %cmp-uge-4 = icmp uge i32 %ret, 1
220   %cmp-uge-5 = icmp uge i32 %ret, 0
221   %cmp-uge-6 = icmp uge i32 %ret, -1
222   tail call void @use3(i1 %cmp-uge-1, i1 %cmp-uge-2, i1 %cmp-uge-3)
223   tail call void @use3(i1 %cmp-uge-4, i1 %cmp-uge-5, i1 %cmp-uge-6)
225   ; ret = [0, 10), sgt
226   %cmp-sgt-1 = icmp sgt i32 %ret, 10
227   %cmp-sgt-2 = icmp sgt i32 %ret, 9
228   %cmp-sgt-3 = icmp sgt i32 %ret, 8
229   %cmp-sgt-4 = icmp sgt i32 %ret, 1
230   %cmp-sgt-5 = icmp sgt i32 %ret, 0
231   %cmp-sgt-6 = icmp sgt i32 %ret, -1
232   tail call void @use3(i1 %cmp-sgt-1, i1 %cmp-sgt-2, i1 %cmp-sgt-3)
233   tail call void @use3(i1 %cmp-sgt-4, i1 %cmp-sgt-5, i1 %cmp-sgt-6)
235   ; ret = [0, 10), sge
236   %cmp-gte-1 = icmp sge i32 %ret, 10
237   %cmp-gte-2 = icmp sge i32 %ret, 9
238   %cmp-gte-3 = icmp sge i32 %ret, 8
239   %cmp-gte-4 = icmp sge i32 %ret, 1
240   %cmp-gte-5 = icmp sge i32 %ret, 0
241   %cmp-gte-6 = icmp sge i32 %ret, -1
242   tail call void @use3(i1 %cmp-gte-1, i1 %cmp-gte-2, i1 %cmp-gte-3)
243   tail call void @use3(i1 %cmp-gte-4, i1 %cmp-gte-5, i1 %cmp-gte-6)
245   ; ret = [0, 10), slt
246   %cmp-slt-1 = icmp slt i32 %ret, 10
247   %cmp-slt-2 = icmp slt i32 %ret, 9
248   %cmp-slt-3 = icmp slt i32 %ret, 8
249   %cmp-slt-4 = icmp slt i32 %ret, 1
250   %cmp-slt-5 = icmp slt i32 %ret, 0
251   %cmp-slt-6 = icmp slt i32 %ret, -1
252   tail call void @use3(i1 %cmp-slt-1, i1 %cmp-slt-2, i1 %cmp-slt-3)
253   tail call void @use3(i1 %cmp-slt-4, i1 %cmp-slt-5, i1 %cmp-slt-6)
255   ; ret = [0, 10), sle
256   %cmp-lte-1 = icmp sle i32 %ret, 10
257   %cmp-lte-2 = icmp sle i32 %ret, 9
258   %cmp-lte-3 = icmp sle i32 %ret, 8
259   %cmp-lte-4 = icmp sle i32 %ret, 1
260   %cmp-lte-5 = icmp sle i32 %ret, 0
261   %cmp-lte-6 = icmp sle i32 %ret, -1
262   tail call void @use3(i1 %cmp-lte-1, i1 %cmp-lte-2, i1 %cmp-lte-3)
263   tail call void @use3(i1 %cmp-lte-4, i1 %cmp-lte-5, i1 %cmp-lte-6)
265   ret void
267 define i32 @test1(ptr %p) {
268 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
269 ; CHECK-LABEL: define {{[^@]+}}@test1
270 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] {
271 ; CHECK-NEXT:    [[LOAD_10_100:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG1:![0-9]+]]
272 ; CHECK-NEXT:    [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
273 ; CHECK-NEXT:    [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
274 ; CHECK-NEXT:    ret i32 [[MUL_10_THEN_200_1091]]
276   %load-10-100 = load i32, ptr %p, !range !1
277   %add-10-then-20-110 = add i32 %load-10-100, 10
278   %mul-10-then-200-1091 = mul i32 %add-10-then-20-110, 10
279   ret i32 %mul-10-then-200-1091
282 define i1 @test1-check(ptr %p) {
284 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
285 ; TUNIT-LABEL: define {{[^@]+}}@test1-check
286 ; TUNIT-SAME: (ptr nocapture nofree readonly align 4 [[P:%.*]]) #[[ATTR0]] {
287 ; TUNIT-NEXT:    [[RES:%.*]] = tail call i32 @test1(ptr nocapture nofree noundef readonly align 4 [[P]]) #[[ATTR3]], !range [[RNG2:![0-9]+]]
288 ; TUNIT-NEXT:    [[CMP:%.*]] = icmp eq i32 [[RES]], 500
289 ; TUNIT-NEXT:    ret i1 [[CMP]]
291 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
292 ; CGSCC-LABEL: define {{[^@]+}}@test1-check
293 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {
294 ; CGSCC-NEXT:    [[RES:%.*]] = tail call i32 @test1(ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5]]
295 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[RES]], 500
296 ; CGSCC-NEXT:    ret i1 [[CMP]]
298   %res = tail call i32 @test1(ptr %p)
299   %cmp = icmp eq i32 %res, 500
300   ret i1 %cmp
303 ;  TEST2
304 ;  int test2(int *p) { return *p == 0 ? 4 : 3; }
305 ;  int test2_check(int *p) {
306 ;    int call = test2(p);
307 ;    if (call == 5) {
308 ;      // dead block
309 ;      return 2;
310 ;    } else {
311 ;      return 3;
312 ;    }
313 ;  }
315 define i32 @test2(ptr %p) {
316 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
317 ; CHECK-LABEL: define {{[^@]+}}@test2
318 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] {
319 ; CHECK-NEXT:  entry:
320 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 4
321 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
322 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3
323 ; CHECK-NEXT:    ret i32 [[COND]]
325 entry:
326   %0 = load i32, ptr %p, align 4
327   %tobool = icmp eq i32 %0, 0
328   %cond = select i1 %tobool, i32 4, i32 3
329   ret i32 %cond
332 define i32 @test2_check(ptr %p) {
333 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
334 ; TUNIT-LABEL: define {{[^@]+}}@test2_check
335 ; TUNIT-SAME: (ptr nocapture nofree readnone align 4 [[P:%.*]]) #[[ATTR1:[0-9]+]] {
336 ; TUNIT-NEXT:  entry:
337 ; TUNIT-NEXT:    br label [[IF_THEN:%.*]]
338 ; TUNIT:       if.then:
339 ; TUNIT-NEXT:    br label [[RETURN:%.*]]
340 ; TUNIT:       if.end:
341 ; TUNIT-NEXT:    unreachable
342 ; TUNIT:       return:
343 ; TUNIT-NEXT:    ret i32 2
345 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
346 ; CGSCC-LABEL: define {{[^@]+}}@test2_check
347 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {
348 ; CGSCC-NEXT:  entry:
349 ; CGSCC-NEXT:    [[CALL:%.*]] = tail call i32 @test2(ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5]]
350 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[CALL]], 5
351 ; CGSCC-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
352 ; CGSCC:       if.then:
353 ; CGSCC-NEXT:    br label [[RETURN:%.*]]
354 ; CGSCC:       if.end:
355 ; CGSCC-NEXT:    br label [[RETURN]]
356 ; CGSCC:       return:
357 ; CGSCC-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ]
358 ; CGSCC-NEXT:    ret i32 [[RETVAL_0]]
360 entry:
361   %call = tail call i32 @test2(ptr %p)
362   %cmp = icmp slt i32 %call, 5
363   br i1 %cmp, label %if.then, label %if.end
365 if.then:                                          ; preds = %entry
366   br label %return
368 if.end:                                           ; preds = %entry
369   br label %return
371 return:                                           ; preds = %if.end, %if.then
372   %retval.0 = phi i32 [ 2, %if.then ], [ 3, %if.end ]
373   ret i32 %retval.0
376 ; TEST 3 SECV test
378 ; void unkown();
379 ; int r1(unsigned int u){
380 ;   int sum = 0;
381 ;   for(int i = 0; i<100;i++){
382 ;     sum += i;
383 ;   }
384 ;   // sum = 50 * 49 / 2
385 ;   if(sum > 10000){
386 ;   // dead block
387 ;     return 20;
388 ;   }else {
389 ;     return 10;
390 ;   }
391 ; }
392 ; void f1(int u){
393 ;   if(r1(u) > 15){
394 ;   // deadblock
395 ;     unkown();
396 ;   }else {
397 ;     return;
398 ;   }
399 ; }
401 declare dso_local void @unkown()
403 define internal i32 @r1(i32) local_unnamed_addr {
404 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
405 ; TUNIT-LABEL: define {{[^@]+}}@r1
406 ; TUNIT-SAME: () local_unnamed_addr #[[ATTR1]] {
407 ; TUNIT-NEXT:    br label [[TMP4:%.*]]
408 ; TUNIT:       1:
409 ; TUNIT-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
410 ; TUNIT-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
411 ; TUNIT:       3:
412 ; TUNIT-NEXT:    ret i32 20
413 ; TUNIT:       f:
414 ; TUNIT-NEXT:    ret i32 10
415 ; TUNIT:       4:
416 ; TUNIT-NEXT:    [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
417 ; TUNIT-NEXT:    [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
418 ; TUNIT-NEXT:    [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
419 ; TUNIT-NEXT:    [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
420 ; TUNIT-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
421 ; TUNIT-NEXT:    br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
423 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
424 ; CGSCC-LABEL: define {{[^@]+}}@r1
425 ; CGSCC-SAME: () local_unnamed_addr #[[ATTR2:[0-9]+]] {
426 ; CGSCC-NEXT:    br label [[TMP4:%.*]]
427 ; CGSCC:       1:
428 ; CGSCC-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
429 ; CGSCC-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
430 ; CGSCC:       3:
431 ; CGSCC-NEXT:    ret i32 20
432 ; CGSCC:       f:
433 ; CGSCC-NEXT:    ret i32 10
434 ; CGSCC:       4:
435 ; CGSCC-NEXT:    [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
436 ; CGSCC-NEXT:    [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
437 ; CGSCC-NEXT:    [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
438 ; CGSCC-NEXT:    [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
439 ; CGSCC-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
440 ; CGSCC-NEXT:    br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
442   br label %5
444 2:                                                ; preds = %5
445   %3 = icmp sgt i32 %8, 10000
446   br i1 %3, label %4, label %f
448   ret i32 20
450   ret i32 10
451 5:                                                ; preds = %5, %1
452   %6 = phi i32 [ 0, %1 ], [ %9, %5 ]
453   %7 = phi i32 [ 0, %1 ], [ %8, %5 ]
454   %8 = add nuw nsw i32 %6, %7
455   %9 = add nuw nsw i32 %6, 1
456   %10 = icmp eq i32 %9, 100
457   br i1 %10, label %2, label %5
460 define void @f1(i32){
461 ; TUNIT-LABEL: define {{[^@]+}}@f1
462 ; TUNIT-SAME: (i32 [[TMP0:%.*]]) {
463 ; TUNIT-NEXT:    [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR4:[0-9]+]]
464 ; TUNIT-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
465 ; TUNIT-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
466 ; TUNIT:       4:
467 ; TUNIT-NEXT:    tail call void @unkown()
468 ; TUNIT-NEXT:    br label [[TMP5]]
469 ; TUNIT:       5:
470 ; TUNIT-NEXT:    ret void
472 ; CGSCC-LABEL: define {{[^@]+}}@f1
473 ; CGSCC-SAME: (i32 [[TMP0:%.*]]) {
474 ; CGSCC-NEXT:    [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR6:[0-9]+]]
475 ; CGSCC-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
476 ; CGSCC-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
477 ; CGSCC:       4:
478 ; CGSCC-NEXT:    tail call void @unkown()
479 ; CGSCC-NEXT:    br label [[TMP5]]
480 ; CGSCC:       5:
481 ; CGSCC-NEXT:    ret void
483   %2 = tail call i32 @r1(i32 %0)
484   %3 = icmp sgt i32 %2, 15
485   br i1 %3, label %4, label %5
487 4:                                                ; preds = %1
488   tail call void @unkown()
489   br label %5
491 5:                                                ; preds = %1, %4
492   ret void
495 ; TEST4 LVI test
497 ; f1
498 ; int test4-f1(int u){
499 ;   if(u>=0) {
500 ;     return u;
501 ;   }else{
502 ;     return 0;
503 ;   }
504 ; }
505 define dso_local i32 @test4-f1(i32 %u) {
506 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
507 ; TUNIT-LABEL: define {{[^@]+}}@test4-f1
508 ; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
509 ; TUNIT-NEXT:  entry:
510 ; TUNIT-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[U]], -1
511 ; TUNIT-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
512 ; TUNIT:       if.then:
513 ; TUNIT-NEXT:    br label [[RETURN]]
514 ; TUNIT:       return:
515 ; TUNIT-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
516 ; TUNIT-NEXT:    ret i32 [[RETVAL_0]]
518 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
519 ; CGSCC-LABEL: define {{[^@]+}}@test4-f1
520 ; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR2]] {
521 ; CGSCC-NEXT:  entry:
522 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[U]], -1
523 ; CGSCC-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
524 ; CGSCC:       if.then:
525 ; CGSCC-NEXT:    br label [[RETURN]]
526 ; CGSCC:       return:
527 ; CGSCC-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
528 ; CGSCC-NEXT:    ret i32 [[RETVAL_0]]
530 ; FIXME: RETVAL_0 >= 0
531 entry:
532   %cmp = icmp sgt i32 %u, -1
533   br i1 %cmp, label %if.then, label %return
535 if.then:                                          ; preds = %entry
536   br label %return
538 return:                                           ; preds = %entry, %if.then
539   %retval.0 = phi i32 [ %u, %if.then ], [ 0, %entry ]
540   ret i32 %retval.0
544 define dso_local i32 @test4-g1(i32 %u) {
545 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
546 ; TUNIT-LABEL: define {{[^@]+}}@test4-g1
547 ; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
548 ; TUNIT-NEXT:  entry:
549 ; TUNIT-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR4]]
550 ; TUNIT-NEXT:    ret i32 [[CALL]]
552 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
553 ; CGSCC-LABEL: define {{[^@]+}}@test4-g1
554 ; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3:[0-9]+]] {
555 ; CGSCC-NEXT:  entry:
556 ; CGSCC-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR7:[0-9]+]]
557 ; CGSCC-NEXT:    ret i32 [[CALL]]
559 ; FIXME: %call should have range [0, inf]
561 entry:
562   %call = tail call i32 @test4-f1(i32 %u)
563   ret i32 %call
566 ; f2
567 ; int test4-f1(int u){
568 ;   if(u>-1) {
569 ;     return u+1;
570 ;   }else{
571 ;     return 1;
572 ;   }
573 ; }
574 define dso_local i32 @test4-f2(i32 %u) {
575 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
576 ; TUNIT-LABEL: define {{[^@]+}}@test4-f2
577 ; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
578 ; TUNIT-NEXT:  entry:
579 ; TUNIT-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[U]], -1
580 ; TUNIT-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
581 ; TUNIT:       if.then:
582 ; TUNIT-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
583 ; TUNIT-NEXT:    br label [[RETURN:%.*]]
584 ; TUNIT:       if.else:
585 ; TUNIT-NEXT:    br label [[RETURN]]
586 ; TUNIT:       return:
587 ; TUNIT-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
588 ; TUNIT-NEXT:    ret i32 [[RETVAL_0]]
590 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
591 ; CGSCC-LABEL: define {{[^@]+}}@test4-f2
592 ; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR2]] {
593 ; CGSCC-NEXT:  entry:
594 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[U]], -1
595 ; CGSCC-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
596 ; CGSCC:       if.then:
597 ; CGSCC-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
598 ; CGSCC-NEXT:    br label [[RETURN:%.*]]
599 ; CGSCC:       if.else:
600 ; CGSCC-NEXT:    br label [[RETURN]]
601 ; CGSCC:       return:
602 ; CGSCC-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
603 ; CGSCC-NEXT:    ret i32 [[RETVAL_0]]
605 entry:
606   %cmp = icmp sgt i32 %u, -1
607   br i1 %cmp, label %if.then, label %if.else
609 if.then:                                          ; preds = %entry
610   %add = add nuw nsw i32 %u, 1
611   br label %return
613 if.else:                                          ; preds = %entry
614   br label %return
616 return:                                           ; preds = %if.else, %if.then
617   %retval.0 = phi i32 [ %add, %if.then ], [ 1, %if.else ]
618   ret i32 %retval.0
622 define dso_local i32 @test4-g2(i32 %u) {
623 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
624 ; TUNIT-LABEL: define {{[^@]+}}@test4-g2
625 ; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
626 ; TUNIT-NEXT:  entry:
627 ; TUNIT-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR4]], !range [[RNG3:![0-9]+]]
628 ; TUNIT-NEXT:    ret i32 [[CALL]]
630 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
631 ; CGSCC-LABEL: define {{[^@]+}}@test4-g2
632 ; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3]] {
633 ; CGSCC-NEXT:  entry:
634 ; CGSCC-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR7]]
635 ; CGSCC-NEXT:    ret i32 [[CALL]]
637 entry:
638   %call = tail call i32 @test4-f2(i32 %u)
639   ret i32 %call
642 define dso_local i32 @test-5() {
643 ; TUNIT-LABEL: define {{[^@]+}}@test-5() {
644 ; TUNIT-NEXT:  entry:
645 ; TUNIT-NEXT:    [[CALL:%.*]] = call i32 @rec(i32 noundef 0)
646 ; TUNIT-NEXT:    ret i32 [[CALL]]
648 ; CGSCC-LABEL: define {{[^@]+}}@test-5() {
649 ; CGSCC-NEXT:  entry:
650 ; CGSCC-NEXT:    [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0)
651 ; CGSCC-NEXT:    ret i32 [[CALL]]
653 entry:
654   %call = call i32 @rec(i32 0)
655   ret i32 %call
657 define internal i32 @rec(i32 %depth) {
658 ; CHECK-LABEL: define {{[^@]+}}@rec
659 ; CHECK-SAME: (i32 [[DEPTH:%.*]]) {
660 ; CHECK-NEXT:  entry:
661 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @foo(i32 [[DEPTH]])
662 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[CALL]], 0
663 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
664 ; CHECK:       if.then:
665 ; CHECK-NEXT:    br label [[RETURN:%.*]]
666 ; CHECK:       if.end:
667 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[DEPTH]], 10
668 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END3:%.*]]
669 ; CHECK:       if.then1:
670 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[DEPTH]], 1
671 ; CHECK-NEXT:    [[CALL2:%.*]] = call i32 @rec(i32 [[ADD]])
672 ; CHECK-NEXT:    br label [[IF_END3]]
673 ; CHECK:       if.end3:
674 ; CHECK-NEXT:    br label [[RETURN]]
675 ; CHECK:       return:
676 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ 1, [[IF_END3]] ]
677 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
679 entry:
680   %call = call i32 @foo(i32 %depth)
681   %tobool = icmp ne i32 %call, 0
682   br i1 %tobool, label %if.then, label %if.end
684 if.then:                                          ; preds = %entry
685   br label %return
687 if.end:                                           ; preds = %entry
688   %cmp = icmp slt i32 %depth, 10
689   br i1 %cmp, label %if.then1, label %if.end3
691 if.then1:                                         ; preds = %if.end
692   %add = add nsw i32 %depth, 1
693   %call2 = call i32 @rec(i32 %add)
694   br label %if.end3
696 if.end3:                                          ; preds = %if.then1, %if.end
697   br label %return
699 return:                                           ; preds = %if.end3, %if.then
700   %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.end3 ]
701   ret i32 %retval.0
703 declare dso_local i32 @foo(i32)
706 ; Examples taken from https://llvm.discourse.group/t/impossible-condition-optimization/461/1
708 ; The important part is that we return a constant (false)
710 ; {
712 ; FIXME: All but the return is not needed anymore
713 define dso_local zeroext i1 @phi(i32 %arg) {
714 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
715 ; TUNIT-LABEL: define {{[^@]+}}@phi
716 ; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {
717 ; TUNIT-NEXT:  bb:
718 ; TUNIT-NEXT:    [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
719 ; TUNIT-NEXT:    br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
720 ; TUNIT:       bb1:
721 ; TUNIT-NEXT:    br label [[BB3:%.*]]
722 ; TUNIT:       bb2:
723 ; TUNIT-NEXT:    br label [[BB3]]
724 ; TUNIT:       bb3:
725 ; TUNIT-NEXT:    [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
726 ; TUNIT-NEXT:    br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
727 ; TUNIT:       bb5:
728 ; TUNIT-NEXT:    br label [[BB9:%.*]]
729 ; TUNIT:       bb7:
730 ; TUNIT-NEXT:    br label [[BB9]]
731 ; TUNIT:       bb9:
732 ; TUNIT-NEXT:    br label [[BB12:%.*]]
733 ; TUNIT:       bb11:
734 ; TUNIT-NEXT:    unreachable
735 ; TUNIT:       bb12:
736 ; TUNIT-NEXT:    br label [[BB13:%.*]]
737 ; TUNIT:       bb13:
738 ; TUNIT-NEXT:    ret i1 false
740 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
741 ; CGSCC-LABEL: define {{[^@]+}}@phi
742 ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] {
743 ; CGSCC-NEXT:  bb:
744 ; CGSCC-NEXT:    [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
745 ; CGSCC-NEXT:    br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
746 ; CGSCC:       bb1:
747 ; CGSCC-NEXT:    br label [[BB3:%.*]]
748 ; CGSCC:       bb2:
749 ; CGSCC-NEXT:    br label [[BB3]]
750 ; CGSCC:       bb3:
751 ; CGSCC-NEXT:    [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
752 ; CGSCC-NEXT:    br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
753 ; CGSCC:       bb5:
754 ; CGSCC-NEXT:    br label [[BB9:%.*]]
755 ; CGSCC:       bb7:
756 ; CGSCC-NEXT:    br label [[BB9]]
757 ; CGSCC:       bb9:
758 ; CGSCC-NEXT:    br label [[BB12:%.*]]
759 ; CGSCC:       bb11:
760 ; CGSCC-NEXT:    unreachable
761 ; CGSCC:       bb12:
762 ; CGSCC-NEXT:    br label [[BB13:%.*]]
763 ; CGSCC:       bb13:
764 ; CGSCC-NEXT:    ret i1 false
767   %tmp = icmp sgt i32 %arg, 5
768   br i1 %tmp, label %bb1, label %bb2
770 bb1:                                              ; preds = %bb
771   br label %bb3
773 bb2:                                              ; preds = %bb
774   br label %bb3
776 bb3:                                              ; preds = %bb2, %bb1
777   %.02 = phi i32 [ 1, %bb1 ], [ 2, %bb2 ]
778   %tmp4 = icmp sgt i32 %arg, 10
779   br i1 %tmp4, label %bb5, label %bb7
781 bb5:                                              ; preds = %bb3
782   %tmp6 = add nsw i32 %.02, 1
783   br label %bb9
785 bb7:                                              ; preds = %bb3
786   %tmp8 = add nsw i32 %.02, 2
787   br label %bb9
789 bb9:                                              ; preds = %bb7, %bb5
790   %.01 = phi i32 [ %tmp6, %bb5 ], [ %tmp8, %bb7 ]
791   %tmp10 = icmp eq i32 %.01, 5
792   br i1 %tmp10, label %bb11, label %bb12
794 bb11:                                             ; preds = %bb9
795   br label %bb13
797 bb12:                                             ; preds = %bb9
798   br label %bb13
800 bb13:                                             ; preds = %bb12, %bb11
801   %.0 = phi i1 [ true, %bb11 ], [ false, %bb12 ]
802   ret i1 %.0
805 define dso_local i1 @select(i32 %a) local_unnamed_addr #0 {
806 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
807 ; TUNIT-LABEL: define {{[^@]+}}@select
808 ; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
809 ; TUNIT-NEXT:  entry:
810 ; TUNIT-NEXT:    ret i1 false
812 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
813 ; CGSCC-LABEL: define {{[^@]+}}@select
814 ; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
815 ; CGSCC-NEXT:  entry:
816 ; CGSCC-NEXT:    ret i1 false
818 entry:
819   %cmp = icmp sgt i32 %a, 5
820   %. = select i1 %cmp, i32 1, i32 2
821   %cmp1 = icmp sgt i32 %a, 10
822   %y.0.v = select i1 %cmp1, i32 1, i32 2
823   %y.0 = add nuw nsw i32 %., %y.0.v
824   %cmp6 = icmp eq i32 %y.0, 5
825   ret i1 %cmp6
828 define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 {
829 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
830 ; TUNIT-LABEL: define {{[^@]+}}@select_zext
831 ; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
832 ; TUNIT-NEXT:  entry:
833 ; TUNIT-NEXT:    ret i32 0
835 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
836 ; CGSCC-LABEL: define {{[^@]+}}@select_zext
837 ; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
838 ; CGSCC-NEXT:  entry:
839 ; CGSCC-NEXT:    ret i32 0
841 entry:
842   %cmp = icmp sgt i32 %a, 5
843   %. = select i1 %cmp, i32 1, i32 2
844   %cmp1 = icmp sgt i32 %a, 10
845   %y.0.v = select i1 %cmp1, i32 1, i32 2
846   %y.0 = add nuw nsw i32 %., %y.0.v
847   %cmp6 = icmp eq i32 %y.0, 5
848   %.13 = zext i1 %cmp6 to i32
849   ret i32 %.13
852 define dso_local i64 @select_int2ptr_bitcast_ptr2int(i32 %a) local_unnamed_addr #0 {
853 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
854 ; TUNIT-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
855 ; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
856 ; TUNIT-NEXT:  entry:
857 ; TUNIT-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 5
858 ; TUNIT-NEXT:    [[DOT:%.*]] = select i1 [[CMP]], i32 1, i32 2
859 ; TUNIT-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], 10
860 ; TUNIT-NEXT:    [[Y_0_V:%.*]] = select i1 [[CMP1]], i32 1, i32 2
861 ; TUNIT-NEXT:    [[Y_0:%.*]] = add nuw nsw i32 [[DOT]], [[Y_0_V]]
862 ; TUNIT-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[Y_0]], 5
863 ; TUNIT-NEXT:    [[I2P:%.*]] = inttoptr i1 [[CMP6]] to ptr
864 ; TUNIT-NEXT:    [[P2I:%.*]] = ptrtoint ptr [[I2P]] to i64
865 ; TUNIT-NEXT:    ret i64 [[P2I]]
867 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
868 ; CGSCC-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
869 ; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
870 ; CGSCC-NEXT:  entry:
871 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 5
872 ; CGSCC-NEXT:    [[DOT:%.*]] = select i1 [[CMP]], i32 1, i32 2
873 ; CGSCC-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], 10
874 ; CGSCC-NEXT:    [[Y_0_V:%.*]] = select i1 [[CMP1]], i32 1, i32 2
875 ; CGSCC-NEXT:    [[Y_0:%.*]] = add nuw nsw i32 [[DOT]], [[Y_0_V]]
876 ; CGSCC-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[Y_0]], 5
877 ; CGSCC-NEXT:    [[I2P:%.*]] = inttoptr i1 [[CMP6]] to ptr
878 ; CGSCC-NEXT:    [[P2I:%.*]] = ptrtoint ptr [[I2P]] to i64
879 ; CGSCC-NEXT:    ret i64 [[P2I]]
881 entry:
882   %cmp = icmp sgt i32 %a, 5
883   %. = select i1 %cmp, i32 1, i32 2
884   %cmp1 = icmp sgt i32 %a, 10
885   %y.0.v = select i1 %cmp1, i32 1, i32 2
886   %y.0 = add nuw nsw i32 %., %y.0.v
887   %cmp6 = icmp eq i32 %y.0, 5
888   %i2p = inttoptr i1 %cmp6 to ptr
889   %p2i = ptrtoint ptr %i2p to i64
890   ret i64 %p2i
893 ; }
895 define i1 @f_fcmp(float %a, float %b) {
896 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
897 ; TUNIT-LABEL: define {{[^@]+}}@f_fcmp
898 ; TUNIT-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR1]] {
899 ; TUNIT-NEXT:    [[R:%.*]] = fcmp uge float [[A]], [[B]]
900 ; TUNIT-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
901 ; TUNIT-NEXT:    ret i1 [[S]]
903 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
904 ; CGSCC-LABEL: define {{[^@]+}}@f_fcmp
905 ; CGSCC-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR2]] {
906 ; CGSCC-NEXT:    [[R:%.*]] = fcmp uge float [[A]], [[B]]
907 ; CGSCC-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
908 ; CGSCC-NEXT:    ret i1 [[S]]
910   %r = fcmp uge float %a, %b
911   %s = select i1 %r, i1 %r, i1 0
912   ret i1 %s
914 define i1 @d_fcmp(double %a, double %b) {
915 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
916 ; TUNIT-LABEL: define {{[^@]+}}@d_fcmp
917 ; TUNIT-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR1]] {
918 ; TUNIT-NEXT:    [[R:%.*]] = fcmp oeq double [[A]], [[B]]
919 ; TUNIT-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
920 ; TUNIT-NEXT:    ret i1 [[S]]
922 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
923 ; CGSCC-LABEL: define {{[^@]+}}@d_fcmp
924 ; CGSCC-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR2]] {
925 ; CGSCC-NEXT:    [[R:%.*]] = fcmp oeq double [[A]], [[B]]
926 ; CGSCC-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
927 ; CGSCC-NEXT:    ret i1 [[S]]
929   %r = fcmp oeq double %a, %b
930   %s = select i1 %r, i1 %r, i1 0
931   ret i1 %s
933 define i1 @dp_icmp(ptr %a, ptr %b) {
934 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
935 ; TUNIT-LABEL: define {{[^@]+}}@dp_icmp
936 ; TUNIT-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR1]] {
937 ; TUNIT-NEXT:    [[R:%.*]] = icmp sge ptr [[A]], [[B]]
938 ; TUNIT-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
939 ; TUNIT-NEXT:    ret i1 [[S]]
941 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
942 ; CGSCC-LABEL: define {{[^@]+}}@dp_icmp
943 ; CGSCC-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR2]] {
944 ; CGSCC-NEXT:    [[R:%.*]] = icmp sge ptr [[A]], [[B]]
945 ; CGSCC-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
946 ; CGSCC-NEXT:    ret i1 [[S]]
948   %r = icmp sge ptr %a, %b
949   %s = select i1 %r, i1 %r, i1 0
950   ret i1 %s
952 define i1 @ip_icmp(ptr %a, ptr %b) {
953 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
954 ; TUNIT-LABEL: define {{[^@]+}}@ip_icmp
955 ; TUNIT-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR1]] {
956 ; TUNIT-NEXT:    [[R:%.*]] = icmp ult ptr [[A]], [[B]]
957 ; TUNIT-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
958 ; TUNIT-NEXT:    ret i1 [[S]]
960 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
961 ; CGSCC-LABEL: define {{[^@]+}}@ip_icmp
962 ; CGSCC-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR2]] {
963 ; CGSCC-NEXT:    [[R:%.*]] = icmp ult ptr [[A]], [[B]]
964 ; CGSCC-NEXT:    [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
965 ; CGSCC-NEXT:    ret i1 [[S]]
967   %r = icmp ult ptr %a, %b
968   %s = select i1 %r, i1 %r, i1 0
969   ret i1 %s
971 define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, ptr %dpa, ptr %dpb, ptr %ipa, ptr %ipb) {
972 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
973 ; TUNIT-LABEL: define {{[^@]+}}@fcmp_caller
974 ; TUNIT-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR1]] {
975 ; TUNIT-NEXT:    [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR4]]
976 ; TUNIT-NEXT:    [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR4]]
977 ; TUNIT-NEXT:    [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR4]]
978 ; TUNIT-NEXT:    [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR4]]
979 ; TUNIT-NEXT:    [[O1:%.*]] = or i1 [[R1]], [[R2]]
980 ; TUNIT-NEXT:    [[O2:%.*]] = or i1 [[R3]], [[R4]]
981 ; TUNIT-NEXT:    [[O3:%.*]] = or i1 [[O1]], [[O2]]
982 ; TUNIT-NEXT:    ret i1 [[O3]]
984 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
985 ; CGSCC-LABEL: define {{[^@]+}}@fcmp_caller
986 ; CGSCC-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR3]] {
987 ; CGSCC-NEXT:    [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR7]]
988 ; CGSCC-NEXT:    [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR7]]
989 ; CGSCC-NEXT:    [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR7]]
990 ; CGSCC-NEXT:    [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR7]]
991 ; CGSCC-NEXT:    [[O1:%.*]] = or i1 [[R1]], [[R2]]
992 ; CGSCC-NEXT:    [[O2:%.*]] = or i1 [[R3]], [[R4]]
993 ; CGSCC-NEXT:    [[O3:%.*]] = or i1 [[O1]], [[O2]]
994 ; CGSCC-NEXT:    ret i1 [[O3]]
996   %r1 = call i1 @f_fcmp(float %fa, float %fb)
997   %r2 = call i1 @d_fcmp(double %da, double %db)
998   %r3 = call i1 @dp_icmp(ptr %dpa, ptr %dpb)
999   %r4 = call i1 @ip_icmp(ptr %ipa, ptr %ipb)
1000   %o1 = or i1 %r1, %r2
1001   %o2 = or i1 %r3, %r4
1002   %o3 = or i1 %o1, %o2
1003   ret i1 %o3
1006 define i8 @ret_two() {
1007 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1008 ; TUNIT-LABEL: define {{[^@]+}}@ret_two
1009 ; TUNIT-SAME: () #[[ATTR1]] {
1010 ; TUNIT-NEXT:    ret i8 2
1012 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1013 ; CGSCC-LABEL: define {{[^@]+}}@ret_two
1014 ; CGSCC-SAME: () #[[ATTR2]] {
1015 ; CGSCC-NEXT:    ret i8 2
1017   ret i8 2
1019 define i8 @ret_undef() {
1020 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1021 ; TUNIT-LABEL: define {{[^@]+}}@ret_undef
1022 ; TUNIT-SAME: () #[[ATTR1]] {
1023 ; TUNIT-NEXT:    ret i8 undef
1025 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1026 ; CGSCC-LABEL: define {{[^@]+}}@ret_undef
1027 ; CGSCC-SAME: () #[[ATTR2]] {
1028 ; CGSCC-NEXT:    ret i8 undef
1030   ret i8 undef
1033 ; Verify we collapse undef to a value and return something non-undef here.
1034 define i8 @undef_collapse_1() {
1035 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1036 ; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_1
1037 ; TUNIT-SAME: () #[[ATTR1]] {
1038 ; TUNIT-NEXT:    ret i8 0
1040 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1041 ; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_1
1042 ; CGSCC-SAME: () #[[ATTR3]] {
1043 ; CGSCC-NEXT:    [[C:%.*]] = call i8 @ret_undef() #[[ATTR7]]
1044 ; CGSCC-NEXT:    [[S:%.*]] = shl i8 [[C]], 2
1045 ; CGSCC-NEXT:    ret i8 [[S]]
1047   %c = call i8 @ret_undef()
1048   %s = shl i8 %c, 2
1049   ret i8 %s
1052 ; Verify we collapse undef to a value and return something non-undef here.
1053 define i8 @undef_collapse_2() {
1054 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1055 ; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_2
1056 ; TUNIT-SAME: () #[[ATTR1]] {
1057 ; TUNIT-NEXT:    ret i8 0
1059 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1060 ; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_2
1061 ; CGSCC-SAME: () #[[ATTR3]] {
1062 ; CGSCC-NEXT:    [[C:%.*]] = call i8 @ret_two() #[[ATTR7]]
1063 ; CGSCC-NEXT:    [[S:%.*]] = shl i8 undef, [[C]]
1064 ; CGSCC-NEXT:    ret i8 [[S]]
1066   %c = call i8 @ret_two()
1067   %s = shl i8 undef, %c
1068   ret i8 %s
1071 define i8 @undef_collapse_caller() {
1073 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1074 ; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_caller
1075 ; TUNIT-SAME: () #[[ATTR1]] {
1076 ; TUNIT-NEXT:    ret i8 0
1078 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1079 ; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_caller
1080 ; CGSCC-SAME: () #[[ATTR3]] {
1081 ; CGSCC-NEXT:    [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR7]]
1082 ; CGSCC-NEXT:    [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR7]]
1083 ; CGSCC-NEXT:    [[A:%.*]] = add i8 [[C1]], [[C2]]
1084 ; CGSCC-NEXT:    ret i8 [[A]]
1086   %c1 = call i8 @undef_collapse_1()
1087   %c2 = call i8 @undef_collapse_2()
1088   %a = add i8 %c1, %c2
1089   ret i8 %a
1092 define i32 @ret1or2(i1 %c) {
1093 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1094 ; TUNIT-LABEL: define {{[^@]+}}@ret1or2
1095 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
1096 ; TUNIT-NEXT:    [[S:%.*]] = select i1 [[C]], i32 1, i32 2
1097 ; TUNIT-NEXT:    ret i32 [[S]]
1099 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1100 ; CGSCC-LABEL: define {{[^@]+}}@ret1or2
1101 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
1102 ; CGSCC-NEXT:    [[S:%.*]] = select i1 [[C]], i32 1, i32 2
1103 ; CGSCC-NEXT:    ret i32 [[S]]
1105   %s = select i1 %c, i32 1, i32 2
1106   ret i32 %s
1108 define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
1110 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1111 ; TUNIT-LABEL: define {{[^@]+}}@callee_range_1
1112 ; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR1]] {
1113 ; TUNIT-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]
1114 ; TUNIT-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]
1115 ; TUNIT-NEXT:    [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]
1116 ; TUNIT-NEXT:    [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
1117 ; TUNIT-NEXT:    [[I1:%.*]] = icmp sle i32 [[A]], 4
1118 ; TUNIT-NEXT:    [[I2:%.*]] = icmp sge i32 [[A]], 2
1119 ; TUNIT-NEXT:    [[F:%.*]] = and i1 [[I1]], [[I2]]
1120 ; TUNIT-NEXT:    ret i1 [[F]]
1122 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1123 ; CGSCC-LABEL: define {{[^@]+}}@callee_range_1
1124 ; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR3]] {
1125 ; CGSCC-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]
1126 ; CGSCC-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]
1127 ; CGSCC-NEXT:    [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]
1128 ; CGSCC-NEXT:    [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
1129 ; CGSCC-NEXT:    [[I1:%.*]] = icmp sle i32 [[A]], 4
1130 ; CGSCC-NEXT:    [[I2:%.*]] = icmp sge i32 [[A]], 2
1131 ; CGSCC-NEXT:    [[F:%.*]] = and i1 [[I1]], [[I2]]
1132 ; CGSCC-NEXT:    ret i1 [[F]]
1134   %r1 = call i32 @ret1or2(i1 %c1)
1135   %r2 = call i32 @ret1or2(i1 %c2)
1136   %indirection = select i1 %c3, i32 %r1, i32 %r2
1137   %a = add i32 %r1, %indirection
1138   %i1 = icmp sle i32 %a, 4
1139   %i2 = icmp sge i32 %a, 2
1140   %f = and i1 %i1, %i2
1141   ret i1 %f
1144 define i1 @callee_range_2(i1 %c1, i1 %c2) {
1146 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1147 ; TUNIT-LABEL: define {{[^@]+}}@callee_range_2
1148 ; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] {
1149 ; TUNIT-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]
1150 ; TUNIT-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]
1151 ; TUNIT-NEXT:    [[A:%.*]] = add i32 [[R1]], [[R2]]
1152 ; TUNIT-NEXT:    [[I1:%.*]] = icmp sle i32 [[A]], 3
1153 ; TUNIT-NEXT:    [[I2:%.*]] = icmp sge i32 [[A]], 2
1154 ; TUNIT-NEXT:    [[F:%.*]] = and i1 [[I1]], [[I2]]
1155 ; TUNIT-NEXT:    ret i1 [[F]]
1157 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1158 ; CGSCC-LABEL: define {{[^@]+}}@callee_range_2
1159 ; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR3]] {
1160 ; CGSCC-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]
1161 ; CGSCC-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]
1162 ; CGSCC-NEXT:    [[A:%.*]] = add i32 [[R1]], [[R2]]
1163 ; CGSCC-NEXT:    [[I1:%.*]] = icmp sle i32 [[A]], 3
1164 ; CGSCC-NEXT:    [[I2:%.*]] = icmp sge i32 [[A]], 2
1165 ; CGSCC-NEXT:    [[F:%.*]] = and i1 [[I1]], [[I2]]
1166 ; CGSCC-NEXT:    ret i1 [[F]]
1168   %r1 = call i32 @ret1or2(i1 %c1)
1169   %r2 = call i32 @ret1or2(i1 %c2)
1170   %a = add i32 %r1, %r2
1171   %i1 = icmp sle i32 %a, 3
1172   %i2 = icmp sge i32 %a, 2
1173   %f = and i1 %i1, %i2
1174   ret i1 %f
1178 define i32 @ret100() {
1179 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1180 ; TUNIT-LABEL: define {{[^@]+}}@ret100
1181 ; TUNIT-SAME: () #[[ATTR1]] {
1182 ; TUNIT-NEXT:    ret i32 100
1184 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1185 ; CGSCC-LABEL: define {{[^@]+}}@ret100
1186 ; CGSCC-SAME: () #[[ATTR2]] {
1187 ; CGSCC-NEXT:    ret i32 100
1189   ret i32 100
1192 define i1 @ctx_adjustment(i32 %V) {
1194 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1195 ; TUNIT-LABEL: define {{[^@]+}}@ctx_adjustment
1196 ; TUNIT-SAME: (i32 [[V:%.*]]) #[[ATTR1]] {
1197 ; TUNIT-NEXT:    [[C1:%.*]] = icmp sge i32 [[V]], 100
1198 ; TUNIT-NEXT:    br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1199 ; TUNIT:       if.true:
1200 ; TUNIT-NEXT:    br label [[END:%.*]]
1201 ; TUNIT:       if.false:
1202 ; TUNIT-NEXT:    br label [[END]]
1203 ; TUNIT:       end:
1204 ; TUNIT-NEXT:    [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ]
1205 ; TUNIT-NEXT:    [[C2:%.*]] = icmp sge i32 [[PHI]], 100
1206 ; TUNIT-NEXT:    ret i1 [[C2]]
1208 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1209 ; CGSCC-LABEL: define {{[^@]+}}@ctx_adjustment
1210 ; CGSCC-SAME: (i32 [[V:%.*]]) #[[ATTR3]] {
1211 ; CGSCC-NEXT:    [[C1:%.*]] = icmp sge i32 [[V]], 100
1212 ; CGSCC-NEXT:    br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
1213 ; CGSCC:       if.true:
1214 ; CGSCC-NEXT:    br label [[END:%.*]]
1215 ; CGSCC:       if.false:
1216 ; CGSCC-NEXT:    [[CALL:%.*]] = call i32 @ret100() #[[ATTR7]]
1217 ; CGSCC-NEXT:    br label [[END]]
1218 ; CGSCC:       end:
1219 ; CGSCC-NEXT:    [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ [[CALL]], [[IF_FALSE]] ]
1220 ; CGSCC-NEXT:    [[C2:%.*]] = icmp sge i32 [[PHI]], 100
1221 ; CGSCC-NEXT:    ret i1 [[C2]]
1223   %c1 = icmp sge i32 %V, 100
1224   br i1 %c1, label %if.true, label %if.false
1225 if.true:
1226   br label %end
1227 if.false:
1228   %call = call i32 @ret100()
1229   br label %end
1230 end:
1231   %phi = phi i32 [ %V, %if.true ], [ %call, %if.false ]
1232   %c2 = icmp sge i32 %phi, 100
1233   ret i1 %c2
1237 define i32 @func(i1 %c) {
1238 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1239 ; TUNIT-LABEL: define {{[^@]+}}@func
1240 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
1241 ; TUNIT-NEXT:    [[RET:%.*]] = select i1 [[C]], i32 0, i32 1
1242 ; TUNIT-NEXT:    ret i32 [[RET]]
1244 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1245 ; CGSCC-LABEL: define {{[^@]+}}@func
1246 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
1247 ; CGSCC-NEXT:    [[RET:%.*]] = select i1 [[C]], i32 0, i32 1
1248 ; CGSCC-NEXT:    ret i32 [[RET]]
1250   %ret = select i1 %c, i32 0, i32 1
1251   ret i32 %ret
1254 define i32 @simplify_callsite_argument(i1 %d) {
1255 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1256 ; TUNIT-LABEL: define {{[^@]+}}@simplify_callsite_argument
1257 ; TUNIT-SAME: (i1 [[D:%.*]]) #[[ATTR1]] {
1258 ; TUNIT-NEXT:    [[C:%.*]] = select i1 [[D]], i1 true, i1 false
1259 ; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1260 ; TUNIT:       t:
1261 ; TUNIT-NEXT:    [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR4]]
1262 ; TUNIT-NEXT:    ret i32 [[RET1]]
1263 ; TUNIT:       f:
1264 ; TUNIT-NEXT:    [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR4]]
1265 ; TUNIT-NEXT:    ret i32 [[RET2]]
1267 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1268 ; CGSCC-LABEL: define {{[^@]+}}@simplify_callsite_argument
1269 ; CGSCC-SAME: (i1 [[D:%.*]]) #[[ATTR3]] {
1270 ; CGSCC-NEXT:    [[C:%.*]] = select i1 [[D]], i1 true, i1 false
1271 ; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1272 ; CGSCC:       t:
1273 ; CGSCC-NEXT:    [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR7]]
1274 ; CGSCC-NEXT:    ret i32 [[RET1]]
1275 ; CGSCC:       f:
1276 ; CGSCC-NEXT:    [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR7]]
1277 ; CGSCC-NEXT:    ret i32 [[RET2]]
1279   %c = select i1 %d, i1 true, i1 false
1280   br i1 %c, label %t, label %f
1282   %ret1 = call i32 @func(i1 %c)
1283   ret i32 %ret1
1285   %ret2 = call i32 @func(i1 false)
1286   ret i32 %ret2
1289 define internal i32 @less_than_65536(i32 %arg) {
1291 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1292 ; CGSCC-LABEL: define {{[^@]+}}@less_than_65536
1293 ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] {
1294 ; CGSCC-NEXT:    [[SHRINKED:%.*]] = udiv i32 [[ARG]], 65536
1295 ; CGSCC-NEXT:    ret i32 [[SHRINKED]]
1297   %shrinked = udiv i32 %arg, 65536
1298   ret i32 %shrinked
1301 define internal i1 @is_less_than_65536(i32 %arg) {
1302 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1303 ; CGSCC-LABEL: define {{[^@]+}}@is_less_than_65536
1304 ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] {
1305 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ARG]], 65536
1306 ; CGSCC-NEXT:    ret i1 [[CMP]]
1308   %cmp = icmp ult i32 %arg, 65536
1309   ret i1 %cmp
1312 define i1 @check_divided_range(i32 %arg) {
1313 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1314 ; TUNIT-LABEL: define {{[^@]+}}@check_divided_range
1315 ; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {
1316 ; TUNIT-NEXT:    ret i1 true
1318 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1319 ; CGSCC-LABEL: define {{[^@]+}}@check_divided_range
1320 ; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
1321 ; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR7]]
1322 ; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR7]]
1323 ; CGSCC-NEXT:    [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR7]]
1324 ; CGSCC-NEXT:    [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR7]]
1325 ; CGSCC-NEXT:    [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
1326 ; CGSCC-NEXT:    ret i1 [[RET]]
1328   %csret1 = call i32 @less_than_65536(i32 0)
1329   %csret2 = call i32 @less_than_65536(i32 %arg)
1330   %true1 = call i1 @is_less_than_65536(i32 %csret1)
1331   %true2 = call i1 @is_less_than_65536(i32 %csret2)
1332   %ret = and i1 %true1, %true2
1333   ret i1 %ret
1336 define internal i32 @cast_and_return(i1 %c) {
1338 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1339 ; CGSCC-LABEL: define {{[^@]+}}@cast_and_return
1340 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
1341 ; CGSCC-NEXT:    [[RET:%.*]] = zext i1 [[C]] to i32
1342 ; CGSCC-NEXT:    ret i32 [[RET]]
1344   %ret = zext i1 %c to i32
1345   ret i32 %ret
1348 define internal i1 @is_less_than_3(i32 %c) {
1349 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1350 ; CGSCC-LABEL: define {{[^@]+}}@is_less_than_3
1351 ; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR2]] {
1352 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 3
1353 ; CGSCC-NEXT:    ret i1 [[CMP]]
1355   %cmp = icmp slt i32 %c, 3
1356   ret i1 %cmp
1359 define i1 @check_casted_range(i1 %c) {
1360 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1361 ; TUNIT-LABEL: define {{[^@]+}}@check_casted_range
1362 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
1363 ; TUNIT-NEXT:    ret i1 true
1365 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1366 ; CGSCC-LABEL: define {{[^@]+}}@check_casted_range
1367 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
1368 ; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR7]]
1369 ; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR7]]
1370 ; CGSCC-NEXT:    [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
1371 ; CGSCC-NEXT:    [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR7]]
1372 ; CGSCC-NEXT:    ret i1 [[RET]]
1374   %csret1 = call i32 @cast_and_return(i1 true)
1375   %csret2 = call i32 @cast_and_return(i1 %c)
1376   %add = add i32 %csret1, %csret2
1377   %ret = call i1 @is_less_than_3(i32 %add)
1378   ret i1 %ret
1381 define internal i32 @less_than_100_1(i32 %c) {
1382 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1383 ; CGSCC-LABEL: define {{[^@]+}}@less_than_100_1
1384 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {
1385 ; CGSCC-NEXT:    switch i32 [[C]], label [[OTHERWISE:%.*]] [
1386 ; CGSCC-NEXT:      i32 0, label [[ONZERO:%.*]]
1387 ; CGSCC-NEXT:      i32 1, label [[ONONE:%.*]]
1388 ; CGSCC-NEXT:      i32 2, label [[ONTWO:%.*]]
1389 ; CGSCC-NEXT:      i32 3, label [[ONTHREE:%.*]]
1390 ; CGSCC-NEXT:      i32 4, label [[ONFOUR:%.*]]
1391 ; CGSCC-NEXT:      i32 5, label [[ONFIVE:%.*]]
1392 ; CGSCC-NEXT:      i32 6, label [[ONSIX:%.*]]
1393 ; CGSCC-NEXT:    ]
1394 ; CGSCC:       onzero:
1395 ; CGSCC-NEXT:    ret i32 0
1396 ; CGSCC:       onone:
1397 ; CGSCC-NEXT:    ret i32 1
1398 ; CGSCC:       ontwo:
1399 ; CGSCC-NEXT:    ret i32 2
1400 ; CGSCC:       onthree:
1401 ; CGSCC-NEXT:    ret i32 3
1402 ; CGSCC:       onfour:
1403 ; CGSCC-NEXT:    ret i32 4
1404 ; CGSCC:       onfive:
1405 ; CGSCC-NEXT:    ret i32 5
1406 ; CGSCC:       onsix:
1407 ; CGSCC-NEXT:    ret i32 6
1408 ; CGSCC:       otherwise:
1409 ; CGSCC-NEXT:    ret i32 99
1411   switch i32 %c, label %otherwise [ i32 0, label %onzero
1412   i32 1, label %onone
1413   i32 2, label %ontwo
1414   i32 3, label %onthree
1415   i32 4, label %onfour
1416   i32 5, label %onfive
1417   i32 6, label %onsix]
1418 onzero:
1419   ret i32 0
1420 onone:
1421   ret i32 1
1422 ontwo:
1423   ret i32 2
1424 onthree:
1425   ret i32 3
1426 onfour:
1427   ret i32 4
1428 onfive:
1429   ret i32 5
1430 onsix:
1431   ret i32 6
1432 otherwise:
1433   ret i32 99
1436 define internal i1 @is_less_than_100_1(i32 %c) {
1437 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1438 ; CGSCC-LABEL: define {{[^@]+}}@is_less_than_100_1
1439 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {
1440 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 100
1441 ; CGSCC-NEXT:    ret i1 [[CMP]]
1443   %cmp = icmp slt i32 %c, 100
1444   ret i1 %cmp
1447 define i1 @propagate_range1(i32 %c){
1448 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1449 ; TUNIT-LABEL: define {{[^@]+}}@propagate_range1
1450 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
1451 ; TUNIT-NEXT:    ret i1 true
1453 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1454 ; CGSCC-LABEL: define {{[^@]+}}@propagate_range1
1455 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {
1456 ; CGSCC-NEXT:    [[CSRET:%.*]] = call i32 @less_than_100_1(i32 noundef [[C]]) #[[ATTR7]]
1457 ; CGSCC-NEXT:    [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR7]]
1458 ; CGSCC-NEXT:    ret i1 [[TRUE]]
1460   %csret = call i32 @less_than_100_1(i32 %c)
1461   %true = call i1 @is_less_than_100_1(i32 %csret)
1462   ret i1 %true
1465 define internal i32 @less_than_100_2(i32 %c) {
1467 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1468 ; TUNIT-LABEL: define {{[^@]+}}@less_than_100_2
1469 ; TUNIT-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] {
1470 ; TUNIT-NEXT:    switch i32 [[C]], label [[OTHERWISE:%.*]] [
1471 ; TUNIT-NEXT:      i32 0, label [[ONZERO:%.*]]
1472 ; TUNIT-NEXT:      i32 1, label [[ONONE:%.*]]
1473 ; TUNIT-NEXT:      i32 2, label [[ONTWO:%.*]]
1474 ; TUNIT-NEXT:      i32 3, label [[ONTHREE:%.*]]
1475 ; TUNIT-NEXT:      i32 4, label [[ONFOUR:%.*]]
1476 ; TUNIT-NEXT:      i32 5, label [[ONFIVE:%.*]]
1477 ; TUNIT-NEXT:      i32 6, label [[ONSIX:%.*]]
1478 ; TUNIT-NEXT:    ]
1479 ; TUNIT:       onzero:
1480 ; TUNIT-NEXT:    ret i32 0
1481 ; TUNIT:       onone:
1482 ; TUNIT-NEXT:    ret i32 1
1483 ; TUNIT:       ontwo:
1484 ; TUNIT-NEXT:    ret i32 2
1485 ; TUNIT:       onthree:
1486 ; TUNIT-NEXT:    ret i32 3
1487 ; TUNIT:       onfour:
1488 ; TUNIT-NEXT:    ret i32 4
1489 ; TUNIT:       onfive:
1490 ; TUNIT-NEXT:    ret i32 5
1491 ; TUNIT:       onsix:
1492 ; TUNIT-NEXT:    ret i32 6
1493 ; TUNIT:       otherwise:
1494 ; TUNIT-NEXT:    ret i32 99
1496 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1497 ; CGSCC-LABEL: define {{[^@]+}}@less_than_100_2
1498 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {
1499 ; CGSCC-NEXT:    switch i32 [[C]], label [[OTHERWISE:%.*]] [
1500 ; CGSCC-NEXT:      i32 0, label [[ONZERO:%.*]]
1501 ; CGSCC-NEXT:      i32 1, label [[ONONE:%.*]]
1502 ; CGSCC-NEXT:      i32 2, label [[ONTWO:%.*]]
1503 ; CGSCC-NEXT:      i32 3, label [[ONTHREE:%.*]]
1504 ; CGSCC-NEXT:      i32 4, label [[ONFOUR:%.*]]
1505 ; CGSCC-NEXT:      i32 5, label [[ONFIVE:%.*]]
1506 ; CGSCC-NEXT:      i32 6, label [[ONSIX:%.*]]
1507 ; CGSCC-NEXT:    ]
1508 ; CGSCC:       onzero:
1509 ; CGSCC-NEXT:    ret i32 0
1510 ; CGSCC:       onone:
1511 ; CGSCC-NEXT:    ret i32 1
1512 ; CGSCC:       ontwo:
1513 ; CGSCC-NEXT:    ret i32 2
1514 ; CGSCC:       onthree:
1515 ; CGSCC-NEXT:    ret i32 3
1516 ; CGSCC:       onfour:
1517 ; CGSCC-NEXT:    ret i32 4
1518 ; CGSCC:       onfive:
1519 ; CGSCC-NEXT:    ret i32 5
1520 ; CGSCC:       onsix:
1521 ; CGSCC-NEXT:    ret i32 6
1522 ; CGSCC:       otherwise:
1523 ; CGSCC-NEXT:    ret i32 99
1525   switch i32 %c, label %otherwise [ i32 0, label %onzero
1526   i32 1, label %onone
1527   i32 2, label %ontwo
1528   i32 3, label %onthree
1529   i32 4, label %onfour
1530   i32 5, label %onfive
1531   i32 6, label %onsix]
1532 onzero:
1533   ret i32 0
1534 onone:
1535   ret i32 1
1536 ontwo:
1537   ret i32 2
1538 onthree:
1539   ret i32 3
1540 onfour:
1541   ret i32 4
1542 onfive:
1543   ret i32 5
1544 onsix:
1545   ret i32 6
1546 otherwise:
1547   ret i32 99
1550 define internal i1 @is_less_than_100_2(i32 %c) {
1552 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1553 ; TUNIT-LABEL: define {{[^@]+}}@is_less_than_100_2
1554 ; TUNIT-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] {
1555 ; TUNIT-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 100
1556 ; TUNIT-NEXT:    ret i1 [[CMP]]
1558 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1559 ; CGSCC-LABEL: define {{[^@]+}}@is_less_than_100_2
1560 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {
1561 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 100
1562 ; CGSCC-NEXT:    ret i1 [[CMP]]
1564   %cmp = icmp slt i32 %c, 100
1565   ret i1 %cmp
1568 define i1 @propagate_range2(i32 %c) {
1569 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1570 ; TUNIT-LABEL: define {{[^@]+}}@propagate_range2
1571 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
1572 ; TUNIT-NEXT:    [[CSRET1:%.*]] = call noundef i32 @less_than_100_2(i32 noundef 0) #[[ATTR4]]
1573 ; TUNIT-NEXT:    [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR4]]
1574 ; TUNIT-NEXT:    [[CSRET2:%.*]] = call noundef i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR4]]
1575 ; TUNIT-NEXT:    [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR4]]
1576 ; TUNIT-NEXT:    [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
1577 ; TUNIT-NEXT:    ret i1 [[TRUE]]
1579 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
1580 ; CGSCC-LABEL: define {{[^@]+}}@propagate_range2
1581 ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {
1582 ; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR7]]
1583 ; CGSCC-NEXT:    [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR7]]
1584 ; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR7]]
1585 ; CGSCC-NEXT:    [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR7]]
1586 ; CGSCC-NEXT:    [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
1587 ; CGSCC-NEXT:    ret i1 [[TRUE]]
1589   %csret1 = call i32 @less_than_100_2(i32 0)
1590   %true1 = call i1 @is_less_than_100_2(i32 %csret1)
1591   %csret2 = call i32 @less_than_100_2(i32 %c)
1592   %true2 = call i1 @is_less_than_100_2(i32 %csret2)
1593   %true = and i1 %true1, %true2
1594   ret i1 %true
1597 define internal i1 @non_zero(i8 %v) {
1598 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1599 ; TUNIT-LABEL: define {{[^@]+}}@non_zero
1600 ; TUNIT-SAME: (i8 [[V:%.*]]) #[[ATTR1]] {
1601 ; TUNIT-NEXT:    [[R:%.*]] = icmp ne i8 [[V]], 0
1602 ; TUNIT-NEXT:    ret i1 [[R]]
1604 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1605 ; CGSCC-LABEL: define {{[^@]+}}@non_zero
1606 ; CGSCC-SAME: (i8 [[V:%.*]]) #[[ATTR2]] {
1607 ; CGSCC-NEXT:    ret i1 true
1609   %r = icmp ne i8 %v, 0
1610   ret i1 %r
1613 ; Avoid range metadata for %l below
1614 define i1 @context(ptr %p) {
1615 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
1616 ; TUNIT-LABEL: define {{[^@]+}}@context
1617 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR0]] {
1618 ; TUNIT-NEXT:    [[L:%.*]] = load i8, ptr [[P]], align 1
1619 ; TUNIT-NEXT:    [[C:%.*]] = icmp slt i8 0, [[L]]
1620 ; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1621 ; TUNIT:       t:
1622 ; TUNIT-NEXT:    [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR4]]
1623 ; TUNIT-NEXT:    ret i1 [[R]]
1624 ; TUNIT:       f:
1625 ; TUNIT-NEXT:    ret i1 false
1627 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
1628 ; CGSCC-LABEL: define {{[^@]+}}@context
1629 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR1]] {
1630 ; CGSCC-NEXT:    [[L:%.*]] = load i8, ptr [[P]], align 1
1631 ; CGSCC-NEXT:    [[C:%.*]] = icmp slt i8 0, [[L]]
1632 ; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
1633 ; CGSCC:       t:
1634 ; CGSCC-NEXT:    [[R:%.*]] = call noundef i1 @non_zero(i8 [[L]]) #[[ATTR7]]
1635 ; CGSCC-NEXT:    ret i1 [[R]]
1636 ; CGSCC:       f:
1637 ; CGSCC-NEXT:    ret i1 false
1639   %l = load i8, ptr %p
1640   %c = icmp slt i8 0, %l
1641   br i1 %c, label %t, label %f
1643   %r = call i1 @non_zero(i8 %l)
1644   ret i1 %r
1646   ret i1 false
1650 define void @spam(ptr %arg, ptr %arg1) {
1651 ; CHECK-LABEL: define {{[^@]+}}@spam
1652 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[ARG:%.*]], ptr nocapture nofree readnone [[ARG1:%.*]]) {
1653 ; CHECK-NEXT:  bb:
1654 ; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr [[ARG]], align 8
1655 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP]], 4
1656 ; CHECK-NEXT:    br i1 [[TMP2]], label [[BB3:%.*]], label [[BB4:%.*]]
1657 ; CHECK:       bb3:
1658 ; CHECK-NEXT:    call fastcc void @wobble(i32 signext [[TMP]])
1659 ; CHECK-NEXT:    br label [[BB5:%.*]]
1660 ; CHECK:       bb4:
1661 ; CHECK-NEXT:    call void @ham(i32 [[TMP]])
1662 ; CHECK-NEXT:    br label [[BB5]]
1663 ; CHECK:       bb5:
1664 ; CHECK-NEXT:    ret void
1667   %tmp = load i32, ptr %arg, align 8
1668   %tmp2 = icmp ult i32 %tmp, 4
1669   br i1 %tmp2, label %bb3, label %bb4
1671 bb3:                                              ; preds = %bb
1672   call fastcc void @wobble(i32 signext %tmp)
1673   br label %bb5
1675 bb4:                                              ; preds = %bb
1676   call void @ham(i32 %tmp)
1677   br label %bb5
1679 bb5:                                              ; preds = %bb4, %bb3
1680   ret void
1683 define internal fastcc void @wobble(i32 signext %arg) {
1684 ; CHECK-LABEL: define {{[^@]+}}@wobble
1685 ; CHECK-SAME: (i32 signext [[ARG:%.*]]) {
1686 ; CHECK-NEXT:  bb:
1687 ; CHECK-NEXT:    [[TMP:%.*]] = icmp ult i32 [[ARG]], 2
1688 ; CHECK-NEXT:    br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
1689 ; CHECK:       bb1:
1690 ; CHECK-NEXT:    call void @barney(i32 noundef signext 32, i32 noundef signext 0)
1691 ; CHECK-NEXT:    br label [[BB3:%.*]]
1692 ; CHECK:       bb2:
1693 ; CHECK-NEXT:    br label [[BB3]]
1694 ; CHECK:       bb3:
1695 ; CHECK-NEXT:    ret void
1698   %tmp = icmp ult i32 %arg, 2
1699   br i1 %tmp, label %bb1, label %bb2
1701 bb1:                                              ; preds = %bb
1702   call void @barney(i32 signext 32, i32 signext 0)
1703   br label %bb3
1705 bb2:                                              ; preds = %bb
1706   br label %bb3
1708 bb3:                                              ; preds = %bb2, %bb1
1709   ret void
1712 define i1 @loop_1(i32 %N) {
1713 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)
1714 ; TUNIT-LABEL: define {{[^@]+}}@loop_1
1715 ; TUNIT-SAME: (i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] {
1716 ; TUNIT-NEXT:  entry:
1717 ; TUNIT-NEXT:    br label [[HEADER:%.*]]
1718 ; TUNIT:       header:
1719 ; TUNIT-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ]
1720 ; TUNIT-NEXT:    [[INC:%.*]] = add i32 [[I]], 1
1721 ; TUNIT-NEXT:    [[AND]] = and i32 [[INC]], 9999
1722 ; TUNIT-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]]
1723 ; TUNIT-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
1724 ; TUNIT:       exit:
1725 ; TUNIT-NEXT:    [[R:%.*]] = icmp sle i32 [[I]], 5
1726 ; TUNIT-NEXT:    ret i1 [[R]]
1728 ; CGSCC: Function Attrs: nofree norecurse nosync nounwind memory(none)
1729 ; CGSCC-LABEL: define {{[^@]+}}@loop_1
1730 ; CGSCC-SAME: (i32 [[N:%.*]]) #[[ATTR4:[0-9]+]] {
1731 ; CGSCC-NEXT:  entry:
1732 ; CGSCC-NEXT:    br label [[HEADER:%.*]]
1733 ; CGSCC:       header:
1734 ; CGSCC-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ]
1735 ; CGSCC-NEXT:    [[INC:%.*]] = add i32 [[I]], 1
1736 ; CGSCC-NEXT:    [[AND]] = and i32 [[INC]], 9999
1737 ; CGSCC-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]]
1738 ; CGSCC-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
1739 ; CGSCC:       exit:
1740 ; CGSCC-NEXT:    [[R:%.*]] = icmp sle i32 [[I]], 5
1741 ; CGSCC-NEXT:    ret i1 [[R]]
1743 entry:
1744   br label %header
1745 header:
1746   %i = phi i32 [0, %entry], [%and, %header]
1747   %inc = add i32 %i, 1
1748   %and = and i32 %inc, 9999
1749   %cmp = icmp ne i32 %N, %and
1750   br i1 %cmp, label %header, label %exit
1751 exit:
1752   %r = icmp sle i32 %i, 5
1753   ret i1 %r
1756 declare void @ham(i32)
1758 declare void @barney(i32 signext, i32 signext)
1761 !0 = !{i32 0, i32 10}
1762 !1 = !{i32 10, i32 100}
1764 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
1765 ; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
1766 ; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(none) }
1767 ; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(read) }
1768 ; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(none) }
1770 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
1771 ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: read) }
1772 ; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
1773 ; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
1774 ; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind memory(none) }
1775 ; CGSCC: attributes #[[ATTR5]] = { nofree willreturn memory(read) }
1776 ; CGSCC: attributes #[[ATTR6]] = { nofree willreturn }
1777 ; CGSCC: attributes #[[ATTR7]] = { nofree nosync willreturn }
1779 ; TUNIT: [[RNG0]] = !{i32 0, i32 10}
1780 ; TUNIT: [[RNG1]] = !{i32 10, i32 100}
1781 ; TUNIT: [[RNG2]] = !{i32 200, i32 1091}
1782 ; TUNIT: [[RNG3]] = !{i32 1, i32 -2147483648}
1784 ; CGSCC: [[RNG0]] = !{i32 0, i32 10}
1785 ; CGSCC: [[RNG1]] = !{i32 10, i32 100}