Skip to content

Commit bda4875

Browse files
authored
Enable gcc-c-torture suite for hexagon ; Add HVX test for hexagon (#205)
* Add HVX intrinsic test for Hexagon * Enable gcc torture suite for hexagon
1 parent 94ca491 commit bda4875

File tree

7 files changed

+404
-1
lines changed

7 files changed

+404
-1
lines changed

SingleSource/Regression/C/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
if(ARCH MATCHES "x86" OR ARCH MATCHES "riscv" OR
22
ARCH MATCHES "SystemZ" OR ARCH MATCHES "Mips" OR
33
ARCH MATCHES "AArch64" OR ARCH MATCHES "ARM" OR
4-
ARCH MATCHES "LoongArch")
4+
ARCH MATCHES "LoongArch" OR ARCH MATCHES "Hexagon")
55
add_subdirectory(gcc-c-torture)
66
endif()
77

SingleSource/Regression/C/gcc-c-torture/execute/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,20 @@ if(ARCH MATCHES "ARM")
337337
list(APPEND TestsToSkip ${ARMTestsToSkip})
338338
endif()
339339

340+
if(ARCH MATCHES "Hexagon")
341+
file(GLOB HexagonTestsToSkip CONFIGURE_DEPENDS
342+
990127-1.c
343+
alloca-1.c
344+
va-arg-22.c
345+
# No support for __int128 on Hexagon
346+
pr84748.c
347+
built-in-setjmp.c
348+
pr84521.c
349+
)
350+
351+
list(APPEND TestsToSkip ${HexagonTestsToSkip})
352+
endif()
353+
340354
# Darwin Test Blacklist
341355
if(TARGET_OS STREQUAL "Darwin")
342356
file(GLOB DarwinTestsToSkip CONFIGURE_DEPENDS

SingleSource/Regression/C/gcc-c-torture/execute/ieee/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ file(GLOB UnsupportedTests
1919
)
2020
list(APPEND TestsToSkip ${UnsupportedTests})
2121

22+
if(ARCH MATCHES "Hexagon")
23+
file(GLOB HexagonTestsToSkip
24+
CONFIGURE_DEPENDS
25+
fp-cmp-8.c
26+
fp-cmp-8f.c
27+
fp-cmp-8l.c
28+
pr38016.c
29+
pr50310.c
30+
)
31+
list(APPEND TestsToSkip ${HexagonTestsToSkip})
32+
endif()
33+
34+
2235
##
2336
## Tests that require extra CFLAGS in Clang
2437
##

SingleSource/UnitTests/Vector/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,7 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
5353
endif()
5454
endif()
5555
endif()
56+
if(ARCH STREQUAL "Hexagon")
57+
add_subdirectory(HVX)
58+
endif()
5659
llvm_singlesource(PREFIX "Vector-")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
list(APPEND CFLAGS -mhvx)
2+
list(APPEND CFLAGS -mv69)
3+
llvm_singlesource(PREFIX "Vector-HVX-")
Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
5+
#include <hexagon_types.h>
6+
#if !defined(__linux__)
7+
#include <hexagon_standalone.h>
8+
#endif
9+
10+
union ui32f {
11+
int32_t i;
12+
float f;
13+
};
14+
union ui16f16 {
15+
int16_t i;
16+
__fp16 f16;
17+
};
18+
19+
// 128 byte vectors
20+
#define VSIZE_BYTES 128
21+
#define VSIZE_WORDS VSIZE_BYTES / 4
22+
23+
void print_vector_words(HVX_Vector x) {
24+
for (int i = 0; i < VSIZE_WORDS; i++) {
25+
if (!(i % 8))
26+
printf("\n");
27+
printf("0x%08lx ", x[i]);
28+
}
29+
30+
printf("\n");
31+
}
32+
33+
//
34+
// Create vectors
35+
//
36+
37+
// create a vector of floats from a float
38+
static __attribute__((always_inline)) HVX_Vector
39+
create_sfv_from_sf(float value) {
40+
union ui32f cvt;
41+
cvt.f = value;
42+
HVX_Vector tmp = Q6_V_vsplat_R(cvt.i);
43+
return tmp;
44+
}
45+
46+
// create a vector of half floats from a float
47+
static __attribute__((always_inline)) HVX_Vector
48+
create_hfv_from_sf(float value) {
49+
__fp16 hf = value;
50+
union ui16f16 cvt;
51+
cvt.f16 = hf;
52+
HVX_Vector tmp = Q6_Vh_vsplat_R(cvt.i);
53+
return tmp;
54+
}
55+
56+
// create a vector of qf32's from a float
57+
static __attribute__((always_inline)) HVX_Vector
58+
create_qf32v_from_sf(float value) {
59+
HVX_Vector tmp =
60+
Q6_Vqf32_vadd_Vqf32Vsf(Q6_V_vsplat_R(0), create_sfv_from_sf(value));
61+
return tmp;
62+
}
63+
64+
// create a vector of qf16's from a float
65+
static __attribute__((always_inline)) HVX_Vector
66+
create_qf16v_from_sf(float value) {
67+
// create qf16 vector from hf
68+
HVX_Vector tmp =
69+
Q6_Vqf16_vadd_Vqf16Vhf(Q6_V_vsplat_R(0), create_hfv_from_sf(value));
70+
return tmp;
71+
}
72+
73+
//
74+
// Conversion vectors
75+
//
76+
77+
// convert qf32 vector to float vector
78+
static __attribute__((always_inline)) HVX_Vector
79+
convert_qf32v_to_fltv(HVX_Vector vect) {
80+
HVX_Vector tmp = Q6_Vsf_equals_Vqf32(vect);
81+
return tmp;
82+
}
83+
84+
// convert qf16 vector to half float vector
85+
static __attribute__((always_inline)) HVX_Vector
86+
convert_qf16v_to_hfv(HVX_Vector vect) {
87+
HVX_Vector tmp = Q6_Vhf_equals_Vqf16(vect);
88+
return tmp;
89+
}
90+
91+
//
92+
// Extraction routines
93+
//
94+
95+
// get lowest float from a vector of floats
96+
static __attribute__((always_inline)) float
97+
get_flt0_from_fltv(HVX_Vector vect) {
98+
union ui32f cvt;
99+
cvt.i = vect[0];
100+
return cvt.f;
101+
}
102+
103+
// get lowest float from a vector of qf32's
104+
static __attribute__((always_inline)) float
105+
get_flt0_from_qf32v(HVX_Vector vect) {
106+
union ui32f cvt;
107+
HVX_Vector tmp = convert_qf32v_to_fltv(vect);
108+
cvt.i = tmp[0];
109+
return cvt.f;
110+
}
111+
112+
// get lowest float from a vector of halfs
113+
static __attribute__((always_inline)) float
114+
get_flt0_from_halfv(HVX_Vector vect) {
115+
union ui16f16 cvt;
116+
cvt.i = (vect[0] & 0xffff);
117+
return (float)cvt.f16;
118+
}
119+
120+
// get lowest float from a vector of qf16's
121+
static __attribute__((always_inline)) float
122+
get_flt0_from_qf16v(HVX_Vector vect) {
123+
return get_flt0_from_halfv(convert_qf16v_to_hfv(vect));
124+
}
125+
126+
// get lowest float from a vector pair of qf32's
127+
static __attribute__((always_inline)) float
128+
get_flt0_from_qf32vp(HVX_VectorPair vect) {
129+
union ui32f cvt;
130+
HVX_Vector tmp = convert_qf32v_to_fltv(HEXAGON_HVX_GET_V0(vect));
131+
cvt.i = tmp[0];
132+
return cvt.f;
133+
}
134+
135+
int main(int argc, char **argv) {
136+
#if !defined(__linux__)
137+
SIM_ACQUIRE_HVX;
138+
SIM_SET_HVX_DOUBLE_MODE;
139+
#endif
140+
141+
// create 2 sf vectors in IEEE-754 format
142+
HVX_Vector v1 = create_sfv_from_sf(0.5);
143+
HVX_Vector v2 = create_sfv_from_sf(0.25);
144+
145+
// create 2 vectors in the qf32 format
146+
HVX_Vector v3 = create_qf32v_from_sf(0.5);
147+
HVX_Vector v4 = create_qf32v_from_sf(0.25);
148+
149+
printf("\nAdd intrinsics with a qf32 result\n");
150+
151+
// add the IEEE vectors into a qf32 vector
152+
HVX_Vector result1 = Q6_Vqf32_vadd_VsfVsf(v1, v2);
153+
printf("The sum of flt %f and flt %f is %f\n", get_flt0_from_fltv(v1),
154+
get_flt0_from_fltv(v2), get_flt0_from_qf32v(result1));
155+
156+
// add the qf32 vectors into a qf32 vector
157+
HVX_Vector result2 = Q6_Vqf32_vadd_Vqf32Vqf32(v3, v4);
158+
printf("The sum of qf32 %f and qf32 %f is %f\n", get_flt0_from_qf32v(v3),
159+
get_flt0_from_qf32v(v4), get_flt0_from_qf32v(result2));
160+
161+
// add a qf32 vector and an IEEE vector into a qf32 vector
162+
HVX_Vector result3 = Q6_Vqf32_vadd_Vqf32Vsf(v3, v2);
163+
printf("The sum of qf32 %f and flt %f is %f\n", get_flt0_from_qf32v(v3),
164+
get_flt0_from_fltv(v2), get_flt0_from_qf32v(result3));
165+
166+
printf("\nSubtract intrinsics with a qf32 result\n");
167+
168+
// subtract the IEEE vectors into a qf32 vector
169+
HVX_Vector result4 = Q6_Vqf32_vsub_VsfVsf(v1, v2);
170+
printf("The sum of flt %f and flt -%f is %f\n", get_flt0_from_fltv(v1),
171+
get_flt0_from_fltv(v2), get_flt0_from_qf32v(result4));
172+
173+
// add the qf32 vectors into a qf32 vector
174+
HVX_Vector result5 = Q6_Vqf32_vsub_Vqf32Vqf32(v3, v4);
175+
printf("The sum of qf32 %f and qf32 -%f is %f\n", get_flt0_from_qf32v(v3),
176+
get_flt0_from_qf32v(v4), get_flt0_from_qf32v(result5));
177+
178+
// add a qf32 vector and an IEEE vector into a qf32 vector
179+
HVX_Vector result6 = Q6_Vqf32_vsub_Vqf32Vsf(v3, v2);
180+
printf("The sum of qf32 %f and flt -%f is %f\n", get_flt0_from_qf32v(v3),
181+
get_flt0_from_fltv(v2), get_flt0_from_qf32v(result6));
182+
183+
printf("\nMultiply intrinsics with a qf32 result\n");
184+
185+
// multiply the IEEE vectors into a qf32 vector
186+
HVX_Vector result7 = Q6_Vqf32_vmpy_VsfVsf(v1, v2);
187+
printf("The result of flt %f * flt %f is %f\n", get_flt0_from_fltv(v1),
188+
get_flt0_from_fltv(v2), get_flt0_from_qf32v(result7));
189+
190+
// multiply the qf32 vectors into a qf32 vector
191+
HVX_Vector result8 = Q6_Vqf32_vmpy_Vqf32Vqf32(v3, v4);
192+
printf("The result of qf32 %f * qf32 %f is %f\n", get_flt0_from_qf32v(v3),
193+
get_flt0_from_qf32v(v4), get_flt0_from_qf32v(result8));
194+
195+
// create 2 half vectors in the IEEE-754 format
196+
HVX_Vector v5 = create_hfv_from_sf(0.5);
197+
HVX_Vector v6 = create_hfv_from_sf(0.25);
198+
199+
// create 2 vectors in the qf16 format
200+
HVX_Vector v7 = create_qf16v_from_sf(0.5);
201+
HVX_Vector v8 = create_qf16v_from_sf(0.25);
202+
203+
printf("\nAdd intrinsics with a qf16 result\n");
204+
205+
// add the IEEE hf vectors into a qf16 vector
206+
HVX_Vector result9 = Q6_Vqf16_vadd_VhfVhf(v5, v6);
207+
printf("The sum of hf %.3f and hf %.3f is %.3f\n",
208+
get_flt0_from_halfv(v5), get_flt0_from_halfv(v6),
209+
get_flt0_from_qf16v(result9));
210+
211+
// add the qf16 vectors into a qf16 vector
212+
HVX_Vector result10 = Q6_Vqf16_vadd_Vqf16Vqf16(v7, v8);
213+
printf("The sum of qf16 %.3f and qf16 %.3f is %.3f\n",
214+
get_flt0_from_qf16v(v7), get_flt0_from_qf16v(v8),
215+
get_flt0_from_qf16v(result10));
216+
217+
// add a qf16 vector and an IEEE hf vector into a qf16 vector
218+
HVX_Vector result11 = Q6_Vqf16_vadd_Vqf16Vhf(v7, v6);
219+
printf("The sum of qf16 %.3f and hf %.3f is %.3f\n",
220+
get_flt0_from_qf16v(v7), get_flt0_from_halfv(v6),
221+
get_flt0_from_qf16v(result11));
222+
223+
printf("\nSubtract intrinsics with a qf16 result\n");
224+
225+
// add the IEEE hf vectors into a qf16 vector
226+
HVX_Vector result12 = Q6_Vqf16_vsub_VhfVhf(v5, v6);
227+
printf("The sum of hf %.3f and hf -%.3f is %.3f\n",
228+
get_flt0_from_halfv(v5), get_flt0_from_halfv(v6),
229+
get_flt0_from_qf16v(result12));
230+
231+
// add the qf16 vectors into a qf16 vector
232+
HVX_Vector result13 = Q6_Vqf16_vsub_Vqf16Vqf16(v7, v8);
233+
printf("The sum of qf16 %.3f and qf16 -%.3f is %.3f\n",
234+
get_flt0_from_qf16v(v7), get_flt0_from_qf16v(v8),
235+
get_flt0_from_qf16v(result13));
236+
237+
// add a qf16 vector and an IEEE hf vector into a qf16 vector
238+
HVX_Vector result14 = Q6_Vqf16_vsub_Vqf16Vhf(v7, v6);
239+
printf("The sum of qf16 %.3f and hf -%.3f is %.3f\n",
240+
get_flt0_from_qf16v(v7), get_flt0_from_halfv(v6),
241+
get_flt0_from_qf16v(result14));
242+
243+
printf("\nMultiply intrinsics with a qf16 result\n");
244+
245+
// multiply the IEEE hf vectors into a qf16 vector
246+
HVX_Vector result15 = Q6_Vqf16_vmpy_VhfVhf(v5, v6);
247+
printf("The result of hf %.3f * hf %.3f is %.3f\n",
248+
get_flt0_from_halfv(v5), get_flt0_from_halfv(v6),
249+
get_flt0_from_qf16v(result15));
250+
251+
// multiply the qf16 vectors into a qf16 vector
252+
HVX_Vector result16 = Q6_Vqf16_vmpy_Vqf16Vqf16(v7, v8);
253+
printf("The result of qf16 %.3f * qf16 %.3f is %.3f\n",
254+
get_flt0_from_qf16v(v7), get_flt0_from_qf16v(v8),
255+
get_flt0_from_qf16v(result16));
256+
257+
// multiply the qf16 vector with a hf vector into a qf16 vector
258+
HVX_Vector result17 = Q6_Vqf16_vmpy_Vqf16Vhf(v7, v6);
259+
printf("The result of qf16 %.3f * hf %.3f is %.3f\n",
260+
get_flt0_from_qf16v(v7), get_flt0_from_halfv(v6),
261+
get_flt0_from_qf16v(result17));
262+
263+
// multiply with pair results
264+
265+
printf("\nMultiply hf/qf16 intrinsics with a qf32 result\n");
266+
267+
// multiply the IEEE hf vectors into a qf32 vector pair
268+
HVX_VectorPair result18 = Q6_Wqf32_vmpy_VhfVhf(v5, v6);
269+
printf("The result of hf %.3f * hf %.3f is %.3f\n",
270+
get_flt0_from_halfv(v5), get_flt0_from_halfv(v6),
271+
get_flt0_from_qf32vp(result18));
272+
273+
// multiply the qf16 vectors into a qf32 vector pair
274+
HVX_VectorPair result19 = Q6_Wqf32_vmpy_Vqf16Vqf16(v7, v8);
275+
printf("The result of qf16 %.3f * qf16 %.3f is %.3f\n",
276+
get_flt0_from_qf16v(v7), get_flt0_from_qf16v(v8),
277+
get_flt0_from_qf32vp(result19));
278+
279+
// multiply the qf16 vector with a hf vector into a qf32 vector
280+
HVX_VectorPair result20 = Q6_Wqf32_vmpy_Vqf16Vhf(v7, v6);
281+
printf("The result of qf16 %.3f * hf %.3f is %.3f\n",
282+
get_flt0_from_qf16v(v7), get_flt0_from_halfv(v6),
283+
get_flt0_from_qf32vp(result20));
284+
285+
// create_qf32v_from_qf16v(HVX_Vector qf16)
286+
287+
printf("\nCompare instrinsics\n");
288+
289+
// compare 2 single float vectors
290+
HVX_VectorPred Pred = Q6_Q_vcmp_gt_VsfVsf(v1, v2);
291+
292+
// sum the bits
293+
HVX_Vector sum = Q6_Vw_prefixsum_Q(Pred);
294+
printf("The sum of the predicate bits from the sf compare is %ld\n", sum[31]);
295+
296+
// compare 2 half float vectors
297+
Pred = Q6_Q_vcmp_gt_VhfVhf(v5, v6);
298+
299+
// sum the bits
300+
sum = Q6_Vh_prefixsum_Q(Pred);
301+
printf("The sum of the predicate bits from the hf compare is %ld\n",
302+
sum[31] >> 16);
303+
304+
printf("\nMin/Max instrinsics\n");
305+
306+
// get a vector that is the max of 2 sf vectors
307+
HVX_Vector sfmax = Q6_Vsf_vmax_VsfVsf(v1, v2);
308+
printf("The max value of sf v1 and sf v2 is %f\n", get_flt0_from_fltv(sfmax));
309+
310+
// get a vector that is the min of 2 sf vectors
311+
HVX_Vector sfmin = Q6_Vsf_vmin_VsfVsf(v1, v2);
312+
printf("The min value of sf v1 and sf v2 is %f\n", get_flt0_from_fltv(sfmin));
313+
314+
// get a vector that is the max of 2 hf vectors
315+
HVX_Vector hfmax = Q6_Vhf_vmax_VhfVhf(v5, v6);
316+
printf("The max value of hf v5 and sf v6 is %f\n",
317+
get_flt0_from_halfv(hfmax));
318+
319+
// get a vector that is the min of 2 hf vectors
320+
HVX_Vector hfmin = Q6_Vhf_vmin_VhfVhf(v5, v6);
321+
printf("The min value of hf v5 and sf v6 is %f\n",
322+
get_flt0_from_halfv(hfmin));
323+
324+
return 0;
325+
}

0 commit comments

Comments
 (0)