interleave-mask.patch.txt

text/plain

Filename: interleave-mask.patch.txt
Type: text/plain
Part: 0
Message: Re: [PATCH] Hex-coding optimizations using SVE on ARM.
diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c
index 87126a003b3..db734481a60 100644
--- a/src/backend/utils/adt/encode.c
+++ b/src/backend/utils/adt/encode.c
@@ -315,6 +315,8 @@ static inline bool
 hex_decode_simd_helper(const Vector8 src, Vector8 *dst)
 {
 	Vector8		sub;
+	Vector8		mask_hi = vector8_interleave_low(vector8_zero(), vector8_broadcast(0x0f));
+	Vector8		mask_lo = vector8_interleave_low(vector8_broadcast(0x0f), vector8_zero());
 	Vector8		msk;
 	bool		ret;
 
@@ -332,9 +334,9 @@ hex_decode_simd_helper(const Vector8 src, Vector8 *dst)
 	*dst = vector8_issub(src, sub);
 	ret = !vector8_has_ge(*dst, 0x10);
 
-	msk = vector8_and(*dst, vector8_broadcast_u32(0x0f000f00));
+	msk = vector8_and(*dst, mask_hi);
 	msk = vector8_shift_right(msk, 8);
-	*dst = vector8_and(*dst, vector8_broadcast_u32(0x000f000f));
+	*dst = vector8_and(*dst, mask_lo);
 	*dst = vector8_shift_left(*dst, 4);
 	*dst = vector8_or(*dst, msk);
 	return ret;
diff --git a/src/include/port/simd.h b/src/include/port/simd.h
index 0261179e9e7..e316233b7aa 100644
--- a/src/include/port/simd.h
+++ b/src/include/port/simd.h
@@ -101,6 +101,17 @@ static inline Vector8 vector8_min(const Vector8 v1, const Vector8 v2);
 static inline Vector32 vector32_eq(const Vector32 v1, const Vector32 v2);
 #endif
 
+/* return a zeroed register */
+static inline Vector8
+vector8_zero()
+{
+#if defined(USE_SSE2)
+	return _mm_setzero_si128();
+#elif defined(USE_NEON)
+	return vmovq_n_u8(0);
+#endif
+}
+
 /*
  * Load a chunk of memory into the given vector.
  */
@@ -170,24 +181,6 @@ vector32_broadcast(const uint32 c)
 }
 #endif							/* ! USE_NO_SIMD */
 
-/*
- * Some compilers are picky about casts to the same underlying type, and others
- * are picky about implicit conversions with vector types.  This function does
- * the same thing as vector32_broadcast(), but it returns a Vector8 and is
- * carefully crafted to avoid compiler indigestion.
- */
-#ifndef USE_NO_SIMD
-static inline Vector8
-vector8_broadcast_u32(const uint32 c)
-{
-#ifdef USE_SSE2
-	return vector32_broadcast(c);
-#elif defined(USE_NEON)
-	return (Vector8) vector32_broadcast(c);
-#endif
-}
-#endif							/* ! USE_NO_SIMD */
-
 /*
  * Return true if any elements in the vector are equal to the given scalar.
  */
@@ -577,8 +570,9 @@ vector8_interleave_high(const Vector8 v1, const Vector8 v2)
 static inline Vector8
 vector8_pack_16(const Vector8 v1, const Vector8 v2)
 {
-	Vector32	mask PG_USED_FOR_ASSERTS_ONLY = vector32_broadcast(0xff00ff00);
+	Vector8		mask PG_USED_FOR_ASSERTS_ONLY;
 
+	mask = vector8_interleave_low(vector8_zero(), vector8_broadcast(0xff));
 	Assert(!vector8_has_ge(vector8_and(v1, mask), 1));
 	Assert(!vector8_has_ge(vector8_and(v2, mask), 1));
 #ifdef USE_SSE2