Skip to content

Commit 2c3f23b

Browse files
committed
fix dereferencing type-punned pointer error
1 parent 40f64f3 commit 2c3f23b

1 file changed

Lines changed: 64 additions & 58 deletions

File tree

lib/compress/zstd_compress.c

Lines changed: 64 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7287,7 +7287,7 @@ static size_t convertSequences_noRepcodes(
72877287
#elif defined ZSTD_ARCH_RISCV_RVV
72887288
#include <riscv_vector.h>
72897289
/*
7290-
* Convert `vl` sequences per iteration, using AVX2 intrinsics:
7290+
* Convert `vl` sequences per iteration, using RVV intrinsics:
72917291
* - offset -> offBase = offset + 2
72927292
* - litLength -> (U16) litLength
72937293
* - matchLength -> (U16)(matchLength - 3)
@@ -7300,7 +7300,8 @@ static size_t convertSequences_noRepcodes(
73007300
*/
73017301
static size_t convertSequences_noRepcodes(SeqDef* dstSeqs, const ZSTD_Sequence* inSeqs, size_t nbSequences) {
73027302
size_t longLen = 0;
7303-
7303+
size_t vl = 0;
7304+
typedef uint32_t __attribute__((may_alias)) aliased_u32;
73047305
/* RVV depends on the specific definition of target structures */
73057306
ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
73067307
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, offset) == 0);
@@ -7310,62 +7311,68 @@ static size_t convertSequences_noRepcodes(SeqDef* dstSeqs, const ZSTD_Sequence*
73107311
ZSTD_STATIC_ASSERT(offsetof(SeqDef, offBase) == 0);
73117312
ZSTD_STATIC_ASSERT(offsetof(SeqDef, litLength) == 4);
73127313
ZSTD_STATIC_ASSERT(offsetof(SeqDef, mlBase) == 6);
7313-
size_t vl = 0;
7314+
73147315
for (size_t i = 0; i < nbSequences; i += vl) {
73157316

7316-
vl = __riscv_vsetvl_e32m2(nbSequences-i);
7317-
// Loading structure member variables
7318-
vuint32m2x4_t v_tuple = __riscv_vlseg4e32_v_u32m2x4(
7319-
(const int32_t*)&inSeqs[i],
7320-
vl
7321-
);
7322-
vuint32m2_t v_offset = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 0);
7323-
vuint32m2_t v_lit = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 1);
7324-
vuint32m2_t v_match = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 2);
7325-
// offset + ZSTD_REP_NUM
7326-
vuint32m2_t v_offBase = __riscv_vadd_vx_u32m2(v_offset, ZSTD_REP_NUM, vl);
7327-
// Check for integer overflow
7328-
// Cast to a 16-bit variable
7329-
vbool16_t lit_overflow = __riscv_vmsgtu_vx_u32m2_b16(v_lit, 65535, vl);
7330-
vuint16m1_t v_lit_clamped = __riscv_vncvt_x_x_w_u16m1(v_lit, vl);
7331-
7332-
vbool16_t ml_overflow = __riscv_vmsgtu_vx_u32m2_b16(v_match, 65535+MINMATCH, vl);
7333-
vuint16m1_t v_ml_clamped = __riscv_vncvt_x_x_w_u16m1(__riscv_vsub_vx_u32m2(v_match, MINMATCH, vl), vl);
7334-
7335-
// Pack two 16-bit fields into a 32-bit value (little-endian)
7336-
// The lower 16 bits contain litLength, and the upper 16 bits contain mlBase
7337-
vuint32m2_t v_lit_ml_combined = __riscv_vsll_vx_u32m2(
7338-
__riscv_vwcvtu_x_x_v_u32m2(v_ml_clamped, vl), // Convert matchLength to 32-bit
7339-
16,
7340-
vl
7341-
);
7342-
v_lit_ml_combined = __riscv_vor_vv_u32m2(
7343-
v_lit_ml_combined,
7344-
__riscv_vwcvtu_x_x_v_u32m2(v_lit_clamped, vl),
7345-
vl
7346-
);
7347-
// Create a vector of SeqDef structures
7348-
// Store the offBase, litLength, and mlBase in a vector of SeqDef
7349-
vuint32m2x2_t store_data = __riscv_vcreate_v_u32m2x2(
7350-
v_offBase,
7351-
v_lit_ml_combined
7352-
);
7353-
__riscv_vsseg2e32_v_u32m2x2(
7354-
(uint32_t*)&dstSeqs[i],
7355-
store_data,
7356-
vl
7357-
);
7358-
// Find the first index where an overflow occurs
7359-
int first_ml = __riscv_vfirst_m_b16(ml_overflow, vl);
7360-
int first_lit = __riscv_vfirst_m_b16(lit_overflow, vl);
7317+
vl = __riscv_vsetvl_e32m2(nbSequences-i);
7318+
{
7319+
// Loading structure member variables
7320+
vuint32m2x4_t v_tuple = __riscv_vlseg4e32_v_u32m2x4(
7321+
(const aliased_u32*)((const void*)&inSeqs[i]),
7322+
vl
7323+
);
7324+
vuint32m2_t v_offset = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 0);
7325+
vuint32m2_t v_lit = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 1);
7326+
vuint32m2_t v_match = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 2);
7327+
// offset + ZSTD_REP_NUM
7328+
vuint32m2_t v_offBase = __riscv_vadd_vx_u32m2(v_offset, ZSTD_REP_NUM, vl);
7329+
// Check for integer overflow
7330+
// Cast to a 16-bit variable
7331+
vbool16_t lit_overflow = __riscv_vmsgtu_vx_u32m2_b16(v_lit, 65535, vl);
7332+
vuint16m1_t v_lit_clamped = __riscv_vncvt_x_x_w_u16m1(v_lit, vl);
7333+
7334+
vbool16_t ml_overflow = __riscv_vmsgtu_vx_u32m2_b16(v_match, 65535+MINMATCH, vl);
7335+
vuint16m1_t v_ml_clamped = __riscv_vncvt_x_x_w_u16m1(__riscv_vsub_vx_u32m2(v_match, MINMATCH, vl), vl);
7336+
7337+
// Pack two 16-bit fields into a 32-bit value (little-endian)
7338+
// The lower 16 bits contain litLength, and the upper 16 bits contain mlBase
7339+
vuint32m2_t v_lit_ml_combined = __riscv_vsll_vx_u32m2(
7340+
__riscv_vwcvtu_x_x_v_u32m2(v_ml_clamped, vl), // Convert matchLength to 32-bit
7341+
16,
7342+
vl
7343+
);
7344+
v_lit_ml_combined = __riscv_vor_vv_u32m2(
7345+
v_lit_ml_combined,
7346+
__riscv_vwcvtu_x_x_v_u32m2(v_lit_clamped, vl),
7347+
vl
7348+
);
7349+
{
7350+
// Create a vector of SeqDef structures
7351+
// Store the offBase, litLength, and mlBase in a vector of SeqDef
7352+
vuint32m2x2_t store_data = __riscv_vcreate_v_u32m2x2(
7353+
v_offBase,
7354+
v_lit_ml_combined
7355+
);
7356+
__riscv_vsseg2e32_v_u32m2x2(
7357+
(aliased_u32*)((void*)&dstSeqs[i]),
7358+
store_data,
7359+
vl
7360+
);
7361+
}
7362+
{
7363+
// Find the first index where an overflow occurs
7364+
int first_ml = __riscv_vfirst_m_b16(ml_overflow, vl);
7365+
int first_lit = __riscv_vfirst_m_b16(lit_overflow, vl);
73617366

7362-
if (UNLIKELY(first_ml != -1)) {
7363-
assert(longLen == 0);
7364-
longLen = i + first_ml + 1;
7365-
}
7366-
if (UNLIKELY(first_lit != -1)) {
7367-
assert(longLen == 0);
7368-
longLen = i + first_lit + 1 + nbSequences;
7367+
if (UNLIKELY(first_ml != -1)) {
7368+
assert(longLen == 0);
7369+
longLen = i + first_ml + 1;
7370+
}
7371+
if (UNLIKELY(first_lit != -1)) {
7372+
assert(longLen == 0);
7373+
longLen = i + first_lit + 1 + nbSequences;
7374+
}
7375+
}
73697376
}
73707377
}
73717378
return longLen;
@@ -7547,18 +7554,17 @@ BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
75477554
size_t i = 0;
75487555
int found_terminator = 0;
75497556
size_t vl_max = __riscv_vsetvlmax_e32m1();
7557+
typedef uint32_t __attribute__((may_alias)) aliased_u32;
75507558
vuint32m1_t v_lit_sum = __riscv_vmv_v_x_u32m1(0, vl_max);
75517559
vuint32m1_t v_match_sum = __riscv_vmv_v_x_u32m1(0, vl_max);
75527560

75537561
for (; i < nbSeqs; ) {
75547562
size_t vl = __riscv_vsetvl_e32m2(nbSeqs - i);
75557563

7556-
ptrdiff_t stride = sizeof(ZSTD_Sequence); // 16
75577564
vuint32m2x4_t v_tuple = __riscv_vlseg4e32_v_u32m2x4(
7558-
(const int32_t*)&seqs[i],
7565+
(const aliased_u32*)((const void*)&seqs[i]),
75597566
vl
75607567
);
7561-
vuint32m2_t v_offset = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 0);
75627568
vuint32m2_t v_lit = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 1);
75637569
vuint32m2_t v_match = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 2);
75647570

0 commit comments

Comments
 (0)