1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
7 ; Outer 'add' is commutative - 2 variants.
9 define i32 @sink_add_of_const_to_add0(i32 %a, i32 %b) {
10 ; CHECK-LABEL: sink_add_of_const_to_add0:
12 ; CHECK-NEXT: add w8, w0, w1
13 ; CHECK-NEXT: add w0, w8, #32
15 %t0 = add i32 %a, 32 ; constant always on RHS
19 define i32 @sink_add_of_const_to_add1(i32 %a, i32 %b) {
20 ; CHECK-LABEL: sink_add_of_const_to_add1:
22 ; CHECK-NEXT: add w8, w0, w1
23 ; CHECK-NEXT: add w0, w8, #32
25 %t0 = add i32 %a, 32 ; constant always on RHS
31 ; Outer 'add' is commutative - 2 variants.
33 define i32 @sink_sub_of_const_to_add0(i32 %a, i32 %b) {
34 ; CHECK-LABEL: sink_sub_of_const_to_add0:
36 ; CHECK-NEXT: add w8, w0, w1
37 ; CHECK-NEXT: sub w0, w8, #32
43 define i32 @sink_sub_of_const_to_add1(i32 %a, i32 %b) {
44 ; CHECK-LABEL: sink_sub_of_const_to_add1:
46 ; CHECK-NEXT: add w8, w0, w1
47 ; CHECK-NEXT: sub w0, w8, #32
55 ; Outer 'add' is commutative - 2 variants.
57 define i32 @sink_sub_from_const_to_add0(i32 %a, i32 %b) {
58 ; CHECK-LABEL: sink_sub_from_const_to_add0:
60 ; CHECK-NEXT: sub w8, w1, w0
61 ; CHECK-NEXT: add w0, w8, #32
67 define i32 @sink_sub_from_const_to_add1(i32 %a, i32 %b) {
68 ; CHECK-LABEL: sink_sub_from_const_to_add1:
70 ; CHECK-NEXT: sub w8, w1, w0
71 ; CHECK-NEXT: add w0, w8, #32
81 define i32 @sink_add_of_const_to_sub(i32 %a, i32 %b) {
82 ; CHECK-LABEL: sink_add_of_const_to_sub:
84 ; CHECK-NEXT: sub w8, w0, w1
85 ; CHECK-NEXT: add w0, w8, #32
87 %t0 = add i32 %a, 32 ; constant always on RHS
91 define i32 @sink_add_of_const_to_sub2(i32 %a, i32 %b) {
92 ; CHECK-LABEL: sink_add_of_const_to_sub2:
94 ; CHECK-NEXT: sub w8, w1, w0
95 ; CHECK-NEXT: sub w0, w8, #32
97 %t0 = add i32 %a, 32 ; constant always on RHS
102 ; sub (sub %x, C), %y
103 ; sub %y, (sub %x, C)
105 define i32 @sink_sub_of_const_to_sub(i32 %a, i32 %b) {
106 ; CHECK-LABEL: sink_sub_of_const_to_sub:
108 ; CHECK-NEXT: sub w8, w0, w1
109 ; CHECK-NEXT: sub w0, w8, #32
115 define i32 @sink_sub_of_const_to_sub2(i32 %a, i32 %b) {
116 ; CHECK-LABEL: sink_sub_of_const_to_sub2:
118 ; CHECK-NEXT: sub w8, w1, w0
119 ; CHECK-NEXT: add w0, w8, #32
126 ; sub (sub C, %x), %y
127 ; sub %y, (sub C, %x)
129 define i32 @sink_sub_from_const_to_sub(i32 %a, i32 %b) {
130 ; CHECK-LABEL: sink_sub_from_const_to_sub:
132 ; CHECK-NEXT: mov w8, #32 // =0x20
133 ; CHECK-NEXT: add w9, w0, w1
134 ; CHECK-NEXT: sub w0, w8, w9
140 define i32 @sink_sub_from_const_to_sub2(i32 %a, i32 %b) {
141 ; CHECK-LABEL: sink_sub_from_const_to_sub2:
143 ; CHECK-NEXT: add w8, w0, w1
144 ; CHECK-NEXT: sub w0, w8, #32
151 ;------------------------------------------------------------------------------;
152 ; Basic vector tests. Here it is easier to see where the constant operand is.
153 ;------------------------------------------------------------------------------;
155 ; add (add %x, C), %y
156 ; Outer 'add' is commutative - 2 variants.
158 define <4 x i32> @vec_sink_add_of_const_to_add0(<4 x i32> %a, <4 x i32> %b) {
159 ; CHECK-LABEL: vec_sink_add_of_const_to_add0:
161 ; CHECK-NEXT: adrp x8, .LCPI12_0
162 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
163 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI12_0]
164 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
166 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS
167 %r = add <4 x i32> %t0, %b
170 define <4 x i32> @vec_sink_add_of_const_to_add1(<4 x i32> %a, <4 x i32> %b) {
171 ; CHECK-LABEL: vec_sink_add_of_const_to_add1:
173 ; CHECK-NEXT: adrp x8, .LCPI13_0
174 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
175 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI13_0]
176 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
178 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS
179 %r = add <4 x i32> %b, %t0
183 ; add (sub %x, C), %y
184 ; Outer 'add' is commutative - 2 variants.
186 define <4 x i32> @vec_sink_sub_of_const_to_add0(<4 x i32> %a, <4 x i32> %b) {
187 ; CHECK-LABEL: vec_sink_sub_of_const_to_add0:
189 ; CHECK-NEXT: adrp x8, .LCPI14_0
190 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
191 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI14_0]
192 ; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s
194 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>
195 %r = add <4 x i32> %t0, %b
198 define <4 x i32> @vec_sink_sub_of_const_to_add1(<4 x i32> %a, <4 x i32> %b) {
199 ; CHECK-LABEL: vec_sink_sub_of_const_to_add1:
201 ; CHECK-NEXT: adrp x8, .LCPI15_0
202 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
203 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI15_0]
204 ; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s
206 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>
207 %r = add <4 x i32> %b, %t0
211 ; add (sub C, %x), %y
212 ; Outer 'add' is commutative - 2 variants.
214 define <4 x i32> @vec_sink_sub_from_const_to_add0(<4 x i32> %a, <4 x i32> %b) {
215 ; CHECK-LABEL: vec_sink_sub_from_const_to_add0:
217 ; CHECK-NEXT: adrp x8, .LCPI16_0
218 ; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s
219 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI16_0]
220 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
222 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a
223 %r = add <4 x i32> %t0, %b
226 define <4 x i32> @vec_sink_sub_from_const_to_add1(<4 x i32> %a, <4 x i32> %b) {
227 ; CHECK-LABEL: vec_sink_sub_from_const_to_add1:
229 ; CHECK-NEXT: adrp x8, .LCPI17_0
230 ; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s
231 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI17_0]
232 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
234 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a
235 %r = add <4 x i32> %b, %t0
239 ; sub (add %x, C), %y
240 ; sub %y, (add %x, C)
242 define <4 x i32> @vec_sink_add_of_const_to_sub(<4 x i32> %a, <4 x i32> %b) {
243 ; CHECK-LABEL: vec_sink_add_of_const_to_sub:
245 ; CHECK-NEXT: adrp x8, .LCPI18_0
246 ; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s
247 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI18_0]
248 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
250 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS
251 %r = sub <4 x i32> %t0, %b
254 define <4 x i32> @vec_sink_add_of_const_to_sub2(<4 x i32> %a, <4 x i32> %b) {
255 ; CHECK-LABEL: vec_sink_add_of_const_to_sub2:
257 ; CHECK-NEXT: adrp x8, .LCPI19_0
258 ; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s
259 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI19_0]
260 ; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s
262 %t0 = add <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46> ; constant always on RHS
263 %r = sub <4 x i32> %b, %t0
267 ; sub (sub %x, C), %y
268 ; sub %y, (sub %x, C)
270 define <4 x i32> @vec_sink_sub_of_const_to_sub(<4 x i32> %a, <4 x i32> %b) {
271 ; CHECK-LABEL: vec_sink_sub_of_const_to_sub:
273 ; CHECK-NEXT: adrp x8, .LCPI20_0
274 ; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s
275 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI20_0]
276 ; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s
278 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>
279 %r = sub <4 x i32> %t0, %b
282 define <4 x i32> @vec_sink_sub_of_const_to_sub2(<4 x i32> %a, <4 x i32> %b) {
283 ; CHECK-LABEL: vec_sink_sub_of_const_to_sub2:
285 ; CHECK-NEXT: adrp x8, .LCPI21_0
286 ; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s
287 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI21_0]
288 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
290 %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>
291 %r = sub <4 x i32> %b, %t0
295 ; sub (sub C, %x), %y
296 ; sub %y, (sub C, %x)
298 define <4 x i32> @vec_sink_sub_from_const_to_sub(<4 x i32> %a, <4 x i32> %b) {
299 ; CHECK-LABEL: vec_sink_sub_from_const_to_sub:
301 ; CHECK-NEXT: adrp x8, .LCPI22_0
302 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
303 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI22_0]
304 ; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s
306 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a
307 %r = sub <4 x i32> %t0, %b
310 define <4 x i32> @vec_sink_sub_from_const_to_sub2(<4 x i32> %a, <4 x i32> %b) {
311 ; CHECK-LABEL: vec_sink_sub_from_const_to_sub2:
313 ; CHECK-NEXT: adrp x8, .LCPI23_0
314 ; CHECK-NEXT: add v0.4s, v0.4s, v1.4s
315 ; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI23_0]
316 ; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s
318 %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a
319 %r = sub <4 x i32> %b, %t0