[AArch64] Also custom-lowering mismatched vector/f16 FCOPYSIGN.
[oota-llvm.git] / test / CodeGen / AArch64 / vector-fcopysign.ll
1 ; RUN: llc < %s -mtriple aarch64-apple-darwin | FileCheck %s
2
3 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
4
5 ;============ v1f32
6
7 ; WidenVecRes same
8 define <1 x float> @test_copysign_v1f32_v1f32(<1 x float> %a, <1 x float> %b) #0 {
9 ; CHECK-LABEL: test_copysign_v1f32_v1f32:
10 ; CHECK:       ; BB#0:
11 ; CHECK-NEXT:    movi.2s v2, #0x80, lsl #24
12 ; CHECK-NEXT:    bit.8b v0, v1, v2
13 ; CHECK-NEXT:    ret
14   %r = call <1 x float> @llvm.copysign.v1f32(<1 x float> %a, <1 x float> %b)
15   ret <1 x float> %r
16 }
17
18 ; WidenVecRes mismatched
19 define <1 x float> @test_copysign_v1f32_v1f64(<1 x float> %a, <1 x double> %b) #0 {
20 ; CHECK-LABEL: test_copysign_v1f32_v1f64:
21 ; CHECK:       ; BB#0:
22 ; CHECK-NEXT:    fcvt s1, d1
23 ; CHECK-NEXT:    movi.4s v2, #0x80, lsl #24
24 ; CHECK-NEXT:    bit.16b v0, v1, v2
25 ; CHECK-NEXT:    ret
26   %tmp0 = fptrunc <1 x double> %b to <1 x float>
27   %r = call <1 x float> @llvm.copysign.v1f32(<1 x float> %a, <1 x float> %tmp0)
28   ret <1 x float> %r
29 }
30
31 declare <1 x float> @llvm.copysign.v1f32(<1 x float> %a, <1 x float> %b) #0
32
33 ;============ v1f64
34
35 ; WidenVecOp #1
36 define <1 x double> @test_copysign_v1f64_v1f32(<1 x double> %a, <1 x float> %b) #0 {
37 ; CHECK-LABEL: test_copysign_v1f64_v1f32:
38 ; CHECK:       ; BB#0:
39 ; CHECK-NEXT:    fcvt d1, s1
40 ; CHECK-NEXT:    movi.2d v2, #0000000000000000
41 ; CHECK-NEXT:    fneg.2d v2, v2
42 ; CHECK-NEXT:    bit.16b v0, v1, v2
43 ; CHECK-NEXT:    ret
44   %tmp0 = fpext <1 x float> %b to <1 x double>
45   %r = call <1 x double> @llvm.copysign.v1f64(<1 x double> %a, <1 x double> %tmp0)
46   ret <1 x double> %r
47 }
48
49 define <1 x double> @test_copysign_v1f64_v1f64(<1 x double> %a, <1 x double> %b) #0 {
50 ; CHECK-LABEL: test_copysign_v1f64_v1f64:
51 ; CHECK:       ; BB#0:
52 ; CHECK-NEXT:    movi.2d v2, #0000000000000000
53 ; CHECK-NEXT:    fneg.2d v2, v2
54 ; CHECK-NEXT:    bit.16b v0, v1, v2
55 ; CHECK-NEXT:    ret
56   %r = call <1 x double> @llvm.copysign.v1f64(<1 x double> %a, <1 x double> %b)
57   ret <1 x double> %r
58 }
59
60 declare <1 x double> @llvm.copysign.v1f64(<1 x double> %a, <1 x double> %b) #0
61
62 ;============ v2f32
63
64 define <2 x float> @test_copysign_v2f32_v2f32(<2 x float> %a, <2 x float> %b) #0 {
65 ; CHECK-LABEL: test_copysign_v2f32_v2f32:
66 ; CHECK:       ; BB#0:
67 ; CHECK-NEXT:    movi.2s v2, #0x80, lsl #24
68 ; CHECK-NEXT:    bit.8b v0, v1, v2
69 ; CHECK-NEXT:    ret
70   %r = call <2 x float> @llvm.copysign.v2f32(<2 x float> %a, <2 x float> %b)
71   ret <2 x float> %r
72 }
73
74 define <2 x float> @test_copysign_v2f32_v2f64(<2 x float> %a, <2 x double> %b) #0 {
75 ; CHECK-LABEL: test_copysign_v2f32_v2f64:
76 ; CHECK:       ; BB#0:
77 ; CHECK-NEXT:    fcvtn v1.2s, v1.2d
78 ; CHECK-NEXT:    movi.2s v2, #0x80, lsl #24
79 ; CHECK-NEXT:    bit.8b v0, v1, v2
80 ; CHECK-NEXT:    ret
81   %tmp0 = fptrunc <2 x double> %b to <2 x float>
82   %r = call <2 x float> @llvm.copysign.v2f32(<2 x float> %a, <2 x float> %tmp0)
83   ret <2 x float> %r
84 }
85
86 declare <2 x float> @llvm.copysign.v2f32(<2 x float> %a, <2 x float> %b) #0
87
88 ;============ v4f32
89
90 define <4 x float> @test_copysign_v4f32_v4f32(<4 x float> %a, <4 x float> %b) #0 {
91 ; CHECK-LABEL: test_copysign_v4f32_v4f32:
92 ; CHECK:       ; BB#0:
93 ; CHECK-NEXT:    movi.4s v2, #0x80, lsl #24
94 ; CHECK-NEXT:    bit.16b v0, v1, v2
95 ; CHECK-NEXT:    ret
96   %r = call <4 x float> @llvm.copysign.v4f32(<4 x float> %a, <4 x float> %b)
97   ret <4 x float> %r
98 }
99
100 ; SplitVecOp #1
101 define <4 x float> @test_copysign_v4f32_v4f64(<4 x float> %a, <4 x double> %b) #0 {
102 ; CHECK-LABEL: test_copysign_v4f32_v4f64:
103 ; CHECK:       ; BB#0:
104 ; CHECK-NEXT:    mov s3, v0[1]
105 ; CHECK-NEXT:    mov d4, v1[1]
106 ; CHECK-NEXT:    movi.4s v5, #0x80, lsl #24
107 ; CHECK-NEXT:    fcvt s1, d1
108 ; CHECK-NEXT:    mov s6, v0[2]
109 ; CHECK-NEXT:    mov s7, v0[3]
110 ; CHECK-NEXT:    fcvt s16, d2
111 ; CHECK-NEXT:    bit.16b v0, v1, v5
112 ; CHECK-NEXT:    bit.16b v6, v16, v5
113 ; CHECK-NEXT:    fcvt s1, d4
114 ; CHECK-NEXT:    bit.16b v3, v1, v5
115 ; CHECK-NEXT:    mov d1, v2[1]
116 ; CHECK-NEXT:    fcvt s1, d1
117 ; CHECK-NEXT:    ins.s v0[1], v3[0]
118 ; CHECK-NEXT:    ins.s v0[2], v6[0]
119 ; CHECK-NEXT:    bit.16b v7, v1, v5
120 ; CHECK-NEXT:    ins.s v0[3], v7[0]
121 ; CHECK-NEXT:    ret
122   %tmp0 = fptrunc <4 x double> %b to <4 x float>
123   %r = call <4 x float> @llvm.copysign.v4f32(<4 x float> %a, <4 x float> %tmp0)
124   ret <4 x float> %r
125 }
126
127 declare <4 x float> @llvm.copysign.v4f32(<4 x float> %a, <4 x float> %b) #0
128
129 ;============ v2f64
130
131 define <2 x double> @test_copysign_v2f64_v232(<2 x double> %a, <2 x float> %b) #0 {
132 ; CHECK-LABEL: test_copysign_v2f64_v232:
133 ; CHECK:       ; BB#0:
134 ; CHECK-NEXT:    movi.2d v2, #0000000000000000
135 ; CHECK-NEXT:    fneg.2d v2, v2
136 ; CHECK-NEXT:    fcvtl v1.2d, v1.2s
137 ; CHECK-NEXT:    bit.16b v0, v1, v2
138 ; CHECK-NEXT:    ret
139   %tmp0 = fpext <2 x float> %b to <2 x double>
140   %r = call <2 x double> @llvm.copysign.v2f64(<2 x double> %a, <2 x double> %tmp0)
141   ret <2 x double> %r
142 }
143
144 define <2 x double> @test_copysign_v2f64_v2f64(<2 x double> %a, <2 x double> %b) #0 {
145 ; CHECK-LABEL: test_copysign_v2f64_v2f64:
146 ; CHECK:       ; BB#0:
147 ; CHECK-NEXT:    movi.2d v2, #0000000000000000
148 ; CHECK-NEXT:    fneg.2d v2, v2
149 ; CHECK-NEXT:    bit.16b v0, v1, v2
150 ; CHECK-NEXT:    ret
151   %r = call <2 x double> @llvm.copysign.v2f64(<2 x double> %a, <2 x double> %b)
152   ret <2 x double> %r
153 }
154
155 declare <2 x double> @llvm.copysign.v2f64(<2 x double> %a, <2 x double> %b) #0
156
157 ;============ v4f64
158
159 ; SplitVecRes mismatched
160 define <4 x double> @test_copysign_v4f64_v4f32(<4 x double> %a, <4 x float> %b) #0 {
161 ; CHECK-LABEL: test_copysign_v4f64_v4f32:
162 ; CHECK:       ; BB#0:
163 ; CHECK-NEXT:    movi.2d v3, #0000000000000000
164 ; CHECK-NEXT:    fcvtl2 v4.2d, v2.4s
165 ; CHECK-NEXT:    fcvtl v2.2d, v2.2s
166 ; CHECK-NEXT:    fneg.2d v3, v3
167 ; CHECK-NEXT:    bit.16b v1, v4, v3
168 ; CHECK-NEXT:    bit.16b v0, v2, v3
169 ; CHECK-NEXT:    ret
170   %tmp0 = fpext <4 x float> %b to <4 x double>
171   %r = call <4 x double> @llvm.copysign.v4f64(<4 x double> %a, <4 x double> %tmp0)
172   ret <4 x double> %r
173 }
174
175 ; SplitVecRes same
176 define <4 x double> @test_copysign_v4f64_v4f64(<4 x double> %a, <4 x double> %b) #0 {
177 ; CHECK-LABEL: test_copysign_v4f64_v4f64:
178 ; CHECK:       ; BB#0:
179 ; CHECK-NEXT:    movi.2d v4, #0000000000000000
180 ; CHECK-NEXT:    fneg.2d v4, v4
181 ; CHECK-NEXT:    bit.16b v0, v2, v4
182 ; CHECK-NEXT:    bit.16b v1, v3, v4
183 ; CHECK-NEXT:    ret
184   %r = call <4 x double> @llvm.copysign.v4f64(<4 x double> %a, <4 x double> %b)
185   ret <4 x double> %r
186 }
187
188 declare <4 x double> @llvm.copysign.v4f64(<4 x double> %a, <4 x double> %b) #0
189
190 attributes #0 = { nounwind }