1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4declare void @use(i32 %arg)
5declare void @vec_use(<4 x i32> %arg)
6
7; (x+c1)+c2
8
9define 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]]
13;
14  %t0 = add i32 %arg, 8
15  %t1 = add i32 %t0, 2
16  ret i32 %t1
17}
18
19define 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]]
25;
26  %t0 = add i32 %arg, 8
27  call void @use(i32 %t0)
28  %t1 = add i32 %t0, 2
29  ret i32 %t1
30}
31
32define <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]]
36;
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
40}
41
42define <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]]
48;
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
53}
54
55define <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]]
59;
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
63}
64
65; (x+c1)-c2
66
67define 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]]
71;
72  %t0 = add i32 %arg, 8
73  %t1 = sub i32 %t0, 2
74  ret i32 %t1
75}
76
77define 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]]
83;
84  %t0 = add i32 %arg, 8
85  call void @use(i32 %t0)
86  %t1 = sub i32 %t0, 2
87  ret i32 %t1
88}
89
90define <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]]
94;
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
98}
99
100define <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]]
106;
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
111}
112
113define <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]]
117;
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
121}
122
123; c2-(x+c1)
124
125define 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]]
129;
130  %t0 = add i32 %arg, 8
131  %t1 = sub i32 2, %t0
132  ret i32 %t1
133}
134
135define 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]]
141;
142  %t0 = add i32 %arg, 8
143  call void @use(i32 %t0)
144  %t1 = sub i32 2, %t0
145  ret i32 %t1
146}
147
148define <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]]
152;
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
156}
157
158define <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]]
164;
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
169}
170
171define <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]]
175;
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
179}
180
181; (x-c1)+c2
182
183define 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]]
187;
188  %t0 = sub i32 %arg, 8
189  %t1 = add i32 %t0, 2
190  ret i32 %t1
191}
192
193define 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]]
199;
200  %t0 = sub i32 %arg, 8
201  call void @use(i32 %t0)
202  %t1 = add i32 %t0, 2
203  ret i32 %t1
204}
205
206define <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]]
210;
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
214}
215
216define <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]]
222;
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
227}
228
229define <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]]
233;
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
237}
238
239; (x-c1)-c2
240
241define 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]]
245;
246  %t0 = sub i32 %arg, 8
247  %t1 = sub i32 %t0, 2
248  ret i32 %t1
249}
250
251define 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]]
257;
258  %t0 = sub i32 %arg, 8
259  call void @use(i32 %t0)
260  %t1 = sub i32 %t0, 2
261  ret i32 %t1
262}
263
264define <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]]
268;
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
272}
273
274define <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]]
280;
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
285}
286
287define <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]]
291;
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
295}
296
297; c2-(x-c1)
298
299define 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]]
303;
304  %t0 = sub i32 %arg, 8
305  %t1 = sub i32 2, %t0
306  ret i32 %t1
307}
308
309define 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]]
315;
316  %t0 = sub i32 %arg, 8
317  call void @use(i32 %t0)
318  %t1 = sub i32 2, %t0
319  ret i32 %t1
320}
321
322define <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]]
326;
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
330}
331
332define <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]]
338;
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
343}
344
345define <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]]
349;
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
353}
354
355; (c1-x)+c2
356
357define 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]]
361;
362  %t0 = sub i32 8, %arg
363  %t1 = add i32 %t0, 2
364  ret i32 %t1
365}
366
367define 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]]
373;
374  %t0 = sub i32 8, %arg
375  call void @use(i32 %t0)
376  %t1 = add i32 %t0, 2
377  ret i32 %t1
378}
379
380define <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]]
384;
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
388}
389
390define <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]]
396;
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
401}
402
403define <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]]
407;
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
411}
412
413; (c1-x)-c2
414
415define 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]]
419;
420  %t0 = sub i32 8, %arg
421  %t1 = sub i32 %t0, 2
422  ret i32 %t1
423}
424
425define 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]]
431;
432  %t0 = sub i32 8, %arg
433  call void @use(i32 %t0)
434  %t1 = sub i32 %t0, 2
435  ret i32 %t1
436}
437
438define <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]]
442;
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
446}
447
448define <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]]
454;
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
459}
460
461define <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]]
465;
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
469}
470
471; c2-(c1-x)
472; FIXME
473
474define 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]]
478;
479  %t0 = sub i32 8, %arg
480  %t1 = sub i32 2, %t0
481  ret i32 %t1
482}
483
484define 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]]
490;
491  %t0 = sub i32 8, %arg
492  call void @use(i32 %t0)
493  %t1 = sub i32 2, %t0
494  ret i32 %t1
495}
496
497define <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]]
501;
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
505}
506
507define <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]]
513;
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
518}
519
520define <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]]
524;
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
528}
529