freedreno,u_trace: Fix various UBSAN errors

These are a handful of errors that pop up in UBSAN, a lot of them
depend on compiler-specific behavior such as zero-sized VLAs being
valid, while others plugged some potential bug prone code such as
nullptr derefs.

Signed-off-by: Dhruv Mark Collins <mark@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39662>
This commit is contained in:
Dhruv Mark Collins 2026-01-29 08:40:52 +00:00 committed by Marge Bot
parent ae41474d8c
commit e8fc50ef46
14 changed files with 64 additions and 29 deletions

View file

@ -233,20 +233,27 @@ fdl6_layout_image(struct fdl_layout *layout, const struct fd_dev_info *info,
uint32_t ubwc_width0 = params->width0;
uint32_t ubwc_height0 = params->height0;
uint32_t ubwc_tile_height_alignment = RGB_TILE_HEIGHT_ALIGNMENT;
if (params->mip_levels > 1) {
/* With mipmapping enabled, UBWC layout is power-of-two sized,
* specified in log2 width/height in the descriptors. The height
* alignment is 64 for mipmapping, but for buffer sharing (always
* single level) other participants expect 16.
*/
ubwc_width0 = util_next_power_of_two(params->width0);
ubwc_height0 = util_next_power_of_two(params->height0);
ubwc_tile_height_alignment = 64;
if (layout->ubwc) {
if (params->mip_levels > 1) {
/* With mipmapping enabled, UBWC layout is power-of-two sized,
* specified in log2 width/height in the descriptors. The height
* alignment is 64 for mipmapping, but for buffer sharing (always
* single level) other participants expect 16.
*/
ubwc_width0 = util_next_power_of_two(params->width0);
ubwc_height0 = util_next_power_of_two(params->height0);
ubwc_tile_height_alignment = 64;
}
layout->ubwc_width0 = align(DIV_ROUND_UP(ubwc_width0, ubwc_blockwidth),
RGB_TILE_WIDTH_ALIGNMENT);
ubwc_height0 = align(DIV_ROUND_UP(ubwc_height0, ubwc_blockheight),
ubwc_tile_height_alignment);
} else {
layout->ubwc_width0 = 0;
ubwc_height0 = 0;
layout->ubwc_layer_size = 0;
}
layout->ubwc_width0 = align(DIV_ROUND_UP(ubwc_width0, ubwc_blockwidth),
RGB_TILE_WIDTH_ALIGNMENT);
ubwc_height0 = align(DIV_ROUND_UP(ubwc_height0, ubwc_blockheight),
ubwc_tile_height_alignment);
uint32_t min_3d_layer_size = 0;
bool in_sparse_miptail = false;

View file

@ -1971,7 +1971,7 @@ ir3_valid_immediate(struct ir3_instruction *instr, int32_t immed)
}
/* Other than cat1 (mov) we can only encode up to 10 bits, sign-extended: */
return !(immed & ~0x1ff) || !(-immed & ~0x1ff);
return !(immed & ~0x1ff) || !(-(uint32_t)immed & ~0x1ff);
}
struct ir3_instruction *

View file

