Revert 374373: [Codegen] Alter the default promotion for saturating adds and subs
[llvm-core.git] / test / CodeGen / AArch64 / sink-addsub-of-const.ll
blobd55310cad76b70d9bba75809a9f424b57685eeb0
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
4 ; Scalar tests.
6 ; add (add %x, C), %y
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:
11 ; CHECK:       // %bb.0:
12 ; CHECK-NEXT:    add w8, w0, w1
13 ; CHECK-NEXT:    add w0, w8, #32 // =32
14 ; CHECK-NEXT:    ret
15   %t0 = add i32 %a, 32 ; constant always on RHS
16   %r = add i32 %t0, %b
17   ret i32 %r
19 define i32 @sink_add_of_const_to_add1(i32 %a, i32 %b) {
20 ; CHECK-LABEL: sink_add_of_const_to_add1:
21 ; CHECK:       // %bb.0:
22 ; CHECK-NEXT:    add w8, w0, w1
23 ; CHECK-NEXT:    add w0, w8, #32 // =32
24 ; CHECK-NEXT:    ret
25   %t0 = add i32 %a, 32 ; constant always on RHS
26   %r = add i32 %b, %t0
27   ret i32 %r
30 ; add (sub %x, C), %y
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:
35 ; CHECK:       // %bb.0:
36 ; CHECK-NEXT:    add w8, w0, w1
37 ; CHECK-NEXT:    sub w0, w8, #32 // =32
38 ; CHECK-NEXT:    ret
39   %t0 = sub i32 %a, 32
40   %r = add i32 %t0, %b
41   ret i32 %r
43 define i32 @sink_sub_of_const_to_add1(i32 %a, i32 %b) {
44 ; CHECK-LABEL: sink_sub_of_const_to_add1:
45 ; CHECK:       // %bb.0:
46 ; CHECK-NEXT:    add w8, w0, w1
47 ; CHECK-NEXT:    sub w0, w8, #32 // =32
48 ; CHECK-NEXT:    ret
49   %t0 = sub i32 %a, 32
50   %r = add i32 %b, %t0
51   ret i32 %r
54 ; add (sub C, %x), %y
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:
59 ; CHECK:       // %bb.0:
60 ; CHECK-NEXT:    sub w8, w1, w0
61 ; CHECK-NEXT:    add w0, w8, #32 // =32
62 ; CHECK-NEXT:    ret
63   %t0 = sub i32 32, %a
64   %r = add i32 %t0, %b
65   ret i32 %r
67 define i32 @sink_sub_from_const_to_add1(i32 %a, i32 %b) {
68 ; CHECK-LABEL: sink_sub_from_const_to_add1:
69 ; CHECK:       // %bb.0:
70 ; CHECK-NEXT:    sub w8, w1, w0
71 ; CHECK-NEXT:    add w0, w8, #32 // =32
72 ; CHECK-NEXT:    ret
73   %t0 = sub i32 32, %a
74   %r = add i32 %b, %t0
75   ret i32 %r
78 ; sub (add %x, C), %y
79 ; sub %y, (add %x, C)
81 define i32 @sink_add_of_const_to_sub(i32 %a, i32 %b) {
82 ; CHECK-LABEL: sink_add_of_const_to_sub:
83 ; CHECK:       // %bb.0:
84 ; CHECK-NEXT:    sub w8, w0, w1
85 ; CHECK-NEXT:    add w0, w8, #32 // =32
86 ; CHECK-NEXT:    ret
87   %t0 = add i32 %a, 32 ; constant always on RHS
88   %r = sub i32 %t0, %b
89   ret i32 %r
91 define i32 @sink_add_of_const_to_sub2(i32 %a, i32 %b) {
92 ; CHECK-LABEL: sink_add_of_const_to_sub2:
93 ; CHECK:       // %bb.0:
94 ; CHECK-NEXT:    sub w8, w1, w0
95 ; CHECK-NEXT:    sub w0, w8, #32 // =32
96 ; CHECK-NEXT:    ret
97   %t0 = add i32 %a, 32 ; constant always on RHS
98   %r = sub i32 %b, %t0
99   ret i32 %r
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:
107 ; CHECK:       // %bb.0:
108 ; CHECK-NEXT:    sub w8, w0, w1
109 ; CHECK-NEXT:    sub w0, w8, #32 // =32
110 ; CHECK-NEXT:    ret
111   %t0 = sub i32 %a, 32
112   %r = sub i32 %t0, %b
113   ret i32 %r
115 define i32 @sink_sub_of_const_to_sub2(i32 %a, i32 %b) {
116 ; CHECK-LABEL: sink_sub_of_const_to_sub2:
117 ; CHECK:       // %bb.0:
118 ; CHECK-NEXT:    sub w8, w1, w0
119 ; CHECK-NEXT:    add w0, w8, #32 // =32
120 ; CHECK-NEXT:    ret
121   %t0 = sub i32 %a, 32
122   %r = sub i32 %b, %t0
123   ret i32 %r
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:
131 ; CHECK:       // %bb.0:
132 ; CHECK-NEXT:    add w8, w0, w1
133 ; CHECK-NEXT:    mov w9, #32
134 ; CHECK-NEXT:    sub w0, w9, w8
135 ; CHECK-NEXT:    ret
136   %t0 = sub i32 32, %a
137   %r = sub i32 %t0, %b
138   ret i32 %r
140 define i32 @sink_sub_from_const_to_sub2(i32 %a, i32 %b) {
141 ; CHECK-LABEL: sink_sub_from_const_to_sub2:
142 ; CHECK:       // %bb.0:
143 ; CHECK-NEXT:    add w8, w0, w1
144 ; CHECK-NEXT:    sub w0, w8, #32 // =32
145 ; CHECK-NEXT:    ret
146   %t0 = sub i32 32, %a
147   %r = sub i32 %b, %t0
148   ret i32 %r
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:
160 ; CHECK:       // %bb.0:
161 ; CHECK-NEXT:    adrp x8, .LCPI12_0
162 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI12_0]
163 ; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
164 ; CHECK-NEXT:    add v0.4s, v0.4s, v2.4s
165 ; CHECK-NEXT:    ret
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
168   ret <4 x i32> %r
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:
172 ; CHECK:       // %bb.0:
173 ; CHECK-NEXT:    adrp x8, .LCPI13_0
174 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI13_0]
175 ; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
176 ; CHECK-NEXT:    add v0.4s, v0.4s, v2.4s
177 ; CHECK-NEXT:    ret
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
180   ret <4 x i32> %r
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:
188 ; CHECK:       // %bb.0:
189 ; CHECK-NEXT:    adrp x8, .LCPI14_0
190 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI14_0]
191 ; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
192 ; CHECK-NEXT:    sub v0.4s, v0.4s, v2.4s
193 ; CHECK-NEXT:    ret
194   %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>
195   %r = add <4 x i32> %t0, %b
196   ret <4 x i32> %r
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:
200 ; CHECK:       // %bb.0:
201 ; CHECK-NEXT:    adrp x8, .LCPI15_0
202 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI15_0]
203 ; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
204 ; CHECK-NEXT:    sub v0.4s, v0.4s, v2.4s
205 ; CHECK-NEXT:    ret
206   %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>
207   %r = add <4 x i32> %b, %t0
208   ret <4 x i32> %r
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:
216 ; CHECK:       // %bb.0:
217 ; CHECK-NEXT:    adrp x8, .LCPI16_0
218 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI16_0]
219 ; CHECK-NEXT:    sub v0.4s, v1.4s, v0.4s
220 ; CHECK-NEXT:    add v0.4s, v0.4s, v2.4s
221 ; CHECK-NEXT:    ret
222   %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a
223   %r = add <4 x i32> %t0, %b
224   ret <4 x i32> %r
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:
228 ; CHECK:       // %bb.0:
229 ; CHECK-NEXT:    adrp x8, .LCPI17_0
230 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI17_0]
231 ; CHECK-NEXT:    sub v0.4s, v1.4s, v0.4s
232 ; CHECK-NEXT:    add v0.4s, v0.4s, v2.4s
233 ; CHECK-NEXT:    ret
234   %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a
235   %r = add <4 x i32> %b, %t0
236   ret <4 x i32> %r
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:
244 ; CHECK:       // %bb.0:
245 ; CHECK-NEXT:    adrp x8, .LCPI18_0
246 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI18_0]
247 ; CHECK-NEXT:    sub v0.4s, v0.4s, v1.4s
248 ; CHECK-NEXT:    add v0.4s, v0.4s, v2.4s
249 ; CHECK-NEXT:    ret
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
252   ret <4 x i32> %r
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:
256 ; CHECK:       // %bb.0:
257 ; CHECK-NEXT:    adrp x8, .LCPI19_0
258 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI19_0]
259 ; CHECK-NEXT:    sub v0.4s, v1.4s, v0.4s
260 ; CHECK-NEXT:    sub v0.4s, v0.4s, v2.4s
261 ; CHECK-NEXT:    ret
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
264   ret <4 x i32> %r
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:
272 ; CHECK:       // %bb.0:
273 ; CHECK-NEXT:    adrp x8, .LCPI20_0
274 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI20_0]
275 ; CHECK-NEXT:    sub v0.4s, v0.4s, v1.4s
276 ; CHECK-NEXT:    sub v0.4s, v0.4s, v2.4s
277 ; CHECK-NEXT:    ret
278   %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>
279   %r = sub <4 x i32> %t0, %b
280   ret <4 x i32> %r
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:
284 ; CHECK:       // %bb.0:
285 ; CHECK-NEXT:    adrp x8, .LCPI21_0
286 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI21_0]
287 ; CHECK-NEXT:    sub v0.4s, v1.4s, v0.4s
288 ; CHECK-NEXT:    add v0.4s, v0.4s, v2.4s
289 ; CHECK-NEXT:    ret
290   %t0 = sub <4 x i32> %a, <i32 42, i32 24, i32 undef, i32 46>
291   %r = sub <4 x i32> %b, %t0
292   ret <4 x i32> %r
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:
300 ; CHECK:       // %bb.0:
301 ; CHECK-NEXT:    adrp x8, .LCPI22_0
302 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI22_0]
303 ; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
304 ; CHECK-NEXT:    sub v0.4s, v2.4s, v0.4s
305 ; CHECK-NEXT:    ret
306   %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a
307   %r = sub <4 x i32> %t0, %b
308   ret <4 x i32> %r
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:
312 ; CHECK:       // %bb.0:
313 ; CHECK-NEXT:    adrp x8, .LCPI23_0
314 ; CHECK-NEXT:    ldr q2, [x8, :lo12:.LCPI23_0]
315 ; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
316 ; CHECK-NEXT:    sub v0.4s, v0.4s, v2.4s
317 ; CHECK-NEXT:    ret
318   %t0 = sub <4 x i32> <i32 42, i32 24, i32 undef, i32 46>, %a
319   %r = sub <4 x i32> %b, %t0
320   ret <4 x i32> %r