[ConstraintElim] Add support for decomposing gep nuw (#118639)
[llvm-project.git] / llvm / test / Transforms / SCCP / load-store-range.ll
blob1760121c14e6c70d1d1fef774fa1760dde8bd51c
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=ipsccp -S | FileCheck %s
4 declare void @use(i1)
6 @G = internal global i32 0
8 define void @test1a() {
9 ; CHECK-LABEL: @test1a(
10 ; CHECK-NEXT:    [[X:%.*]] = load i32, ptr @G
11 ; CHECK-NEXT:    call void @use(i1 true)
12 ; CHECK-NEXT:    call void @use(i1 true)
13 ; CHECK-NEXT:    call void @use(i1 false)
14 ; CHECK-NEXT:    call void @use(i1 false)
15 ; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i32 [[X]], 20
16 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
17 ; CHECK-NEXT:    ret void
19   %X = load i32, ptr @G
20   %t.1 = icmp ne i32 %X, 124
21   call void @use(i1 %t.1)
22   %t.2 = icmp ult i32 %X, 124
23   call void @use(i1 %t.2)
24   %f.1 = icmp eq i32 %X, 124
25   call void @use(i1 %f.1)
26   %f.2 = icmp ugt i32 %X, 123
27   call void @use(i1 %f.2)
28   %c.1 = icmp eq i32 %X, 20
29   call void @use(i1 %c.1)
30   ret void
33 define void @test1b(i1 %c) {
34 ; CHECK-LABEL: @test1b(
35 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[T:%.*]], label [[F:%.*]]
36 ; CHECK:       T:
37 ; CHECK-NEXT:    store i32 17, ptr @G
38 ; CHECK-NEXT:    ret void
39 ; CHECK:       F:
40 ; CHECK-NEXT:    store i32 123, ptr @G
41 ; CHECK-NEXT:    ret void
43   br i1 %c, label %T, label %F
45   store i32 17, ptr @G
46   ret void
48   store i32 123, ptr @G
49   ret void
53 @H = internal global i32 0
55 define void @test2a() {
56 ; CHECK-LABEL: @test2a(
57 ; CHECK-NEXT:    [[X:%.*]] = load i32, ptr @H
58 ; CHECK-NEXT:    call void @use(i1 true)
59 ; CHECK-NEXT:    call void @use(i1 true)
60 ; CHECK-NEXT:    call void @use(i1 false)
61 ; CHECK-NEXT:    call void @use(i1 false)
62 ; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i32 [[X]], 20
63 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
64 ; CHECK-NEXT:    ret void
66   %X = load i32, ptr @H
67   %t.1 = icmp ne i32 %X, 124
68   call void @use(i1 %t.1)
69   %t.2 = icmp ult i32 %X, 124
70   call void @use(i1 %t.2)
71   %f.1 = icmp eq i32 %X, 124
72   call void @use(i1 %f.1)
73   %f.2 = icmp ugt i32 %X, 123
74   call void @use(i1 %f.2)
75   %c.1 = icmp eq i32 %X, 20
76   call void @use(i1 %c.1)
77   ret void
80 define void @test2b(i1 %c.1, i1 %c.2) {
81 ; CHECK-LABEL: @test2b(
82 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[T:%.*]], label [[F:%.*]]
83 ; CHECK:       T:
84 ; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[T_1:%.*]], label [[F_1:%.*]]
85 ; CHECK:       T.1:
86 ; CHECK-NEXT:    store i32 17, ptr @H
87 ; CHECK-NEXT:    ret void
88 ; CHECK:       F.1:
89 ; CHECK-NEXT:    store i32 20, ptr @H
90 ; CHECK-NEXT:    ret void
91 ; CHECK:       F:
92 ; CHECK-NEXT:    store i32 123, ptr @H
93 ; CHECK-NEXT:    ret void
95   br i1 %c.1, label %T, label %F
97   br i1 %c.2, label %T.1, label %F.1
99 T.1:
100   store i32 17, ptr @H
101   ret void
103 F.1:
104   store i32 20, ptr @H
105   ret void
108   store i32 123, ptr @H
109   ret void
113 @I = internal global i32 0
115 define void @test3a() {
116 ; CHECK-LABEL: @test3a(
117 ; CHECK-NEXT:    [[X:%.*]] = load i32, ptr @I
118 ; CHECK-NEXT:    call void @use(i1 true)
119 ; CHECK-NEXT:    call void @use(i1 true)
120 ; CHECK-NEXT:    call void @use(i1 false)
121 ; CHECK-NEXT:    call void @use(i1 false)
122 ; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i32 [[X]], 20
123 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
124 ; CHECK-NEXT:    ret void
126   %X = load i32, ptr @I
127   %t.1 = icmp ne i32 %X, 124
128   call void @use(i1 %t.1)
129   %t.2 = icmp ult i32 %X, 124
130   call void @use(i1 %t.2)
131   %f.1 = icmp eq i32 %X, 124
132   call void @use(i1 %f.1)
133   %f.2 = icmp ugt i32 %X, 123
134   call void @use(i1 %f.2)
135   %c.1 = icmp eq i32 %X, 20
136   call void @use(i1 %c.1)
137   ret void
140 define void @test3b(i1 %c.1, i1 %c.2) {
141 ; CHECK-LABEL: @test3b(
142 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[T:%.*]], label [[F:%.*]]
143 ; CHECK:       T:
144 ; CHECK-NEXT:    br label [[EXIT:%.*]]
145 ; CHECK:       F:
146 ; CHECK-NEXT:    br label [[EXIT]]
147 ; CHECK:       exit:
148 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 17, [[T]] ], [ 123, [[F]] ]
149 ; CHECK-NEXT:    store i32 [[P]], ptr @I
150 ; CHECK-NEXT:    ret void
152   br i1 %c.1, label %T, label %F
155   br label %exit
158   br label %exit
160 exit:
161   %p = phi i32 [ 17, %T ], [ 123, %F ]
162   store i32 %p, ptr @I
163   ret void
167 ; Make sure stored values are correctly updated to overdefined.
168 @J = internal global i32 0
170 define void @test4a() {
171 ; CHECK-LABEL: @test4a(
172 ; CHECK-NEXT:    [[X:%.*]] = load i32, ptr @J
173 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ne i32 [[X]], 124
174 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
175 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ult i32 [[X]], 124
176 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
177 ; CHECK-NEXT:    [[C_3:%.*]] = icmp eq i32 [[X]], 124
178 ; CHECK-NEXT:    call void @use(i1 [[C_3]])
179 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[X]], 123
180 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
181 ; CHECK-NEXT:    [[C_5:%.*]] = icmp eq i32 [[X]], 20
182 ; CHECK-NEXT:    call void @use(i1 [[C_5]])
183 ; CHECK-NEXT:    ret void
185   %X = load i32, ptr @J
186   %c.1 = icmp ne i32 %X, 124
187   call void @use(i1 %c.1)
188   %c.2 = icmp ult i32 %X, 124
189   call void @use(i1 %c.2)
190   %c.3 = icmp eq i32 %X, 124
191   call void @use(i1 %c.3)
192   %c.4 = icmp ugt i32 %X, 123
193   call void @use(i1 %c.4)
194   %c.5 = icmp eq i32 %X, 20
195   call void @use(i1 %c.5)
196   ret void
199 define void @test4b(i1 %c.1, i1 %c.2, i32 %x) {
200 ; CHECK-LABEL: @test4b(
201 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[T:%.*]], label [[F:%.*]]
202 ; CHECK:       T:
203 ; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[T_1:%.*]], label [[F_1:%.*]]
204 ; CHECK:       T.1:
205 ; CHECK-NEXT:    br label [[EXIT:%.*]]
206 ; CHECK:       F.1:
207 ; CHECK-NEXT:    br label [[EXIT]]
208 ; CHECK:       F:
209 ; CHECK-NEXT:    br label [[EXIT]]
210 ; CHECK:       exit:
211 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 17, [[T_1]] ], [ [[X:%.*]], [[F_1]] ], [ 123, [[F]] ]
212 ; CHECK-NEXT:    store i32 [[P]], ptr @J
213 ; CHECK-NEXT:    ret void
215   br i1 %c.1, label %T, label %F
217   br i1 %c.2, label %T.1, label %F.1
219 T.1:
220   br label %exit
222 F.1:
223   br label %exit
226   br label %exit
228 exit:
229   %p = phi i32 [ 17, %T.1 ], [ %x, %F.1 ], [ 123, %F ]
230   store i32 %p, ptr @J
231   ret void
234 ; Same as test1, but storing 4 different values.
236 @K = internal global i32 501
238 define void @test5a() {
239 ; CHECK-LABEL: @test5a(
240 ; CHECK-NEXT:    [[X:%.*]] = load i32, ptr @K
241 ; CHECK-NEXT:    call void @use(i1 true)
242 ; CHECK-NEXT:    call void @use(i1 true)
243 ; CHECK-NEXT:    call void @use(i1 false)
244 ; CHECK-NEXT:    call void @use(i1 false)
245 ; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i32 [[X]], 510
246 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
247 ; CHECK-NEXT:    ret void
249   %X = load i32, ptr @K
250   %t.1 = icmp ne i32 %X, 499
251   call void @use(i1 %t.1)
252   %t.2 = icmp ult i32 %X, 600
253   call void @use(i1 %t.2)
254   %f.1 = icmp eq i32 %X, 600
255   call void @use(i1 %f.1)
256   %f.2 = icmp ugt i32 %X, 600
257   call void @use(i1 %f.2)
258   %c.1 = icmp eq i32 %X, 510
259   call void @use(i1 %c.1)
260   ret void
263 define void @test5b(i1 %c.1, i1 %c.2) {
264 ; CHECK-LABEL: @test5b(
265 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[T_1:%.*]], label [[F_1:%.*]]
266 ; CHECK:       T.1:
267 ; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[T_2:%.*]], label [[F_2:%.*]]
268 ; CHECK:       T.2:
269 ; CHECK-NEXT:    store i32 500, ptr @K
270 ; CHECK-NEXT:    ret void
271 ; CHECK:       F.2:
272 ; CHECK-NEXT:    store i32 510, ptr @K
273 ; CHECK-NEXT:    ret void
274 ; CHECK:       F.1:
275 ; CHECK-NEXT:    br i1 [[C_2]], label [[T_3:%.*]], label [[F_3:%.*]]
276 ; CHECK:       T.3:
277 ; CHECK-NEXT:    store i32 520, ptr @K
278 ; CHECK-NEXT:    ret void
279 ; CHECK:       F.3:
280 ; CHECK-NEXT:    store i32 530, ptr @K
281 ; CHECK-NEXT:    ret void
283   br i1 %c.1, label %T.1, label %F.1
285 T.1:
286   br i1 %c.2, label %T.2, label %F.2
288 T.2:
289   store i32 500, ptr @K
290   ret void
292 F.2:
293   store i32 510, ptr @K
294   ret void
296 F.1:
297   br i1 %c.2, label %T.3, label %F.3
299 T.3:
300   store i32 520, ptr @K
301   ret void
303 F.3:
304   store i32 530, ptr @K
305   ret void