• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,NOBMI -enable-var-scope
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs -mattr=+bmi | FileCheck %s -check-prefixes=CHECK,BMI -enable-var-scope
4
5define i32 @select_and1(i32 %x, i32 %y) {
6; CHECK-LABEL: select_and1:
7; CHECK:       # %bb.0:
8; CHECK-NEXT:    xorl %eax, %eax
9; CHECK-NEXT:    cmpl $11, %edi
10; CHECK-NEXT:    cmovgel %esi, %eax
11; CHECK-NEXT:    retq
12  %c = icmp slt i32 %x, 11
13  %s = select i1 %c, i32 0, i32 -1
14  %a = and i32 %y, %s
15  ret i32 %a
16}
17
18define i32 @select_and2(i32 %x, i32 %y) {
19; CHECK-LABEL: select_and2:
20; CHECK:       # %bb.0:
21; CHECK-NEXT:    xorl %eax, %eax
22; CHECK-NEXT:    cmpl $11, %edi
23; CHECK-NEXT:    cmovgel %esi, %eax
24; CHECK-NEXT:    retq
25  %c = icmp slt i32 %x, 11
26  %s = select i1 %c, i32 0, i32 -1
27  %a = and i32 %s, %y
28  ret i32 %a
29}
30
31define i32 @select_and3(i32 %x, i32 %y) {
32; CHECK-LABEL: select_and3:
33; CHECK:       # %bb.0:
34; CHECK-NEXT:    xorl %eax, %eax
35; CHECK-NEXT:    cmpl $11, %edi
36; CHECK-NEXT:    cmovll %esi, %eax
37; CHECK-NEXT:    retq
38  %c = icmp slt i32 %x, 11
39  %s = select i1 %c, i32 -1, i32 0
40  %a = and i32 %y, %s
41  ret i32 %a
42}
43
44define <4 x i32> @select_and_v4(i32 %x, <4 x i32> %y) {
45; CHECK-LABEL: select_and_v4:
46; CHECK:       # %bb.0:
47; CHECK-NEXT:    cmpl $11, %edi
48; CHECK-NEXT:    xorps %xmm1, %xmm1
49; CHECK-NEXT:    jl .LBB3_2
50; CHECK-NEXT:  # %bb.1:
51; CHECK-NEXT:    movaps %xmm0, %xmm1
52; CHECK-NEXT:  .LBB3_2:
53; CHECK-NEXT:    movaps %xmm1, %xmm0
54; CHECK-NEXT:    retq
55  %c = icmp slt i32 %x, 11
56  %s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1>
57  %a = and <4 x i32> %s, %y
58  ret <4 x i32> %a
59}
60
61define i32 @select_or1(i32 %x, i32 %y) {
62; CHECK-LABEL: select_or1:
63; CHECK:       # %bb.0:
64; CHECK-NEXT:    cmpl $11, %edi
65; CHECK-NEXT:    movl $-1, %eax
66; CHECK-NEXT:    cmovll %esi, %eax
67; CHECK-NEXT:    retq
68  %c = icmp slt i32 %x, 11
69  %s = select i1 %c, i32 0, i32 -1
70  %a = or i32 %y, %s
71  ret i32 %a
72}
73
74define i32 @select_or2(i32 %x, i32 %y) {
75; CHECK-LABEL: select_or2:
76; CHECK:       # %bb.0:
77; CHECK-NEXT:    cmpl $11, %edi
78; CHECK-NEXT:    movl $-1, %eax
79; CHECK-NEXT:    cmovll %esi, %eax
80; CHECK-NEXT:    retq
81  %c = icmp slt i32 %x, 11
82  %s = select i1 %c, i32 0, i32 -1
83  %a = or i32 %s, %y
84  ret i32 %a
85}
86
87define i32 @select_or3(i32 %x, i32 %y) {
88; CHECK-LABEL: select_or3:
89; CHECK:       # %bb.0:
90; CHECK-NEXT:    cmpl $11, %edi
91; CHECK-NEXT:    movl $-1, %eax
92; CHECK-NEXT:    cmovgel %esi, %eax
93; CHECK-NEXT:    retq
94  %c = icmp slt i32 %x, 11
95  %s = select i1 %c, i32 -1, i32 0
96  %a = or i32 %y, %s
97  ret i32 %a
98}
99
100define <4 x i32> @select_or_v4(i32 %x, <4 x i32> %y) {
101; CHECK-LABEL: select_or_v4:
102; CHECK:       # %bb.0:
103; CHECK-NEXT:    cmpl $11, %edi
104; CHECK-NEXT:    jl .LBB7_2
105; CHECK-NEXT:  # %bb.1:
106; CHECK-NEXT:    pcmpeqd %xmm0, %xmm0
107; CHECK-NEXT:  .LBB7_2:
108; CHECK-NEXT:    retq
109  %c = icmp slt i32 %x, 11
110  %s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1>
111  %a = or <4 x i32> %s, %y
112  ret <4 x i32> %a
113}
114
115define i32 @sel_constants_sub_constant_sel_constants(i1 %cond) {
116; CHECK-LABEL: sel_constants_sub_constant_sel_constants:
117; CHECK:       # %bb.0:
118; CHECK-NEXT:    testb $1, %dil
119; CHECK-NEXT:    movl $9, %ecx
120; CHECK-NEXT:    movl $2, %eax
121; CHECK-NEXT:    cmovnel %ecx, %eax
122; CHECK-NEXT:    retq
123  %sel = select i1 %cond, i32 -4, i32 3
124  %bo = sub i32 5, %sel
125  ret i32 %bo
126}
127
128define i32 @sdiv_constant_sel_constants(i1 %cond) {
129; CHECK-LABEL: sdiv_constant_sel_constants:
130; CHECK:       # %bb.0:
131; CHECK-NEXT:    notb %dil
132; CHECK-NEXT:    movzbl %dil, %eax
133; CHECK-NEXT:    andl $1, %eax
134; CHECK-NEXT:    leal (%rax,%rax,4), %eax
135; CHECK-NEXT:    retq
136  %sel = select i1 %cond, i32 121, i32 23
137  %bo = sdiv i32 120, %sel
138  ret i32 %bo
139}
140
141define i32 @udiv_constant_sel_constants(i1 %cond) {
142; CHECK-LABEL: udiv_constant_sel_constants:
143; CHECK:       # %bb.0:
144; CHECK-NEXT:    notb %dil
145; CHECK-NEXT:    movzbl %dil, %eax
146; CHECK-NEXT:    andl $1, %eax
147; CHECK-NEXT:    leal (%rax,%rax,4), %eax
148; CHECK-NEXT:    retq
149  %sel = select i1 %cond, i32 -4, i32 23
150  %bo = udiv i32 120, %sel
151  ret i32 %bo
152}
153
154define i32 @srem_constant_sel_constants(i1 %cond) {
155; CHECK-LABEL: srem_constant_sel_constants:
156; CHECK:       # %bb.0:
157; CHECK-NEXT:    testb $1, %dil
158; CHECK-NEXT:    movl $120, %ecx
159; CHECK-NEXT:    movl $5, %eax
160; CHECK-NEXT:    cmovnel %ecx, %eax
161; CHECK-NEXT:    retq
162  %sel = select i1 %cond, i32 121, i32 23
163  %bo = srem i32 120, %sel
164  ret i32 %bo
165}
166
167define i32 @urem_constant_sel_constants(i1 %cond) {
168; CHECK-LABEL: urem_constant_sel_constants:
169; CHECK:       # %bb.0:
170; CHECK-NEXT:    testb $1, %dil
171; CHECK-NEXT:    movl $120, %ecx
172; CHECK-NEXT:    movl $5, %eax
173; CHECK-NEXT:    cmovnel %ecx, %eax
174; CHECK-NEXT:    retq
175  %sel = select i1 %cond, i32 -4, i32 23
176  %bo = urem i32 120, %sel
177  ret i32 %bo
178}
179
180define i32 @sel_constants_shl_constant(i1 %cond) {
181; CHECK-LABEL: sel_constants_shl_constant:
182; CHECK:       # %bb.0:
183; CHECK-NEXT:    notb %dil
184; CHECK-NEXT:    movzbl %dil, %eax
185; CHECK-NEXT:    andl $1, %eax
186; CHECK-NEXT:    orl $2, %eax
187; CHECK-NEXT:    shll $8, %eax
188; CHECK-NEXT:    retq
189  %sel = select i1 %cond, i32 2, i32 3
190  %bo = shl i32 %sel, 8
191  ret i32 %bo
192}
193
194define i32 @shl_constant_sel_constants(i1 %cond) {
195; CHECK-LABEL: shl_constant_sel_constants:
196; CHECK:       # %bb.0:
197; CHECK-NEXT:    andb $1, %dil
198; CHECK-NEXT:    xorb $3, %dil
199; CHECK-NEXT:    movl $1, %eax
200; CHECK-NEXT:    movl %edi, %ecx
201; CHECK-NEXT:    shll %cl, %eax
202; CHECK-NEXT:    retq
203  %sel = select i1 %cond, i32 2, i32 3
204  %bo = shl i32 1, %sel
205  ret i32 %bo
206}
207
208define i32 @lshr_constant_sel_constants(i1 %cond) {
209; CHECK-LABEL: lshr_constant_sel_constants:
210; CHECK:       # %bb.0:
211; CHECK-NEXT:    andb $1, %dil
212; CHECK-NEXT:    xorb $3, %dil
213; CHECK-NEXT:    movl $64, %eax
214; CHECK-NEXT:    movl %edi, %ecx
215; CHECK-NEXT:    shrl %cl, %eax
216; CHECK-NEXT:    retq
217  %sel = select i1 %cond, i32 2, i32 3
218  %bo = lshr i32 64, %sel
219  ret i32 %bo
220}
221
222define i32 @ashr_constant_sel_constants(i1 %cond) {
223; CHECK-LABEL: ashr_constant_sel_constants:
224; CHECK:       # %bb.0:
225; CHECK-NEXT:    andb $1, %dil
226; CHECK-NEXT:    xorb $3, %dil
227; CHECK-NEXT:    movl $128, %eax
228; CHECK-NEXT:    movl %edi, %ecx
229; CHECK-NEXT:    shrl %cl, %eax
230; CHECK-NEXT:    retq
231  %sel = select i1 %cond, i32 2, i32 3
232  %bo = ashr i32 128, %sel
233  ret i32 %bo
234}
235
236define double @fsub_constant_sel_constants(i1 %cond) {
237; CHECK-LABEL: fsub_constant_sel_constants:
238; CHECK:       # %bb.0:
239; CHECK-NEXT:    testb $1, %dil
240; CHECK-NEXT:    jne .LBB17_1
241; CHECK-NEXT:  # %bb.2:
242; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
243; CHECK-NEXT:    retq
244; CHECK-NEXT:  .LBB17_1:
245; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
246; CHECK-NEXT:    retq
247  %sel = select i1 %cond, double -4.0, double 23.3
248  %bo = fsub double 5.1, %sel
249  ret double %bo
250}
251
252define double @fdiv_constant_sel_constants(i1 %cond) {
253; CHECK-LABEL: fdiv_constant_sel_constants:
254; CHECK:       # %bb.0:
255; CHECK-NEXT:    testb $1, %dil
256; CHECK-NEXT:    jne .LBB18_1
257; CHECK-NEXT:  # %bb.2:
258; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
259; CHECK-NEXT:    retq
260; CHECK-NEXT:  .LBB18_1:
261; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
262; CHECK-NEXT:    retq
263  %sel = select i1 %cond, double -4.0, double 23.3
264  %bo = fdiv double 5.1, %sel
265  ret double %bo
266}
267
268define double @frem_constant_sel_constants(i1 %cond) {
269; CHECK-LABEL: frem_constant_sel_constants:
270; CHECK:       # %bb.0:
271; CHECK-NEXT:    testb $1, %dil
272; CHECK-NEXT:    jne .LBB19_1
273; CHECK-NEXT:  # %bb.2:
274; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
275; CHECK-NEXT:    retq
276; CHECK-NEXT:  .LBB19_1:
277; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
278; CHECK-NEXT:    retq
279  %sel = select i1 %cond, double -4.0, double 23.3
280  %bo = frem double 5.1, %sel
281  ret double %bo
282}
283
284declare i64 @llvm.cttz.i64(i64, i1)
285define i64 @cttz_64_eq_select(i64 %v) nounwind {
286; NOBMI-LABEL: cttz_64_eq_select:
287; NOBMI:       # %bb.0:
288; NOBMI-NEXT:    bsfq %rdi, %rcx
289; NOBMI-NEXT:    movq $-1, %rax
290; NOBMI-NEXT:    cmovneq %rcx, %rax
291; NOBMI-NEXT:    addq $6, %rax
292; NOBMI-NEXT:    retq
293;
294; BMI-LABEL: cttz_64_eq_select:
295; BMI:       # %bb.0:
296; BMI-NEXT:    tzcntq %rdi, %rcx
297; BMI-NEXT:    movq $-1, %rax
298; BMI-NEXT:    cmovaeq %rcx, %rax
299; BMI-NEXT:    addq $6, %rax
300; BMI-NEXT:    retq
301
302  %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
303  %tobool = icmp eq i64 %v, 0
304  %.op = add nuw nsw i64 %cnt, 6
305  %add = select i1 %tobool, i64 5, i64 %.op
306  ret i64 %add
307}
308
309define i64 @cttz_64_ne_select(i64 %v) nounwind {
310; NOBMI-LABEL: cttz_64_ne_select:
311; NOBMI:       # %bb.0:
312; NOBMI-NEXT:    bsfq %rdi, %rcx
313; NOBMI-NEXT:    movq $-1, %rax
314; NOBMI-NEXT:    cmovneq %rcx, %rax
315; NOBMI-NEXT:    addq $6, %rax
316; NOBMI-NEXT:    retq
317;
318; BMI-LABEL: cttz_64_ne_select:
319; BMI:       # %bb.0:
320; BMI-NEXT:    tzcntq %rdi, %rcx
321; BMI-NEXT:    movq $-1, %rax
322; BMI-NEXT:    cmovaeq %rcx, %rax
323; BMI-NEXT:    addq $6, %rax
324; BMI-NEXT:    retq
325
326  %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
327  %tobool = icmp ne i64 %v, 0
328  %.op = add nuw nsw i64 %cnt, 6
329  %add = select i1 %tobool, i64 %.op, i64 5
330  ret i64 %add
331}
332
333declare i32 @llvm.cttz.i32(i32, i1)
334define i32 @cttz_32_eq_select(i32 %v) nounwind {
335; NOBMI-LABEL: cttz_32_eq_select:
336; NOBMI:       # %bb.0:
337; NOBMI-NEXT:    bsfl %edi, %ecx
338; NOBMI-NEXT:    movl $-1, %eax
339; NOBMI-NEXT:    cmovnel %ecx, %eax
340; NOBMI-NEXT:    addl $6, %eax
341; NOBMI-NEXT:    retq
342;
343; BMI-LABEL: cttz_32_eq_select:
344; BMI:       # %bb.0:
345; BMI-NEXT:    tzcntl %edi, %ecx
346; BMI-NEXT:    movl $-1, %eax
347; BMI-NEXT:    cmovael %ecx, %eax
348; BMI-NEXT:    addl $6, %eax
349; BMI-NEXT:    retq
350
351  %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
352  %tobool = icmp eq i32 %v, 0
353  %.op = add nuw nsw i32 %cnt, 6
354  %add = select i1 %tobool, i32 5, i32 %.op
355  ret i32 %add
356}
357
358define i32 @cttz_32_ne_select(i32 %v) nounwind {
359; NOBMI-LABEL: cttz_32_ne_select:
360; NOBMI:       # %bb.0:
361; NOBMI-NEXT:    bsfl %edi, %ecx
362; NOBMI-NEXT:    movl $-1, %eax
363; NOBMI-NEXT:    cmovnel %ecx, %eax
364; NOBMI-NEXT:    addl $6, %eax
365; NOBMI-NEXT:    retq
366;
367; BMI-LABEL: cttz_32_ne_select:
368; BMI:       # %bb.0:
369; BMI-NEXT:    tzcntl %edi, %ecx
370; BMI-NEXT:    movl $-1, %eax
371; BMI-NEXT:    cmovael %ecx, %eax
372; BMI-NEXT:    addl $6, %eax
373; BMI-NEXT:    retq
374
375  %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
376  %tobool = icmp ne i32 %v, 0
377  %.op = add nuw nsw i32 %cnt, 6
378  %add = select i1 %tobool, i32 %.op, i32 5
379  ret i32 %add
380}
381