xref: /llvm-project/llvm/test/CodeGen/ARM/fadd-select-fneg-combine.ll (revision e0ed0333f0fed2e73f805afd58b61176a87aa3ad)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=arm-- -mattr=+mve.fp < %s | FileCheck %s
3
4define float @fadd_select_fneg_fneg_f32(i32 %arg0, float %x, float %y, float %z) {
5; CHECK-LABEL: fadd_select_fneg_fneg_f32:
6; CHECK:       @ %bb.0:
7; CHECK-NEXT:    vmov s0, r2
8; CHECK-NEXT:    cmp r0, #0
9; CHECK-NEXT:    vmov s4, r1
10; CHECK-NEXT:    vmov s2, r3
11; CHECK-NEXT:    vseleq.f32 s0, s4, s0
12; CHECK-NEXT:    vsub.f32 s0, s2, s0
13; CHECK-NEXT:    vmov r0, s0
14; CHECK-NEXT:    bx lr
15  %cmp = icmp eq i32 %arg0, 0
16  %neg.x = fneg float %x
17  %neg.y  = fneg float %y
18  %select = select i1 %cmp, float %neg.x, float %neg.y
19  %add = fadd float %select, %z
20  ret float %add
21}
22
23define half @fadd_select_fneg_fneg_f16(i32 %arg0, half %x, half %y, half %z) {
24; CHECK-LABEL: fadd_select_fneg_fneg_f16:
25; CHECK:       @ %bb.0:
26; CHECK-NEXT:    vmov.f16 s0, r2
27; CHECK-NEXT:    cmp r0, #0
28; CHECK-NEXT:    vmov.f16 s2, r1
29; CHECK-NEXT:    vseleq.f16 s0, s2, s0
30; CHECK-NEXT:    vmov.f16 s2, r3
31; CHECK-NEXT:    vsub.f16 s0, s2, s0
32; CHECK-NEXT:    vmov r0, s0
33; CHECK-NEXT:    bx lr
34  %cmp = icmp eq i32 %arg0, 0
35  %neg.x = fneg half %x
36  %neg.y = fneg half %y
37  %select = select i1 %cmp, half %neg.x, half %neg.y
38  %add = fadd half %select, %z
39  ret half %add
40}
41
42define <2 x float> @fadd_select_fneg_fneg_v2f32(i32 %arg0, <2 x float> %x, <2 x float> %y, <2 x float> %z) {
43; CHECK-LABEL: fadd_select_fneg_fneg_v2f32:
44; CHECK:       @ %bb.0:
45; CHECK-NEXT:    add r1, sp, #24
46; CHECK-NEXT:    cmp r0, #0
47; CHECK-NEXT:    vldrw.u32 q0, [r1]
48; CHECK-NEXT:    beq .LBB2_2
49; CHECK-NEXT:  @ %bb.1: @ %select.false
50; CHECK-NEXT:    add r0, sp, #8
51; CHECK-NEXT:    vldrw.u32 q1, [r0]
52; CHECK-NEXT:    b .LBB2_3
53; CHECK-NEXT:  .LBB2_2:
54; CHECK-NEXT:    vmov d2, r2, r3
55; CHECK-NEXT:  .LBB2_3: @ %select.end
56; CHECK-NEXT:    vneg.f32 q1, q1
57; CHECK-NEXT:    vadd.f32 q0, q1, q0
58; CHECK-NEXT:    vmov r0, r1, d0
59; CHECK-NEXT:    vmov r2, r3, d1
60; CHECK-NEXT:    bx lr
61  %cmp = icmp eq i32 %arg0, 0
62  %neg.x = fneg <2 x float> %x
63  %neg.y  = fneg <2 x float> %y
64  %select = select i1 %cmp, <2 x float> %neg.x, <2 x float> %neg.y
65  %add = fadd <2 x float> %select, %z
66  ret <2 x float> %add
67}
68
69define <2 x half> @fadd_select_fneg_fneg_v2f16(i32 %arg0, <2 x half> %x, <2 x half> %y, <2 x half> %z) {
70; CHECK-LABEL: fadd_select_fneg_fneg_v2f16:
71; CHECK:       @ %bb.0:
72; CHECK-NEXT:    add r1, sp, #24
73; CHECK-NEXT:    cmp r0, #0
74; CHECK-NEXT:    vldrw.u32 q0, [r1]
75; CHECK-NEXT:    beq .LBB3_2
76; CHECK-NEXT:  @ %bb.1: @ %select.false
77; CHECK-NEXT:    add r0, sp, #8
78; CHECK-NEXT:    vldrw.u32 q1, [r0]
79; CHECK-NEXT:    b .LBB3_3
80; CHECK-NEXT:  .LBB3_2:
81; CHECK-NEXT:    vmov d2, r2, r3
82; CHECK-NEXT:  .LBB3_3: @ %select.end
83; CHECK-NEXT:    vneg.f16 q1, q1
84; CHECK-NEXT:    vadd.f16 q0, q1, q0
85; CHECK-NEXT:    vmov r0, r1, d0
86; CHECK-NEXT:    vmov r2, r3, d1
87; CHECK-NEXT:    bx lr
88  %cmp = icmp eq i32 %arg0, 0
89  %neg.x = fneg <2 x half> %x
90  %neg.y = fneg <2 x half> %y
91  %select = select i1 %cmp, <2 x half> %neg.x, <2 x half> %neg.y
92  %add = fadd <2 x half> %select, %z
93  ret <2 x half> %add
94}
95
96define float @fadd_select_fsub_fsub_f32(i32 %arg0, float %x, float %y, float %z) {
97; CHECK-LABEL: fadd_select_fsub_fsub_f32:
98; CHECK:       @ %bb.0:
99; CHECK-NEXT:    vmov.f32 s0, #2.000000e+00
100; CHECK-NEXT:    cmp r0, #0
101; CHECK-NEXT:    vmov s4, r2
102; CHECK-NEXT:    vmov s2, r1
103; CHECK-NEXT:    vmov s6, r3
104; CHECK-NEXT:    vsub.f32 s4, s4, s0
105; CHECK-NEXT:    vsub.f32 s0, s2, s0
106; CHECK-NEXT:    vseleq.f32 s0, s0, s4
107; CHECK-NEXT:    vadd.f32 s0, s0, s6
108; CHECK-NEXT:    vmov r0, s0
109; CHECK-NEXT:    bx lr
110  %cmp = icmp eq i32 %arg0, 0
111  %neg.x = fsub nsz float %x, 2.0
112  %neg.y  = fsub nsz float %y, 2.0
113  %select = select i1 %cmp, float %neg.x, float %neg.y
114  %add = fadd float %select, %z
115  ret float %add
116}
117
118define float @fneg_select_fmul_fmul_f32(i32 %arg0, float %x, float %y) {
119; CHECK-LABEL: fneg_select_fmul_fmul_f32:
120; CHECK:       @ %bb.0:
121; CHECK-NEXT:    vmov.f32 s0, #4.000000e+00
122; CHECK-NEXT:    cmp r0, #0
123; CHECK-NEXT:    vmov.f32 s2, #8.000000e+00
124; CHECK-NEXT:    vmov s4, r2
125; CHECK-NEXT:    vmov s6, r1
126; CHECK-NEXT:    vmul.f32 s0, s4, s0
127; CHECK-NEXT:    vmul.f32 s2, s6, s2
128; CHECK-NEXT:    vseleq.f32 s0, s2, s0
129; CHECK-NEXT:    vmov r0, s0
130; CHECK-NEXT:    eor r0, r0, #-2147483648
131; CHECK-NEXT:    bx lr
132  %cmp = icmp eq i32 %arg0, 0
133  %neg.x = fmul float %x, 8.0
134  %neg.y  = fmul float %y, 4.0
135  %select = select i1 %cmp, float %neg.x, float %neg.y
136  %neg = fneg float %select
137  ret float %neg
138}
139
140define half @fadd_select_fsub_fsub_f16(i32 %arg0, half %x, half %y, half %z) {
141; CHECK-LABEL: fadd_select_fsub_fsub_f16:
142; CHECK:       @ %bb.0:
143; CHECK-NEXT:    vmov.f16 s0, r2
144; CHECK-NEXT:    vmov.f16 s2, #2.000000e+00
145; CHECK-NEXT:    vmov.f16 s4, r1
146; CHECK-NEXT:    vsub.f16 s0, s0, s2
147; CHECK-NEXT:    vsub.f16 s2, s4, s2
148; CHECK-NEXT:    cmp r0, #0
149; CHECK-NEXT:    vseleq.f16 s0, s2, s0
150; CHECK-NEXT:    vmov.f16 s2, r3
151; CHECK-NEXT:    vadd.f16 s0, s0, s2
152; CHECK-NEXT:    vmov r0, s0
153; CHECK-NEXT:    bx lr
154  %cmp = icmp eq i32 %arg0, 0
155  %sub.x = fsub nsz half %x, 2.0
156  %sub.y  = fsub nsz half %y, 2.0
157  %select = select i1 %cmp, half %sub.x, half %sub.y
158  %add = fadd half %select, %z
159  ret half %add
160}
161
162define half @fneg_select_fmul_fmul_f16(i32 %arg0, half %x, half %y) {
163; CHECK-LABEL: fneg_select_fmul_fmul_f16:
164; CHECK:       @ %bb.0:
165; CHECK-NEXT:    vmov.f16 s0, r2
166; CHECK-NEXT:    vmov.f16 s2, #4.000000e+00
167; CHECK-NEXT:    vmul.f16 s0, s0, s2
168; CHECK-NEXT:    vmov.f16 s2, r1
169; CHECK-NEXT:    vmov.f16 s4, #8.000000e+00
170; CHECK-NEXT:    cmp r0, #0
171; CHECK-NEXT:    vmul.f16 s2, s2, s4
172; CHECK-NEXT:    vseleq.f16 s0, s2, s0
173; CHECK-NEXT:    vneg.f16 s0, s0
174; CHECK-NEXT:    vmov r0, s0
175; CHECK-NEXT:    bx lr
176  %cmp = icmp eq i32 %arg0, 0
177  %mul.x = fmul half %x, 8.0
178  %mul.y  = fmul half %y, 4.0
179  %select = select i1 %cmp, half %mul.x, half %mul.y
180  %neg = fneg half %select
181  ret half %neg
182}
183
184define half @fadd_select_fsub_arg_f16(i32 %arg0, half %x, half %y, half %z) {
185; CHECK-LABEL: fadd_select_fsub_arg_f16:
186; CHECK:       @ %bb.0:
187; CHECK-NEXT:    vmov.f16 s0, r1
188; CHECK-NEXT:    vmov.f16 s2, #-2.000000e+00
189; CHECK-NEXT:    vadd.f16 s0, s0, s2
190; CHECK-NEXT:    vmov.f16 s2, r2
191; CHECK-NEXT:    cmp r0, #0
192; CHECK-NEXT:    vseleq.f16 s0, s0, s2
193; CHECK-NEXT:    vmov.f16 s2, r3
194; CHECK-NEXT:    vadd.f16 s0, s0, s2
195; CHECK-NEXT:    vmov r0, s0
196; CHECK-NEXT:    bx lr
197  %cmp = icmp eq i32 %arg0, 0
198  %sub.x = fsub nsz half %x, 2.0
199  %select = select i1 %cmp, half %sub.x, half %y
200  %add = fadd half %select, %z
201  ret half %add
202}
203
204define half @fadd_select_arg_fsub_f16(i32 %arg0, half %x, half %y, half %z) {
205; CHECK-LABEL: fadd_select_arg_fsub_f16:
206; CHECK:       @ %bb.0:
207; CHECK-NEXT:    vmov.f16 s0, r2
208; CHECK-NEXT:    vmov.f16 s2, #-2.000000e+00
209; CHECK-NEXT:    vadd.f16 s0, s0, s2
210; CHECK-NEXT:    vmov.f16 s2, r1
211; CHECK-NEXT:    cmp r0, #0
212; CHECK-NEXT:    vseleq.f16 s0, s2, s0
213; CHECK-NEXT:    vmov.f16 s2, r3
214; CHECK-NEXT:    vadd.f16 s0, s0, s2
215; CHECK-NEXT:    vmov r0, s0
216; CHECK-NEXT:    bx lr
217  %cmp = icmp eq i32 %arg0, 0
218  %sub.y = fsub nsz half %y, 2.0
219  %select = select i1 %cmp, half %x, half %sub.y
220  %add = fadd half %select, %z
221  ret half %add
222}
223
224define half @fadd_select_fsub_select_f16(i32 %arg0, half %x, half %y, half %z) {
225; CHECK-LABEL: fadd_select_fsub_select_f16:
226; CHECK:       @ %bb.0:
227; CHECK-NEXT:    vmov.f16 s0, r1
228; CHECK-NEXT:    vmov.f16 s2, #2.000000e+00
229; CHECK-NEXT:    vsub.f16 s0, s0, s2
230; CHECK-NEXT:    vmov.f16 s4, r2
231; CHECK-NEXT:    cmp r0, #0
232; CHECK-NEXT:    vsub.f16 s2, s4, s2
233; CHECK-NEXT:    vseleq.f16 s0, s0, s4
234; CHECK-NEXT:    vseleq.f16 s0, s2, s0
235; CHECK-NEXT:    vmov.f16 s2, r3
236; CHECK-NEXT:    vadd.f16 s0, s0, s2
237; CHECK-NEXT:    vmov r0, s0
238; CHECK-NEXT:    bx lr
239  %cmp = icmp eq i32 %arg0, 0
240  %sub.x = fsub nsz half %x, 2.0
241  %sub.y = fsub nsz half %y, 2.0
242  %select0 = select i1 %cmp, half %sub.x, half %y
243  %select1 = select i1 %cmp, half %sub.y, half %select0
244  %add = fadd half %select1, %z
245  ret half %add
246}
247
248define half @fadd_select_fneg_negk_f16(i32 %arg0, half %x, half %y) {
249; CHECK-LABEL: fadd_select_fneg_negk_f16:
250; CHECK:       @ %bb.0:
251; CHECK-NEXT:    vmov.f16 s0, #4.000000e+00
252; CHECK-NEXT:    vmov.f16 s2, r1
253; CHECK-NEXT:    cmp r0, #0
254; CHECK-NEXT:    vseleq.f16 s0, s2, s0
255; CHECK-NEXT:    vmov.f16 s2, r2
256; CHECK-NEXT:    vsub.f16 s0, s2, s0
257; CHECK-NEXT:    vmov r0, s0
258; CHECK-NEXT:    bx lr
259  %cmp = icmp eq i32 %arg0, 0
260  %neg.x = fneg half %x
261  %select = select i1 %cmp, half %neg.x, half -4.0
262  %add = fadd half %select, %y
263  ret half %add
264}
265
266define half @fadd_select_fneg_posk_f16(i32 %arg0, half %x, half %y) {
267; CHECK-LABEL: fadd_select_fneg_posk_f16:
268; CHECK:       @ %bb.0:
269; CHECK-NEXT:    vmov.f16 s0, #-4.000000e+00
270; CHECK-NEXT:    vmov.f16 s2, r1
271; CHECK-NEXT:    cmp r0, #0
272; CHECK-NEXT:    vseleq.f16 s0, s2, s0
273; CHECK-NEXT:    vmov.f16 s2, r2
274; CHECK-NEXT:    vsub.f16 s0, s2, s0
275; CHECK-NEXT:    vmov r0, s0
276; CHECK-NEXT:    bx lr
277  %cmp = icmp eq i32 %arg0, 0
278  %neg.x = fneg half %x
279  %select = select i1 %cmp, half %neg.x, half 4.0
280  %add = fadd half %select, %y
281  ret half %add
282}
283
284define <8 x half> @fadd_vselect_fneg_posk_v8f16(<8 x i32> %arg0, <8 x half> %x, <8 x half> %y) {
285; CHECK-LABEL: fadd_vselect_fneg_posk_v8f16:
286; CHECK:       @ %bb.0:
287; CHECK-NEXT:    sub sp, sp, #16
288; CHECK-NEXT:    vmov d0, r0, r1
289; CHECK-NEXT:    add r0, sp, #16
290; CHECK-NEXT:    vmov d1, r2, r3
291; CHECK-NEXT:    vldrw.u32 q3, [r0]
292; CHECK-NEXT:    vcmp.i32 eq, q0, zr
293; CHECK-NEXT:    vmov.i8 q0, #0x0
294; CHECK-NEXT:    vmov.i8 q1, #0xff
295; CHECK-NEXT:    mov r0, sp
296; CHECK-NEXT:    vpsel q2, q1, q0
297; CHECK-NEXT:    vcmp.i32 eq, q3, zr
298; CHECK-NEXT:    vpsel q0, q1, q0
299; CHECK-NEXT:    vstrh.32 q2, [r0]
300; CHECK-NEXT:    vstrh.32 q0, [r0, #8]
301; CHECK-NEXT:    add r1, sp, #32
302; CHECK-NEXT:    vldrw.u32 q2, [r0]
303; CHECK-NEXT:    vldrw.u32 q0, [r1]
304; CHECK-NEXT:    vmov.i16 q1, #0xc400
305; CHECK-NEXT:    add r0, sp, #48
306; CHECK-NEXT:    vcmp.i16 ne, q2, zr
307; CHECK-NEXT:    vpsel q0, q0, q1
308; CHECK-NEXT:    vldrw.u32 q1, [r0]
309; CHECK-NEXT:    vsub.f16 q0, q1, q0
310; CHECK-NEXT:    vmov r0, r1, d0
311; CHECK-NEXT:    vmov r2, r3, d1
312; CHECK-NEXT:    add sp, sp, #16
313; CHECK-NEXT:    bx lr
314  %cmp = icmp eq <8 x i32> %arg0, zeroinitializer
315  %neg.x = fneg <8 x half> %x
316  %select = select <8 x i1> %cmp, <8 x half> %neg.x, <8 x half> <half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0, half 4.0>
317  %add = fadd <8 x half> %select, %y
318  ret <8 x half> %add
319}
320