xref: /llvm-project/llvm/test/CodeGen/X86/addsub-constant-folding.ll (revision 4318b033bddc64d5654f3e368fddde859ff4d02e)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=X86
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=X64
4
5declare void @use(i32 %arg)
6declare void @vec_use(<4 x i32> %arg)
7
8; (x+c1)+c2
9
10define i32 @add_const_add_const(i32 %arg) {
11; X86-LABEL: add_const_add_const:
12; X86:       # %bb.0:
13; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
14; X86-NEXT:    addl $10, %eax
15; X86-NEXT:    retl
16;
17; X64-LABEL: add_const_add_const:
18; X64:       # %bb.0:
19; X64-NEXT:    # kill: def $edi killed $edi def $rdi
20; X64-NEXT:    leal 10(%rdi), %eax
21; X64-NEXT:    retq
22  %t0 = add i32 %arg, 8
23  %t1 = add i32 %t0, 2
24  ret i32 %t1
25}
26
27define i32 @add_const_add_const_extrause(i32 %arg) {
28; X86-LABEL: add_const_add_const_extrause:
29; X86:       # %bb.0:
30; X86-NEXT:    pushl %esi
31; X86-NEXT:    .cfi_def_cfa_offset 8
32; X86-NEXT:    .cfi_offset %esi, -8
33; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
34; X86-NEXT:    leal 8(%esi), %eax
35; X86-NEXT:    pushl %eax
36; X86-NEXT:    .cfi_adjust_cfa_offset 4
37; X86-NEXT:    calll use@PLT
38; X86-NEXT:    addl $4, %esp
39; X86-NEXT:    .cfi_adjust_cfa_offset -4
40; X86-NEXT:    addl $10, %esi
41; X86-NEXT:    movl %esi, %eax
42; X86-NEXT:    popl %esi
43; X86-NEXT:    .cfi_def_cfa_offset 4
44; X86-NEXT:    retl
45;
46; X64-LABEL: add_const_add_const_extrause:
47; X64:       # %bb.0:
48; X64-NEXT:    pushq %rbx
49; X64-NEXT:    .cfi_def_cfa_offset 16
50; X64-NEXT:    .cfi_offset %rbx, -16
51; X64-NEXT:    movl %edi, %ebx
52; X64-NEXT:    leal 8(%rbx), %edi
53; X64-NEXT:    callq use@PLT
54; X64-NEXT:    addl $10, %ebx
55; X64-NEXT:    movl %ebx, %eax
56; X64-NEXT:    popq %rbx
57; X64-NEXT:    .cfi_def_cfa_offset 8
58; X64-NEXT:    retq
59  %t0 = add i32 %arg, 8
60  call void @use(i32 %t0)
61  %t1 = add i32 %t0, 2
62  ret i32 %t1
63}
64
65define <4 x i32> @vec_add_const_add_const(<4 x i32> %arg) {
66; X86-LABEL: vec_add_const_add_const:
67; X86:       # %bb.0:
68; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
69; X86-NEXT:    retl
70;
71; X64-LABEL: vec_add_const_add_const:
72; X64:       # %bb.0:
73; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
74; X64-NEXT:    retq
75  %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
76  %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
77  ret <4 x i32> %t1
78}
79
80define <4 x i32> @vec_add_const_add_const_extrause(<4 x i32> %arg) {
81; X86-LABEL: vec_add_const_add_const_extrause:
82; X86:       # %bb.0:
83; X86-NEXT:    subl $16, %esp
84; X86-NEXT:    .cfi_def_cfa_offset 20
85; X86-NEXT:    movdqa %xmm0, %xmm1
86; X86-NEXT:    movdqu %xmm0, (%esp) # 16-byte Spill
87; X86-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
88; X86-NEXT:    paddd %xmm1, %xmm0
89; X86-NEXT:    calll vec_use@PLT
90; X86-NEXT:    movdqu (%esp), %xmm0 # 16-byte Reload
91; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
92; X86-NEXT:    addl $16, %esp
93; X86-NEXT:    .cfi_def_cfa_offset 4
94; X86-NEXT:    retl
95;
96; X64-LABEL: vec_add_const_add_const_extrause:
97; X64:       # %bb.0:
98; X64-NEXT:    subq $24, %rsp
99; X64-NEXT:    .cfi_def_cfa_offset 32
100; X64-NEXT:    movdqa %xmm0, %xmm1
101; X64-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
102; X64-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
103; X64-NEXT:    paddd %xmm1, %xmm0
104; X64-NEXT:    callq vec_use@PLT
105; X64-NEXT:    movdqa (%rsp), %xmm0 # 16-byte Reload
106; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
107; X64-NEXT:    addq $24, %rsp
108; X64-NEXT:    .cfi_def_cfa_offset 8
109; X64-NEXT:    retq
110  %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
111  call void @vec_use(<4 x i32> %t0)
112  %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
113  ret <4 x i32> %t1
114}
115
116define <4 x i32> @vec_add_const_add_const_nonsplat(<4 x i32> %arg) {
117; X86-LABEL: vec_add_const_add_const_nonsplat:
118; X86:       # %bb.0:
119; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
120; X86-NEXT:    retl
121;
122; X64-LABEL: vec_add_const_add_const_nonsplat:
123; X64:       # %bb.0:
124; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
125; X64-NEXT:    retq
126  %t0 = add <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
127  %t1 = add <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
128  ret <4 x i32> %t1
129}
130
131; (x+c1)-c2
132
133define i32 @add_const_sub_const(i32 %arg) {
134; X86-LABEL: add_const_sub_const:
135; X86:       # %bb.0:
136; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
137; X86-NEXT:    addl $6, %eax
138; X86-NEXT:    retl
139;
140; X64-LABEL: add_const_sub_const:
141; X64:       # %bb.0:
142; X64-NEXT:    # kill: def $edi killed $edi def $rdi
143; X64-NEXT:    leal 6(%rdi), %eax
144; X64-NEXT:    retq
145  %t0 = add i32 %arg, 8
146  %t1 = sub i32 %t0, 2
147  ret i32 %t1
148}
149
150define i32 @add_const_sub_const_extrause(i32 %arg) {
151; X86-LABEL: add_const_sub_const_extrause:
152; X86:       # %bb.0:
153; X86-NEXT:    pushl %esi
154; X86-NEXT:    .cfi_def_cfa_offset 8
155; X86-NEXT:    .cfi_offset %esi, -8
156; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
157; X86-NEXT:    leal 8(%esi), %eax
158; X86-NEXT:    pushl %eax
159; X86-NEXT:    .cfi_adjust_cfa_offset 4
160; X86-NEXT:    calll use@PLT
161; X86-NEXT:    addl $4, %esp
162; X86-NEXT:    .cfi_adjust_cfa_offset -4
163; X86-NEXT:    addl $6, %esi
164; X86-NEXT:    movl %esi, %eax
165; X86-NEXT:    popl %esi
166; X86-NEXT:    .cfi_def_cfa_offset 4
167; X86-NEXT:    retl
168;
169; X64-LABEL: add_const_sub_const_extrause:
170; X64:       # %bb.0:
171; X64-NEXT:    pushq %rbx
172; X64-NEXT:    .cfi_def_cfa_offset 16
173; X64-NEXT:    .cfi_offset %rbx, -16
174; X64-NEXT:    movl %edi, %ebx
175; X64-NEXT:    leal 8(%rbx), %edi
176; X64-NEXT:    callq use@PLT
177; X64-NEXT:    addl $6, %ebx
178; X64-NEXT:    movl %ebx, %eax
179; X64-NEXT:    popq %rbx
180; X64-NEXT:    .cfi_def_cfa_offset 8
181; X64-NEXT:    retq
182  %t0 = add i32 %arg, 8
183  call void @use(i32 %t0)
184  %t1 = sub i32 %t0, 2
185  ret i32 %t1
186}
187
188define <4 x i32> @vec_add_const_sub_const(<4 x i32> %arg) {
189; X86-LABEL: vec_add_const_sub_const:
190; X86:       # %bb.0:
191; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
192; X86-NEXT:    retl
193;
194; X64-LABEL: vec_add_const_sub_const:
195; X64:       # %bb.0:
196; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
197; X64-NEXT:    retq
198  %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
199  %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
200  ret <4 x i32> %t1
201}
202
203define <4 x i32> @vec_add_const_sub_const_extrause(<4 x i32> %arg) {
204; X86-LABEL: vec_add_const_sub_const_extrause:
205; X86:       # %bb.0:
206; X86-NEXT:    subl $16, %esp
207; X86-NEXT:    .cfi_def_cfa_offset 20
208; X86-NEXT:    movdqa %xmm0, %xmm1
209; X86-NEXT:    movdqu %xmm0, (%esp) # 16-byte Spill
210; X86-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
211; X86-NEXT:    paddd %xmm1, %xmm0
212; X86-NEXT:    calll vec_use@PLT
213; X86-NEXT:    movdqu (%esp), %xmm0 # 16-byte Reload
214; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
215; X86-NEXT:    addl $16, %esp
216; X86-NEXT:    .cfi_def_cfa_offset 4
217; X86-NEXT:    retl
218;
219; X64-LABEL: vec_add_const_sub_const_extrause:
220; X64:       # %bb.0:
221; X64-NEXT:    subq $24, %rsp
222; X64-NEXT:    .cfi_def_cfa_offset 32
223; X64-NEXT:    movdqa %xmm0, %xmm1
224; X64-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
225; X64-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
226; X64-NEXT:    paddd %xmm1, %xmm0
227; X64-NEXT:    callq vec_use@PLT
228; X64-NEXT:    movdqa (%rsp), %xmm0 # 16-byte Reload
229; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
230; X64-NEXT:    addq $24, %rsp
231; X64-NEXT:    .cfi_def_cfa_offset 8
232; X64-NEXT:    retq
233  %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
234  call void @vec_use(<4 x i32> %t0)
235  %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
236  ret <4 x i32> %t1
237}
238
239define <4 x i32> @vec_add_const_sub_const_nonsplat(<4 x i32> %arg) {
240; X86-LABEL: vec_add_const_sub_const_nonsplat:
241; X86:       # %bb.0:
242; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
243; X86-NEXT:    retl
244;
245; X64-LABEL: vec_add_const_sub_const_nonsplat:
246; X64:       # %bb.0:
247; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
248; X64-NEXT:    retq
249  %t0 = add <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
250  %t1 = sub <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
251  ret <4 x i32> %t1
252}
253
254; c2-(x+c1)
255
256define i32 @add_const_const_sub(i32 %arg) {
257; X86-LABEL: add_const_const_sub:
258; X86:       # %bb.0:
259; X86-NEXT:    movl $-6, %eax
260; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
261; X86-NEXT:    retl
262;
263; X64-LABEL: add_const_const_sub:
264; X64:       # %bb.0:
265; X64-NEXT:    movl $-6, %eax
266; X64-NEXT:    subl %edi, %eax
267; X64-NEXT:    retq
268  %t0 = add i32 %arg, 8
269  %t1 = sub i32 2, %t0
270  ret i32 %t1
271}
272
273define i32 @add_const_const_sub_extrause(i32 %arg) {
274; X86-LABEL: add_const_const_sub_extrause:
275; X86:       # %bb.0:
276; X86-NEXT:    pushl %esi
277; X86-NEXT:    .cfi_def_cfa_offset 8
278; X86-NEXT:    .cfi_offset %esi, -8
279; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
280; X86-NEXT:    leal 8(%esi), %eax
281; X86-NEXT:    pushl %eax
282; X86-NEXT:    .cfi_adjust_cfa_offset 4
283; X86-NEXT:    calll use@PLT
284; X86-NEXT:    addl $4, %esp
285; X86-NEXT:    .cfi_adjust_cfa_offset -4
286; X86-NEXT:    movl $-6, %eax
287; X86-NEXT:    subl %esi, %eax
288; X86-NEXT:    popl %esi
289; X86-NEXT:    .cfi_def_cfa_offset 4
290; X86-NEXT:    retl
291;
292; X64-LABEL: add_const_const_sub_extrause:
293; X64:       # %bb.0:
294; X64-NEXT:    pushq %rbx
295; X64-NEXT:    .cfi_def_cfa_offset 16
296; X64-NEXT:    .cfi_offset %rbx, -16
297; X64-NEXT:    movl %edi, %ebx
298; X64-NEXT:    leal 8(%rbx), %edi
299; X64-NEXT:    callq use@PLT
300; X64-NEXT:    movl $-6, %eax
301; X64-NEXT:    subl %ebx, %eax
302; X64-NEXT:    popq %rbx
303; X64-NEXT:    .cfi_def_cfa_offset 8
304; X64-NEXT:    retq
305  %t0 = add i32 %arg, 8
306  call void @use(i32 %t0)
307  %t1 = sub i32 2, %t0
308  ret i32 %t1
309}
310
311define <4 x i32> @vec_add_const_const_sub(<4 x i32> %arg) {
312; X86-LABEL: vec_add_const_const_sub:
313; X86:       # %bb.0:
314; X86-NEXT:    movdqa {{.*#+}} xmm1 = [4294967290,4294967290,4294967290,4294967290]
315; X86-NEXT:    psubd %xmm0, %xmm1
316; X86-NEXT:    movdqa %xmm1, %xmm0
317; X86-NEXT:    retl
318;
319; X64-LABEL: vec_add_const_const_sub:
320; X64:       # %bb.0:
321; X64-NEXT:    movdqa {{.*#+}} xmm1 = [4294967290,4294967290,4294967290,4294967290]
322; X64-NEXT:    psubd %xmm0, %xmm1
323; X64-NEXT:    movdqa %xmm1, %xmm0
324; X64-NEXT:    retq
325  %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
326  %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
327  ret <4 x i32> %t1
328}
329
330define <4 x i32> @vec_add_const_const_sub_extrause(<4 x i32> %arg) {
331; X86-LABEL: vec_add_const_const_sub_extrause:
332; X86:       # %bb.0:
333; X86-NEXT:    subl $16, %esp
334; X86-NEXT:    .cfi_def_cfa_offset 20
335; X86-NEXT:    movdqa %xmm0, %xmm1
336; X86-NEXT:    movdqu %xmm0, (%esp) # 16-byte Spill
337; X86-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
338; X86-NEXT:    paddd %xmm1, %xmm0
339; X86-NEXT:    calll vec_use@PLT
340; X86-NEXT:    movdqa {{.*#+}} xmm0 = [4294967290,4294967290,4294967290,4294967290]
341; X86-NEXT:    movdqu (%esp), %xmm1 # 16-byte Reload
342; X86-NEXT:    psubd %xmm1, %xmm0
343; X86-NEXT:    addl $16, %esp
344; X86-NEXT:    .cfi_def_cfa_offset 4
345; X86-NEXT:    retl
346;
347; X64-LABEL: vec_add_const_const_sub_extrause:
348; X64:       # %bb.0:
349; X64-NEXT:    subq $24, %rsp
350; X64-NEXT:    .cfi_def_cfa_offset 32
351; X64-NEXT:    movdqa %xmm0, %xmm1
352; X64-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
353; X64-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
354; X64-NEXT:    paddd %xmm1, %xmm0
355; X64-NEXT:    callq vec_use@PLT
356; X64-NEXT:    movdqa {{.*#+}} xmm0 = [4294967290,4294967290,4294967290,4294967290]
357; X64-NEXT:    psubd (%rsp), %xmm0 # 16-byte Folded Reload
358; X64-NEXT:    addq $24, %rsp
359; X64-NEXT:    .cfi_def_cfa_offset 8
360; X64-NEXT:    retq
361  %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
362  call void @vec_use(<4 x i32> %t0)
363  %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
364  ret <4 x i32> %t1
365}
366
367define <4 x i32> @vec_add_const_const_sub_nonsplat(<4 x i32> %arg) {
368; X86-LABEL: vec_add_const_const_sub_nonsplat:
369; X86:       # %bb.0:
370; X86-NEXT:    movdqa {{.*#+}} xmm1 = [4294967277,u,u,4294967290]
371; X86-NEXT:    psubd %xmm0, %xmm1
372; X86-NEXT:    movdqa %xmm1, %xmm0
373; X86-NEXT:    retl
374;
375; X64-LABEL: vec_add_const_const_sub_nonsplat:
376; X64:       # %bb.0:
377; X64-NEXT:    movdqa {{.*#+}} xmm1 = [4294967277,u,u,4294967290]
378; X64-NEXT:    psubd %xmm0, %xmm1
379; X64-NEXT:    movdqa %xmm1, %xmm0
380; X64-NEXT:    retq
381  %t0 = add <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
382  %t1 = sub <4 x i32> <i32 2, i32 3, i32 undef, i32 2>, %t0
383  ret <4 x i32> %t1
384}
385
386; (x-c1)+c2
387
388define i32 @sub_const_add_const(i32 %arg) {
389; X86-LABEL: sub_const_add_const:
390; X86:       # %bb.0:
391; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
392; X86-NEXT:    addl $-6, %eax
393; X86-NEXT:    retl
394;
395; X64-LABEL: sub_const_add_const:
396; X64:       # %bb.0:
397; X64-NEXT:    # kill: def $edi killed $edi def $rdi
398; X64-NEXT:    leal -6(%rdi), %eax
399; X64-NEXT:    retq
400  %t0 = sub i32 %arg, 8
401  %t1 = add i32 %t0, 2
402  ret i32 %t1
403}
404
405define i32 @sub_const_add_const_extrause(i32 %arg) {
406; X86-LABEL: sub_const_add_const_extrause:
407; X86:       # %bb.0:
408; X86-NEXT:    pushl %esi
409; X86-NEXT:    .cfi_def_cfa_offset 8
410; X86-NEXT:    .cfi_offset %esi, -8
411; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
412; X86-NEXT:    leal -8(%esi), %eax
413; X86-NEXT:    pushl %eax
414; X86-NEXT:    .cfi_adjust_cfa_offset 4
415; X86-NEXT:    calll use@PLT
416; X86-NEXT:    addl $4, %esp
417; X86-NEXT:    .cfi_adjust_cfa_offset -4
418; X86-NEXT:    addl $-6, %esi
419; X86-NEXT:    movl %esi, %eax
420; X86-NEXT:    popl %esi
421; X86-NEXT:    .cfi_def_cfa_offset 4
422; X86-NEXT:    retl
423;
424; X64-LABEL: sub_const_add_const_extrause:
425; X64:       # %bb.0:
426; X64-NEXT:    pushq %rbx
427; X64-NEXT:    .cfi_def_cfa_offset 16
428; X64-NEXT:    .cfi_offset %rbx, -16
429; X64-NEXT:    movl %edi, %ebx
430; X64-NEXT:    leal -8(%rbx), %edi
431; X64-NEXT:    callq use@PLT
432; X64-NEXT:    addl $-6, %ebx
433; X64-NEXT:    movl %ebx, %eax
434; X64-NEXT:    popq %rbx
435; X64-NEXT:    .cfi_def_cfa_offset 8
436; X64-NEXT:    retq
437  %t0 = sub i32 %arg, 8
438  call void @use(i32 %t0)
439  %t1 = add i32 %t0, 2
440  ret i32 %t1
441}
442
443define <4 x i32> @vec_sub_const_add_const(<4 x i32> %arg) {
444; X86-LABEL: vec_sub_const_add_const:
445; X86:       # %bb.0:
446; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
447; X86-NEXT:    retl
448;
449; X64-LABEL: vec_sub_const_add_const:
450; X64:       # %bb.0:
451; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
452; X64-NEXT:    retq
453  %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
454  %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
455  ret <4 x i32> %t1
456}
457
458define <4 x i32> @vec_sub_const_add_const_extrause(<4 x i32> %arg) {
459; X86-LABEL: vec_sub_const_add_const_extrause:
460; X86:       # %bb.0:
461; X86-NEXT:    subl $16, %esp
462; X86-NEXT:    .cfi_def_cfa_offset 20
463; X86-NEXT:    movdqu %xmm0, (%esp) # 16-byte Spill
464; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
465; X86-NEXT:    calll vec_use@PLT
466; X86-NEXT:    movdqu (%esp), %xmm0 # 16-byte Reload
467; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
468; X86-NEXT:    addl $16, %esp
469; X86-NEXT:    .cfi_def_cfa_offset 4
470; X86-NEXT:    retl
471;
472; X64-LABEL: vec_sub_const_add_const_extrause:
473; X64:       # %bb.0:
474; X64-NEXT:    subq $24, %rsp
475; X64-NEXT:    .cfi_def_cfa_offset 32
476; X64-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
477; X64-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
478; X64-NEXT:    callq vec_use@PLT
479; X64-NEXT:    movdqa (%rsp), %xmm0 # 16-byte Reload
480; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
481; X64-NEXT:    addq $24, %rsp
482; X64-NEXT:    .cfi_def_cfa_offset 8
483; X64-NEXT:    retq
484  %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
485  call void @vec_use(<4 x i32> %t0)
486  %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
487  ret <4 x i32> %t1
488}
489
490define <4 x i32> @vec_sub_const_add_const_nonsplat(<4 x i32> %arg) {
491; X86-LABEL: vec_sub_const_add_const_nonsplat:
492; X86:       # %bb.0:
493; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
494; X86-NEXT:    retl
495;
496; X64-LABEL: vec_sub_const_add_const_nonsplat:
497; X64:       # %bb.0:
498; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
499; X64-NEXT:    retq
500  %t0 = sub <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
501  %t1 = add <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
502  ret <4 x i32> %t1
503}
504
505; (x-c1)-c2
506
507define i32 @sub_const_sub_const(i32 %arg) {
508; X86-LABEL: sub_const_sub_const:
509; X86:       # %bb.0:
510; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
511; X86-NEXT:    addl $-10, %eax
512; X86-NEXT:    retl
513;
514; X64-LABEL: sub_const_sub_const:
515; X64:       # %bb.0:
516; X64-NEXT:    # kill: def $edi killed $edi def $rdi
517; X64-NEXT:    leal -10(%rdi), %eax
518; X64-NEXT:    retq
519  %t0 = sub i32 %arg, 8
520  %t1 = sub i32 %t0, 2
521  ret i32 %t1
522}
523
524define i32 @sub_const_sub_const_extrause(i32 %arg) {
525; X86-LABEL: sub_const_sub_const_extrause:
526; X86:       # %bb.0:
527; X86-NEXT:    pushl %esi
528; X86-NEXT:    .cfi_def_cfa_offset 8
529; X86-NEXT:    .cfi_offset %esi, -8
530; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
531; X86-NEXT:    leal -8(%esi), %eax
532; X86-NEXT:    pushl %eax
533; X86-NEXT:    .cfi_adjust_cfa_offset 4
534; X86-NEXT:    calll use@PLT
535; X86-NEXT:    addl $4, %esp
536; X86-NEXT:    .cfi_adjust_cfa_offset -4
537; X86-NEXT:    addl $-10, %esi
538; X86-NEXT:    movl %esi, %eax
539; X86-NEXT:    popl %esi
540; X86-NEXT:    .cfi_def_cfa_offset 4
541; X86-NEXT:    retl
542;
543; X64-LABEL: sub_const_sub_const_extrause:
544; X64:       # %bb.0:
545; X64-NEXT:    pushq %rbx
546; X64-NEXT:    .cfi_def_cfa_offset 16
547; X64-NEXT:    .cfi_offset %rbx, -16
548; X64-NEXT:    movl %edi, %ebx
549; X64-NEXT:    leal -8(%rbx), %edi
550; X64-NEXT:    callq use@PLT
551; X64-NEXT:    addl $-10, %ebx
552; X64-NEXT:    movl %ebx, %eax
553; X64-NEXT:    popq %rbx
554; X64-NEXT:    .cfi_def_cfa_offset 8
555; X64-NEXT:    retq
556  %t0 = sub i32 %arg, 8
557  call void @use(i32 %t0)
558  %t1 = sub i32 %t0, 2
559  ret i32 %t1
560}
561
562define <4 x i32> @vec_sub_const_sub_const(<4 x i32> %arg) {
563; X86-LABEL: vec_sub_const_sub_const:
564; X86:       # %bb.0:
565; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
566; X86-NEXT:    retl
567;
568; X64-LABEL: vec_sub_const_sub_const:
569; X64:       # %bb.0:
570; X64-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
571; X64-NEXT:    retq
572  %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
573  %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
574  ret <4 x i32> %t1
575}
576
577define <4 x i32> @vec_sub_const_sub_const_extrause(<4 x i32> %arg) {
578; X86-LABEL: vec_sub_const_sub_const_extrause:
579; X86:       # %bb.0:
580; X86-NEXT:    subl $16, %esp
581; X86-NEXT:    .cfi_def_cfa_offset 20
582; X86-NEXT:    movdqu %xmm0, (%esp) # 16-byte Spill
583; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
584; X86-NEXT:    calll vec_use@PLT
585; X86-NEXT:    movdqu (%esp), %xmm0 # 16-byte Reload
586; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
587; X86-NEXT:    addl $16, %esp
588; X86-NEXT:    .cfi_def_cfa_offset 4
589; X86-NEXT:    retl
590;
591; X64-LABEL: vec_sub_const_sub_const_extrause:
592; X64:       # %bb.0:
593; X64-NEXT:    subq $24, %rsp
594; X64-NEXT:    .cfi_def_cfa_offset 32
595; X64-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
596; X64-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
597; X64-NEXT:    callq vec_use@PLT
598; X64-NEXT:    movdqa (%rsp), %xmm0 # 16-byte Reload
599; X64-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
600; X64-NEXT:    addq $24, %rsp
601; X64-NEXT:    .cfi_def_cfa_offset 8
602; X64-NEXT:    retq
603  %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
604  call void @vec_use(<4 x i32> %t0)
605  %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
606  ret <4 x i32> %t1
607}
608
609define <4 x i32> @vec_sub_const_sub_const_nonsplat(<4 x i32> %arg) {
610; X86-LABEL: vec_sub_const_sub_const_nonsplat:
611; X86:       # %bb.0:
612; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
613; X86-NEXT:    retl
614;
615; X64-LABEL: vec_sub_const_sub_const_nonsplat:
616; X64:       # %bb.0:
617; X64-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
618; X64-NEXT:    retq
619  %t0 = sub <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
620  %t1 = sub <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
621  ret <4 x i32> %t1
622}
623
624; c2-(x-c1)
625
626define i32 @sub_const_const_sub(i32 %arg) {
627; X86-LABEL: sub_const_const_sub:
628; X86:       # %bb.0:
629; X86-NEXT:    movl $10, %eax
630; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
631; X86-NEXT:    retl
632;
633; X64-LABEL: sub_const_const_sub:
634; X64:       # %bb.0:
635; X64-NEXT:    movl $10, %eax
636; X64-NEXT:    subl %edi, %eax
637; X64-NEXT:    retq
638  %t0 = sub i32 %arg, 8
639  %t1 = sub i32 2, %t0
640  ret i32 %t1
641}
642
643define i32 @sub_const_const_sub_extrause(i32 %arg) {
644; X86-LABEL: sub_const_const_sub_extrause:
645; X86:       # %bb.0:
646; X86-NEXT:    pushl %esi
647; X86-NEXT:    .cfi_def_cfa_offset 8
648; X86-NEXT:    .cfi_offset %esi, -8
649; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
650; X86-NEXT:    leal -8(%esi), %eax
651; X86-NEXT:    pushl %eax
652; X86-NEXT:    .cfi_adjust_cfa_offset 4
653; X86-NEXT:    calll use@PLT
654; X86-NEXT:    addl $4, %esp
655; X86-NEXT:    .cfi_adjust_cfa_offset -4
656; X86-NEXT:    movl $10, %eax
657; X86-NEXT:    subl %esi, %eax
658; X86-NEXT:    popl %esi
659; X86-NEXT:    .cfi_def_cfa_offset 4
660; X86-NEXT:    retl
661;
662; X64-LABEL: sub_const_const_sub_extrause:
663; X64:       # %bb.0:
664; X64-NEXT:    pushq %rbx
665; X64-NEXT:    .cfi_def_cfa_offset 16
666; X64-NEXT:    .cfi_offset %rbx, -16
667; X64-NEXT:    movl %edi, %ebx
668; X64-NEXT:    leal -8(%rbx), %edi
669; X64-NEXT:    callq use@PLT
670; X64-NEXT:    movl $10, %eax
671; X64-NEXT:    subl %ebx, %eax
672; X64-NEXT:    popq %rbx
673; X64-NEXT:    .cfi_def_cfa_offset 8
674; X64-NEXT:    retq
675  %t0 = sub i32 %arg, 8
676  call void @use(i32 %t0)
677  %t1 = sub i32 2, %t0
678  ret i32 %t1
679}
680
681define <4 x i32> @vec_sub_const_const_sub(<4 x i32> %arg) {
682; X86-LABEL: vec_sub_const_const_sub:
683; X86:       # %bb.0:
684; X86-NEXT:    movdqa {{.*#+}} xmm1 = [10,10,10,10]
685; X86-NEXT:    psubd %xmm0, %xmm1
686; X86-NEXT:    movdqa %xmm1, %xmm0
687; X86-NEXT:    retl
688;
689; X64-LABEL: vec_sub_const_const_sub:
690; X64:       # %bb.0:
691; X64-NEXT:    movdqa {{.*#+}} xmm1 = [10,10,10,10]
692; X64-NEXT:    psubd %xmm0, %xmm1
693; X64-NEXT:    movdqa %xmm1, %xmm0
694; X64-NEXT:    retq
695  %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
696  %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
697  ret <4 x i32> %t1
698}
699
700define <4 x i32> @vec_sub_const_const_sub_extrause(<4 x i32> %arg) {
701; X86-LABEL: vec_sub_const_const_sub_extrause:
702; X86:       # %bb.0:
703; X86-NEXT:    subl $16, %esp
704; X86-NEXT:    .cfi_def_cfa_offset 20
705; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
706; X86-NEXT:    movdqu %xmm0, (%esp) # 16-byte Spill
707; X86-NEXT:    calll vec_use@PLT
708; X86-NEXT:    movdqa {{.*#+}} xmm0 = [2,2,2,2]
709; X86-NEXT:    movdqu (%esp), %xmm1 # 16-byte Reload
710; X86-NEXT:    psubd %xmm1, %xmm0
711; X86-NEXT:    addl $16, %esp
712; X86-NEXT:    .cfi_def_cfa_offset 4
713; X86-NEXT:    retl
714;
715; X64-LABEL: vec_sub_const_const_sub_extrause:
716; X64:       # %bb.0:
717; X64-NEXT:    subq $24, %rsp
718; X64-NEXT:    .cfi_def_cfa_offset 32
719; X64-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
720; X64-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
721; X64-NEXT:    callq vec_use@PLT
722; X64-NEXT:    movdqa {{.*#+}} xmm0 = [2,2,2,2]
723; X64-NEXT:    psubd (%rsp), %xmm0 # 16-byte Folded Reload
724; X64-NEXT:    addq $24, %rsp
725; X64-NEXT:    .cfi_def_cfa_offset 8
726; X64-NEXT:    retq
727  %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
728  call void @vec_use(<4 x i32> %t0)
729  %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
730  ret <4 x i32> %t1
731}
732
733define <4 x i32> @vec_sub_const_const_sub_nonsplat(<4 x i32> %arg) {
734; X86-LABEL: vec_sub_const_const_sub_nonsplat:
735; X86:       # %bb.0:
736; X86-NEXT:    movdqa {{.*#+}} xmm1 = [23,u,u,10]
737; X86-NEXT:    psubd %xmm0, %xmm1
738; X86-NEXT:    movdqa %xmm1, %xmm0
739; X86-NEXT:    retl
740;
741; X64-LABEL: vec_sub_const_const_sub_nonsplat:
742; X64:       # %bb.0:
743; X64-NEXT:    movdqa {{.*#+}} xmm1 = [23,u,u,10]
744; X64-NEXT:    psubd %xmm0, %xmm1
745; X64-NEXT:    movdqa %xmm1, %xmm0
746; X64-NEXT:    retq
747  %t0 = sub <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8>
748  %t1 = sub <4 x i32> <i32 2, i32 3, i32 undef, i32 2>, %t0
749  ret <4 x i32> %t1
750}
751
752; (c1-x)+c2
753
754define i32 @const_sub_add_const(i32 %arg) {
755; X86-LABEL: const_sub_add_const:
756; X86:       # %bb.0:
757; X86-NEXT:    movl $10, %eax
758; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
759; X86-NEXT:    retl
760;
761; X64-LABEL: const_sub_add_const:
762; X64:       # %bb.0:
763; X64-NEXT:    movl $10, %eax
764; X64-NEXT:    subl %edi, %eax
765; X64-NEXT:    retq
766  %t0 = sub i32 8, %arg
767  %t1 = add i32 %t0, 2
768  ret i32 %t1
769}
770
771define i32 @const_sub_add_const_extrause(i32 %arg) {
772; X86-LABEL: const_sub_add_const_extrause:
773; X86:       # %bb.0:
774; X86-NEXT:    pushl %esi
775; X86-NEXT:    .cfi_def_cfa_offset 8
776; X86-NEXT:    .cfi_offset %esi, -8
777; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
778; X86-NEXT:    movl $8, %eax
779; X86-NEXT:    subl %esi, %eax
780; X86-NEXT:    pushl %eax
781; X86-NEXT:    .cfi_adjust_cfa_offset 4
782; X86-NEXT:    calll use@PLT
783; X86-NEXT:    addl $4, %esp
784; X86-NEXT:    .cfi_adjust_cfa_offset -4
785; X86-NEXT:    movl $10, %eax
786; X86-NEXT:    subl %esi, %eax
787; X86-NEXT:    popl %esi
788; X86-NEXT:    .cfi_def_cfa_offset 4
789; X86-NEXT:    retl
790;
791; X64-LABEL: const_sub_add_const_extrause:
792; X64:       # %bb.0:
793; X64-NEXT:    pushq %rbx
794; X64-NEXT:    .cfi_def_cfa_offset 16
795; X64-NEXT:    .cfi_offset %rbx, -16
796; X64-NEXT:    movl %edi, %ebx
797; X64-NEXT:    movl $8, %edi
798; X64-NEXT:    subl %ebx, %edi
799; X64-NEXT:    callq use@PLT
800; X64-NEXT:    movl $10, %eax
801; X64-NEXT:    subl %ebx, %eax
802; X64-NEXT:    popq %rbx
803; X64-NEXT:    .cfi_def_cfa_offset 8
804; X64-NEXT:    retq
805  %t0 = sub i32 8, %arg
806  call void @use(i32 %t0)
807  %t1 = add i32 %t0, 2
808  ret i32 %t1
809}
810
811define <4 x i32> @vec_const_sub_add_const(<4 x i32> %arg) {
812; X86-LABEL: vec_const_sub_add_const:
813; X86:       # %bb.0:
814; X86-NEXT:    movdqa {{.*#+}} xmm1 = [10,10,10,10]
815; X86-NEXT:    psubd %xmm0, %xmm1
816; X86-NEXT:    movdqa %xmm1, %xmm0
817; X86-NEXT:    retl
818;
819; X64-LABEL: vec_const_sub_add_const:
820; X64:       # %bb.0:
821; X64-NEXT:    movdqa {{.*#+}} xmm1 = [10,10,10,10]
822; X64-NEXT:    psubd %xmm0, %xmm1
823; X64-NEXT:    movdqa %xmm1, %xmm0
824; X64-NEXT:    retq
825  %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
826  %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
827  ret <4 x i32> %t1
828}
829
830define <4 x i32> @vec_const_sub_add_const_extrause(<4 x i32> %arg) {
831; X86-LABEL: vec_const_sub_add_const_extrause:
832; X86:       # %bb.0:
833; X86-NEXT:    subl $16, %esp
834; X86-NEXT:    .cfi_def_cfa_offset 20
835; X86-NEXT:    movdqa %xmm0, %xmm1
836; X86-NEXT:    movdqu %xmm0, (%esp) # 16-byte Spill
837; X86-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
838; X86-NEXT:    psubd %xmm1, %xmm0
839; X86-NEXT:    calll vec_use@PLT
840; X86-NEXT:    movdqa {{.*#+}} xmm0 = [10,10,10,10]
841; X86-NEXT:    movdqu (%esp), %xmm1 # 16-byte Reload
842; X86-NEXT:    psubd %xmm1, %xmm0
843; X86-NEXT:    addl $16, %esp
844; X86-NEXT:    .cfi_def_cfa_offset 4
845; X86-NEXT:    retl
846;
847; X64-LABEL: vec_const_sub_add_const_extrause:
848; X64:       # %bb.0:
849; X64-NEXT:    subq $24, %rsp
850; X64-NEXT:    .cfi_def_cfa_offset 32
851; X64-NEXT:    movdqa %xmm0, %xmm1
852; X64-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
853; X64-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
854; X64-NEXT:    psubd %xmm1, %xmm0
855; X64-NEXT:    callq vec_use@PLT
856; X64-NEXT:    movdqa {{.*#+}} xmm0 = [10,10,10,10]
857; X64-NEXT:    psubd (%rsp), %xmm0 # 16-byte Folded Reload
858; X64-NEXT:    addq $24, %rsp
859; X64-NEXT:    .cfi_def_cfa_offset 8
860; X64-NEXT:    retq
861  %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
862  call void @vec_use(<4 x i32> %t0)
863  %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
864  ret <4 x i32> %t1
865}
866
867define <4 x i32> @vec_const_sub_add_const_nonsplat(<4 x i32> %arg) {
868; X86-LABEL: vec_const_sub_add_const_nonsplat:
869; X86:       # %bb.0:
870; X86-NEXT:    movdqa {{.*#+}} xmm1 = [23,u,u,10]
871; X86-NEXT:    psubd %xmm0, %xmm1
872; X86-NEXT:    movdqa %xmm1, %xmm0
873; X86-NEXT:    retl
874;
875; X64-LABEL: vec_const_sub_add_const_nonsplat:
876; X64:       # %bb.0:
877; X64-NEXT:    movdqa {{.*#+}} xmm1 = [23,u,u,10]
878; X64-NEXT:    psubd %xmm0, %xmm1
879; X64-NEXT:    movdqa %xmm1, %xmm0
880; X64-NEXT:    retq
881  %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg
882  %t1 = add <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
883  ret <4 x i32> %t1
884}
885
886; (c1-x)-c2
887
888define i32 @const_sub_sub_const(i32 %arg) {
889; X86-LABEL: const_sub_sub_const:
890; X86:       # %bb.0:
891; X86-NEXT:    movl $6, %eax
892; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
893; X86-NEXT:    retl
894;
895; X64-LABEL: const_sub_sub_const:
896; X64:       # %bb.0:
897; X64-NEXT:    movl $6, %eax
898; X64-NEXT:    subl %edi, %eax
899; X64-NEXT:    retq
900  %t0 = sub i32 8, %arg
901  %t1 = sub i32 %t0, 2
902  ret i32 %t1
903}
904
905define i32 @const_sub_sub_const_extrause(i32 %arg) {
906; X86-LABEL: const_sub_sub_const_extrause:
907; X86:       # %bb.0:
908; X86-NEXT:    pushl %esi
909; X86-NEXT:    .cfi_def_cfa_offset 8
910; X86-NEXT:    .cfi_offset %esi, -8
911; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
912; X86-NEXT:    movl $8, %eax
913; X86-NEXT:    subl %esi, %eax
914; X86-NEXT:    pushl %eax
915; X86-NEXT:    .cfi_adjust_cfa_offset 4
916; X86-NEXT:    calll use@PLT
917; X86-NEXT:    addl $4, %esp
918; X86-NEXT:    .cfi_adjust_cfa_offset -4
919; X86-NEXT:    movl $6, %eax
920; X86-NEXT:    subl %esi, %eax
921; X86-NEXT:    popl %esi
922; X86-NEXT:    .cfi_def_cfa_offset 4
923; X86-NEXT:    retl
924;
925; X64-LABEL: const_sub_sub_const_extrause:
926; X64:       # %bb.0:
927; X64-NEXT:    pushq %rbx
928; X64-NEXT:    .cfi_def_cfa_offset 16
929; X64-NEXT:    .cfi_offset %rbx, -16
930; X64-NEXT:    movl %edi, %ebx
931; X64-NEXT:    movl $8, %edi
932; X64-NEXT:    subl %ebx, %edi
933; X64-NEXT:    callq use@PLT
934; X64-NEXT:    movl $6, %eax
935; X64-NEXT:    subl %ebx, %eax
936; X64-NEXT:    popq %rbx
937; X64-NEXT:    .cfi_def_cfa_offset 8
938; X64-NEXT:    retq
939  %t0 = sub i32 8, %arg
940  call void @use(i32 %t0)
941  %t1 = sub i32 %t0, 2
942  ret i32 %t1
943}
944
945define <4 x i32> @vec_const_sub_sub_const(<4 x i32> %arg) {
946; X86-LABEL: vec_const_sub_sub_const:
947; X86:       # %bb.0:
948; X86-NEXT:    movdqa {{.*#+}} xmm1 = [6,6,6,6]
949; X86-NEXT:    psubd %xmm0, %xmm1
950; X86-NEXT:    movdqa %xmm1, %xmm0
951; X86-NEXT:    retl
952;
953; X64-LABEL: vec_const_sub_sub_const:
954; X64:       # %bb.0:
955; X64-NEXT:    movdqa {{.*#+}} xmm1 = [6,6,6,6]
956; X64-NEXT:    psubd %xmm0, %xmm1
957; X64-NEXT:    movdqa %xmm1, %xmm0
958; X64-NEXT:    retq
959  %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
960  %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
961  ret <4 x i32> %t1
962}
963
964define <4 x i32> @vec_const_sub_sub_const_extrause(<4 x i32> %arg) {
965; X86-LABEL: vec_const_sub_sub_const_extrause:
966; X86:       # %bb.0:
967; X86-NEXT:    subl $16, %esp
968; X86-NEXT:    .cfi_def_cfa_offset 20
969; X86-NEXT:    movdqa %xmm0, %xmm1
970; X86-NEXT:    movdqu %xmm0, (%esp) # 16-byte Spill
971; X86-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
972; X86-NEXT:    psubd %xmm1, %xmm0
973; X86-NEXT:    calll vec_use@PLT
974; X86-NEXT:    movdqa {{.*#+}} xmm0 = [6,6,6,6]
975; X86-NEXT:    movdqu (%esp), %xmm1 # 16-byte Reload
976; X86-NEXT:    psubd %xmm1, %xmm0
977; X86-NEXT:    addl $16, %esp
978; X86-NEXT:    .cfi_def_cfa_offset 4
979; X86-NEXT:    retl
980;
981; X64-LABEL: vec_const_sub_sub_const_extrause:
982; X64:       # %bb.0:
983; X64-NEXT:    subq $24, %rsp
984; X64-NEXT:    .cfi_def_cfa_offset 32
985; X64-NEXT:    movdqa %xmm0, %xmm1
986; X64-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
987; X64-NEXT:    movdqa {{.*#+}} xmm0 = [8,8,8,8]
988; X64-NEXT:    psubd %xmm1, %xmm0
989; X64-NEXT:    callq vec_use@PLT
990; X64-NEXT:    movdqa {{.*#+}} xmm0 = [6,6,6,6]
991; X64-NEXT:    psubd (%rsp), %xmm0 # 16-byte Folded Reload
992; X64-NEXT:    addq $24, %rsp
993; X64-NEXT:    .cfi_def_cfa_offset 8
994; X64-NEXT:    retq
995  %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
996  call void @vec_use(<4 x i32> %t0)
997  %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2>
998  ret <4 x i32> %t1
999}
1000
1001define <4 x i32> @vec_const_sub_sub_const_nonsplat(<4 x i32> %arg) {
1002; X86-LABEL: vec_const_sub_sub_const_nonsplat:
1003; X86:       # %bb.0:
1004; X86-NEXT:    movdqa {{.*#+}} xmm1 = [19,u,u,6]
1005; X86-NEXT:    psubd %xmm0, %xmm1
1006; X86-NEXT:    movdqa %xmm1, %xmm0
1007; X86-NEXT:    retl
1008;
1009; X64-LABEL: vec_const_sub_sub_const_nonsplat:
1010; X64:       # %bb.0:
1011; X64-NEXT:    movdqa {{.*#+}} xmm1 = [19,u,u,6]
1012; X64-NEXT:    psubd %xmm0, %xmm1
1013; X64-NEXT:    movdqa %xmm1, %xmm0
1014; X64-NEXT:    retq
1015  %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg
1016  %t1 = sub <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2>
1017  ret <4 x i32> %t1
1018}
1019
1020; c2-(c1-x)
1021
1022define i32 @const_sub_const_sub(i32 %arg) {
1023; X86-LABEL: const_sub_const_sub:
1024; X86:       # %bb.0:
1025; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1026; X86-NEXT:    addl $-6, %eax
1027; X86-NEXT:    retl
1028;
1029; X64-LABEL: const_sub_const_sub:
1030; X64:       # %bb.0:
1031; X64-NEXT:    # kill: def $edi killed $edi def $rdi
1032; X64-NEXT:    leal -6(%rdi), %eax
1033; X64-NEXT:    retq
1034  %t0 = sub i32 8, %arg
1035  %t1 = sub i32 2, %t0
1036  ret i32 %t1
1037}
1038
1039define i32 @const_sub_const_sub_extrause(i32 %arg) {
1040; X86-LABEL: const_sub_const_sub_extrause:
1041; X86:       # %bb.0:
1042; X86-NEXT:    pushl %esi
1043; X86-NEXT:    .cfi_def_cfa_offset 8
1044; X86-NEXT:    .cfi_offset %esi, -8
1045; X86-NEXT:    movl $8, %esi
1046; X86-NEXT:    subl {{[0-9]+}}(%esp), %esi
1047; X86-NEXT:    pushl %esi
1048; X86-NEXT:    .cfi_adjust_cfa_offset 4
1049; X86-NEXT:    calll use@PLT
1050; X86-NEXT:    addl $4, %esp
1051; X86-NEXT:    .cfi_adjust_cfa_offset -4
1052; X86-NEXT:    movl $2, %eax
1053; X86-NEXT:    subl %esi, %eax
1054; X86-NEXT:    popl %esi
1055; X86-NEXT:    .cfi_def_cfa_offset 4
1056; X86-NEXT:    retl
1057;
1058; X64-LABEL: const_sub_const_sub_extrause:
1059; X64:       # %bb.0:
1060; X64-NEXT:    pushq %rbx
1061; X64-NEXT:    .cfi_def_cfa_offset 16
1062; X64-NEXT:    .cfi_offset %rbx, -16
1063; X64-NEXT:    movl $8, %ebx
1064; X64-NEXT:    subl %edi, %ebx
1065; X64-NEXT:    movl %ebx, %edi
1066; X64-NEXT:    callq use@PLT
1067; X64-NEXT:    movl $2, %eax
1068; X64-NEXT:    subl %ebx, %eax
1069; X64-NEXT:    popq %rbx
1070; X64-NEXT:    .cfi_def_cfa_offset 8
1071; X64-NEXT:    retq
1072  %t0 = sub i32 8, %arg
1073  call void @use(i32 %t0)
1074  %t1 = sub i32 2, %t0
1075  ret i32 %t1
1076}
1077
1078define <4 x i32> @vec_const_sub_const_sub(<4 x i32> %arg) {
1079; X86-LABEL: vec_const_sub_const_sub:
1080; X86:       # %bb.0:
1081; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
1082; X86-NEXT:    retl
1083;
1084; X64-LABEL: vec_const_sub_const_sub:
1085; X64:       # %bb.0:
1086; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
1087; X64-NEXT:    retq
1088  %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
1089  %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
1090  ret <4 x i32> %t1
1091}
1092
1093define <4 x i32> @vec_const_sub_const_sub_extrause(<4 x i32> %arg) {
1094; X86-LABEL: vec_const_sub_const_sub_extrause:
1095; X86:       # %bb.0:
1096; X86-NEXT:    subl $16, %esp
1097; X86-NEXT:    .cfi_def_cfa_offset 20
1098; X86-NEXT:    movdqa {{.*#+}} xmm1 = [8,8,8,8]
1099; X86-NEXT:    psubd %xmm0, %xmm1
1100; X86-NEXT:    movdqu %xmm1, (%esp) # 16-byte Spill
1101; X86-NEXT:    movdqa %xmm1, %xmm0
1102; X86-NEXT:    calll vec_use@PLT
1103; X86-NEXT:    movdqa {{.*#+}} xmm0 = [2,2,2,2]
1104; X86-NEXT:    movdqu (%esp), %xmm1 # 16-byte Reload
1105; X86-NEXT:    psubd %xmm1, %xmm0
1106; X86-NEXT:    addl $16, %esp
1107; X86-NEXT:    .cfi_def_cfa_offset 4
1108; X86-NEXT:    retl
1109;
1110; X64-LABEL: vec_const_sub_const_sub_extrause:
1111; X64:       # %bb.0:
1112; X64-NEXT:    subq $24, %rsp
1113; X64-NEXT:    .cfi_def_cfa_offset 32
1114; X64-NEXT:    movdqa {{.*#+}} xmm1 = [8,8,8,8]
1115; X64-NEXT:    psubd %xmm0, %xmm1
1116; X64-NEXT:    movdqa %xmm1, (%rsp) # 16-byte Spill
1117; X64-NEXT:    movdqa %xmm1, %xmm0
1118; X64-NEXT:    callq vec_use@PLT
1119; X64-NEXT:    movdqa {{.*#+}} xmm0 = [2,2,2,2]
1120; X64-NEXT:    psubd (%rsp), %xmm0 # 16-byte Folded Reload
1121; X64-NEXT:    addq $24, %rsp
1122; X64-NEXT:    .cfi_def_cfa_offset 8
1123; X64-NEXT:    retq
1124  %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
1125  call void @vec_use(<4 x i32> %t0)
1126  %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0
1127  ret <4 x i32> %t1
1128}
1129
1130define <4 x i32> @vec_const_sub_const_sub_nonsplat(<4 x i32> %arg) {
1131; X86-LABEL: vec_const_sub_const_sub_nonsplat:
1132; X86:       # %bb.0:
1133; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
1134; X86-NEXT:    retl
1135;
1136; X64-LABEL: vec_const_sub_const_sub_nonsplat:
1137; X64:       # %bb.0:
1138; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
1139; X64-NEXT:    retq
1140  %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg
1141  %t1 = sub <4 x i32> <i32 2, i32 3, i32 undef, i32 2>, %t0
1142  ret <4 x i32> %t1
1143}
1144
1145; (x|c1)+c2 where (x|c1) is addlike
1146define i32 @add_const_disjoint_or_const(i32 %arg) {
1147; X86-LABEL: add_const_disjoint_or_const:
1148; X86:       # %bb.0:
1149; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1150; X86-NEXT:    addl $10, %eax
1151; X86-NEXT:    retl
1152;
1153; X64-LABEL: add_const_disjoint_or_const:
1154; X64:       # %bb.0:
1155; X64-NEXT:    # kill: def $edi killed $edi def $rdi
1156; X64-NEXT:    leal 10(%rdi), %eax
1157; X64-NEXT:    retq
1158  %t0 = or disjoint i32 %arg, 8
1159  %t1 = add i32 %t0, 2
1160  ret i32 %t1
1161}
1162
1163; (x+c1)|c2 where the outer or is addlike
1164define i32 @disjoint_or_const_add_const(i32 %arg) {
1165; X86-LABEL: disjoint_or_const_add_const:
1166; X86:       # %bb.0:
1167; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1168; X86-NEXT:    addl $10, %eax
1169; X86-NEXT:    retl
1170;
1171; X64-LABEL: disjoint_or_const_add_const:
1172; X64:       # %bb.0:
1173; X64-NEXT:    # kill: def $edi killed $edi def $rdi
1174; X64-NEXT:    leal 10(%rdi), %eax
1175; X64-NEXT:    retq
1176  %t0 = add i32 %arg, 8
1177  %t1 = or disjoint i32 %t0, 2
1178  ret i32 %t1
1179}
1180