[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / addsub-constant-folding.ll
blobe9584f35238e31b35ae5bb7ea18f14fed2095eef
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare void @use(i32 %arg)
5 declare void @vec_use(<4 x i32> %arg)
7 ; (x+c1)+c2
9 define i32 @add_const_add_const(i32 %arg) {
10 ; CHECK-LABEL: @add_const_add_const(
11 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG:%.*]], 10
12 ; CHECK-NEXT:    ret i32 [[T1]]
14   %t0 = add i32 %arg, 8
15   %t1 = add i32 %t0, 2
16   ret i32 %t1
19 define i32 @add_const_add_const_extrause(i32 %arg) {
20 ; CHECK-LABEL: @add_const_add_const_extrause(
21 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[ARG:%.*]], 8
22 ; CHECK-NEXT:    call void @use(i32 [[T0]])
23 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG]], 10
24 ; CHECK-NEXT:    ret i32 [[T1]]
26   %t0 = add i32 %arg, 8
27   call void @use(i32 %t0)
28   %t1 = add i32 %t0, 2
29   ret i32 %t1
32 define <4 x i32> @vec_add_const_add_const(<4 x i32> %arg) {
33 ; CHECK-LABEL: @vec_add_const_add_const(
34 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 10, i32 10, i32 10, i32 10>
35 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
37   %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
38   %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
39   ret <4 x i32> %t1
42 define <4 x i32> @vec_add_const_add_const_extrause(<4 x i32> %arg) {
43 ; CHECK-LABEL: @vec_add_const_add_const_extrause(
44 ; CHECK-NEXT:    [[T0:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 8, i32 8, i32 8, i32 8>
45 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
46 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG]], <i32 10, i32 10, i32 10, i32 10>
47 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
49   %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
50   call void @vec_use(<4 x i32> %t0)
51   %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
52   ret <4 x i32> %t1
55 define <4 x i32> @vec_add_const_add_const_nonsplat(<4 x i32> %arg) {
56 ; CHECK-LABEL: @vec_add_const_add_const_nonsplat(
57 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 23, i32 undef, i32 undef, i32 10>
58 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
60   %t0 = add <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
61   %t1 = add <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
62   ret <4 x i32> %t1
65 ; (x+c1)-c2
67 define i32 @add_const_sub_const(i32 %arg) {
68 ; CHECK-LABEL: @add_const_sub_const(
69 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG:%.*]], 6
70 ; CHECK-NEXT:    ret i32 [[T1]]
72   %t0 = add i32 %arg, 8
73   %t1 = sub i32 %t0, 2
74   ret i32 %t1
77 define i32 @add_const_sub_const_extrause(i32 %arg) {
78 ; CHECK-LABEL: @add_const_sub_const_extrause(
79 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[ARG:%.*]], 8
80 ; CHECK-NEXT:    call void @use(i32 [[T0]])
81 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG]], 6
82 ; CHECK-NEXT:    ret i32 [[T1]]
84   %t0 = add i32 %arg, 8
85   call void @use(i32 %t0)
86   %t1 = sub i32 %t0, 2
87   ret i32 %t1
90 define <4 x i32> @vec_add_const_sub_const(<4 x i32> %arg) {
91 ; CHECK-LABEL: @vec_add_const_sub_const(
92 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 6, i32 6, i32 6, i32 6>
93 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
95   %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
96   %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
97   ret <4 x i32> %t1
100 define <4 x i32> @vec_add_const_sub_const_extrause(<4 x i32> %arg) {
101 ; CHECK-LABEL: @vec_add_const_sub_const_extrause(
102 ; CHECK-NEXT:    [[T0:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 8, i32 8, i32 8, i32 8>
103 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
104 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG]], <i32 6, i32 6, i32 6, i32 6>
105 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
107   %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
108   call void @vec_use(<4 x i32> %t0)
109   %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
110   ret <4 x i32> %t1
113 define <4 x i32> @vec_add_const_sub_const_nonsplat(<4 x i32> %arg) {
114 ; CHECK-LABEL: @vec_add_const_sub_const_nonsplat(
115 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 19, i32 undef, i32 undef, i32 6>
116 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
118   %t0 = add <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
119   %t1 = sub <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
120   ret <4 x i32> %t1
123 ; c2-(x+c1)
125 define i32 @add_const_const_sub(i32 %arg) {
126 ; CHECK-LABEL: @add_const_const_sub(
127 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 -6, [[ARG:%.*]]
128 ; CHECK-NEXT:    ret i32 [[T1]]
130   %t0 = add i32 %arg, 8
131   %t1 = sub i32 2, %t0
132   ret i32 %t1
135 define i32 @add_const_const_sub_extrause(i32 %arg) {
136 ; CHECK-LABEL: @add_const_const_sub_extrause(
137 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[ARG:%.*]], 8
138 ; CHECK-NEXT:    call void @use(i32 [[T0]])
139 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 -6, [[ARG]]
140 ; CHECK-NEXT:    ret i32 [[T1]]
142   %t0 = add i32 %arg, 8
143   call void @use(i32 %t0)
144   %t1 = sub i32 2, %t0
145   ret i32 %t1
148 define <4 x i32> @vec_add_const_const_sub(<4 x i32> %arg) {
149 ; CHECK-LABEL: @vec_add_const_const_sub(
150 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 -6, i32 -6, i32 -6, i32 -6>, [[ARG:%.*]]
151 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
153   %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
154   %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
155   ret <4 x i32> %t1
158 define <4 x i32> @vec_add_const_const_sub_extrause(<4 x i32> %arg) {
159 ; CHECK-LABEL: @vec_add_const_const_sub_extrause(
160 ; CHECK-NEXT:    [[T0:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 8, i32 8, i32 8, i32 8>
161 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
162 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 -6, i32 -6, i32 -6, i32 -6>, [[ARG]]
163 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
165   %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
166   call void @vec_use(<4 x i32> %t0)
167   %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
168   ret <4 x i32> %t1
171 define <4 x i32> @vec_add_const_const_sub_nonsplat(<4 x i32> %arg) {
172 ; CHECK-LABEL: @vec_add_const_const_sub_nonsplat(
173 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 -19, i32 undef, i32 undef, i32 -6>, [[ARG:%.*]]
174 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
176   %t0 = add <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
177   %t1 = sub <4 x i32> <i32 2, i32 3, i32 undef, i32 2>, %t0
178   ret <4 x i32> %t1
181 ; (x-c1)+c2
183 define i32 @sub_const_add_const(i32 %arg) {
184 ; CHECK-LABEL: @sub_const_add_const(
185 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG:%.*]], -6
186 ; CHECK-NEXT:    ret i32 [[T1]]
188   %t0 = sub i32 %arg, 8
189   %t1 = add i32 %t0, 2
190   ret i32 %t1
193 define i32 @sub_const_add_const_extrause(i32 %arg) {
194 ; CHECK-LABEL: @sub_const_add_const_extrause(
195 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[ARG:%.*]], -8
196 ; CHECK-NEXT:    call void @use(i32 [[T0]])
197 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG]], -6
198 ; CHECK-NEXT:    ret i32 [[T1]]
200   %t0 = sub i32 %arg, 8
201   call void @use(i32 %t0)
202   %t1 = add i32 %t0, 2
203   ret i32 %t1
206 define <4 x i32> @vec_sub_const_add_const(<4 x i32> %arg) {
207 ; CHECK-LABEL: @vec_sub_const_add_const(
208 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -6, i32 -6, i32 -6, i32 -6>
209 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
211   %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
212   %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
213   ret <4 x i32> %t1
216 define <4 x i32> @vec_sub_const_add_const_extrause(<4 x i32> %arg) {
217 ; CHECK-LABEL: @vec_sub_const_add_const_extrause(
218 ; CHECK-NEXT:    [[T0:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -8, i32 -8, i32 -8, i32 -8>
219 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
220 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG]], <i32 -6, i32 -6, i32 -6, i32 -6>
221 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
223   %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
224   call void @vec_use(<4 x i32> %t0)
225   %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
226   ret <4 x i32> %t1
229 define <4 x i32> @vec_sub_const_add_const_nonsplat(<4 x i32> %arg) {
230 ; CHECK-LABEL: @vec_sub_const_add_const_nonsplat(
231 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -19, i32 undef, i32 undef, i32 -6>
232 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
234   %t0 = sub <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
235   %t1 = add <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
236   ret <4 x i32> %t1
239 ; (x-c1)-c2
241 define i32 @sub_const_sub_const(i32 %arg) {
242 ; CHECK-LABEL: @sub_const_sub_const(
243 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG:%.*]], -10
244 ; CHECK-NEXT:    ret i32 [[T1]]
246   %t0 = sub i32 %arg, 8
247   %t1 = sub i32 %t0, 2
248   ret i32 %t1
251 define i32 @sub_const_sub_const_extrause(i32 %arg) {
252 ; CHECK-LABEL: @sub_const_sub_const_extrause(
253 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[ARG:%.*]], -8
254 ; CHECK-NEXT:    call void @use(i32 [[T0]])
255 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG]], -10
256 ; CHECK-NEXT:    ret i32 [[T1]]
258   %t0 = sub i32 %arg, 8
259   call void @use(i32 %t0)
260   %t1 = sub i32 %t0, 2
261   ret i32 %t1
264 define <4 x i32> @vec_sub_const_sub_const(<4 x i32> %arg) {
265 ; CHECK-LABEL: @vec_sub_const_sub_const(
266 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -10, i32 -10, i32 -10, i32 -10>
267 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
269   %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
270   %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
271   ret <4 x i32> %t1
274 define <4 x i32> @vec_sub_const_sub_const_extrause(<4 x i32> %arg) {
275 ; CHECK-LABEL: @vec_sub_const_sub_const_extrause(
276 ; CHECK-NEXT:    [[T0:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -8, i32 -8, i32 -8, i32 -8>
277 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
278 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG]], <i32 -10, i32 -10, i32 -10, i32 -10>
279 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
281   %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
282   call void @vec_use(<4 x i32> %t0)
283   %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
284   ret <4 x i32> %t1
287 define <4 x i32> @vec_sub_const_sub_const_nonsplat(<4 x i32> %arg) {
288 ; CHECK-LABEL: @vec_sub_const_sub_const_nonsplat(
289 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -23, i32 undef, i32 undef, i32 -10>
290 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
292   %t0 = sub <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
293   %t1 = sub <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
294   ret <4 x i32> %t1
297 ; c2-(x-c1)
299 define i32 @sub_const_const_sub(i32 %arg) {
300 ; CHECK-LABEL: @sub_const_const_sub(
301 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 10, [[ARG:%.*]]
302 ; CHECK-NEXT:    ret i32 [[T1]]
304   %t0 = sub i32 %arg, 8
305   %t1 = sub i32 2, %t0
306   ret i32 %t1
309 define i32 @sub_const_const_sub_extrause(i32 %arg) {
310 ; CHECK-LABEL: @sub_const_const_sub_extrause(
311 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[ARG:%.*]], -8
312 ; CHECK-NEXT:    call void @use(i32 [[T0]])
313 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 10, [[ARG]]
314 ; CHECK-NEXT:    ret i32 [[T1]]
316   %t0 = sub i32 %arg, 8
317   call void @use(i32 %t0)
318   %t1 = sub i32 2, %t0
319   ret i32 %t1
322 define <4 x i32> @vec_sub_const_const_sub(<4 x i32> %arg) {
323 ; CHECK-LABEL: @vec_sub_const_const_sub(
324 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 10, i32 10, i32 10, i32 10>, [[ARG:%.*]]
325 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
327   %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
328   %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
329   ret <4 x i32> %t1
332 define <4 x i32> @vec_sub_const_const_sub_extrause(<4 x i32> %arg) {
333 ; CHECK-LABEL: @vec_sub_const_const_sub_extrause(
334 ; CHECK-NEXT:    [[T0:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -8, i32 -8, i32 -8, i32 -8>
335 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
336 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 10, i32 10, i32 10, i32 10>, [[ARG]]
337 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
339   %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
340   call void @vec_use(<4 x i32> %t0)
341   %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
342   ret <4 x i32> %t1
345 define <4 x i32> @vec_sub_const_const_sub_nonsplat(<4 x i32> %arg) {
346 ; CHECK-LABEL: @vec_sub_const_const_sub_nonsplat(
347 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 23, i32 undef, i32 undef, i32 10>, [[ARG:%.*]]
348 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
350   %t0 = sub <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
351   %t1 = sub <4 x i32> <i32 2, i32 3, i32 undef, i32 2>, %t0
352   ret <4 x i32> %t1
355 ; (c1-x)+c2
357 define i32 @const_sub_add_const(i32 %arg) {
358 ; CHECK-LABEL: @const_sub_add_const(
359 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 10, [[ARG:%.*]]
360 ; CHECK-NEXT:    ret i32 [[T1]]
362   %t0 = sub i32 8, %arg
363   %t1 = add i32 %t0, 2
364   ret i32 %t1
367 define i32 @const_sub_add_const_extrause(i32 %arg) {
368 ; CHECK-LABEL: @const_sub_add_const_extrause(
369 ; CHECK-NEXT:    [[T0:%.*]] = sub i32 8, [[ARG:%.*]]
370 ; CHECK-NEXT:    call void @use(i32 [[T0]])
371 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 10, [[ARG]]
372 ; CHECK-NEXT:    ret i32 [[T1]]
374   %t0 = sub i32 8, %arg
375   call void @use(i32 %t0)
376   %t1 = add i32 %t0, 2
377   ret i32 %t1
380 define <4 x i32> @vec_const_sub_add_const(<4 x i32> %arg) {
381 ; CHECK-LABEL: @vec_const_sub_add_const(
382 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 10, i32 10, i32 10, i32 10>, [[ARG:%.*]]
383 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
385   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
386   %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
387   ret <4 x i32> %t1
390 define <4 x i32> @vec_const_sub_add_const_extrause(<4 x i32> %arg) {
391 ; CHECK-LABEL: @vec_const_sub_add_const_extrause(
392 ; CHECK-NEXT:    [[T0:%.*]] = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, [[ARG:%.*]]
393 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
394 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 10, i32 10, i32 10, i32 10>, [[ARG]]
395 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
397   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
398   call void @vec_use(<4 x i32> %t0)
399   %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
400   ret <4 x i32> %t1
403 define <4 x i32> @vec_const_sub_add_const_nonsplat(<4 x i32> %arg) {
404 ; CHECK-LABEL: @vec_const_sub_add_const_nonsplat(
405 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 23, i32 undef, i32 undef, i32 10>, [[ARG:%.*]]
406 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
408   %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg
409   %t1 = add <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
410   ret <4 x i32> %t1
413 ; (c1-x)-c2
415 define i32 @const_sub_sub_const(i32 %arg) {
416 ; CHECK-LABEL: @const_sub_sub_const(
417 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 6, [[ARG:%.*]]
418 ; CHECK-NEXT:    ret i32 [[T1]]
420   %t0 = sub i32 8, %arg
421   %t1 = sub i32 %t0, 2
422   ret i32 %t1
425 define i32 @const_sub_sub_const_extrause(i32 %arg) {
426 ; CHECK-LABEL: @const_sub_sub_const_extrause(
427 ; CHECK-NEXT:    [[T0:%.*]] = sub i32 8, [[ARG:%.*]]
428 ; CHECK-NEXT:    call void @use(i32 [[T0]])
429 ; CHECK-NEXT:    [[T1:%.*]] = sub i32 6, [[ARG]]
430 ; CHECK-NEXT:    ret i32 [[T1]]
432   %t0 = sub i32 8, %arg
433   call void @use(i32 %t0)
434   %t1 = sub i32 %t0, 2
435   ret i32 %t1
438 define <4 x i32> @vec_const_sub_sub_const(<4 x i32> %arg) {
439 ; CHECK-LABEL: @vec_const_sub_sub_const(
440 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 6, i32 6, i32 6, i32 6>, [[ARG:%.*]]
441 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
443   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
444   %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
445   ret <4 x i32> %t1
448 define <4 x i32> @vec_const_sub_sub_const_extrause(<4 x i32> %arg) {
449 ; CHECK-LABEL: @vec_const_sub_sub_const_extrause(
450 ; CHECK-NEXT:    [[T0:%.*]] = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, [[ARG:%.*]]
451 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
452 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 6, i32 6, i32 6, i32 6>, [[ARG]]
453 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
455   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
456   call void @vec_use(<4 x i32> %t0)
457   %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
458   ret <4 x i32> %t1
461 define <4 x i32> @vec_const_sub_sub_const_nonsplat(<4 x i32> %arg) {
462 ; CHECK-LABEL: @vec_const_sub_sub_const_nonsplat(
463 ; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 19, i32 undef, i32 undef, i32 6>, [[ARG:%.*]]
464 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
466   %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg
467   %t1 = sub <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
468   ret <4 x i32> %t1
471 ; c2-(c1-x)
472 ; FIXME
474 define i32 @const_sub_const_sub(i32 %arg) {
475 ; CHECK-LABEL: @const_sub_const_sub(
476 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG:%.*]], -6
477 ; CHECK-NEXT:    ret i32 [[T1]]
479   %t0 = sub i32 8, %arg
480   %t1 = sub i32 2, %t0
481   ret i32 %t1
484 define i32 @const_sub_const_sub_extrause(i32 %arg) {
485 ; CHECK-LABEL: @const_sub_const_sub_extrause(
486 ; CHECK-NEXT:    [[T0:%.*]] = sub i32 8, [[ARG:%.*]]
487 ; CHECK-NEXT:    call void @use(i32 [[T0]])
488 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG]], -6
489 ; CHECK-NEXT:    ret i32 [[T1]]
491   %t0 = sub i32 8, %arg
492   call void @use(i32 %t0)
493   %t1 = sub i32 2, %t0
494   ret i32 %t1
497 define <4 x i32> @vec_const_sub_const_sub(<4 x i32> %arg) {
498 ; CHECK-LABEL: @vec_const_sub_const_sub(
499 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -6, i32 -6, i32 -6, i32 -6>
500 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
502   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
503   %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
504   ret <4 x i32> %t1
507 define <4 x i32> @vec_const_sub_const_sub_extrause(<4 x i32> %arg) {
508 ; CHECK-LABEL: @vec_const_sub_const_sub_extrause(
509 ; CHECK-NEXT:    [[T0:%.*]] = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, [[ARG:%.*]]
510 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
511 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG]], <i32 -6, i32 -6, i32 -6, i32 -6>
512 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
514   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
515   call void @vec_use(<4 x i32> %t0)
516   %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
517   ret <4 x i32> %t1
520 define <4 x i32> @vec_const_sub_const_sub_nonsplat(<4 x i32> %arg) {
521 ; CHECK-LABEL: @vec_const_sub_const_sub_nonsplat(
522 ; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -19, i32 undef, i32 undef, i32 -6>
523 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
525   %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg
526   %t1 = sub <4 x i32> <i32 2, i32 3, i32 undef, i32 2>, %t0
527   ret <4 x i32> %t1
530 define i7 @addsub_combine_constants(i7 %x, i7 %y) {
531 ; CHECK-LABEL: @addsub_combine_constants(
532 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i7 [[X:%.*]], [[Y:%.*]]
533 ; CHECK-NEXT:    [[A2:%.*]] = add i7 [[TMP1]], 52
534 ; CHECK-NEXT:    ret i7 [[A2]]
536   %a1 = add i7 %x, 42
537   %s = sub i7 10, %y
538   %a2 = add nsw i7 %a1, %s
539   ret i7 %a2
542 define <4 x i32> @addsub_combine_constants_use1(<4 x i32> %x, <4 x i32> %y) {
543 ; CHECK-LABEL: @addsub_combine_constants_use1(
544 ; CHECK-NEXT:    [[A1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 -7, i32 0, i32 -1>
545 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[A1]])
546 ; CHECK-NEXT:    [[TMP1:%.*]] = sub <4 x i32> [[X]], [[Y:%.*]]
547 ; CHECK-NEXT:    [[A2:%.*]] = add <4 x i32> [[TMP1]], <i32 -58, i32 -6, i32 -1, i32 41>
548 ; CHECK-NEXT:    ret <4 x i32> [[A2]]
550   %a1 = add <4 x i32> %x, <i32 42, i32 -7, i32 0, i32 -1>
551   call void @vec_use(<4 x i32> %a1)
552   %s = sub <4 x i32> <i32 -100, i32 1, i32 -1, i32 42>, %y
553   %a2 = add nuw <4 x i32> %s, %a1
554   ret <4 x i32> %a2
557 define i32 @addsub_combine_constants_use2(i32 %x, i32 %y) {
558 ; CHECK-LABEL: @addsub_combine_constants_use2(
559 ; CHECK-NEXT:    [[S:%.*]] = sub i32 100, [[Y:%.*]]
560 ; CHECK-NEXT:    call void @use(i32 [[S]])
561 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[X:%.*]], [[Y]]
562 ; CHECK-NEXT:    [[A2:%.*]] = add i32 [[TMP1]], 142
563 ; CHECK-NEXT:    ret i32 [[A2]]
565   %a1 = add i32 %x, 42
566   %s = sub i32 100, %y
567   call void @use(i32 %s)
568   %a2 = add i32 %a1, %s
569   ret i32 %a2
572 ; negative test - too many uses
574 define i32 @addsub_combine_constants_use3(i32 %x, i32 %y) {
575 ; CHECK-LABEL: @addsub_combine_constants_use3(
576 ; CHECK-NEXT:    [[A1:%.*]] = add i32 [[X:%.*]], 42
577 ; CHECK-NEXT:    call void @use(i32 [[A1]])
578 ; CHECK-NEXT:    [[S:%.*]] = sub i32 100, [[Y:%.*]]
579 ; CHECK-NEXT:    call void @use(i32 [[S]])
580 ; CHECK-NEXT:    [[A2:%.*]] = add i32 [[A1]], [[S]]
581 ; CHECK-NEXT:    ret i32 [[A2]]
583   %a1 = add i32 %x, 42
584   call void @use(i32 %a1)
585   %s = sub i32 100, %y
586   call void @use(i32 %s)
587   %a2 = add i32 %a1, %s
588   ret i32 %a2