[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / AArch64 / signbit-shift.ll
blob250290aa2348f9661c112f69cf3d4e6a7801404a
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
4 ; If positive...
6 define i32 @zext_ifpos(i32 %x) {
7 ; CHECK-LABEL: zext_ifpos:
8 ; CHECK:       // %bb.0:
9 ; CHECK-NEXT:    mvn w8, w0
10 ; CHECK-NEXT:    lsr w0, w8, #31
11 ; CHECK-NEXT:    ret
12   %c = icmp sgt i32 %x, -1
13   %e = zext i1 %c to i32
14   ret i32 %e
17 define i32 @add_zext_ifpos(i32 %x) {
18 ; CHECK-LABEL: add_zext_ifpos:
19 ; CHECK:       // %bb.0:
20 ; CHECK-NEXT:    asr w8, w0, #31
21 ; CHECK-NEXT:    add w0, w8, #42 // =42
22 ; CHECK-NEXT:    ret
23   %c = icmp sgt i32 %x, -1
24   %e = zext i1 %c to i32
25   %r = add i32 %e, 41
26   ret i32 %r
29 define <4 x i32> @add_zext_ifpos_vec_splat(<4 x i32> %x) {
30 ; CHECK-LABEL: add_zext_ifpos_vec_splat:
31 ; CHECK:       // %bb.0:
32 ; CHECK-NEXT:    movi v1.2d, #0xffffffffffffffff
33 ; CHECK-NEXT:    cmgt v0.4s, v0.4s, v1.4s
34 ; CHECK-NEXT:    movi v1.4s, #41
35 ; CHECK-NEXT:    sub v0.4s, v1.4s, v0.4s
36 ; CHECK-NEXT:    ret
37   %c = icmp sgt <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
38   %e = zext <4 x i1> %c to <4 x i32>
39   %r = add <4 x i32> %e, <i32 41, i32 41, i32 41, i32 41>
40   ret <4 x i32> %r
43 define i32 @sel_ifpos_tval_bigger(i32 %x) {
44 ; CHECK-LABEL: sel_ifpos_tval_bigger:
45 ; CHECK:       // %bb.0:
46 ; CHECK-NEXT:    cmp w0, #0 // =0
47 ; CHECK-NEXT:    mov w8, #41
48 ; CHECK-NEXT:    cinc w0, w8, ge
49 ; CHECK-NEXT:    ret
50   %c = icmp sgt i32 %x, -1
51   %r = select i1 %c, i32 42, i32 41
52   ret i32 %r
55 define i32 @sext_ifpos(i32 %x) {
56 ; CHECK-LABEL: sext_ifpos:
57 ; CHECK:       // %bb.0:
58 ; CHECK-NEXT:    mvn w8, w0
59 ; CHECK-NEXT:    asr w0, w8, #31
60 ; CHECK-NEXT:    ret
61   %c = icmp sgt i32 %x, -1
62   %e = sext i1 %c to i32
63   ret i32 %e
66 define i32 @add_sext_ifpos(i32 %x) {
67 ; CHECK-LABEL: add_sext_ifpos:
68 ; CHECK:       // %bb.0:
69 ; CHECK-NEXT:    lsr w8, w0, #31
70 ; CHECK-NEXT:    add w0, w8, #41 // =41
71 ; CHECK-NEXT:    ret
72   %c = icmp sgt i32 %x, -1
73   %e = sext i1 %c to i32
74   %r = add i32 %e, 42
75   ret i32 %r
78 define <4 x i32> @add_sext_ifpos_vec_splat(<4 x i32> %x) {
79 ; CHECK-LABEL: add_sext_ifpos_vec_splat:
80 ; CHECK:       // %bb.0:
81 ; CHECK-NEXT:    movi v1.2d, #0xffffffffffffffff
82 ; CHECK-NEXT:    cmgt v0.4s, v0.4s, v1.4s
83 ; CHECK-NEXT:    movi v1.4s, #42
84 ; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
85 ; CHECK-NEXT:    ret
86   %c = icmp sgt <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
87   %e = sext <4 x i1> %c to <4 x i32>
88   %r = add <4 x i32> %e, <i32 42, i32 42, i32 42, i32 42>
89   ret <4 x i32> %r
92 define i32 @sel_ifpos_fval_bigger(i32 %x) {
93 ; CHECK-LABEL: sel_ifpos_fval_bigger:
94 ; CHECK:       // %bb.0:
95 ; CHECK-NEXT:    cmp w0, #0 // =0
96 ; CHECK-NEXT:    mov w8, #41
97 ; CHECK-NEXT:    cinc w0, w8, lt
98 ; CHECK-NEXT:    ret
99   %c = icmp sgt i32 %x, -1
100   %r = select i1 %c, i32 41, i32 42
101   ret i32 %r
104 ; If negative...
106 define i32 @zext_ifneg(i32 %x) {
107 ; CHECK-LABEL: zext_ifneg:
108 ; CHECK:       // %bb.0:
109 ; CHECK-NEXT:    lsr w0, w0, #31
110 ; CHECK-NEXT:    ret
111   %c = icmp slt i32 %x, 0
112   %r = zext i1 %c to i32
113   ret i32 %r
116 define i32 @add_zext_ifneg(i32 %x) {
117 ; CHECK-LABEL: add_zext_ifneg:
118 ; CHECK:       // %bb.0:
119 ; CHECK-NEXT:    lsr w8, w0, #31
120 ; CHECK-NEXT:    add w0, w8, #41 // =41
121 ; CHECK-NEXT:    ret
122   %c = icmp slt i32 %x, 0
123   %e = zext i1 %c to i32
124   %r = add i32 %e, 41
125   ret i32 %r
128 define i32 @sel_ifneg_tval_bigger(i32 %x) {
129 ; CHECK-LABEL: sel_ifneg_tval_bigger:
130 ; CHECK:       // %bb.0:
131 ; CHECK-NEXT:    cmp w0, #0 // =0
132 ; CHECK-NEXT:    mov w8, #41
133 ; CHECK-NEXT:    cinc w0, w8, lt
134 ; CHECK-NEXT:    ret
135   %c = icmp slt i32 %x, 0
136   %r = select i1 %c, i32 42, i32 41
137   ret i32 %r
140 define i32 @sext_ifneg(i32 %x) {
141 ; CHECK-LABEL: sext_ifneg:
142 ; CHECK:       // %bb.0:
143 ; CHECK-NEXT:    asr w0, w0, #31
144 ; CHECK-NEXT:    ret
145   %c = icmp slt i32 %x, 0
146   %r = sext i1 %c to i32
147   ret i32 %r
150 define i32 @add_sext_ifneg(i32 %x) {
151 ; CHECK-LABEL: add_sext_ifneg:
152 ; CHECK:       // %bb.0:
153 ; CHECK-NEXT:    asr w8, w0, #31
154 ; CHECK-NEXT:    add w0, w8, #42 // =42
155 ; CHECK-NEXT:    ret
156   %c = icmp slt i32 %x, 0
157   %e = sext i1 %c to i32
158   %r = add i32 %e, 42
159   ret i32 %r
162 define i32 @sel_ifneg_fval_bigger(i32 %x) {
163 ; CHECK-LABEL: sel_ifneg_fval_bigger:
164 ; CHECK:       // %bb.0:
165 ; CHECK-NEXT:    cmp w0, #0 // =0
166 ; CHECK-NEXT:    mov w8, #41
167 ; CHECK-NEXT:    cinc w0, w8, ge
168 ; CHECK-NEXT:    ret
169   %c = icmp slt i32 %x, 0
170   %r = select i1 %c, i32 41, i32 42
171   ret i32 %r
174 define i32 @add_lshr_not(i32 %x) {
175 ; CHECK-LABEL: add_lshr_not:
176 ; CHECK:       // %bb.0:
177 ; CHECK-NEXT:    asr w8, w0, #31
178 ; CHECK-NEXT:    add w0, w8, #42 // =42
179 ; CHECK-NEXT:    ret
180   %not = xor i32 %x, -1
181   %sh = lshr i32 %not, 31
182   %r = add i32 %sh, 41
183   ret i32 %r
186 define <4 x i32> @add_lshr_not_vec_splat(<4 x i32> %x) {
187 ; CHECK-LABEL: add_lshr_not_vec_splat:
188 ; CHECK:       // %bb.0:
189 ; CHECK-NEXT:    movi v1.4s, #43
190 ; CHECK-NEXT:    ssra v1.4s, v0.4s, #31
191 ; CHECK-NEXT:    mov v0.16b, v1.16b
192 ; CHECK-NEXT:    ret
193   %c = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
194   %e = lshr <4 x i32> %c, <i32 31, i32 31, i32 31, i32 31>
195   %r = add <4 x i32> %e, <i32 42, i32 42, i32 42, i32 42>
196   ret <4 x i32> %r
199 define i32 @sub_lshr_not(i32 %x) {
200 ; CHECK-LABEL: sub_lshr_not:
201 ; CHECK:       // %bb.0:
202 ; CHECK-NEXT:    mov w8, #42
203 ; CHECK-NEXT:    bfxil w8, w0, #31, #1
204 ; CHECK-NEXT:    mov w0, w8
205 ; CHECK-NEXT:    ret
206   %not = xor i32 %x, -1
207   %sh = lshr i32 %not, 31
208   %r = sub i32 43, %sh
209   ret i32 %r
212 define <4 x i32> @sub_lshr_not_vec_splat(<4 x i32> %x) {
213 ; CHECK-LABEL: sub_lshr_not_vec_splat:
214 ; CHECK:       // %bb.0:
215 ; CHECK-NEXT:    movi v1.4s, #41
216 ; CHECK-NEXT:    usra v1.4s, v0.4s, #31
217 ; CHECK-NEXT:    mov v0.16b, v1.16b
218 ; CHECK-NEXT:    ret
219   %c = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
220   %e = lshr <4 x i32> %c, <i32 31, i32 31, i32 31, i32 31>
221   %r = sub <4 x i32> <i32 42, i32 42, i32 42, i32 42>, %e
222   ret <4 x i32> %r
225 define i32 @sub_lshr(i32 %x, i32 %y) {
226 ; CHECK-LABEL: sub_lshr:
227 ; CHECK:       // %bb.0:
228 ; CHECK-NEXT:    add w0, w1, w0, asr #31
229 ; CHECK-NEXT:    ret
230   %sh = lshr i32 %x, 31
231   %r = sub i32 %y, %sh
232   ret i32 %r
235 define <4 x i32> @sub_lshr_vec(<4 x i32> %x, <4 x i32> %y) {
236 ; CHECK-LABEL: sub_lshr_vec:
237 ; CHECK:       // %bb.0:
238 ; CHECK-NEXT:    ssra v1.4s, v0.4s, #31
239 ; CHECK-NEXT:    mov v0.16b, v1.16b
240 ; CHECK-NEXT:    ret
241   %sh = lshr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>
242   %r = sub <4 x i32> %y, %sh
243   ret <4 x i32> %r
246 define i32 @sub_const_op_lshr(i32 %x) {
247 ; CHECK-LABEL: sub_const_op_lshr:
248 ; CHECK:       // %bb.0:
249 ; CHECK-NEXT:    asr w8, w0, #31
250 ; CHECK-NEXT:    add w0, w8, #43 // =43
251 ; CHECK-NEXT:    ret
252   %sh = lshr i32 %x, 31
253   %r = sub i32 43, %sh
254   ret i32 %r
257 define <4 x i32> @sub_const_op_lshr_vec(<4 x i32> %x) {
258 ; CHECK-LABEL: sub_const_op_lshr_vec:
259 ; CHECK:       // %bb.0:
260 ; CHECK-NEXT:    movi v1.4s, #42
261 ; CHECK-NEXT:    ssra v1.4s, v0.4s, #31
262 ; CHECK-NEXT:    mov v0.16b, v1.16b
263 ; CHECK-NEXT:    ret
264   %sh = lshr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>
265   %r = sub <4 x i32> <i32 42, i32 42, i32 42, i32 42>, %sh
266   ret <4 x i32> %r