1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s --mattr=+complxnum,+neon,+fullfp16 -o - | FileCheck %s
4 target triple = "aarch64"
6 ; Expected to not transform
7 define <2 x half> @complex_mul_v2f16(<2 x half> %a, <2 x half> %b) {
8 ; CHECK-LABEL: complex_mul_v2f16:
9 ; CHECK: // %bb.0: // %entry
10 ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
11 ; CHECK-NEXT: mov h2, v0.h[1]
12 ; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1
13 ; CHECK-NEXT: fmul h3, h0, v1.h[1]
14 ; CHECK-NEXT: fmul h2, h2, v1.h[1]
15 ; CHECK-NEXT: fmla h3, h1, v0.h[1]
16 ; CHECK-NEXT: fnmsub h0, h1, h0, h2
17 ; CHECK-NEXT: mov v0.h[1], v3.h[0]
18 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
21 %a.real = shufflevector <2 x half> %a, <2 x half> poison, <1 x i32> <i32 0>
22 %a.imag = shufflevector <2 x half> %a, <2 x half> poison, <1 x i32> <i32 1>
23 %b.real = shufflevector <2 x half> %b, <2 x half> poison, <1 x i32> <i32 0>
24 %b.imag = shufflevector <2 x half> %b, <2 x half> poison, <1 x i32> <i32 1>
25 %0 = fmul fast <1 x half> %b.imag, %a.real
26 %1 = fmul fast <1 x half> %b.real, %a.imag
27 %2 = fadd fast <1 x half> %1, %0
28 %3 = fmul fast <1 x half> %b.real, %a.real
29 %4 = fmul fast <1 x half> %a.imag, %b.imag
30 %5 = fsub fast <1 x half> %3, %4
31 %interleaved.vec = shufflevector <1 x half> %5, <1 x half> %2, <2 x i32> <i32 0, i32 1>
32 ret <2 x half> %interleaved.vec
35 ; Expected to transform
36 define <4 x half> @complex_mul_v4f16(<4 x half> %a, <4 x half> %b) {
37 ; CHECK-LABEL: complex_mul_v4f16:
38 ; CHECK: // %bb.0: // %entry
39 ; CHECK-NEXT: movi d2, #0000000000000000
40 ; CHECK-NEXT: fcmla v2.4h, v1.4h, v0.4h, #0
41 ; CHECK-NEXT: fcmla v2.4h, v1.4h, v0.4h, #90
42 ; CHECK-NEXT: fmov d0, d2
45 %a.real = shufflevector <4 x half> %a, <4 x half> poison, <2 x i32> <i32 0, i32 2>
46 %a.imag = shufflevector <4 x half> %a, <4 x half> poison, <2 x i32> <i32 1, i32 3>
47 %b.real = shufflevector <4 x half> %b, <4 x half> poison, <2 x i32> <i32 0, i32 2>
48 %b.imag = shufflevector <4 x half> %b, <4 x half> poison, <2 x i32> <i32 1, i32 3>
49 %0 = fmul fast <2 x half> %b.imag, %a.real
50 %1 = fmul fast <2 x half> %b.real, %a.imag
51 %2 = fadd fast <2 x half> %1, %0
52 %3 = fmul fast <2 x half> %b.real, %a.real
53 %4 = fmul fast <2 x half> %a.imag, %b.imag
54 %5 = fsub fast <2 x half> %3, %4
55 %interleaved.vec = shufflevector <2 x half> %5, <2 x half> %2, <4 x i32> <i32 0, i32 2, i32 1, i32 3>
56 ret <4 x half> %interleaved.vec
59 ; Expected to transform
60 define <8 x half> @complex_mul_v8f16(<8 x half> %a, <8 x half> %b) {
61 ; CHECK-LABEL: complex_mul_v8f16:
62 ; CHECK: // %bb.0: // %entry
63 ; CHECK-NEXT: movi v2.2d, #0000000000000000
64 ; CHECK-NEXT: fcmla v2.8h, v1.8h, v0.8h, #0
65 ; CHECK-NEXT: fcmla v2.8h, v1.8h, v0.8h, #90
66 ; CHECK-NEXT: mov v0.16b, v2.16b
69 %a.real = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
70 %a.imag = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
71 %b.real = shufflevector <8 x half> %b, <8 x half> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
72 %b.imag = shufflevector <8 x half> %b, <8 x half> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
73 %0 = fmul fast <4 x half> %b.imag, %a.real
74 %1 = fmul fast <4 x half> %b.real, %a.imag
75 %2 = fadd fast <4 x half> %1, %0
76 %3 = fmul fast <4 x half> %b.real, %a.real
77 %4 = fmul fast <4 x half> %a.imag, %b.imag
78 %5 = fsub fast <4 x half> %3, %4
79 %interleaved.vec = shufflevector <4 x half> %5, <4 x half> %2, <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7>
80 ret <8 x half> %interleaved.vec
83 ; Expected to transform
84 define <16 x half> @complex_mul_v16f16(<16 x half> %a, <16 x half> %b) {
85 ; CHECK-LABEL: complex_mul_v16f16:
86 ; CHECK: // %bb.0: // %entry
87 ; CHECK-NEXT: movi v4.2d, #0000000000000000
88 ; CHECK-NEXT: movi v5.2d, #0000000000000000
89 ; CHECK-NEXT: fcmla v5.8h, v2.8h, v0.8h, #0
90 ; CHECK-NEXT: fcmla v4.8h, v3.8h, v1.8h, #0
91 ; CHECK-NEXT: fcmla v5.8h, v2.8h, v0.8h, #90
92 ; CHECK-NEXT: fcmla v4.8h, v3.8h, v1.8h, #90
93 ; CHECK-NEXT: mov v0.16b, v5.16b
94 ; CHECK-NEXT: mov v1.16b, v4.16b
97 %a.real = shufflevector <16 x half> %a, <16 x half> poison, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
98 %a.imag = shufflevector <16 x half> %a, <16 x half> poison, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
99 %b.real = shufflevector <16 x half> %b, <16 x half> poison, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
100 %b.imag = shufflevector <16 x half> %b, <16 x half> poison, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
101 %0 = fmul fast <8 x half> %b.imag, %a.real
102 %1 = fmul fast <8 x half> %b.real, %a.imag
103 %2 = fadd fast <8 x half> %1, %0
104 %3 = fmul fast <8 x half> %b.real, %a.real
105 %4 = fmul fast <8 x half> %a.imag, %b.imag
106 %5 = fsub fast <8 x half> %3, %4
107 %interleaved.vec = shufflevector <8 x half> %5, <8 x half> %2, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
108 ret <16 x half> %interleaved.vec
111 ; Expected to transform
112 define <32 x half> @complex_mul_v32f16(<32 x half> %a, <32 x half> %b) {
113 ; CHECK-LABEL: complex_mul_v32f16:
114 ; CHECK: // %bb.0: // %entry
115 ; CHECK-NEXT: movi v16.2d, #0000000000000000
116 ; CHECK-NEXT: movi v17.2d, #0000000000000000
117 ; CHECK-NEXT: movi v18.2d, #0000000000000000
118 ; CHECK-NEXT: movi v19.2d, #0000000000000000
119 ; CHECK-NEXT: fcmla v16.8h, v4.8h, v0.8h, #0
120 ; CHECK-NEXT: fcmla v18.8h, v5.8h, v1.8h, #0
121 ; CHECK-NEXT: fcmla v17.8h, v7.8h, v3.8h, #0
122 ; CHECK-NEXT: fcmla v19.8h, v6.8h, v2.8h, #0
123 ; CHECK-NEXT: fcmla v16.8h, v4.8h, v0.8h, #90
124 ; CHECK-NEXT: fcmla v18.8h, v5.8h, v1.8h, #90
125 ; CHECK-NEXT: fcmla v17.8h, v7.8h, v3.8h, #90
126 ; CHECK-NEXT: fcmla v19.8h, v6.8h, v2.8h, #90
127 ; CHECK-NEXT: mov v0.16b, v16.16b
128 ; CHECK-NEXT: mov v1.16b, v18.16b
129 ; CHECK-NEXT: mov v3.16b, v17.16b
130 ; CHECK-NEXT: mov v2.16b, v19.16b
133 %a.real = shufflevector <32 x half> %a, <32 x half> poison, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
134 %a.imag = shufflevector <32 x half> %a, <32 x half> poison, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15, i32 17, i32 19, i32 21, i32 23, i32 25, i32 27, i32 29, i32 31>
135 %b.real = shufflevector <32 x half> %b, <32 x half> poison, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
136 %b.imag = shufflevector <32 x half> %b, <32 x half> poison, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15, i32 17, i32 19, i32 21, i32 23, i32 25, i32 27, i32 29, i32 31>
137 %0 = fmul fast <16 x half> %b.imag, %a.real
138 %1 = fmul fast <16 x half> %b.real, %a.imag
139 %2 = fadd fast <16 x half> %1, %0
140 %3 = fmul fast <16 x half> %b.real, %a.real
141 %4 = fmul fast <16 x half> %a.imag, %b.imag
142 %5 = fsub fast <16 x half> %3, %4
143 %interleaved.vec = shufflevector <16 x half> %5, <16 x half> %2, <32 x i32> <i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23, i32 8, i32 24, i32 9, i32 25, i32 10, i32 26, i32 11, i32 27, i32 12, i32 28, i32 13, i32 29, i32 14, i32 30, i32 15, i32 31>
144 ret <32 x half> %interleaved.vec