xref: /llvm-project/llvm/test/CodeGen/AArch64/addimm-mulimm.ll (revision fcf945f4edbad1f2d82df067c2826baa6165dd3e)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-linux-gnu | FileCheck %s
3
4define i64 @addimm_mulimm_accept_00(i64 %a) {
5; CHECK-LABEL: addimm_mulimm_accept_00:
6; CHECK:       // %bb.0:
7; CHECK-NEXT:    mov w8, #37 // =0x25
8; CHECK-NEXT:    mov x9, #1147 // =0x47b
9; CHECK-NEXT:    madd x0, x0, x8, x9
10; CHECK-NEXT:    ret
11  %tmp0 = add i64 %a, 31
12  %tmp1 = mul i64 %tmp0, 37
13  ret i64 %tmp1
14}
15
16define i64 @addimm_mulimm_accept_01(i64 %a) {
17; CHECK-LABEL: addimm_mulimm_accept_01:
18; CHECK:       // %bb.0:
19; CHECK-NEXT:    mov w8, #37 // =0x25
20; CHECK-NEXT:    mov x9, #-1147 // =0xfffffffffffffb85
21; CHECK-NEXT:    madd x0, x0, x8, x9
22; CHECK-NEXT:    ret
23  %tmp0 = add i64 %a, -31
24  %tmp1 = mul i64 %tmp0, 37
25  ret i64 %tmp1
26}
27
28define signext i32 @addimm_mulimm_accept_02(i32 signext %a) {
29; CHECK-LABEL: addimm_mulimm_accept_02:
30; CHECK:       // %bb.0:
31; CHECK-NEXT:    mov w8, #37 // =0x25
32; CHECK-NEXT:    mov w9, #1147 // =0x47b
33; CHECK-NEXT:    madd w0, w0, w8, w9
34; CHECK-NEXT:    ret
35  %tmp0 = add i32 %a, 31
36  %tmp1 = mul i32 %tmp0, 37
37  ret i32 %tmp1
38}
39
40define signext i32 @addimm_mulimm_accept_03(i32 signext %a) {
41; CHECK-LABEL: addimm_mulimm_accept_03:
42; CHECK:       // %bb.0:
43; CHECK-NEXT:    mov w8, #37 // =0x25
44; CHECK-NEXT:    mov w9, #-1147 // =0xfffffb85
45; CHECK-NEXT:    madd w0, w0, w8, w9
46; CHECK-NEXT:    ret
47  %tmp0 = add i32 %a, -31
48  %tmp1 = mul i32 %tmp0, 37
49  ret i32 %tmp1
50}
51
52define i64 @addimm_mulimm_accept_10(i64 %a) {
53; CHECK-LABEL: addimm_mulimm_accept_10:
54; CHECK:       // %bb.0:
55; CHECK-NEXT:    mov w8, #37 // =0x25
56; CHECK-NEXT:    mov w9, #32888 // =0x8078
57; CHECK-NEXT:    movk w9, #17, lsl #16
58; CHECK-NEXT:    madd x0, x0, x8, x9
59; CHECK-NEXT:    ret
60  %tmp0 = add i64 %a, 31000
61  %tmp1 = mul i64 %tmp0, 37
62  ret i64 %tmp1
63}
64
65define i64 @addimm_mulimm_accept_11(i64 %a) {
66; CHECK-LABEL: addimm_mulimm_accept_11:
67; CHECK:       // %bb.0:
68; CHECK-NEXT:    mov w8, #37 // =0x25
69; CHECK-NEXT:    mov x9, #-32888 // =0xffffffffffff7f88
70; CHECK-NEXT:    movk x9, #65518, lsl #16
71; CHECK-NEXT:    madd x0, x0, x8, x9
72; CHECK-NEXT:    ret
73  %tmp0 = add i64 %a, -31000
74  %tmp1 = mul i64 %tmp0, 37
75  ret i64 %tmp1
76}
77
78define signext i32 @addimm_mulimm_accept_12(i32 signext %a) {
79; CHECK-LABEL: addimm_mulimm_accept_12:
80; CHECK:       // %bb.0:
81; CHECK-NEXT:    mov w8, #37 // =0x25
82; CHECK-NEXT:    mov w9, #32888 // =0x8078
83; CHECK-NEXT:    movk w9, #17, lsl #16
84; CHECK-NEXT:    madd w0, w0, w8, w9
85; CHECK-NEXT:    ret
86  %tmp0 = add i32 %a, 31000
87  %tmp1 = mul i32 %tmp0, 37
88  ret i32 %tmp1
89}
90
91define signext i32 @addimm_mulimm_accept_13(i32 signext %a) {
92; CHECK-LABEL: addimm_mulimm_accept_13:
93; CHECK:       // %bb.0:
94; CHECK-NEXT:    mov w8, #37 // =0x25
95; CHECK-NEXT:    mov w9, #32648 // =0x7f88
96; CHECK-NEXT:    movk w9, #65518, lsl #16
97; CHECK-NEXT:    madd w0, w0, w8, w9
98; CHECK-NEXT:    ret
99  %tmp0 = add i32 %a, -31000
100  %tmp1 = mul i32 %tmp0, 37
101  ret i32 %tmp1
102}
103
104define i64 @addimm_mulimm_reject_00(i64 %a) {
105; CHECK-LABEL: addimm_mulimm_reject_00:
106; CHECK:       // %bb.0:
107; CHECK-NEXT:    mov w8, #3700 // =0xe74
108; CHECK-NEXT:    add x9, x0, #3100
109; CHECK-NEXT:    mul x0, x9, x8
110; CHECK-NEXT:    ret
111  %tmp0 = add i64 %a, 3100
112  %tmp1 = mul i64 %tmp0, 3700
113  ret i64 %tmp1
114}
115
116define i64 @addimm_mulimm_reject_01(i64 %a) {
117; CHECK-LABEL: addimm_mulimm_reject_01:
118; CHECK:       // %bb.0:
119; CHECK-NEXT:    mov w8, #3700 // =0xe74
120; CHECK-NEXT:    sub x9, x0, #3100
121; CHECK-NEXT:    mul x0, x9, x8
122; CHECK-NEXT:    ret
123  %tmp0 = add i64 %a, -3100
124  %tmp1 = mul i64 %tmp0, 3700
125  ret i64 %tmp1
126}
127
128define signext i32 @addimm_mulimm_reject_02(i32 signext %a) {
129; CHECK-LABEL: addimm_mulimm_reject_02:
130; CHECK:       // %bb.0:
131; CHECK-NEXT:    mov w8, #3700 // =0xe74
132; CHECK-NEXT:    add w9, w0, #3100
133; CHECK-NEXT:    mul w0, w9, w8
134; CHECK-NEXT:    ret
135  %tmp0 = add i32 %a, 3100
136  %tmp1 = mul i32 %tmp0, 3700
137  ret i32 %tmp1
138}
139
140define signext i32 @addimm_mulimm_reject_03(i32 signext %a) {
141; CHECK-LABEL: addimm_mulimm_reject_03:
142; CHECK:       // %bb.0:
143; CHECK-NEXT:    mov w8, #3700 // =0xe74
144; CHECK-NEXT:    sub w9, w0, #3100
145; CHECK-NEXT:    mul w0, w9, w8
146; CHECK-NEXT:    ret
147  %tmp0 = add i32 %a, -3100
148  %tmp1 = mul i32 %tmp0, 3700
149  ret i32 %tmp1
150}
151
152define signext i32 @addmuladd(i32 signext %a) {
153; CHECK-LABEL: addmuladd:
154; CHECK:       // %bb.0:
155; CHECK-NEXT:    mov w8, #324 // =0x144
156; CHECK-NEXT:    mov w9, #1300 // =0x514
157; CHECK-NEXT:    madd w0, w0, w8, w9
158; CHECK-NEXT:    ret
159  %tmp0 = add i32 %a, 4
160  %tmp1 = mul i32 %tmp0, 324
161  %tmp2 = add i32 %tmp1, 4
162  ret i32 %tmp2
163}
164
165define signext i32 @addmuladd_multiuse(i32 signext %a) {
166; CHECK-LABEL: addmuladd_multiuse:
167; CHECK:       // %bb.0:
168; CHECK-NEXT:    mov w8, #324 // =0x144
169; CHECK-NEXT:    mov w9, #1300 // =0x514
170; CHECK-NEXT:    madd w8, w0, w8, w9
171; CHECK-NEXT:    add w9, w0, #4
172; CHECK-NEXT:    eor w0, w9, w8
173; CHECK-NEXT:    ret
174  %tmp0 = add i32 %a, 4
175  %tmp1 = mul i32 %tmp0, 324
176  %tmp2 = add i32 %tmp1, 4
177  %tmp3 = xor i32 %tmp0, %tmp2
178  ret i32 %tmp3
179}
180
181define signext i32 @addmuladd_multiusemul(i32 signext %a) {
182; CHECK-LABEL: addmuladd_multiusemul:
183; CHECK:       // %bb.0:
184; CHECK-NEXT:    mov w8, #324 // =0x144
185; CHECK-NEXT:    mul w8, w0, w8
186; CHECK-NEXT:    add w9, w8, #1296
187; CHECK-NEXT:    add w8, w8, #1300
188; CHECK-NEXT:    eor w0, w9, w8
189; CHECK-NEXT:    ret
190  %tmp0 = add i32 %a, 4
191  %tmp1 = mul i32 %tmp0, 324
192  %tmp2 = add i32 %tmp1, 4
193  %tmp3 = xor i32 %tmp1, %tmp2
194  ret i32 %tmp3
195}
196
197define signext i32 @addmuladd_multiuse2(i32 signext %a) {
198; CHECK-LABEL: addmuladd_multiuse2:
199; CHECK:       // %bb.0:
200; CHECK-NEXT:    mov w8, #324 // =0x144
201; CHECK-NEXT:    lsl w9, w0, #2
202; CHECK-NEXT:    mov w10, #1300 // =0x514
203; CHECK-NEXT:    madd w8, w0, w8, w10
204; CHECK-NEXT:    add w9, w9, #20
205; CHECK-NEXT:    eor w0, w8, w9
206; CHECK-NEXT:    ret
207  %tmp0 = add i32 %a, 4
208  %tmp1 = mul i32 %tmp0, 4
209  %tmp2 = add i32 %tmp1, 4
210  %tmp3 = mul i32 %tmp0, 324
211  %tmp4 = add i32 %tmp3, 4
212  %tmp5 = xor i32 %tmp4, %tmp2
213  ret i32 %tmp5
214}
215
216define signext i32 @addaddmuladd(i32 signext %a, i32 %b) {
217; CHECK-LABEL: addaddmuladd:
218; CHECK:       // %bb.0:
219; CHECK-NEXT:    mov w8, #324 // =0x144
220; CHECK-NEXT:    madd w8, w0, w8, w1
221; CHECK-NEXT:    add w0, w8, #1300
222; CHECK-NEXT:    ret
223  %tmp0 = add i32 %a, 4
224  %tmp1 = mul i32 %tmp0, 324
225  %tmp2 = add i32 %tmp1, %b
226  %tmp3 = add i32 %tmp2, 4
227  ret i32 %tmp3
228}
229
230define signext i32 @addaddmuladd_multiuse(i32 signext %a, i32 %b) {
231; CHECK-LABEL: addaddmuladd_multiuse:
232; CHECK:       // %bb.0:
233; CHECK-NEXT:    mov w8, #324 // =0x144
234; CHECK-NEXT:    add w9, w0, #4
235; CHECK-NEXT:    madd w8, w0, w8, w1
236; CHECK-NEXT:    add w8, w8, #1300
237; CHECK-NEXT:    eor w0, w9, w8
238; CHECK-NEXT:    ret
239  %tmp0 = add i32 %a, 4
240  %tmp1 = mul i32 %tmp0, 324
241  %tmp2 = add i32 %tmp1, %b
242  %tmp3 = add i32 %tmp2, 4
243  %tmp4 = xor i32 %tmp0, %tmp3
244  ret i32 %tmp4
245}
246
247define signext i32 @addaddmuladd_multiuse2(i32 signext %a, i32 %b) {
248; CHECK-LABEL: addaddmuladd_multiuse2:
249; CHECK:       // %bb.0:
250; CHECK-NEXT:    mov w8, #324 // =0x144
251; CHECK-NEXT:    mov w9, #162 // =0xa2
252; CHECK-NEXT:    madd w8, w0, w8, w1
253; CHECK-NEXT:    madd w9, w0, w9, w1
254; CHECK-NEXT:    add w8, w8, #1300
255; CHECK-NEXT:    add w9, w9, #652
256; CHECK-NEXT:    eor w0, w9, w8
257; CHECK-NEXT:    ret
258  %tmp0 = add i32 %a, 4
259  %tmp1 = mul i32 %tmp0, 324
260  %tmp2 = add i32 %tmp1, %b
261  %tmp3 = add i32 %tmp2, 4
262  %tmp1b = mul i32 %tmp0, 162
263  %tmp2b = add i32 %tmp1b, %b
264  %tmp3b = add i32 %tmp2b, 4
265  %tmp4 = xor i32 %tmp3b, %tmp3
266  ret i32 %tmp4
267}
268
269define <4 x i32> @addmuladd_vec(<4 x i32> %a) {
270; CHECK-LABEL: addmuladd_vec:
271; CHECK:       // %bb.0:
272; CHECK-NEXT:    mov w8, #324 // =0x144
273; CHECK-NEXT:    mov w9, #1300 // =0x514
274; CHECK-NEXT:    dup v2.4s, w8
275; CHECK-NEXT:    dup v1.4s, w9
276; CHECK-NEXT:    mla v1.4s, v0.4s, v2.4s
277; CHECK-NEXT:    mov v0.16b, v1.16b
278; CHECK-NEXT:    ret
279  %tmp0 = add <4 x i32> %a, <i32 4, i32 4, i32 4, i32 4>
280  %tmp1 = mul <4 x i32> %tmp0, <i32 324, i32 324, i32 324, i32 324>
281  %tmp2 = add <4 x i32> %tmp1, <i32 4, i32 4, i32 4, i32 4>
282  ret <4 x i32> %tmp2
283}
284
285define <4 x i32> @addmuladd_vec_multiuse(<4 x i32> %a) {
286; CHECK-LABEL: addmuladd_vec_multiuse:
287; CHECK:       // %bb.0:
288; CHECK-NEXT:    movi v1.4s, #4
289; CHECK-NEXT:    mov w8, #324 // =0x144
290; CHECK-NEXT:    dup v2.4s, w8
291; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
292; CHECK-NEXT:    mla v1.4s, v0.4s, v2.4s
293; CHECK-NEXT:    eor v0.16b, v0.16b, v1.16b
294; CHECK-NEXT:    ret
295  %tmp0 = add <4 x i32> %a, <i32 4, i32 4, i32 4, i32 4>
296  %tmp1 = mul <4 x i32> %tmp0, <i32 324, i32 324, i32 324, i32 324>
297  %tmp2 = add <4 x i32> %tmp1, <i32 4, i32 4, i32 4, i32 4>
298  %tmp3 = xor <4 x i32> %tmp0, %tmp2
299  ret <4 x i32> %tmp3
300}
301
302define void @addmuladd_gep(ptr %p, i64 %a) {
303; CHECK-LABEL: addmuladd_gep:
304; CHECK:       // %bb.0:
305; CHECK-NEXT:    mov w8, #40 // =0x28
306; CHECK-NEXT:    str wzr, [x0, #10]!
307; CHECK-NEXT:    madd x8, x1, x8, x0
308; CHECK-NEXT:    str wzr, [x8, #20]
309; CHECK-NEXT:    ret
310  %q = getelementptr i8, ptr %p, i64 10
311  %r = getelementptr [10 x [10 x i32]], ptr %q, i64 0, i64 %a, i64 5
312  store i32 0, ptr %q
313  store i32 0, ptr %r
314  ret void
315}
316
317define i32 @addmuladd_gep2(ptr %p, i32 %a) {
318; CHECK-LABEL: addmuladd_gep2:
319; CHECK:       // %bb.0:
320; CHECK-NEXT:    mov w8, #3240 // =0xca8
321; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
322; CHECK-NEXT:    smaddl x8, w1, w8, x0
323; CHECK-NEXT:    ldr w8, [x8, #3260]
324; CHECK-NEXT:    tbnz w8, #31, .LBB22_2
325; CHECK-NEXT:  // %bb.1:
326; CHECK-NEXT:    mov w0, wzr
327; CHECK-NEXT:    ret
328; CHECK-NEXT:  .LBB22_2: // %then
329; CHECK-NEXT:    sxtw x8, w1
330; CHECK-NEXT:    add x8, x8, #1
331; CHECK-NEXT:    str x8, [x0]
332; CHECK-NEXT:    mov w0, #1 // =0x1
333; CHECK-NEXT:    ret
334  %b = sext i32 %a to i64
335  %c = add nsw i64 %b, 1
336  %d = mul nsw i64 %c, 81
337  %g = getelementptr [10 x [10 x i32]], ptr %p, i64 0, i64 %d, i64 5
338  %l = load i32, ptr %g, align 4
339  %cc = icmp slt i32 %l, 0
340  br i1 %cc, label %then, label %else
341then:
342  store i64 %c, ptr %p
343  ret i32 1
344else:
345  ret i32 0
346}
347
348define signext i32 @addmuladd_multiuse2_nsw(i32 signext %a) {
349; CHECK-LABEL: addmuladd_multiuse2_nsw:
350; CHECK:       // %bb.0:
351; CHECK-NEXT:    mov w8, #324 // =0x144
352; CHECK-NEXT:    lsl w9, w0, #2
353; CHECK-NEXT:    mov w10, #1300 // =0x514
354; CHECK-NEXT:    madd w8, w0, w8, w10
355; CHECK-NEXT:    add w9, w9, #20
356; CHECK-NEXT:    eor w0, w8, w9
357; CHECK-NEXT:    ret
358  %tmp0 = add nsw i32 %a, 4
359  %tmp1 = mul nsw i32 %tmp0, 4
360  %tmp2 = add nsw i32 %tmp1, 4
361  %tmp3 = mul nsw i32 %tmp0, 324
362  %tmp4 = add nsw i32 %tmp3, 4
363  %tmp5 = xor i32 %tmp4, %tmp2
364  ret i32 %tmp5
365}
366
367define signext i32 @addmuladd_multiuse2_nuw(i32 signext %a) {
368; CHECK-LABEL: addmuladd_multiuse2_nuw:
369; CHECK:       // %bb.0:
370; CHECK-NEXT:    mov w8, #324 // =0x144
371; CHECK-NEXT:    lsl w9, w0, #2
372; CHECK-NEXT:    mov w10, #1300 // =0x514
373; CHECK-NEXT:    madd w8, w0, w8, w10
374; CHECK-NEXT:    add w9, w9, #20
375; CHECK-NEXT:    eor w0, w8, w9
376; CHECK-NEXT:    ret
377  %tmp0 = add nuw i32 %a, 4
378  %tmp1 = mul nuw i32 %tmp0, 4
379  %tmp2 = add nuw i32 %tmp1, 4
380  %tmp3 = mul nuw i32 %tmp0, 324
381  %tmp4 = add nuw i32 %tmp3, 4
382  %tmp5 = xor i32 %tmp4, %tmp2
383  ret i32 %tmp5
384}
385
386define signext i32 @addmuladd_multiuse2_nswnuw(i32 signext %a) {
387; CHECK-LABEL: addmuladd_multiuse2_nswnuw:
388; CHECK:       // %bb.0:
389; CHECK-NEXT:    mov w8, #324 // =0x144
390; CHECK-NEXT:    lsl w9, w0, #2
391; CHECK-NEXT:    mov w10, #1300 // =0x514
392; CHECK-NEXT:    madd w8, w0, w8, w10
393; CHECK-NEXT:    add w9, w9, #20
394; CHECK-NEXT:    eor w0, w8, w9
395; CHECK-NEXT:    ret
396  %tmp0 = add nsw nuw i32 %a, 4
397  %tmp1 = mul nsw nuw i32 %tmp0, 4
398  %tmp2 = add nsw nuw i32 %tmp1, 4
399  %tmp3 = mul nsw nuw i32 %tmp0, 324
400  %tmp4 = add nsw nuw i32 %tmp3, 4
401  %tmp5 = xor i32 %tmp4, %tmp2
402  ret i32 %tmp5
403}
404
405