Skip to content

Commit b4decff

Browse files
authoredApr 19, 2024
Remove use of UB to keep UBSAN happy (#465)
1 parent 56395a6 commit b4decff

File tree

3 files changed

+31
-20
lines changed

3 files changed

+31
-20
lines changed
 

‎Source/astcenc_entry.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,7 @@ astcenc_error astcenc_decompress_image(
11671167
return ASTCENC_ERR_OUT_OF_MEM;
11681168
}
11691169

1170-
image_block blk;
1170+
image_block blk {};
11711171
blk.texel_count = static_cast<uint8_t>(block_x * block_y * block_z);
11721172

11731173
// Decode mode inferred from the output data type

‎Source/astcenc_internal.h

+18-14
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,10 @@ struct partition_info
326326
uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS];
327327

328328
/** @brief The partition of each texel in the block. */
329-
uint8_t partition_of_texel[BLOCK_MAX_TEXELS];
329+
ASTCENC_ALIGNAS uint8_t partition_of_texel[BLOCK_MAX_TEXELS];
330330

331331
/** @brief The list of texels in each partition. */
332-
uint8_t texels_of_partition[BLOCK_MAX_PARTITIONS][BLOCK_MAX_TEXELS];
332+
ASTCENC_ALIGNAS uint8_t texels_of_partition[BLOCK_MAX_PARTITIONS][BLOCK_MAX_TEXELS];
333333
};
334334

335335
/**
@@ -367,19 +367,19 @@ struct decimation_info
367367
* @brief The number of weights that contribute to each texel.
368368
* Value is between 1 and 4.
369369
*/
370-
uint8_t texel_weight_count[BLOCK_MAX_TEXELS];
370+
ASTCENC_ALIGNAS uint8_t texel_weight_count[BLOCK_MAX_TEXELS];
371371

372372
/**
373373
* @brief The weight index of the N weights that are interpolated for each texel.
374374
* Stored transposed to improve vectorization.
375375
*/
376-
uint8_t texel_weights_tr[4][BLOCK_MAX_TEXELS];
376+
ASTCENC_ALIGNAS uint8_t texel_weights_tr[4][BLOCK_MAX_TEXELS];
377377

378378
/**
379379
* @brief The bilinear contribution of the N weights that are interpolated for each texel.
380380
* Value is between 0 and 16, stored transposed to improve vectorization.
381381
*/
382-
uint8_t texel_weight_contribs_int_tr[4][BLOCK_MAX_TEXELS];
382+
ASTCENC_ALIGNAS uint8_t texel_weight_contribs_int_tr[4][BLOCK_MAX_TEXELS];
383383

384384
/**
385385
* @brief The bilinear contribution of the N weights that are interpolated for each texel.
@@ -388,13 +388,13 @@ struct decimation_info
388388
ASTCENC_ALIGNAS float texel_weight_contribs_float_tr[4][BLOCK_MAX_TEXELS];
389389

390390
/** @brief The number of texels that each stored weight contributes to. */
391-
uint8_t weight_texel_count[BLOCK_MAX_WEIGHTS];
391+
ASTCENC_ALIGNAS uint8_t weight_texel_count[BLOCK_MAX_WEIGHTS];
392392

393393
/**
394394
* @brief The list of texels that use a specific weight index.
395395
* Stored transposed to improve vectorization.
396396
*/
397-
uint8_t weight_texels_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
397+
ASTCENC_ALIGNAS uint8_t weight_texels_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
398398

