Bug 276282 - vectorized code fails on powerpc64le: typedef __vector uint8_t __m128i; in the port misc/randomx
Summary: vectorized code fails on powerpc64le: typedef __vector uint8_t __m128i; in th...
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: misc (show other bugs)
Version: 15.0-CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-toolchain (Nobody)
URL: https://pkg-status.freebsd.org/foul2/...
Keywords:
Depends on:
Blocks:
 
Reported: 2024-01-12 20:41 UTC by Yuri Victorovich
Modified: 2024-01-12 23:35 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yuri Victorovich freebsd_committer freebsd_triage 2024-01-12 20:41:46 UTC
This code fails:
#elif defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) //sadly only POWER7 and newer will be able to use SIMD acceleration. Earlier processors cant use doubles or 64 bit integers with SIMD
#include <cstdint>
#include <stdexcept>
#include <cstdlib>
#include <altivec.h>
#undef vector
#undef pixel
#undef bool

typedef __vector uint8_t __m128i;
typedef __vector uint32_t __m128l;
typedef __vector int      __m128li;
typedef __vector uint64_t __m128ll;
typedef __vector double __m128d;


error:
In file included from /wrkdirs/usr/ports/misc/randomx/work/RandomX-1.2.1/src/bytecode_machine.cpp:29:
In file included from /wrkdirs/usr/ports/misc/randomx/work/RandomX-1.2.1/src/bytecode_machine.hpp:32:
/wrkdirs/usr/ports/misc/randomx/work/RandomX-1.2.1/src/intrin_portable.h:189:18: error: a type specifier is required for all declarations
typedef __vector uint8_t __m128i;
~~~~~~~~~~~~~~~~ ^



I don't know whether this code is valid, but based on the presence of #if defined(__PPC64__) - it likely is valid.

See the linked log URL for details.
Comment 1 Mark Millard 2024-01-12 21:08:01 UTC
Hmm. https://en.wikipedia.org/wiki/AltiVec reports:

QUOTE
In C++, the standard way of accessing AltiVec support is mutually exclusive with the use of the Standard Template Library vector<> class template due to the treatment of "vector" as a reserved word when the compiler does not implement the context-sensitive keyword version of vector. However, it may be possible to combine them using compiler-specific workarounds; for instance, in GCC one may do #undef vector to remove the vector keyword, and then use the GCC-specific __vector keyword in its place.
END QUOTE

The next message after what you report gives a clue:

/wrkdirs/usr/ports/misc/randomx/work/RandomX-1.2.1/src/intrin_portable.h:189:25: error: expected ';' after top level declarator
typedef __vector uint8_t __m128i;
                        ^
                        ;

In other words: __vector is not getting special handling but is
being treated as a fuyll type name of itself, leading to the
compiler expecting (not the codes intent):

typedef __vector uint8_t;

I do not know if clang has a mode supporting the __vector like GCC
for powerpc64* variations or not. Seems like GCC would tolerate the
non-C/C++-standard code. It might be interesting to check if GCC will
build the code.
Comment 2 Piotr Kubaj freebsd_committer freebsd_triage 2024-01-12 23:35:04 UTC
The following patch seems to work:\--- src/intrin_portable.h.orig  2024-01-12 23:32:27 UTC
+++ src/intrin_portable.h
@@ -186,11 +186,11 @@ FORCE_INLINE uint32_t rx_get_rounding_mode() {
 #undef pixel
 #undef bool

-typedef __vector uint8_t __m128i;
-typedef __vector uint32_t __m128l;
-typedef __vector int      __m128li;
-typedef __vector uint64_t __m128ll;
-typedef __vector double __m128d;
+typedef vector unsigned char __m128i;
+typedef vector unsigned int __m128l;
+typedef vector int      __m128li;
+typedef vector unsigned long long __m128ll;
+typedef vector double __m128d;

 typedef __m128i rx_vec_i128;
 typedef __m128d rx_vec_f128;
@@ -209,7 +209,7 @@ typedef union{
 #define rx_prefetch_t0(x)

 /* Splat 64-bit long long to 2 64-bit long longs */
-FORCE_INLINE __m128i vec_splat2sd (int64_t scalar)
+FORCE_INLINE __m128i vec_splat2sd (long long scalar)
 { return (__m128i) vec_splats (scalar); }

 FORCE_INLINE rx_vec_f128 rx_load_vec_f128(const double* pd) {