xref: /llvm-project/llvm/test/CodeGen/ARM/select_const.ll (revision 9b6cfaa7b1bc38f01df2041ecfa8dad360d4d179)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=arm-eabi-unknown-unknown | FileCheck %s
3
4; Select of constants: control flow / conditional moves can always be replaced by logic+math (but may not be worth it?).
5; Test the zeroext/signext variants of each pattern to see if that makes a difference.
6
7; select Cond, 0, 1 --> zext (!Cond)
8
9define i32 @select_0_or_1(i1 %cond) {
10; CHECK-LABEL: select_0_or_1:
11; CHECK:       @ BB#0:
12; CHECK-NEXT:    mov r1, #1
13; CHECK-NEXT:    bic r0, r1, r0
14; CHECK-NEXT:    mov pc, lr
15  %sel = select i1 %cond, i32 0, i32 1
16  ret i32 %sel
17}
18
19define i32 @select_0_or_1_zeroext(i1 zeroext %cond) {
20; CHECK-LABEL: select_0_or_1_zeroext:
21; CHECK:       @ BB#0:
22; CHECK-NEXT:    eor r0, r0, #1
23; CHECK-NEXT:    mov pc, lr
24  %sel = select i1 %cond, i32 0, i32 1
25  ret i32 %sel
26}
27
28define i32 @select_0_or_1_signext(i1 signext %cond) {
29; CHECK-LABEL: select_0_or_1_signext:
30; CHECK:       @ BB#0:
31; CHECK-NEXT:    mov r1, #1
32; CHECK-NEXT:    bic r0, r1, r0
33; CHECK-NEXT:    mov pc, lr
34  %sel = select i1 %cond, i32 0, i32 1
35  ret i32 %sel
36}
37
38; select Cond, 1, 0 --> zext (Cond)
39
40define i32 @select_1_or_0(i1 %cond) {
41; CHECK-LABEL: select_1_or_0:
42; CHECK:       @ BB#0:
43; CHECK-NEXT:    ands r0, r0, #1
44; CHECK-NEXT:    movne r0, #1
45; CHECK-NEXT:    mov pc, lr
46  %sel = select i1 %cond, i32 1, i32 0
47  ret i32 %sel
48}
49
50define i32 @select_1_or_0_zeroext(i1 zeroext %cond) {
51; CHECK-LABEL: select_1_or_0_zeroext:
52; CHECK:       @ BB#0:
53; CHECK-NEXT:    cmp r0, #0
54; CHECK-NEXT:    movne r0, #1
55; CHECK-NEXT:    mov pc, lr
56  %sel = select i1 %cond, i32 1, i32 0
57  ret i32 %sel
58}
59
60define i32 @select_1_or_0_signext(i1 signext %cond) {
61; CHECK-LABEL: select_1_or_0_signext:
62; CHECK:       @ BB#0:
63; CHECK-NEXT:    ands r0, r0, #1
64; CHECK-NEXT:    movne r0, #1
65; CHECK-NEXT:    mov pc, lr
66  %sel = select i1 %cond, i32 1, i32 0
67  ret i32 %sel
68}
69
70; select Cond, 0, -1 --> sext (!Cond)
71
72define i32 @select_0_or_neg1(i1 %cond) {
73; CHECK-LABEL: select_0_or_neg1:
74; CHECK:       @ BB#0:
75; CHECK-NEXT:    mvn r1, #0
76; CHECK-NEXT:    tst r0, #1
77; CHECK-NEXT:    movne r1, #0
78; CHECK-NEXT:    mov r0, r1
79; CHECK-NEXT:    mov pc, lr
80  %sel = select i1 %cond, i32 0, i32 -1
81  ret i32 %sel
82}
83
84define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
85; CHECK-LABEL: select_0_or_neg1_zeroext:
86; CHECK:       @ BB#0:
87; CHECK-NEXT:    mvn r1, #0
88; CHECK-NEXT:    cmp r0, #0
89; CHECK-NEXT:    movne r1, #0
90; CHECK-NEXT:    mov r0, r1
91; CHECK-NEXT:    mov pc, lr
92  %sel = select i1 %cond, i32 0, i32 -1
93  ret i32 %sel
94}
95
96define i32 @select_0_or_neg1_signext(i1 signext %cond) {
97; CHECK-LABEL: select_0_or_neg1_signext:
98; CHECK:       @ BB#0:
99; CHECK-NEXT:    mvn r1, #0
100; CHECK-NEXT:    tst r0, #1
101; CHECK-NEXT:    movne r1, #0
102; CHECK-NEXT:    mov r0, r1
103; CHECK-NEXT:    mov pc, lr
104  %sel = select i1 %cond, i32 0, i32 -1
105  ret i32 %sel
106}
107
108; select Cond, -1, 0 --> sext (Cond)
109
110define i32 @select_neg1_or_0(i1 %cond) {
111; CHECK-LABEL: select_neg1_or_0:
112; CHECK:       @ BB#0:
113; CHECK-NEXT:    ands r0, r0, #1
114; CHECK-NEXT:    mvnne r0, #0
115; CHECK-NEXT:    mov pc, lr
116  %sel = select i1 %cond, i32 -1, i32 0
117  ret i32 %sel
118}
119
120define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) {
121; CHECK-LABEL: select_neg1_or_0_zeroext:
122; CHECK:       @ BB#0:
123; CHECK-NEXT:    cmp r0, #0
124; CHECK-NEXT:    mvnne r0, #0
125; CHECK-NEXT:    mov pc, lr
126  %sel = select i1 %cond, i32 -1, i32 0
127  ret i32 %sel
128}
129
130define i32 @select_neg1_or_0_signext(i1 signext %cond) {
131; CHECK-LABEL: select_neg1_or_0_signext:
132; CHECK:       @ BB#0:
133; CHECK-NEXT:    ands r0, r0, #1
134; CHECK-NEXT:    mvnne r0, #0
135; CHECK-NEXT:    mov pc, lr
136  %sel = select i1 %cond, i32 -1, i32 0
137  ret i32 %sel
138}
139
140; select Cond, C+1, C --> add (zext Cond), C
141
142define i32 @select_Cplus1_C(i1 %cond) {
143; CHECK-LABEL: select_Cplus1_C:
144; CHECK:       @ BB#0:
145; CHECK-NEXT:    mov r1, #41
146; CHECK-NEXT:    tst r0, #1
147; CHECK-NEXT:    movne r1, #42
148; CHECK-NEXT:    mov r0, r1
149; CHECK-NEXT:    mov pc, lr
150  %sel = select i1 %cond, i32 42, i32 41
151  ret i32 %sel
152}
153
154define i32 @select_Cplus1_C_zeroext(i1 zeroext %cond) {
155; CHECK-LABEL: select_Cplus1_C_zeroext:
156; CHECK:       @ BB#0:
157; CHECK-NEXT:    mov r1, #41
158; CHECK-NEXT:    cmp r0, #0
159; CHECK-NEXT:    movne r1, #42
160; CHECK-NEXT:    mov r0, r1
161; CHECK-NEXT:    mov pc, lr
162  %sel = select i1 %cond, i32 42, i32 41
163  ret i32 %sel
164}
165
166define i32 @select_Cplus1_C_signext(i1 signext %cond) {
167; CHECK-LABEL: select_Cplus1_C_signext:
168; CHECK:       @ BB#0:
169; CHECK-NEXT:    mov r1, #41
170; CHECK-NEXT:    tst r0, #1
171; CHECK-NEXT:    movne r1, #42
172; CHECK-NEXT:    mov r0, r1
173; CHECK-NEXT:    mov pc, lr
174  %sel = select i1 %cond, i32 42, i32 41
175  ret i32 %sel
176}
177
178; select Cond, C, C+1 --> add (sext Cond), C
179
180define i32 @select_C_Cplus1(i1 %cond) {
181; CHECK-LABEL: select_C_Cplus1:
182; CHECK:       @ BB#0:
183; CHECK-NEXT:    mov r1, #42
184; CHECK-NEXT:    tst r0, #1
185; CHECK-NEXT:    movne r1, #41
186; CHECK-NEXT:    mov r0, r1
187; CHECK-NEXT:    mov pc, lr
188  %sel = select i1 %cond, i32 41, i32 42
189  ret i32 %sel
190}
191
192define i32 @select_C_Cplus1_zeroext(i1 zeroext %cond) {
193; CHECK-LABEL: select_C_Cplus1_zeroext:
194; CHECK:       @ BB#0:
195; CHECK-NEXT:    mov r1, #42
196; CHECK-NEXT:    cmp r0, #0
197; CHECK-NEXT:    movne r1, #41
198; CHECK-NEXT:    mov r0, r1
199; CHECK-NEXT:    mov pc, lr
200  %sel = select i1 %cond, i32 41, i32 42
201  ret i32 %sel
202}
203
204define i32 @select_C_Cplus1_signext(i1 signext %cond) {
205; CHECK-LABEL: select_C_Cplus1_signext:
206; CHECK:       @ BB#0:
207; CHECK-NEXT:    mov r1, #42
208; CHECK-NEXT:    tst r0, #1
209; CHECK-NEXT:    movne r1, #41
210; CHECK-NEXT:    mov r0, r1
211; CHECK-NEXT:    mov pc, lr
212  %sel = select i1 %cond, i32 41, i32 42
213  ret i32 %sel
214}
215
216; In general, select of 2 constants could be:
217; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2 --> add (and (sext Cond), C1-C2), C2
218
219define i32 @select_C1_C2(i1 %cond) {
220; CHECK-LABEL: select_C1_C2:
221; CHECK:       @ BB#0:
222; CHECK-NEXT:    mov r1, #165
223; CHECK-NEXT:    tst r0, #1
224; CHECK-NEXT:    orr r1, r1, #256
225; CHECK-NEXT:    moveq r1, #42
226; CHECK-NEXT:    mov r0, r1
227; CHECK-NEXT:    mov pc, lr
228  %sel = select i1 %cond, i32 421, i32 42
229  ret i32 %sel
230}
231
232define i32 @select_C1_C2_zeroext(i1 zeroext %cond) {
233; CHECK-LABEL: select_C1_C2_zeroext:
234; CHECK:       @ BB#0:
235; CHECK-NEXT:    mov r1, #165
236; CHECK-NEXT:    cmp r0, #0
237; CHECK-NEXT:    orr r1, r1, #256
238; CHECK-NEXT:    moveq r1, #42
239; CHECK-NEXT:    mov r0, r1
240; CHECK-NEXT:    mov pc, lr
241  %sel = select i1 %cond, i32 421, i32 42
242  ret i32 %sel
243}
244
245define i32 @select_C1_C2_signext(i1 signext %cond) {
246; CHECK-LABEL: select_C1_C2_signext:
247; CHECK:       @ BB#0:
248; CHECK-NEXT:    mov r1, #165
249; CHECK-NEXT:    tst r0, #1
250; CHECK-NEXT:    orr r1, r1, #256
251; CHECK-NEXT:    moveq r1, #42
252; CHECK-NEXT:    mov r0, r1
253; CHECK-NEXT:    mov pc, lr
254  %sel = select i1 %cond, i32 421, i32 42
255  ret i32 %sel
256}
257
258