xref: /llvm-project/llvm/test/CodeGen/X86/freeze-binary.ll (revision 74fe1da01eb149a2234fc0f9570c84a08692e782)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-- -mattr=+sse2 | FileCheck %s --check-prefixes=X86
3; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx2 | FileCheck %s --check-prefixes=X64
4
5define i32 @freeze_and(i32 %a0) nounwind {
6; X86-LABEL: freeze_and:
7; X86:       # %bb.0:
8; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
9; X86-NEXT:    andl $7, %eax
10; X86-NEXT:    retl
11;
12; X64-LABEL: freeze_and:
13; X64:       # %bb.0:
14; X64-NEXT:    movl %edi, %eax
15; X64-NEXT:    andl $7, %eax
16; X64-NEXT:    retq
17  %x = and i32 %a0, 15
18  %y = freeze i32 %x
19  %z = and i32 %y, 7
20  ret i32 %z
21}
22
23define i32 @freeze_and_extra_use(i32 %a0, ptr %escape) nounwind {
24; X86-LABEL: freeze_and_extra_use:
25; X86:       # %bb.0:
26; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
27; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
28; X86-NEXT:    movl %eax, (%ecx)
29; X86-NEXT:    andl $7, %eax
30; X86-NEXT:    retl
31;
32; X64-LABEL: freeze_and_extra_use:
33; X64:       # %bb.0:
34; X64-NEXT:    movl %edi, %eax
35; X64-NEXT:    movl %edi, (%rsi)
36; X64-NEXT:    andl $7, %eax
37; X64-NEXT:    retq
38  store i32 %a0, ptr %escape
39  %x = and i32 %a0, 15
40  %y = freeze i32 %x
41  %z = and i32 %y, 7
42  ret i32 %z
43}
44define i32 @freeze_and_extra_use2(i32 %a0, ptr %escape) nounwind {
45; X86-LABEL: freeze_and_extra_use2:
46; X86:       # %bb.0:
47; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
48; X86-NEXT:    andl $15, %eax
49; X86-NEXT:    retl
50;
51; X64-LABEL: freeze_and_extra_use2:
52; X64:       # %bb.0:
53; X64-NEXT:    movl %edi, %eax
54; X64-NEXT:    andl $15, %eax
55; X64-NEXT:    retq
56  %x = and i32 %a0, 15
57  %y = freeze i32 %x
58  %z = and i32 %y, 7
59  %w = and i32 %y, %a0
60  ret i32 %w
61}
62
63define <2 x i64> @freeze_and_vec(<2 x i64> %a0) nounwind {
64; X86-LABEL: freeze_and_vec:
65; X86:       # %bb.0:
66; X86-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
67; X86-NEXT:    retl
68;
69; X64-LABEL: freeze_and_vec:
70; X64:       # %bb.0:
71; X64-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
72; X64-NEXT:    retq
73  %x = and <2 x i64> %a0, <i64 15, i64 7>
74  %y = freeze <2 x i64> %x
75  %z = and <2 x i64> %y, <i64 7, i64 15>
76  ret <2 x i64> %z
77}
78
79define i32 @freeze_or(i32 %a0) nounwind {
80; X86-LABEL: freeze_or:
81; X86:       # %bb.0:
82; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
83; X86-NEXT:    orl $15, %eax
84; X86-NEXT:    retl
85;
86; X64-LABEL: freeze_or:
87; X64:       # %bb.0:
88; X64-NEXT:    movl %edi, %eax
89; X64-NEXT:    orl $15, %eax
90; X64-NEXT:    retq
91  %x = or i32 %a0, 3
92  %y = freeze i32 %x
93  %z = or i32 %y, 12
94  ret i32 %z
95}
96
97define <2 x i64> @freeze_or_vec(<2 x i64> %a0) nounwind {
98; X86-LABEL: freeze_or_vec:
99; X86:       # %bb.0:
100; X86-NEXT:    orps {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
101; X86-NEXT:    retl
102;
103; X64-LABEL: freeze_or_vec:
104; X64:       # %bb.0:
105; X64-NEXT:    vorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
106; X64-NEXT:    retq
107  %x = or <2 x i64> %a0, <i64 1, i64 3>
108  %y = freeze <2 x i64> %x
109  %z = or <2 x i64> %y, <i64 14, i64 12>
110  ret <2 x i64> %z
111}
112
113define i32 @freeze_xor(i32 %a0) nounwind {
114; X86-LABEL: freeze_xor:
115; X86:       # %bb.0:
116; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
117; X86-NEXT:    xorl $15, %eax
118; X86-NEXT:    retl
119;
120; X64-LABEL: freeze_xor:
121; X64:       # %bb.0:
122; X64-NEXT:    movl %edi, %eax
123; X64-NEXT:    xorl $15, %eax
124; X64-NEXT:    retq
125  %x = xor i32 %a0, 3
126  %y = freeze i32 %x
127  %z = xor i32 %y, 12
128  ret i32 %z
129}
130
131define <8 x i16> @freeze_xor_vec(<8 x i16> %a0) nounwind {
132; X86-LABEL: freeze_xor_vec:
133; X86:       # %bb.0:
134; X86-NEXT:    pcmpeqd %xmm1, %xmm1
135; X86-NEXT:    pxor %xmm1, %xmm0
136; X86-NEXT:    retl
137;
138; X64-LABEL: freeze_xor_vec:
139; X64:       # %bb.0:
140; X64-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
141; X64-NEXT:    vpxor %xmm1, %xmm0, %xmm0
142; X64-NEXT:    retq
143  %x = xor <8 x i16> %a0, <i16 -1, i16 0, i16 -1, i16 0, i16 -1, i16 0, i16 -1, i16 0>
144  %y = freeze <8 x i16> %x
145  %z = xor <8 x i16> %y, <i16 0, i16 -1, i16 0, i16 -1, i16 0, i16 -1, i16 0, i16 -1>
146  ret <8 x i16> %z
147}
148
149define i32 @freeze_add(i32 %a0) nounwind {
150; X86-LABEL: freeze_add:
151; X86:       # %bb.0:
152; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
153; X86-NEXT:    addl $2, %eax
154; X86-NEXT:    retl
155;
156; X64-LABEL: freeze_add:
157; X64:       # %bb.0:
158; X64-NEXT:    # kill: def $edi killed $edi def $rdi
159; X64-NEXT:    leal 2(%rdi), %eax
160; X64-NEXT:    retq
161  %x = add i32 %a0, 1
162  %y = freeze i32 %x
163  %z = add i32 %y, 1
164  ret i32 %z
165}
166
167define i32 @freeze_add_nsw(i32 %a0) nounwind {
168; X86-LABEL: freeze_add_nsw:
169; X86:       # %bb.0:
170; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
171; X86-NEXT:    addl $2, %eax
172; X86-NEXT:    retl
173;
174; X64-LABEL: freeze_add_nsw:
175; X64:       # %bb.0:
176; X64-NEXT:    # kill: def $edi killed $edi def $rdi
177; X64-NEXT:    leal 2(%rdi), %eax
178; X64-NEXT:    retq
179  %x = add nsw i32 %a0, 1
180  %y = freeze i32 %x
181  %z = add i32 %y, 1
182  ret i32 %z
183}
184
185define <4 x i32> @freeze_add_vec(<4 x i32> %a0) nounwind {
186; X86-LABEL: freeze_add_vec:
187; X86:       # %bb.0:
188; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
189; X86-NEXT:    retl
190;
191; X64-LABEL: freeze_add_vec:
192; X64:       # %bb.0:
193; X64-NEXT:    vpbroadcastd {{.*#+}} xmm1 = [5,5,5,5]
194; X64-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
195; X64-NEXT:    retq
196  %x = add <4 x i32> %a0, <i32 1, i32 2, i32 3, i32 4>
197  %y = freeze <4 x i32> %x
198  %z = add <4 x i32> %y, <i32 4, i32 3, i32 2, i32 1>
199  ret <4 x i32> %z
200}
201
202define <4 x i32> @freeze_add_vec_undef(<4 x i32> %a0) nounwind {
203; X86-LABEL: freeze_add_vec_undef:
204; X86:       # %bb.0:
205; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
206; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
207; X86-NEXT:    retl
208;
209; X64-LABEL: freeze_add_vec_undef:
210; X64:       # %bb.0:
211; X64-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
212; X64-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
213; X64-NEXT:    retq
214  %x = add <4 x i32> %a0, <i32 1, i32 2, i32 3, i32 undef>
215  %y = freeze <4 x i32> %x
216  %z = add <4 x i32> %y, <i32 4, i32 3, i32 2, i32 undef>
217  ret <4 x i32> %z
218}
219
220define i32 @freeze_sub(i32 %a0) nounwind {
221; X86-LABEL: freeze_sub:
222; X86:       # %bb.0:
223; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
224; X86-NEXT:    addl $-2, %eax
225; X86-NEXT:    retl
226;
227; X64-LABEL: freeze_sub:
228; X64:       # %bb.0:
229; X64-NEXT:    # kill: def $edi killed $edi def $rdi
230; X64-NEXT:    leal -2(%rdi), %eax
231; X64-NEXT:    retq
232  %x = sub i32 %a0, 1
233  %y = freeze i32 %x
234  %z = sub i32 %y, 1
235  ret i32 %z
236}
237
238define i32 @freeze_sub_nuw(i32 %a0) nounwind {
239; X86-LABEL: freeze_sub_nuw:
240; X86:       # %bb.0:
241; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
242; X86-NEXT:    addl $-2, %eax
243; X86-NEXT:    retl
244;
245; X64-LABEL: freeze_sub_nuw:
246; X64:       # %bb.0:
247; X64-NEXT:    # kill: def $edi killed $edi def $rdi
248; X64-NEXT:    leal -2(%rdi), %eax
249; X64-NEXT:    retq
250  %x = sub nuw i32 %a0, 1
251  %y = freeze i32 %x
252  %z = sub i32 %y, 1
253  ret i32 %z
254}
255
256define <4 x i32> @freeze_sub_vec(<4 x i32> %a0) nounwind {
257; X86-LABEL: freeze_sub_vec:
258; X86:       # %bb.0:
259; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
260; X86-NEXT:    retl
261;
262; X64-LABEL: freeze_sub_vec:
263; X64:       # %bb.0:
264; X64-NEXT:    vpbroadcastd {{.*#+}} xmm1 = [5,5,5,5]
265; X64-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
266; X64-NEXT:    retq
267  %x = sub <4 x i32> %a0, <i32 1, i32 2, i32 3, i32 4>
268  %y = freeze <4 x i32> %x
269  %z = sub <4 x i32> %y, <i32 4, i32 3, i32 2, i32 1>
270  ret <4 x i32> %z
271}
272
273define <4 x i32> @freeze_sub_vec_undef(<4 x i32> %a0) nounwind {
274; X86-LABEL: freeze_sub_vec_undef:
275; X86:       # %bb.0:
276; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
277; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
278; X86-NEXT:    retl
279;
280; X64-LABEL: freeze_sub_vec_undef:
281; X64:       # %bb.0:
282; X64-NEXT:    vpsubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
283; X64-NEXT:    vpsubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
284; X64-NEXT:    retq
285  %x = sub <4 x i32> %a0, <i32 1, i32 2, i32 3, i32 undef>
286  %y = freeze <4 x i32> %x
287  %z = sub <4 x i32> %y, <i32 4, i32 3, i32 2, i32 undef>
288  ret <4 x i32> %z
289}
290
291define i32 @freeze_mul(i32 %a0) nounwind {
292; X86-LABEL: freeze_mul:
293; X86:       # %bb.0:
294; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
295; X86-NEXT:    shll $2, %eax
296; X86-NEXT:    retl
297;
298; X64-LABEL: freeze_mul:
299; X64:       # %bb.0:
300; X64-NEXT:    # kill: def $edi killed $edi def $rdi
301; X64-NEXT:    leal (,%rdi,4), %eax
302; X64-NEXT:    retq
303  %x = mul i32 %a0, 2
304  %y = freeze i32 %x
305  %z = mul i32 %y, 2
306  ret i32 %z
307}
308
309define i32 @freeze_mul_nsw(i32 %a0) nounwind {
310; X86-LABEL: freeze_mul_nsw:
311; X86:       # %bb.0:
312; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
313; X86-NEXT:    leal (%eax,%eax,4), %eax
314; X86-NEXT:    leal (%eax,%eax,2), %eax
315; X86-NEXT:    retl
316;
317; X64-LABEL: freeze_mul_nsw:
318; X64:       # %bb.0:
319; X64-NEXT:    # kill: def $edi killed $edi def $rdi
320; X64-NEXT:    leal (%rdi,%rdi,4), %eax
321; X64-NEXT:    leal (%rax,%rax,2), %eax
322; X64-NEXT:    retq
323  %x = mul nsw i32 %a0, 3
324  %y = freeze i32 %x
325  %z = mul i32 %y, 5
326  ret i32 %z
327}
328
329define <8 x i16> @freeze_mul_vec(<8 x i16> %a0) nounwind {
330; X86-LABEL: freeze_mul_vec:
331; X86:       # %bb.0:
332; X86-NEXT:    pmullw {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0 # [4,6,6,4,4,6,6,4]
333; X86-NEXT:    retl
334;
335; X64-LABEL: freeze_mul_vec:
336; X64:       # %bb.0:
337; X64-NEXT:    vpmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [4,6,6,4,4,6,6,4]
338; X64-NEXT:    retq
339  %x = mul <8 x i16> %a0, <i16 1, i16 2, i16 3, i16 4, i16 4, i16 3, i16 2, i16 1>
340  %y = freeze <8 x i16> %x
341  %z = mul <8 x i16> %y, <i16 4, i16 3, i16 2, i16 1, i16 1, i16 2, i16 3, i16 4>
342  ret <8 x i16> %z
343}
344
345define <8 x i16> @freeze_mul_vec_undef(<8 x i16> %a0) nounwind {
346; X86-LABEL: freeze_mul_vec_undef:
347; X86:       # %bb.0:
348; X86-NEXT:    pmullw {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0 # [1,2,3,4,4,3,0,1]
349; X86-NEXT:    pmullw {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0 # [4,3,2,1,1,2,u,4]
350; X86-NEXT:    retl
351;
352; X64-LABEL: freeze_mul_vec_undef:
353; X64:       # %bb.0:
354; X64-NEXT:    vpmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [1,2,3,4,4,3,0,1]
355; X64-NEXT:    vpmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [4,3,2,1,1,2,u,4]
356; X64-NEXT:    retq
357  %x = mul <8 x i16> %a0, <i16 1, i16 2, i16 3, i16 4, i16 4, i16 3, i16 undef, i16 1>
358  %y = freeze <8 x i16> %x
359  %z = mul <8 x i16> %y, <i16 4, i16 3, i16 2, i16 1, i16 1, i16 2, i16 undef, i16 4>
360  ret <8 x i16> %z
361}
362
363define i32 @freeze_shl(i32 %a0) nounwind {
364; X86-LABEL: freeze_shl:
365; X86:       # %bb.0:
366; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
367; X86-NEXT:    shll $3, %eax
368; X86-NEXT:    retl
369;
370; X64-LABEL: freeze_shl:
371; X64:       # %bb.0:
372; X64-NEXT:    # kill: def $edi killed $edi def $rdi
373; X64-NEXT:    leal (,%rdi,8), %eax
374; X64-NEXT:    retq
375  %x = shl i32 %a0, 1
376  %y = freeze i32 %x
377  %z = shl i32 %y, 2
378  ret i32 %z
379}
380
381define i32 @freeze_shl_nsw(i32 %a0) nounwind {
382; X86-LABEL: freeze_shl_nsw:
383; X86:       # %bb.0:
384; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
385; X86-NEXT:    shll $8, %eax
386; X86-NEXT:    retl
387;
388; X64-LABEL: freeze_shl_nsw:
389; X64:       # %bb.0:
390; X64-NEXT:    movl %edi, %eax
391; X64-NEXT:    shll $8, %eax
392; X64-NEXT:    retq
393  %x = shl nsw i32 %a0, 3
394  %y = freeze i32 %x
395  %z = shl i32 %y, 5
396  ret i32 %z
397}
398
399define i32 @freeze_shl_outofrange(i32 %a0) nounwind {
400; X86-LABEL: freeze_shl_outofrange:
401; X86:       # %bb.0:
402; X86-NEXT:    shll $2, %eax
403; X86-NEXT:    retl
404;
405; X64-LABEL: freeze_shl_outofrange:
406; X64:       # %bb.0:
407; X64-NEXT:    shll $2, %eax
408; X64-NEXT:    retq
409  %x = shl i32 %a0, 32
410  %y = freeze i32 %x
411  %z = shl i32 %y, 2
412  ret i32 %z
413}
414
415define <2 x i64> @freeze_shl_vec(<2 x i64> %a0) nounwind {
416; X86-LABEL: freeze_shl_vec:
417; X86:       # %bb.0:
418; X86-NEXT:    movdqa %xmm0, %xmm1
419; X86-NEXT:    psllq $4, %xmm1
420; X86-NEXT:    psllq $2, %xmm0
421; X86-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
422; X86-NEXT:    retl
423;
424; X64-LABEL: freeze_shl_vec:
425; X64:       # %bb.0:
426; X64-NEXT:    vpsllvq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
427; X64-NEXT:    retq
428  %x = shl <2 x i64> %a0, <i64 2, i64 1>
429  %y = freeze <2 x i64> %x
430  %z = shl <2 x i64> %y, <i64 2, i64 1>
431  ret <2 x i64> %z
432}
433
434define <2 x i64> @freeze_shl_vec_outofrange(<2 x i64> %a0) nounwind {
435; X86-LABEL: freeze_shl_vec_outofrange:
436; X86:       # %bb.0:
437; X86-NEXT:    psllq $3, %xmm0
438; X86-NEXT:    retl
439;
440; X64-LABEL: freeze_shl_vec_outofrange:
441; X64:       # %bb.0:
442; X64-NEXT:    vpsllvq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
443; X64-NEXT:    vpsllq $2, %xmm0, %xmm0
444; X64-NEXT:    retq
445  %x = shl <2 x i64> %a0, <i64 1, i64 64>
446  %y = freeze <2 x i64> %x
447  %z = shl <2 x i64> %y, <i64 2, i64 2>
448  ret <2 x i64> %z
449}
450
451define i32 @freeze_ashr(i32 %a0) nounwind {
452; X86-LABEL: freeze_ashr:
453; X86:       # %bb.0:
454; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
455; X86-NEXT:    sarl $3, %eax
456; X86-NEXT:    sarl $3, %eax
457; X86-NEXT:    retl
458;
459; X64-LABEL: freeze_ashr:
460; X64:       # %bb.0:
461; X64-NEXT:    movl %edi, %eax
462; X64-NEXT:    sarl $6, %eax
463; X64-NEXT:    retq
464  %x = ashr i32 %a0, 3
465  %y = freeze i32 %x
466  %z = ashr i32 %y, 3
467  ret i32 %z
468}
469
470define i32 @freeze_ashr_exact(i32 %a0) nounwind {
471; X86-LABEL: freeze_ashr_exact:
472; X86:       # %bb.0:
473; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
474; X86-NEXT:    sarl $3, %eax
475; X86-NEXT:    sarl $6, %eax
476; X86-NEXT:    retl
477;
478; X64-LABEL: freeze_ashr_exact:
479; X64:       # %bb.0:
480; X64-NEXT:    movl %edi, %eax
481; X64-NEXT:    sarl $3, %eax
482; X64-NEXT:    sarl $6, %eax
483; X64-NEXT:    retq
484  %x = ashr exact i32 %a0, 3
485  %y = freeze i32 %x
486  %z = ashr i32 %y, 6
487  ret i32 %z
488}
489
490define i32 @freeze_ashr_exact_extra_use(i32 %a0, ptr %escape) nounwind {
491; X86-LABEL: freeze_ashr_exact_extra_use:
492; X86:       # %bb.0:
493; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
494; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
495; X86-NEXT:    sarl $3, %eax
496; X86-NEXT:    movl %eax, (%ecx)
497; X86-NEXT:    sarl $6, %eax
498; X86-NEXT:    retl
499;
500; X64-LABEL: freeze_ashr_exact_extra_use:
501; X64:       # %bb.0:
502; X64-NEXT:    movl %edi, %eax
503; X64-NEXT:    sarl $3, %eax
504; X64-NEXT:    movl %eax, (%rsi)
505; X64-NEXT:    sarl $6, %eax
506; X64-NEXT:    retq
507  %x = ashr exact i32 %a0, 3
508  %y = freeze i32 %x
509  %z = ashr i32 %y, 6
510  store i32 %x, ptr %escape
511  ret i32 %z
512}
513
514define i32 @freeze_ashr_outofrange(i32 %a0) nounwind {
515; X86-LABEL: freeze_ashr_outofrange:
516; X86:       # %bb.0:
517; X86-NEXT:    sarl $3, %eax
518; X86-NEXT:    retl
519;
520; X64-LABEL: freeze_ashr_outofrange:
521; X64:       # %bb.0:
522; X64-NEXT:    sarl $3, %eax
523; X64-NEXT:    retq
524  %x = ashr i32 %a0, 32
525  %y = freeze i32 %x
526  %z = ashr i32 %y, 3
527  ret i32 %z
528}
529
530define <8 x i16> @freeze_ashr_vec(<8 x i16> %a0) nounwind {
531; X86-LABEL: freeze_ashr_vec:
532; X86:       # %bb.0:
533; X86-NEXT:    psraw $4, %xmm0
534; X86-NEXT:    retl
535;
536; X64-LABEL: freeze_ashr_vec:
537; X64:       # %bb.0:
538; X64-NEXT:    vpsraw $4, %xmm0, %xmm0
539; X64-NEXT:    retq
540  %x = ashr <8 x i16> %a0, <i16 3, i16 1, i16 3, i16 1, i16 3, i16 1, i16 3, i16 1>
541  %y = freeze <8 x i16> %x
542  %z = ashr <8 x i16> %y, <i16 1, i16 3, i16 1, i16 3, i16 1, i16 3, i16 1, i16 3>
543  ret <8 x i16> %z
544}
545
546define <4 x i32> @freeze_ashr_vec_outofrange(<4 x i32> %a0) nounwind {
547; X86-LABEL: freeze_ashr_vec_outofrange:
548; X86:       # %bb.0:
549; X86-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,3,2,3]
550; X86-NEXT:    psrad $3, %xmm0
551; X86-NEXT:    retl
552;
553; X64-LABEL: freeze_ashr_vec_outofrange:
554; X64:       # %bb.0:
555; X64-NEXT:    vpsravd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
556; X64-NEXT:    vpsrad $2, %xmm0, %xmm0
557; X64-NEXT:    retq
558  %x = ashr <4 x i32> %a0, <i32 1, i32 33, i32 1, i32 1>
559  %y = freeze <4 x i32> %x
560  %z = ashr <4 x i32> %y, <i32 2, i32 2, i32 2, i32 2>
561  ret <4 x i32> %z
562}
563
564define i32 @freeze_lshr(i32 %a0) nounwind {
565; X86-LABEL: freeze_lshr:
566; X86:       # %bb.0:
567; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
568; X86-NEXT:    shrl $2, %eax
569; X86-NEXT:    shrl %eax
570; X86-NEXT:    retl
571;
572; X64-LABEL: freeze_lshr:
573; X64:       # %bb.0:
574; X64-NEXT:    movl %edi, %eax
575; X64-NEXT:    shrl $3, %eax
576; X64-NEXT:    retq
577  %x = lshr i32 %a0, 2
578  %y = freeze i32 %x
579  %z = lshr i32 %y, 1
580  ret i32 %z
581}
582
583define i32 @freeze_lshr_exact(i32 %a0) nounwind {
584; X86-LABEL: freeze_lshr_exact:
585; X86:       # %bb.0:
586; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
587; X86-NEXT:    shrl $3, %eax
588; X86-NEXT:    shrl $5, %eax
589; X86-NEXT:    retl
590;
591; X64-LABEL: freeze_lshr_exact:
592; X64:       # %bb.0:
593; X64-NEXT:    movl %edi, %eax
594; X64-NEXT:    shrl $3, %eax
595; X64-NEXT:    shrl $5, %eax
596; X64-NEXT:    retq
597  %x = lshr exact i32 %a0, 3
598  %y = freeze i32 %x
599  %z = lshr i32 %y, 5
600  ret i32 %z
601}
602
603define i32 @freeze_lshr_exact_extra_use(i32 %a0, ptr %escape) nounwind {
604; X86-LABEL: freeze_lshr_exact_extra_use:
605; X86:       # %bb.0:
606; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
607; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
608; X86-NEXT:    shrl $3, %eax
609; X86-NEXT:    movl %eax, (%ecx)
610; X86-NEXT:    shrl $5, %eax
611; X86-NEXT:    retl
612;
613; X64-LABEL: freeze_lshr_exact_extra_use:
614; X64:       # %bb.0:
615; X64-NEXT:    movl %edi, %eax
616; X64-NEXT:    shrl $3, %eax
617; X64-NEXT:    movl %eax, (%rsi)
618; X64-NEXT:    shrl $5, %eax
619; X64-NEXT:    retq
620  %x = lshr exact i32 %a0, 3
621  %y = freeze i32 %x
622  %z = lshr i32 %y, 5
623  store i32 %x, ptr %escape
624  ret i32 %z
625}
626
627define i32 @freeze_lshr_outofrange(i32 %a0) nounwind {
628; X86-LABEL: freeze_lshr_outofrange:
629; X86:       # %bb.0:
630; X86-NEXT:    shrl %eax
631; X86-NEXT:    retl
632;
633; X64-LABEL: freeze_lshr_outofrange:
634; X64:       # %bb.0:
635; X64-NEXT:    shrl %eax
636; X64-NEXT:    retq
637  %x = lshr i32 %a0, 32
638  %y = freeze i32 %x
639  %z = lshr i32 %y, 1
640  ret i32 %z
641}
642
643define <8 x i16> @freeze_lshr_vec(<8 x i16> %a0) nounwind {
644; X86-LABEL: freeze_lshr_vec:
645; X86:       # %bb.0:
646; X86-NEXT:    psrlw $3, %xmm0
647; X86-NEXT:    retl
648;
649; X64-LABEL: freeze_lshr_vec:
650; X64:       # %bb.0:
651; X64-NEXT:    vpsrlw $3, %xmm0, %xmm0
652; X64-NEXT:    retq
653  %x = lshr <8 x i16> %a0, <i16 2, i16 1, i16 2, i16 1, i16 2, i16 1, i16 2, i16 1>
654  %y = freeze <8 x i16> %x
655  %z = lshr <8 x i16> %y, <i16 1, i16 2, i16 1, i16 2, i16 1, i16 2, i16 1, i16 2>
656  ret <8 x i16> %z
657}
658
659define <4 x i32> @freeze_lshr_vec_outofrange(<4 x i32> %a0) nounwind {
660; X86-LABEL: freeze_lshr_vec_outofrange:
661; X86:       # %bb.0:
662; X86-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,3,2,3]
663; X86-NEXT:    psrld $3, %xmm0
664; X86-NEXT:    retl
665;
666; X64-LABEL: freeze_lshr_vec_outofrange:
667; X64:       # %bb.0:
668; X64-NEXT:    vpsrlvd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
669; X64-NEXT:    vpsrld $2, %xmm0, %xmm0
670; X64-NEXT:    retq
671  %x = lshr <4 x i32> %a0, <i32 1, i32 33, i32 1, i32 1>
672  %y = freeze <4 x i32> %x
673  %z = lshr <4 x i32> %y, <i32 2, i32 2, i32 2, i32 2>
674  ret <4 x i32> %z
675}
676
677define i32 @freeze_rotl(i32 %a0) nounwind {
678; X86-LABEL: freeze_rotl:
679; X86:       # %bb.0:
680; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
681; X86-NEXT:    roll $10, %eax
682; X86-NEXT:    retl
683;
684; X64-LABEL: freeze_rotl:
685; X64:       # %bb.0:
686; X64-NEXT:    movl %edi, %eax
687; X64-NEXT:    roll $10, %eax
688; X64-NEXT:    retq
689  %x = call i32 @llvm.fshl.i32(i32 %a0, i32 %a0, i32 5)
690  %y = freeze i32 %x
691  %z = call i32 @llvm.fshl.i32(i32 %y, i32 %y, i32 5)
692  ret i32 %z
693}
694declare i32 @llvm.fshl.i32(i32, i32, i32)
695
696define <4 x i32> @freeze_rotl_vec(<4 x i32> %a0) nounwind {
697; X86-LABEL: freeze_rotl_vec:
698; X86:       # %bb.0:
699; X86-NEXT:    movdqa %xmm0, %xmm1
700; X86-NEXT:    psrld $2, %xmm1
701; X86-NEXT:    pslld $30, %xmm0
702; X86-NEXT:    por %xmm1, %xmm0
703; X86-NEXT:    retl
704;
705; X64-LABEL: freeze_rotl_vec:
706; X64:       # %bb.0:
707; X64-NEXT:    vpsrld $2, %xmm0, %xmm1
708; X64-NEXT:    vpslld $30, %xmm0, %xmm0
709; X64-NEXT:    vpor %xmm1, %xmm0, %xmm0
710; X64-NEXT:    retq
711  %x = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %a0, <4 x i32> %a0, <4 x i32> <i32 0, i32 1, i32 2, i32 3>)
712  %y = freeze <4 x i32> %x
713  %z = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %y, <4 x i32> %y, <4 x i32> <i32 30, i32 29, i32 28, i32 27>)
714  ret <4 x i32> %z
715}
716declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
717
718define i32 @freeze_rotr(i32 %a0) nounwind {
719; X86-LABEL: freeze_rotr:
720; X86:       # %bb.0:
721; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
722; X86-NEXT:    rorl $24, %eax
723; X86-NEXT:    retl
724;
725; X64-LABEL: freeze_rotr:
726; X64:       # %bb.0:
727; X64-NEXT:    movl %edi, %eax
728; X64-NEXT:    rorl $24, %eax
729; X64-NEXT:    retq
730  %x = call i32 @llvm.fshr.i32(i32 %a0, i32 %a0, i32 11)
731  %y = freeze i32 %x
732  %z = call i32 @llvm.fshr.i32(i32 %y, i32 %y, i32 13)
733  ret i32 %z
734}
735declare i32 @llvm.fshr.i32(i32, i32, i32)
736
737define <4 x i32> @freeze_rotr_vec(<4 x i32> %a0) nounwind {
738; X86-LABEL: freeze_rotr_vec:
739; X86:       # %bb.0:
740; X86-NEXT:    movdqa %xmm0, %xmm1
741; X86-NEXT:    psrld $31, %xmm1
742; X86-NEXT:    paddd %xmm0, %xmm0
743; X86-NEXT:    por %xmm1, %xmm0
744; X86-NEXT:    retl
745;
746; X64-LABEL: freeze_rotr_vec:
747; X64:       # %bb.0:
748; X64-NEXT:    vpsrld $31, %xmm0, %xmm1
749; X64-NEXT:    vpaddd %xmm0, %xmm0, %xmm0
750; X64-NEXT:    vpor %xmm1, %xmm0, %xmm0
751; X64-NEXT:    retq
752  %x = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %a0, <4 x i32> %a0, <4 x i32> <i32 0, i32 1, i32 2, i32 3>)
753  %y = freeze <4 x i32> %x
754  %z = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %y, <4 x i32> %y, <4 x i32> <i32 31, i32 30, i32 29, i32 28>)
755  ret <4 x i32> %z
756}
757declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
758
759define i32 @freeze_fshl(i32 %a0, i32 %a1, i32 %a2) nounwind {
760; X86-LABEL: freeze_fshl:
761; X86:       # %bb.0:
762; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
763; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
764; X86-NEXT:    shrl $27, %eax
765; X86-NEXT:    shldl $27, %ecx, %eax
766; X86-NEXT:    retl
767;
768; X64-LABEL: freeze_fshl:
769; X64:       # %bb.0:
770; X64-NEXT:    movl %esi, %eax
771; X64-NEXT:    shrl $27, %eax
772; X64-NEXT:    shldl $27, %edx, %eax
773; X64-NEXT:    retq
774  %f1 = freeze i32 %a1
775  %f2 = freeze i32 %a2
776  %x = call i32 @llvm.fshl.i32(i32 %a0, i32 %f1, i32 5)
777  %y = freeze i32 %x
778  %z = call i32 @llvm.fshl.i32(i32 %y, i32 %f2, i32 27)
779  ret i32 %z
780}
781
782define i32 @freeze_fshr(i32 %a0, i32 %a1, i32 %a2) nounwind {
783; X86-LABEL: freeze_fshr:
784; X86:       # %bb.0:
785; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
786; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
787; X86-NEXT:    shrl %eax
788; X86-NEXT:    shldl $1, %ecx, %eax
789; X86-NEXT:    retl
790;
791; X64-LABEL: freeze_fshr:
792; X64:       # %bb.0:
793; X64-NEXT:    movl %esi, %eax
794; X64-NEXT:    shrl %eax
795; X64-NEXT:    shldl $1, %edx, %eax
796; X64-NEXT:    retq
797  %f1 = freeze i32 %a1
798  %f2 = freeze i32 %a2
799  %x = call i32 @llvm.fshr.i32(i32 %a0, i32 %f1, i32 1)
800  %y = freeze i32 %x
801  %z = call i32 @llvm.fshr.i32(i32 %y, i32 %f2, i32 31)
802  ret i32 %z
803}
804
805define void @pr59676_frozen(ptr %dst, i32 %x.orig) {
806; X86-LABEL: pr59676_frozen:
807; X86:       # %bb.0:
808; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
809; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
810; X86-NEXT:    imull %eax, %eax
811; X86-NEXT:    imull $84, %eax, %eax
812; X86-NEXT:    movl $818089009, %edx # imm = 0x30C30C31
813; X86-NEXT:    imull %edx
814; X86-NEXT:    movl %edx, %eax
815; X86-NEXT:    shrl $31, %eax
816; X86-NEXT:    sarl $3, %edx
817; X86-NEXT:    addl %eax, %edx
818; X86-NEXT:    movl %edx, (%ecx)
819; X86-NEXT:    retl
820;
821; X64-LABEL: pr59676_frozen:
822; X64:       # %bb.0:
823; X64-NEXT:    imull %esi, %esi
824; X64-NEXT:    imull $84, %esi, %eax
825; X64-NEXT:    cltq
826; X64-NEXT:    imulq $818089009, %rax, %rax # imm = 0x30C30C31
827; X64-NEXT:    movq %rax, %rcx
828; X64-NEXT:    shrq $63, %rcx
829; X64-NEXT:    sarq $35, %rax
830; X64-NEXT:    addl %ecx, %eax
831; X64-NEXT:    movl %eax, (%rdi)
832; X64-NEXT:    retq
833  %x = freeze i32 %x.orig
834  %mul = mul i32 %x, 42
835  %shl = shl i32 %x, 1
836  %mul.frozen = freeze i32 %mul
837  %shl.frozen = freeze i32 %shl
838  %area = mul i32 %mul.frozen, %shl.frozen
839  %div = sdiv i32 %area, 42
840  store i32 %div, ptr %dst, align 4
841  ret void
842}
843define void @pr59676_nsw_frozen(ptr %dst, i32 %x.orig) {
844; X86-LABEL: pr59676_nsw_frozen:
845; X86:       # %bb.0:
846; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
847; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
848; X86-NEXT:    imull %eax, %eax
849; X86-NEXT:    imull $84, %eax, %eax
850; X86-NEXT:    movl $818089009, %edx # imm = 0x30C30C31
851; X86-NEXT:    imull %edx
852; X86-NEXT:    movl %edx, %eax
853; X86-NEXT:    shrl $31, %eax
854; X86-NEXT:    sarl $3, %edx
855; X86-NEXT:    addl %eax, %edx
856; X86-NEXT:    movl %edx, (%ecx)
857; X86-NEXT:    retl
858;
859; X64-LABEL: pr59676_nsw_frozen:
860; X64:       # %bb.0:
861; X64-NEXT:    imull %esi, %esi
862; X64-NEXT:    imull $84, %esi, %eax
863; X64-NEXT:    cltq
864; X64-NEXT:    imulq $818089009, %rax, %rax # imm = 0x30C30C31
865; X64-NEXT:    movq %rax, %rcx
866; X64-NEXT:    shrq $63, %rcx
867; X64-NEXT:    sarq $35, %rax
868; X64-NEXT:    addl %ecx, %eax
869; X64-NEXT:    movl %eax, (%rdi)
870; X64-NEXT:    retq
871  %x = freeze i32 %x.orig
872  %mul = mul nsw i32 %x, 42
873  %shl = shl i32 %x, 1
874  %mul.frozen = freeze i32 %mul
875  %shl.frozen = freeze i32 %shl
876  %area = mul i32 %mul.frozen, %shl.frozen
877  %div = sdiv i32 %area, 42
878  store i32 %div, ptr %dst, align 4
879  ret void
880}
881define void @pr59676_nsw(ptr %dst, i32 %x) {
882; X86-LABEL: pr59676_nsw:
883; X86:       # %bb.0:
884; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
885; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
886; X86-NEXT:    imull %eax, %eax
887; X86-NEXT:    imull $84, %eax, %eax
888; X86-NEXT:    movl $818089009, %edx # imm = 0x30C30C31
889; X86-NEXT:    imull %edx
890; X86-NEXT:    movl %edx, %eax
891; X86-NEXT:    shrl $31, %eax
892; X86-NEXT:    sarl $3, %edx
893; X86-NEXT:    addl %eax, %edx
894; X86-NEXT:    movl %edx, (%ecx)
895; X86-NEXT:    retl
896;
897; X64-LABEL: pr59676_nsw:
898; X64:       # %bb.0:
899; X64-NEXT:    imull %esi, %esi
900; X64-NEXT:    imull $84, %esi, %eax
901; X64-NEXT:    cltq
902; X64-NEXT:    imulq $818089009, %rax, %rax # imm = 0x30C30C31
903; X64-NEXT:    movq %rax, %rcx
904; X64-NEXT:    shrq $63, %rcx
905; X64-NEXT:    sarq $35, %rax
906; X64-NEXT:    addl %ecx, %eax
907; X64-NEXT:    movl %eax, (%rdi)
908; X64-NEXT:    retq
909  %mul = mul nsw i32 %x, 42
910  %shl = shl i32 %x, 1
911  %mul.frozen = freeze i32 %mul
912  %shl.frozen = freeze i32 %shl
913  %area = mul i32 %mul.frozen, %shl.frozen
914  %div = sdiv i32 %area, 42
915  store i32 %div, ptr %dst, align 4
916  ret void
917}
918