399399
/**
400400
* @brief The bilinear contribution to the N texels that use each weight.
@@ -732,24 +732,28 @@ struct block_size_descriptor
732732
*
733733
* The @c data_[rgba] fields store the image data in an encoded SoA float form designed for easy
734734
* vectorization. Input data is converted to float and stored as values between 0 and 65535. LDR
735-
* data is stored as direct UNORM data, HDR data is stored as LNS data.
735+
* data is stored as direct UNORM data, HDR data is stored as LNS data. They are allocated SIMD
736+
* elements over-size to allow vectorized stores of unaligned and partial SIMD lanes (e.g. in a
737+
* 6x6x6 block the final row write will read elements 210-217 (vec8) or 214-217 (vec4), which is
738+
* two elements above the last real data element). The overspill values are never written to memory,
739+
* and would be benign, but the padding avoids hitting undefined behavior.
736740
*
737741
* The @c rgb_lns and @c alpha_lns fields that assigned a per-texel use of HDR are only used during
738742
* decompression. The current compressor will always use HDR endpoint formats when in HDR mode.
739743
*/
740744
struct image_block
741745
{
742746
/** @brief The input (compress) or output (decompress) data for the red color component. */
743-
ASTCENC_ALIGNAS float data_r[BLOCK_MAX_TEXELS];
747+
ASTCENC_ALIGNAS float data_r[BLOCK_MAX_TEXELS + ASTCENC_SIMD_WIDTH - 1];
744748

745749
/** @brief The input (compress) or output (decompress) data for the green color component. */
746-
ASTCENC_ALIGNAS float data_g[BLOCK_MAX_TEXELS];
750+
ASTCENC_ALIGNAS float data_g[BLOCK_MAX_TEXELS + ASTCENC_SIMD_WIDTH - 1];
747751

748752
/** @brief The input (compress) or output (decompress) data for the blue color component. */
749-
ASTCENC_ALIGNAS float data_b[BLOCK_MAX_TEXELS];
753+
ASTCENC_ALIGNAS float data_b[BLOCK_MAX_TEXELS + ASTCENC_SIMD_WIDTH - 1];
750754

751755
/** @brief The input (compress) or output (decompress) data for the alpha color component. */
752-
ASTCENC_ALIGNAS float data_a[BLOCK_MAX_TEXELS];
756+
ASTCENC_ALIGNAS float data_a[BLOCK_MAX_TEXELS + ASTCENC_SIMD_WIDTH - 1];
753757

754758
/** @brief The number of texels in the block. */
755759
uint8_t texel_count;
@@ -957,7 +961,7 @@ struct ASTCENC_ALIGNAS compression_working_buffers
957961
*
958962
* For two planes, second plane starts at @c WEIGHTS_PLANE2_OFFSET offsets.
959963
*/
960-
uint8_t dec_weights_uquant[WEIGHTS_MAX_BLOCK_MODES * BLOCK_MAX_WEIGHTS];
964+
ASTCENC_ALIGNAS uint8_t dec_weights_uquant[WEIGHTS_MAX_BLOCK_MODES * BLOCK_MAX_WEIGHTS];
961965

962966
/** @brief Error of the best encoding combination for each block mode. */
963967
ASTCENC_ALIGNAS float errors_of_best_combination[WEIGHTS_MAX_BLOCK_MODES];
@@ -1111,7 +1115,7 @@ struct symbolic_compressed_block
11111115
*
11121116
* If dual plane, the second plane starts at @c weights[WEIGHTS_PLANE2_OFFSET].
11131117
*/
1114-
uint8_t weights[BLOCK_MAX_WEIGHTS];
1118+
ASTCENC_ALIGNAS uint8_t weights[BLOCK_MAX_WEIGHTS];
11151119

11161120
/**
11171121
* @brief Get the weight quantization used by this block mode.

‎Source/astcenc_vecmathlib_none_4.h

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// ----------------------------------------------------------------------------
3-
// Copyright 2019-2023 Arm Limited
3+
// Copyright 2019-2024 Arm Limited
44
//
55
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
66
// use this file except in compliance with the License. You may obtain a copy
@@ -556,17 +556,24 @@ ASTCENC_SIMD_INLINE vmask4 operator>(vint4 a, vint4 b)
556556
*/
557557
template <int s> ASTCENC_SIMD_INLINE vint4 lsl(vint4 a)
558558
{
559-
return vint4(a.m[0] << s,
560-
a.m[1] << s,
561-
a.m[2] << s,
562-
a.m[3] << s);
559+
// Cast to unsigned to avoid shift in/out of sign bit undefined behavior
560+
unsigned int as0 = static_cast<unsigned int>(a.m[0]) << s;
561+
unsigned int as1 = static_cast<unsigned int>(a.m[1]) << s;
562+
unsigned int as2 = static_cast<unsigned int>(a.m[2]) << s;
563+
unsigned int as3 = static_cast<unsigned int>(a.m[3]) << s;
564+
565+
return vint4(static_cast<int>(as0),
566+
static_cast<int>(as1),
567+
static_cast<int>(as2),
568+
static_cast<int>(as3));
563569
}
564570

565571
/**
566572
* @brief Logical shift right.
567573
*/
568574
template <int s> ASTCENC_SIMD_INLINE vint4 lsr(vint4 a)
569575
{
576+
// Cast to unsigned to avoid shift in/out of sign bit undefined behavior
570577
unsigned int as0 = static_cast<unsigned int>(a.m[0]) >> s;
571578
unsigned int as1 = static_cast<unsigned int>(a.m[1]) >> s;
572579
unsigned int as2 = static_cast<unsigned int>(a.m[2]) >> s;

0 commit comments

Comments
 (0)
Please sign in to comment.