[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / CodeGen / ARM / sat-to-bitop.ll
blob3ccc77ad35a210816f32b8f0064583dbc7d4fe57
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=arm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM
3 ; RUN: llc -mtriple=thumb-eabi %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-T
4 ; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-T2
6 ; Check for clipping against 0 that should result in bic
8 ; Base tests with different bit widths
10 ; x < 0 ? 0 : x
11 ; 32-bit base test
12 define i32 @sat0_base_32bit(i32 %x) #0 {
13 ; CHECK-ARM-LABEL: sat0_base_32bit:
14 ; CHECK-ARM:       @ %bb.0: @ %entry
15 ; CHECK-ARM-NEXT:    bic r0, r0, r0, asr #31
16 ; CHECK-ARM-NEXT:    mov pc, lr
18 ; CHECK-T-LABEL: sat0_base_32bit:
19 ; CHECK-T:       @ %bb.0: @ %entry
20 ; CHECK-T-NEXT:    asrs r1, r0, #31
21 ; CHECK-T-NEXT:    bics r0, r1
22 ; CHECK-T-NEXT:    bx lr
24 ; CHECK-T2-LABEL: sat0_base_32bit:
25 ; CHECK-T2:       @ %bb.0: @ %entry
26 ; CHECK-T2-NEXT:    bic.w r0, r0, r0, asr #31
27 ; CHECK-T2-NEXT:    bx lr
28 entry:
29   %cmpLow = icmp slt i32 %x, 0
30   %saturateLow = select i1 %cmpLow, i32 0, i32 %x
31   ret i32 %saturateLow
34 ; x < 0 ? 0 : x
35 ; 16-bit base test
36 define i16 @sat0_base_16bit(i16 %x) #0 {
37 ; CHECK-ARM-LABEL: sat0_base_16bit:
38 ; CHECK-ARM:       @ %bb.0: @ %entry
39 ; CHECK-ARM-NEXT:    lsl r1, r0, #16
40 ; CHECK-ARM-NEXT:    asr r1, r1, #16
41 ; CHECK-ARM-NEXT:    cmp r1, #0
42 ; CHECK-ARM-NEXT:    movmi r0, #0
43 ; CHECK-ARM-NEXT:    mov pc, lr
45 ; CHECK-T-LABEL: sat0_base_16bit:
46 ; CHECK-T:       @ %bb.0: @ %entry
47 ; CHECK-T-NEXT:    lsls r1, r0, #16
48 ; CHECK-T-NEXT:    asrs r1, r1, #16
49 ; CHECK-T-NEXT:    bpl .LBB1_2
50 ; CHECK-T-NEXT:  @ %bb.1:
51 ; CHECK-T-NEXT:    movs r0, #0
52 ; CHECK-T-NEXT:  .LBB1_2: @ %entry
53 ; CHECK-T-NEXT:    bx lr
55 ; CHECK-T2-LABEL: sat0_base_16bit:
56 ; CHECK-T2:       @ %bb.0: @ %entry
57 ; CHECK-T2-NEXT:    sxth r1, r0
58 ; CHECK-T2-NEXT:    cmp r1, #0
59 ; CHECK-T2-NEXT:    it mi
60 ; CHECK-T2-NEXT:    movmi r0, #0
61 ; CHECK-T2-NEXT:    bx lr
62 entry:
63   %cmpLow = icmp slt i16 %x, 0
64   %saturateLow = select i1 %cmpLow, i16 0, i16 %x
65   ret i16 %saturateLow
68 ; x < 0 ? 0 : x
69 ; 8-bit base test
70 define i8 @sat0_base_8bit(i8 %x) #0 {
71 ; CHECK-ARM-LABEL: sat0_base_8bit:
72 ; CHECK-ARM:       @ %bb.0: @ %entry
73 ; CHECK-ARM-NEXT:    lsl r1, r0, #24
74 ; CHECK-ARM-NEXT:    asr r1, r1, #24
75 ; CHECK-ARM-NEXT:    cmp r1, #0
76 ; CHECK-ARM-NEXT:    movmi r0, #0
77 ; CHECK-ARM-NEXT:    mov pc, lr
79 ; CHECK-T-LABEL: sat0_base_8bit:
80 ; CHECK-T:       @ %bb.0: @ %entry
81 ; CHECK-T-NEXT:    lsls r1, r0, #24
82 ; CHECK-T-NEXT:    asrs r1, r1, #24
83 ; CHECK-T-NEXT:    bpl .LBB2_2
84 ; CHECK-T-NEXT:  @ %bb.1:
85 ; CHECK-T-NEXT:    movs r0, #0
86 ; CHECK-T-NEXT:  .LBB2_2: @ %entry
87 ; CHECK-T-NEXT:    bx lr
89 ; CHECK-T2-LABEL: sat0_base_8bit:
90 ; CHECK-T2:       @ %bb.0: @ %entry
91 ; CHECK-T2-NEXT:    sxtb r1, r0
92 ; CHECK-T2-NEXT:    cmp r1, #0
93 ; CHECK-T2-NEXT:    it mi
94 ; CHECK-T2-NEXT:    movmi r0, #0
95 ; CHECK-T2-NEXT:    bx lr
96 entry:
97   %cmpLow = icmp slt i8 %x, 0
98   %saturateLow = select i1 %cmpLow, i8 0, i8 %x
99   ret i8 %saturateLow
102 ; Test where the conditional is formed in a different way
104 ; x > 0 ? x : 0
105 define i32 @sat0_lower_1(i32 %x) #0 {
106 ; CHECK-ARM-LABEL: sat0_lower_1:
107 ; CHECK-ARM:       @ %bb.0: @ %entry
108 ; CHECK-ARM-NEXT:    bic r0, r0, r0, asr #31
109 ; CHECK-ARM-NEXT:    mov pc, lr
111 ; CHECK-T-LABEL: sat0_lower_1:
112 ; CHECK-T:       @ %bb.0: @ %entry
113 ; CHECK-T-NEXT:    asrs r1, r0, #31
114 ; CHECK-T-NEXT:    bics r0, r1
115 ; CHECK-T-NEXT:    bx lr
117 ; CHECK-T2-LABEL: sat0_lower_1:
118 ; CHECK-T2:       @ %bb.0: @ %entry
119 ; CHECK-T2-NEXT:    bic.w r0, r0, r0, asr #31
120 ; CHECK-T2-NEXT:    bx lr
121 entry:
122   %cmpGt = icmp sgt i32 %x, 0
123   %saturateLow = select i1 %cmpGt, i32 %x, i32 0
124   ret i32 %saturateLow
128 ; Check for clipping against -1 that should result in orr
130 ; Base tests with different bit widths
133 ; x < -1 ? -1 : x
134 ; 32-bit base test
135 define i32 @sat1_base_32bit(i32 %x) #0 {
136 ; CHECK-ARM-LABEL: sat1_base_32bit:
137 ; CHECK-ARM:       @ %bb.0: @ %entry
138 ; CHECK-ARM-NEXT:    orr r0, r0, r0, asr #31
139 ; CHECK-ARM-NEXT:    mov pc, lr
141 ; CHECK-T-LABEL: sat1_base_32bit:
142 ; CHECK-T:       @ %bb.0: @ %entry
143 ; CHECK-T-NEXT:    asrs r1, r0, #31
144 ; CHECK-T-NEXT:    orrs r0, r1
145 ; CHECK-T-NEXT:    bx lr
147 ; CHECK-T2-LABEL: sat1_base_32bit:
148 ; CHECK-T2:       @ %bb.0: @ %entry
149 ; CHECK-T2-NEXT:    orr.w r0, r0, r0, asr #31
150 ; CHECK-T2-NEXT:    bx lr
151 entry:
152   %cmpLow = icmp slt i32 %x, -1
153   %saturateLow = select i1 %cmpLow, i32 -1, i32 %x
154   ret i32 %saturateLow
157 ; x < -1 ? -1 : x
158 ; 16-bit base test
159 define i16 @sat1_base_16bit(i16 %x) #0 {
160 ; CHECK-ARM-LABEL: sat1_base_16bit:
161 ; CHECK-ARM:       @ %bb.0: @ %entry
162 ; CHECK-ARM-NEXT:    lsl r1, r0, #16
163 ; CHECK-ARM-NEXT:    asr r1, r1, #16
164 ; CHECK-ARM-NEXT:    cmn r1, #1
165 ; CHECK-ARM-NEXT:    mvnlt r0, #0
166 ; CHECK-ARM-NEXT:    mov pc, lr
168 ; CHECK-T-LABEL: sat1_base_16bit:
169 ; CHECK-T:       @ %bb.0: @ %entry
170 ; CHECK-T-NEXT:    movs r1, #0
171 ; CHECK-T-NEXT:    mvns r1, r1
172 ; CHECK-T-NEXT:    lsls r2, r0, #16
173 ; CHECK-T-NEXT:    asrs r2, r2, #16
174 ; CHECK-T-NEXT:    cmp r2, r1
175 ; CHECK-T-NEXT:    blt .LBB5_2
176 ; CHECK-T-NEXT:  @ %bb.1: @ %entry
177 ; CHECK-T-NEXT:    movs r1, r0
178 ; CHECK-T-NEXT:  .LBB5_2: @ %entry
179 ; CHECK-T-NEXT:    movs r0, r1
180 ; CHECK-T-NEXT:    bx lr
182 ; CHECK-T2-LABEL: sat1_base_16bit:
183 ; CHECK-T2:       @ %bb.0: @ %entry
184 ; CHECK-T2-NEXT:    sxth r1, r0
185 ; CHECK-T2-NEXT:    cmp.w r1, #-1
186 ; CHECK-T2-NEXT:    it lt
187 ; CHECK-T2-NEXT:    movlt.w r0, #-1
188 ; CHECK-T2-NEXT:    bx lr
189 entry:
190   %cmpLow = icmp slt i16 %x, -1
191   %saturateLow = select i1 %cmpLow, i16 -1, i16 %x
192   ret i16 %saturateLow
195 ; x < -1 ? -1 : x
196 ; 8-bit base test
197 define i8 @sat1_base_8bit(i8 %x) #0 {
198 ; CHECK-ARM-LABEL: sat1_base_8bit:
199 ; CHECK-ARM:       @ %bb.0: @ %entry
200 ; CHECK-ARM-NEXT:    lsl r1, r0, #24
201 ; CHECK-ARM-NEXT:    asr r1, r1, #24
202 ; CHECK-ARM-NEXT:    cmn r1, #1
203 ; CHECK-ARM-NEXT:    mvnlt r0, #0
204 ; CHECK-ARM-NEXT:    mov pc, lr
206 ; CHECK-T-LABEL: sat1_base_8bit:
207 ; CHECK-T:       @ %bb.0: @ %entry
208 ; CHECK-T-NEXT:    movs r1, #0
209 ; CHECK-T-NEXT:    mvns r1, r1
210 ; CHECK-T-NEXT:    lsls r2, r0, #24
211 ; CHECK-T-NEXT:    asrs r2, r2, #24
212 ; CHECK-T-NEXT:    cmp r2, r1
213 ; CHECK-T-NEXT:    blt .LBB6_2
214 ; CHECK-T-NEXT:  @ %bb.1: @ %entry
215 ; CHECK-T-NEXT:    movs r1, r0
216 ; CHECK-T-NEXT:  .LBB6_2: @ %entry
217 ; CHECK-T-NEXT:    movs r0, r1
218 ; CHECK-T-NEXT:    bx lr
220 ; CHECK-T2-LABEL: sat1_base_8bit:
221 ; CHECK-T2:       @ %bb.0: @ %entry
222 ; CHECK-T2-NEXT:    sxtb r1, r0
223 ; CHECK-T2-NEXT:    cmp.w r1, #-1
224 ; CHECK-T2-NEXT:    it lt
225 ; CHECK-T2-NEXT:    movlt.w r0, #-1
226 ; CHECK-T2-NEXT:    bx lr
227 entry:
228   %cmpLow = icmp slt i8 %x, -1
229   %saturateLow = select i1 %cmpLow, i8 -1, i8 %x
230   ret i8 %saturateLow
233 ; Test where the conditional is formed in a different way
235 ; x > -1 ? x : -1
236 define i32 @sat1_lower_1(i32 %x) #0 {
237 ; CHECK-ARM-LABEL: sat1_lower_1:
238 ; CHECK-ARM:       @ %bb.0: @ %entry
239 ; CHECK-ARM-NEXT:    orr r0, r0, r0, asr #31
240 ; CHECK-ARM-NEXT:    mov pc, lr
242 ; CHECK-T-LABEL: sat1_lower_1:
243 ; CHECK-T:       @ %bb.0: @ %entry
244 ; CHECK-T-NEXT:    asrs r1, r0, #31
245 ; CHECK-T-NEXT:    orrs r0, r1
246 ; CHECK-T-NEXT:    bx lr
248 ; CHECK-T2-LABEL: sat1_lower_1:
249 ; CHECK-T2:       @ %bb.0: @ %entry
250 ; CHECK-T2-NEXT:    orr.w r0, r0, r0, asr #31
251 ; CHECK-T2-NEXT:    bx lr
252 entry:
253   %cmpGt = icmp sgt i32 %x, -1
254   %saturateLow = select i1 %cmpGt, i32 %x, i32 -1
255   ret i32 %saturateLow
258 ; The following tests for patterns that should not transform into bitops
259 ; but that are similar enough that could confuse the selector.
261 ; x < 0 ? 0 : y where x and y does not properly match
262 define i32 @no_sat0_incorrect_variable(i32 %x, i32 %y) #0 {
263 ; CHECK-ARM-LABEL: no_sat0_incorrect_variable:
264 ; CHECK-ARM:       @ %bb.0: @ %entry
265 ; CHECK-ARM-NEXT:    cmp r0, #0
266 ; CHECK-ARM-NEXT:    movmi r1, #0
267 ; CHECK-ARM-NEXT:    mov r0, r1
268 ; CHECK-ARM-NEXT:    mov pc, lr
270 ; CHECK-T-LABEL: no_sat0_incorrect_variable:
271 ; CHECK-T:       @ %bb.0: @ %entry
272 ; CHECK-T-NEXT:    cmp r0, #0
273 ; CHECK-T-NEXT:    bpl .LBB8_2
274 ; CHECK-T-NEXT:  @ %bb.1:
275 ; CHECK-T-NEXT:    movs r1, #0
276 ; CHECK-T-NEXT:  .LBB8_2: @ %entry
277 ; CHECK-T-NEXT:    movs r0, r1
278 ; CHECK-T-NEXT:    bx lr
280 ; CHECK-T2-LABEL: no_sat0_incorrect_variable:
281 ; CHECK-T2:       @ %bb.0: @ %entry
282 ; CHECK-T2-NEXT:    cmp r0, #0
283 ; CHECK-T2-NEXT:    it mi
284 ; CHECK-T2-NEXT:    movmi r1, #0
285 ; CHECK-T2-NEXT:    mov r0, r1
286 ; CHECK-T2-NEXT:    bx lr
287 entry:
288   %cmpLow = icmp slt i32 %x, 0
289   %saturateLow = select i1 %cmpLow, i32 0, i32 %y
290   ret i32 %saturateLow
293 ; x < 0 ? -1 : x
294 define i32 @no_sat0_incorrect_constant(i32 %x) {
295 ; CHECK-ARM-LABEL: no_sat0_incorrect_constant:
296 ; CHECK-ARM:       @ %bb.0: @ %entry
297 ; CHECK-ARM-NEXT:    cmp r0, #0
298 ; CHECK-ARM-NEXT:    mvnmi r0, #0
299 ; CHECK-ARM-NEXT:    mov pc, lr
301 ; CHECK-T-LABEL: no_sat0_incorrect_constant:
302 ; CHECK-T:       @ %bb.0: @ %entry
303 ; CHECK-T-NEXT:    cmp r0, #0
304 ; CHECK-T-NEXT:    bpl .LBB9_2
305 ; CHECK-T-NEXT:  @ %bb.1:
306 ; CHECK-T-NEXT:    movs r0, #0
307 ; CHECK-T-NEXT:    mvns r0, r0
308 ; CHECK-T-NEXT:  .LBB9_2: @ %entry
309 ; CHECK-T-NEXT:    bx lr
311 ; CHECK-T2-LABEL: no_sat0_incorrect_constant:
312 ; CHECK-T2:       @ %bb.0: @ %entry
313 ; CHECK-T2-NEXT:    cmp r0, #0
314 ; CHECK-T2-NEXT:    it mi
315 ; CHECK-T2-NEXT:    movmi.w r0, #-1
316 ; CHECK-T2-NEXT:    bx lr
317 entry:
318   %cmpLow = icmp slt i32 %x, 0
319   %saturateLow = select i1 %cmpLow, i32 -1, i32 %x
320   ret i32 %saturateLow