blob: 018cb5dda58288e05c9ef3ea584e8fcc4ba3a3e3 [file] [log] [blame]
Sanjay Patel9b6cfaa2017-02-17 16:34:13 +00001; 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