@ -5842,8 +5842,9 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
chsh->barrier_conflict = IR3_BARRIER_EVERYTHING;
} else {
assert((ctx->noutputs % 4) == 0);
unsigned outidxs[ctx->noutputs / 4];
struct ir3_instruction *outputs[ctx->noutputs / 4];
unsigned alloc_noutputs = ctx->noutputs == 0 ? 1 : ctx->noutputs / 4;
unsigned outidxs[alloc_noutputs];
struct ir3_instruction *outputs[alloc_noutputs];
unsigned outputs_count = 0;
struct ir3_block *b = ctx->block;

View file

@ -1304,6 +1304,11 @@ ir3_filter_vars_to_scratch_single_instr_limit(struct set *set, uint32_t limit,
util_dynarray_append(&candidate_nonspilled, var);
}
if (util_dynarray_num_elements(&candidate_nonspilled, const nir_variable *) == 0) {
util_dynarray_fini(&candidate_nonspilled);
return;
}
qsort(
util_dynarray_begin(&candidate_nonspilled),
util_dynarray_num_elements(&candidate_nonspilled, const nir_variable *),

View file

@ -856,8 +856,9 @@ ir3_nir_lower_preamble(nir_shader *nir, struct ir3_shader_variant *v)
unsigned preamble_size =
const_state->allocs.consts[IR3_CONST_ALLOC_PREAMBLE].size_vec4 * 4;
BITSET_DECLARE(promoted_to_float, preamble_size);
memset(promoted_to_float, 0, sizeof(promoted_to_float));
/* Avoid zero-size VLA. */
BITSET_DECLARE(promoted_to_float, preamble_size > 0 ? preamble_size : 1);
BITSET_ZERO(promoted_to_float);
nir_builder builder_main = nir_builder_create(main);
nir_builder *b = &builder_main;

View file

@ -391,6 +391,9 @@ propagate_parallelcopy(struct ra_val_ctx *ctx, struct ir3_instruction *pcopy)
size += reg_size(pcopy->srcs[i]);
}
if (size == 0)
return;
struct reg_state srcs[size];
unsigned offset = 0;

View file

@ -92,7 +92,7 @@ class Field(object):
val = var_name
elif self.type == "fixed":
type = "float"
val = "((int32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
val = "(uint32_t)((int32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
elif self.type == "ufixed":
type = "float"
val = "((uint32_t)(%s * %d.0))" % (var_name, 1 << self.radix)

View file

@ -8435,8 +8435,13 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
const struct tu_shader *tcs = cmd->state.shaders[MESA_SHADER_TESS_CTRL];
/* maximum number of patches that can fit in tess factor/param buffers */
uint32_t subdraw_size = MIN2(TU_TESS<CHIP>::FACTOR_SIZE / ir3_tess_factor_stride(tes->variant->key.tessellation),
TU_TESS<CHIP>::PARAM_SIZE / (tcs->variant->output_size * 4));
uint32_t subdraw_size =
tcs->variant->output_size != 0
? MIN2(
TU_TESS<CHIP>::FACTOR_SIZE /
ir3_tess_factor_stride(tes->variant->key.tessellation),
TU_TESS<CHIP>::PARAM_SIZE / (tcs->variant->output_size * 4))
: 0;
/* convert from # of patches to draw count */
subdraw_size *= cmd->vk.dynamic_graphics_state.ts.patch_control_points;

View file

@ -378,6 +378,7 @@ tu_cs_alloc(struct tu_cs *cs,
*/
memory->map = NULL;
memory->iova = 0xdead0000;
memory->writeable = false;
return VK_SUCCESS;
}

View file

@ -1336,8 +1336,9 @@ msm_queue_submit(struct tu_queue *queue, void *_submit,
* the memory required for page tables. Sort the entries to make sure
* that neighboring mappings are next to each other.
*/
qsort(submit->binds.data, nr_ops, sizeof(struct drm_msm_vm_bind_op),
compare_binds);
if (nr_ops > 1)
qsort(submit->binds.data, nr_ops, sizeof(struct drm_msm_vm_bind_op),
compare_binds);
u_rwlock_rdlock(&queue->device->vm_bind_fence_lock);

View file

@ -169,6 +169,9 @@ static void
tu_render_pass_add_implicit_deps(struct tu_render_pass *pass,
const VkRenderPassCreateInfo2 *info)
{
if (pass->attachment_count == 0)
return;
const VkAttachmentDescription2* att = info->pAttachments;
bool has_external_src[info->subpassCount];
bool has_external_dst[info->subpassCount];
@ -406,6 +409,9 @@ tu_render_pass_add_implicit_deps(struct tu_render_pass *pass,
static void
tu_render_pass_patch_input_gmem(struct tu_render_pass *pass)
{
if (pass->attachment_count == 0)
return;
bool written[pass->attachment_count];
memset(written, 0, sizeof(written));
@ -752,6 +758,9 @@ static void
tu_render_pass_gmem_config(struct tu_render_pass *pass,
const struct tu_physical_device *phys_dev)
{
if (pass->attachment_count == 0)
return;
for (enum tu_gmem_layout layout = (enum tu_gmem_layout) 0;
layout < TU_GMEM_LAYOUT_COUNT;
layout = (enum tu_gmem_layout)(layout + 1)) {

View file

@ -1280,9 +1280,9 @@ tu6_emit_patch_control_points(struct tu_cs *cs,
tcs->variant->tess.tcs_vertices_out);
}
uint32_t patches_per_wave =
MIN2(vs_hs_local_mem_size / (patch_local_mem_size_16b * 16),
max_patches_per_wave);
uint32_t patches_per_wave = patch_local_mem_size_16b == 0
? 0
: MIN2(vs_hs_local_mem_size / (patch_local_mem_size_16b * 16), max_patches_per_wave);
uint32_t wave_input_size = DIV_ROUND_UP(
patches_per_wave * patch_local_mem_size_16b * 16, 256);

View file

@ -2702,7 +2702,8 @@ tu_shader_init(struct tu_device *dev, const void *key_data, size_t key_size)
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE))
return NULL;
memcpy(obj_key_data, key_data, key_size);
if (key_size > 0)
memcpy(obj_key_data, key_data, key_size);
vk_pipeline_cache_object_init(&dev->vk, &shader->base,
&tu_shader_ops, obj_key_data, key_size);

View file

@ -958,8 +958,9 @@ u_trace_disable_event_range(struct u_trace_iterator begin_it,
list_entry(current_chunk->node.next, struct u_trace_chunk, node);
}
memset(&current_chunk->traces[start_idx], 0,
(end_it.event_idx - start_idx) * sizeof(struct u_trace_event));
if (current_chunk != NULL)
memset(&current_chunk->traces[start_idx], 0,
(end_it.event_idx - start_idx) * sizeof(struct u_trace_event));
}
/**