1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=powerpc64le-unknown-unknown -verify-machineinstrs -mattr=+isel | FileCheck %s --check-prefix=ALL --check-prefix=ISEL
3; RUN: llc < %s -mtriple=powerpc64le-unknown-unknown -verify-machineinstrs -mattr=-isel | FileCheck %s --check-prefix=ALL --check-prefix=NO_ISEL
4
5; Select of constants: control flow / conditional moves can always be replaced by logic+math (but may not be worth it?).
6; Test the zeroext/signext variants of each pattern to see if that makes a difference.
7
8; select Cond, 0, 1 --> zext (!Cond)
9
10define i32 @select_0_or_1(i1 %cond) {
11; ALL-LABEL: select_0_or_1:
12; ALL:       # BB#0:
13; ALL-NEXT:    not 3, 3
14; ALL-NEXT:    clrldi 3, 3, 63
15; ALL-NEXT:    blr
16  %sel = select i1 %cond, i32 0, i32 1
17  ret i32 %sel
18}
19
20define i32 @select_0_or_1_zeroext(i1 zeroext %cond) {
21; ALL-LABEL: select_0_or_1_zeroext:
22; ALL:       # BB#0:
23; ALL-NEXT:    xori 3, 3, 1
24; ALL-NEXT:    blr
25  %sel = select i1 %cond, i32 0, i32 1
26  ret i32 %sel
27}
28
29define i32 @select_0_or_1_signext(i1 signext %cond) {
30; ALL-LABEL: select_0_or_1_signext:
31; ALL:       # BB#0:
32; ALL-NEXT:    not 3, 3
33; ALL-NEXT:    clrldi 3, 3, 63
34; ALL-NEXT:    blr
35  %sel = select i1 %cond, i32 0, i32 1
36  ret i32 %sel
37}
38
39; select Cond, 1, 0 --> zext (Cond)
40
41define i32 @select_1_or_0(i1 %cond) {
42; ISEL-LABEL: select_1_or_0:
43; ISEL:       # BB#0:
44; ISEL-NEXT:    andi. 3, 3, 1
45; ISEL-NEXT:    li 4, 1
46; ISEL-NEXT:    li 3, 0
47; ISEL-NEXT:    isel 3, 4, 3, 1
48; ISEL-NEXT:    blr
49;
50; NO_ISEL-LABEL: select_1_or_0:
51; NO_ISEL:       # BB#0:
52; NO_ISEL-NEXT:    andi. 3, 3, 1
53; NO_ISEL-NEXT:    li 4, 1
54; NO_ISEL-NEXT:    li 3, 0
55; NO_ISEL-NEXT:    bc 12, 1, .LBB3_1
56; NO_ISEL-NEXT:    blr
57; NO_ISEL-NEXT:  .LBB3_1:
58; NO_ISEL-NEXT:    addi 3, 4, 0
59; NO_ISEL-NEXT:    blr
60  %sel = select i1 %cond, i32 1, i32 0
61  ret i32 %sel
62}
63
64define i32 @select_1_or_0_zeroext(i1 zeroext %cond) {
65; ISEL-LABEL: select_1_or_0_zeroext:
66; ISEL:       # BB#0:
67; ISEL-NEXT:    andi. 3, 3, 1
68; ISEL-NEXT:    li 4, 1
69; ISEL-NEXT:    li 3, 0
70; ISEL-NEXT:    isel 3, 4, 3, 1
71; ISEL-NEXT:    blr
72;
73; NO_ISEL-LABEL: select_1_or_0_zeroext:
74; NO_ISEL:       # BB#0:
75; NO_ISEL-NEXT:    andi. 3, 3, 1
76; NO_ISEL-NEXT:    li 4, 1
77; NO_ISEL-NEXT:    li 3, 0
78; NO_ISEL-NEXT:    bc 12, 1, .LBB4_1
79; NO_ISEL-NEXT:    blr
80; NO_ISEL-NEXT:  .LBB4_1:
81; NO_ISEL-NEXT:    addi 3, 4, 0
82; NO_ISEL-NEXT:    blr
83  %sel = select i1 %cond, i32 1, i32 0
84  ret i32 %sel
85}
86
87define i32 @select_1_or_0_signext(i1 signext %cond) {
88; ISEL-LABEL: select_1_or_0_signext:
89; ISEL:       # BB#0:
90; ISEL-NEXT:    andi. 3, 3, 1
91; ISEL-NEXT:    li 4, 1
92; ISEL-NEXT:    li 3, 0
93; ISEL-NEXT:    isel 3, 4, 3, 1
94; ISEL-NEXT:    blr
95;
96; NO_ISEL-LABEL: select_1_or_0_signext:
97; NO_ISEL:       # BB#0:
98; NO_ISEL-NEXT:    andi. 3, 3, 1
99; NO_ISEL-NEXT:    li 4, 1
100; NO_ISEL-NEXT:    li 3, 0
101; NO_ISEL-NEXT:    bc 12, 1, .LBB5_1
102; NO_ISEL-NEXT:    blr
103; NO_ISEL-NEXT:  .LBB5_1:
104; NO_ISEL-NEXT:    addi 3, 4, 0
105; NO_ISEL-NEXT:    blr
106  %sel = select i1 %cond, i32 1, i32 0
107  ret i32 %sel
108}
109
110; select Cond, 0, -1 --> sext (!Cond)
111
112define i32 @select_0_or_neg1(i1 %cond) {
113; ISEL-LABEL: select_0_or_neg1:
114; ISEL:       # BB#0:
115; ISEL-NEXT:    li 4, 0
116; ISEL-NEXT:    andi. 3, 3, 1
117; ISEL-NEXT:    oris 3, 4, 65535
118; ISEL-NEXT:    ori 3, 3, 65535
119; ISEL-NEXT:    isel 3, 0, 3, 1
120; ISEL-NEXT:    blr
121;
122; NO_ISEL-LABEL: select_0_or_neg1:
123; NO_ISEL:       # BB#0:
124; NO_ISEL-NEXT:    li 4, 0
125; NO_ISEL-NEXT:    andi. 3, 3, 1
126; NO_ISEL-NEXT:    oris 3, 4, 65535
127; NO_ISEL-NEXT:    ori 3, 3, 65535
128; NO_ISEL-NEXT:    bc 12, 1, .LBB6_1
129; NO_ISEL-NEXT:    blr
130; NO_ISEL-NEXT:  .LBB6_1:
131; NO_ISEL-NEXT:    addi 3, 0, 0
132; NO_ISEL-NEXT:    blr
133  %sel = select i1 %cond, i32 0, i32 -1
134  ret i32 %sel
135}
136
137define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
138; ISEL-LABEL: select_0_or_neg1_zeroext:
139; ISEL:       # BB#0:
140; ISEL-NEXT:    li 4, 0
141; ISEL-NEXT:    andi. 3, 3, 1
142; ISEL-NEXT:    oris 3, 4, 65535
143; ISEL-NEXT:    ori 3, 3, 65535
144; ISEL-NEXT:    isel 3, 0, 3, 1
145; ISEL-NEXT:    blr
146;
147; NO_ISEL-LABEL: select_0_or_neg1_zeroext:
148; NO_ISEL:       # BB#0:
149; NO_ISEL-NEXT:    li 4, 0
150; NO_ISEL-NEXT:    andi. 3, 3, 1
151; NO_ISEL-NEXT:    oris 3, 4, 65535
152; NO_ISEL-NEXT:    ori 3, 3, 65535
153; NO_ISEL-NEXT:    bc 12, 1, .LBB7_1
154; NO_ISEL-NEXT:    blr
155; NO_ISEL-NEXT:  .LBB7_1:
156; NO_ISEL-NEXT:    addi 3, 0, 0
157; NO_ISEL-NEXT:    blr
158  %sel = select i1 %cond, i32 0, i32 -1
159  ret i32 %sel
160}
161
162define i32 @select_0_or_neg1_signext(i1 signext %cond) {
163; ISEL-LABEL: select_0_or_neg1_signext:
164; ISEL:       # BB#0:
165; ISEL-NEXT:    li 4, 0
166; ISEL-NEXT:    andi. 3, 3, 1
167; ISEL-NEXT:    oris 3, 4, 65535
168; ISEL-NEXT:    ori 3, 3, 65535
169; ISEL-NEXT:    isel 3, 0, 3, 1
170; ISEL-NEXT:    blr
171;
172; NO_ISEL-LABEL: select_0_or_neg1_signext:
173; NO_ISEL:       # BB#0:
174; NO_ISEL-NEXT:    li 4, 0
175; NO_ISEL-NEXT:    andi. 3, 3, 1
176; NO_ISEL-NEXT:    oris 3, 4, 65535
177; NO_ISEL-NEXT:    ori 3, 3, 65535
178; NO_ISEL-NEXT:    bc 12, 1, .LBB8_1
179; NO_ISEL-NEXT:    blr
180; NO_ISEL-NEXT:  .LBB8_1:
181; NO_ISEL-NEXT:    addi 3, 0, 0
182; NO_ISEL-NEXT:    blr
183  %sel = select i1 %cond, i32 0, i32 -1
184  ret i32 %sel
185}
186
187; select Cond, -1, 0 --> sext (Cond)
188
189define i32 @select_neg1_or_0(i1 %cond) {
190; ISEL-LABEL: select_neg1_or_0:
191; ISEL:       # BB#0:
192; ISEL-NEXT:    li 4, 0
193; ISEL-NEXT:    andi. 3, 3, 1
194; ISEL-NEXT:    oris 3, 4, 65535
195; ISEL-NEXT:    ori 3, 3, 65535
196; ISEL-NEXT:    isel 3, 3, 4, 1
197; ISEL-NEXT:    blr
198;
199; NO_ISEL-LABEL: select_neg1_or_0:
200; NO_ISEL:       # BB#0:
201; NO_ISEL-NEXT:    li 4, 0
202; NO_ISEL-NEXT:    andi. 3, 3, 1
203; NO_ISEL-NEXT:    oris 3, 4, 65535
204; NO_ISEL-NEXT:    ori 3, 3, 65535
205; NO_ISEL-NEXT:    bclr 12, 1, 0
206; NO_ISEL-NEXT:  # BB#1:
207; NO_ISEL-NEXT:    ori 3, 4, 0
208; NO_ISEL-NEXT:    blr
209  %sel = select i1 %cond, i32 -1, i32 0
210  ret i32 %sel
211}
212
213define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) {
214; ISEL-LABEL: select_neg1_or_0_zeroext:
215; ISEL:       # BB#0:
216; ISEL-NEXT:    li 4, 0
217; ISEL-NEXT:    andi. 3, 3, 1
218; ISEL-NEXT:    oris 3, 4, 65535
219; ISEL-NEXT:    ori 3, 3, 65535
220; ISEL-NEXT:    isel 3, 3, 4, 1
221; ISEL-NEXT:    blr
222;
223; NO_ISEL-LABEL: select_neg1_or_0_zeroext:
224; NO_ISEL:       # BB#0:
225; NO_ISEL-NEXT:    li 4, 0
226; NO_ISEL-NEXT:    andi. 3, 3, 1
227; NO_ISEL-NEXT:    oris 3, 4, 65535
228; NO_ISEL-NEXT:    ori 3, 3, 65535
229; NO_ISEL-NEXT:    bclr 12, 1, 0
230; NO_ISEL-NEXT:  # BB#1:
231; NO_ISEL-NEXT:    ori 3, 4, 0
232; NO_ISEL-NEXT:    blr
233  %sel = select i1 %cond, i32 -1, i32 0
234  ret i32 %sel
235}
236
237define i32 @select_neg1_or_0_signext(i1 signext %cond) {
238; ISEL-LABEL: select_neg1_or_0_signext:
239; ISEL:       # BB#0:
240; ISEL-NEXT:    li 4, 0
241; ISEL-NEXT:    andi. 3, 3, 1
242; ISEL-NEXT:    oris 3, 4, 65535
243; ISEL-NEXT:    ori 3, 3, 65535
244; ISEL-NEXT:    isel 3, 3, 4, 1
245; ISEL-NEXT:    blr
246;
247; NO_ISEL-LABEL: select_neg1_or_0_signext:
248; NO_ISEL:       # BB#0:
249; NO_ISEL-NEXT:    li 4, 0
250; NO_ISEL-NEXT:    andi. 3, 3, 1
251; NO_ISEL-NEXT:    oris 3, 4, 65535
252; NO_ISEL-NEXT:    ori 3, 3, 65535
253; NO_ISEL-NEXT:    bclr 12, 1, 0
254; NO_ISEL-NEXT:  # BB#1:
255; NO_ISEL-NEXT:    ori 3, 4, 0
256; NO_ISEL-NEXT:    blr
257  %sel = select i1 %cond, i32 -1, i32 0
258  ret i32 %sel
259}
260
261; select Cond, C+1, C --> add (zext Cond), C
262
263define i32 @select_Cplus1_C(i1 %cond) {
264; ISEL-LABEL: select_Cplus1_C:
265; ISEL:       # BB#0:
266; ISEL-NEXT:    andi. 3, 3, 1
267; ISEL-NEXT:    li 4, 42
268; ISEL-NEXT:    li 3, 41
269; ISEL-NEXT:    isel 3, 4, 3, 1
270; ISEL-NEXT:    blr
271;
272; NO_ISEL-LABEL: select_Cplus1_C:
273; NO_ISEL:       # BB#0:
274; NO_ISEL-NEXT:    andi. 3, 3, 1
275; NO_ISEL-NEXT:    li 4, 42
276; NO_ISEL-NEXT:    li 3, 41
277; NO_ISEL-NEXT:    bc 12, 1, .LBB12_1
278; NO_ISEL-NEXT:    blr
279; NO_ISEL-NEXT:  .LBB12_1:
280; NO_ISEL-NEXT:    addi 3, 4, 0
281; NO_ISEL-NEXT:    blr
282  %sel = select i1 %cond, i32 42, i32 41
283  ret i32 %sel
284}
285
286define i32 @select_Cplus1_C_zeroext(i1 zeroext %cond) {
287; ISEL-LABEL: select_Cplus1_C_zeroext:
288; ISEL:       # BB#0:
289; ISEL-NEXT:    andi. 3, 3, 1
290; ISEL-NEXT:    li 4, 42
291; ISEL-NEXT:    li 3, 41
292; ISEL-NEXT:    isel 3, 4, 3, 1
293; ISEL-NEXT:    blr
294;
295; NO_ISEL-LABEL: select_Cplus1_C_zeroext:
296; NO_ISEL:       # BB#0:
297; NO_ISEL-NEXT:    andi. 3, 3, 1
298; NO_ISEL-NEXT:    li 4, 42
299; NO_ISEL-NEXT:    li 3, 41
300; NO_ISEL-NEXT:    bc 12, 1, .LBB13_1
301; NO_ISEL-NEXT:    blr
302; NO_ISEL-NEXT:  .LBB13_1:
303; NO_ISEL-NEXT:    addi 3, 4, 0
304; NO_ISEL-NEXT:    blr
305  %sel = select i1 %cond, i32 42, i32 41
306  ret i32 %sel
307}
308
309define i32 @select_Cplus1_C_signext(i1 signext %cond) {
310; ISEL-LABEL: select_Cplus1_C_signext:
311; ISEL:       # BB#0:
312; ISEL-NEXT:    andi. 3, 3, 1
313; ISEL-NEXT:    li 4, 42
314; ISEL-NEXT:    li 3, 41
315; ISEL-NEXT:    isel 3, 4, 3, 1
316; ISEL-NEXT:    blr
317;
318; NO_ISEL-LABEL: select_Cplus1_C_signext:
319; NO_ISEL:       # BB#0:
320; NO_ISEL-NEXT:    andi. 3, 3, 1
321; NO_ISEL-NEXT:    li 4, 42
322; NO_ISEL-NEXT:    li 3, 41
323; NO_ISEL-NEXT:    bc 12, 1, .LBB14_1
324; NO_ISEL-NEXT:    blr
325; NO_ISEL-NEXT:  .LBB14_1:
326; NO_ISEL-NEXT:    addi 3, 4, 0
327; NO_ISEL-NEXT:    blr
328  %sel = select i1 %cond, i32 42, i32 41
329  ret i32 %sel
330}
331
332; select Cond, C, C+1 --> add (sext Cond), C
333
334define i32 @select_C_Cplus1(i1 %cond) {
335; ISEL-LABEL: select_C_Cplus1:
336; ISEL:       # BB#0:
337; ISEL-NEXT:    andi. 3, 3, 1
338; ISEL-NEXT:    li 4, 41
339; ISEL-NEXT:    li 3, 42
340; ISEL-NEXT:    isel 3, 4, 3, 1
341; ISEL-NEXT:    blr
342;
343; NO_ISEL-LABEL: select_C_Cplus1:
344; NO_ISEL:       # BB#0:
345; NO_ISEL-NEXT:    andi. 3, 3, 1
346; NO_ISEL-NEXT:    li 4, 41
347; NO_ISEL-NEXT:    li 3, 42
348; NO_ISEL-NEXT:    bc 12, 1, .LBB15_1
349; NO_ISEL-NEXT:    blr
350; NO_ISEL-NEXT:  .LBB15_1:
351; NO_ISEL-NEXT:    addi 3, 4, 0
352; NO_ISEL-NEXT:    blr
353  %sel = select i1 %cond, i32 41, i32 42
354  ret i32 %sel
355}
356
357define i32 @select_C_Cplus1_zeroext(i1 zeroext %cond) {
358; ISEL-LABEL: select_C_Cplus1_zeroext:
359; ISEL:       # BB#0:
360; ISEL-NEXT:    andi. 3, 3, 1
361; ISEL-NEXT:    li 4, 41
362; ISEL-NEXT:    li 3, 42
363; ISEL-NEXT:    isel 3, 4, 3, 1
364; ISEL-NEXT:    blr
365;
366; NO_ISEL-LABEL: select_C_Cplus1_zeroext:
367; NO_ISEL:       # BB#0:
368; NO_ISEL-NEXT:    andi. 3, 3, 1
369; NO_ISEL-NEXT:    li 4, 41
370; NO_ISEL-NEXT:    li 3, 42
371; NO_ISEL-NEXT:    bc 12, 1, .LBB16_1
372; NO_ISEL-NEXT:    blr
373; NO_ISEL-NEXT:  .LBB16_1:
374; NO_ISEL-NEXT:    addi 3, 4, 0
375; NO_ISEL-NEXT:    blr
376  %sel = select i1 %cond, i32 41, i32 42
377  ret i32 %sel
378}
379
380define i32 @select_C_Cplus1_signext(i1 signext %cond) {
381; ISEL-LABEL: select_C_Cplus1_signext:
382; ISEL:       # BB#0:
383; ISEL-NEXT:    andi. 3, 3, 1
384; ISEL-NEXT:    li 4, 41
385; ISEL-NEXT:    li 3, 42
386; ISEL-NEXT:    isel 3, 4, 3, 1
387; ISEL-NEXT:    blr
388;
389; NO_ISEL-LABEL: select_C_Cplus1_signext:
390; NO_ISEL:       # BB#0:
391; NO_ISEL-NEXT:    andi. 3, 3, 1
392; NO_ISEL-NEXT:    li 4, 41
393; NO_ISEL-NEXT:    li 3, 42
394; NO_ISEL-NEXT:    bc 12, 1, .LBB17_1
395; NO_ISEL-NEXT:    blr
396; NO_ISEL-NEXT:  .LBB17_1:
397; NO_ISEL-NEXT:    addi 3, 4, 0
398; NO_ISEL-NEXT:    blr
399  %sel = select i1 %cond, i32 41, i32 42
400  ret i32 %sel
401}
402
403; In general, select of 2 constants could be:
404; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2 --> add (and (sext Cond), C1-C2), C2
405
406define i32 @select_C1_C2(i1 %cond) {
407; ISEL-LABEL: select_C1_C2:
408; ISEL:       # BB#0:
409; ISEL-NEXT:    andi. 3, 3, 1
410; ISEL-NEXT:    li 4, 421
411; ISEL-NEXT:    li 3, 42
412; ISEL-NEXT:    isel 3, 4, 3, 1
413; ISEL-NEXT:    blr
414;
415; NO_ISEL-LABEL: select_C1_C2:
416; NO_ISEL:       # BB#0:
417; NO_ISEL-NEXT:    andi. 3, 3, 1
418; NO_ISEL-NEXT:    li 4, 421
419; NO_ISEL-NEXT:    li 3, 42
420; NO_ISEL-NEXT:    bc 12, 1, .LBB18_1
421; NO_ISEL-NEXT:    blr
422; NO_ISEL-NEXT:  .LBB18_1:
423; NO_ISEL-NEXT:    addi 3, 4, 0
424; NO_ISEL-NEXT:    blr
425  %sel = select i1 %cond, i32 421, i32 42
426  ret i32 %sel
427}
428
429define i32 @select_C1_C2_zeroext(i1 zeroext %cond) {
430; ISEL-LABEL: select_C1_C2_zeroext:
431; ISEL:       # BB#0:
432; ISEL-NEXT:    andi. 3, 3, 1
433; ISEL-NEXT:    li 4, 421
434; ISEL-NEXT:    li 3, 42
435; ISEL-NEXT:    isel 3, 4, 3, 1
436; ISEL-NEXT:    blr
437;
438; NO_ISEL-LABEL: select_C1_C2_zeroext:
439; NO_ISEL:       # BB#0:
440; NO_ISEL-NEXT:    andi. 3, 3, 1
441; NO_ISEL-NEXT:    li 4, 421
442; NO_ISEL-NEXT:    li 3, 42
443; NO_ISEL-NEXT:    bc 12, 1, .LBB19_1
444; NO_ISEL-NEXT:    blr
445; NO_ISEL-NEXT:  .LBB19_1:
446; NO_ISEL-NEXT:    addi 3, 4, 0
447; NO_ISEL-NEXT:    blr
448  %sel = select i1 %cond, i32 421, i32 42
449  ret i32 %sel
450}
451
452define i32 @select_C1_C2_signext(i1 signext %cond) {
453; ISEL-LABEL: select_C1_C2_signext:
454; ISEL:       # BB#0:
455; ISEL-NEXT:    andi. 3, 3, 1
456; ISEL-NEXT:    li 4, 421
457; ISEL-NEXT:    li 3, 42
458; ISEL-NEXT:    isel 3, 4, 3, 1
459; ISEL-NEXT:    blr
460;
461; NO_ISEL-LABEL: select_C1_C2_signext:
462; NO_ISEL:       # BB#0:
463; NO_ISEL-NEXT:    andi. 3, 3, 1
464; NO_ISEL-NEXT:    li 4, 421
465; NO_ISEL-NEXT:    li 3, 42
466; NO_ISEL-NEXT:    bc 12, 1, .LBB20_1
467; NO_ISEL-NEXT:    blr
468; NO_ISEL-NEXT:  .LBB20_1:
469; NO_ISEL-NEXT:    addi 3, 4, 0
470; NO_ISEL-NEXT:    blr
471  %sel = select i1 %cond, i32 421, i32 42
472  ret i32 %sel
473}
474
475