mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-02 08:50:24 +01:00
util/rmq: Fix uninitialized read in preprocess
We were previously always reading table->width elements from the previous row in this loop, but we write fewer entries than that to the current row. Fix this by adjusting the element count. Fixes:0d07b86073("util: Add range_minimum_query") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14593 Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com> (cherry picked from commit4171161227) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39462>
This commit is contained in:
parent
3a24ffc6e9
commit
46130bc721
2 changed files with 27 additions and 2 deletions
|
|
@ -794,7 +794,7 @@
|
|||
"description": "util/rmq: Fix uninitialized read in preprocess",
|
||||
"nominated": true,
|
||||
"nomination_type": 2,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "0d07b86073342820196e00213f240158481f3b4a",
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -35,6 +35,13 @@ elementwise_minimum(uint32_t *restrict out,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given level (row) of the table, how many input values is the
|
||||
* minimum computed over?
|
||||
*
|
||||
* Each row of the table has (table->width - rmq_distance(level) + 1)
|
||||
* valid elements.
|
||||
*/
|
||||
static uint32_t
|
||||
rmq_distance(int32_t level)
|
||||
{
|
||||
|
|
@ -46,10 +53,18 @@ range_minimum_query_table_preprocess(struct range_minimum_query_table *table)
|
|||
{
|
||||
for (uint32_t i = 1; i < table->height; i++) {
|
||||
uint32_t in_distance = rmq_distance(i - 1);
|
||||
uint32_t out_distance = rmq_distance(i);
|
||||
uint32_t *in_row = table->table + table->width * (i - 1);
|
||||
uint32_t *out_row = table->table + table->width * i;
|
||||
/*
|
||||
* This reads elements [0, x) from in_row, where x is:
|
||||
* in_distance + table->width - out_distance + 1
|
||||
* in_distance + table->width - (2 * in_distance) + 1
|
||||
* table->width - in_distance + 1
|
||||
* which is the number of valid elements in in_row
|
||||
*/
|
||||
elementwise_minimum(out_row, in_row, in_row + in_distance,
|
||||
table->width - in_distance);
|
||||
table->width - out_distance + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +73,7 @@ range_minimum_query(struct range_minimum_query_table *const table,
|
|||
uint32_t left_idx, uint32_t right_idx)
|
||||
{
|
||||
assert(left_idx < right_idx);
|
||||
assert(right_idx <= table->width);
|
||||
const uint32_t distance = right_idx - left_idx;
|
||||
|
||||
uint32_t level = util_logbase2(distance);
|
||||
|
|
@ -65,6 +81,15 @@ range_minimum_query(struct range_minimum_query_table *const table,
|
|||
assert(distance < 2 * rmq_distance(level));
|
||||
assert(level < table->height);
|
||||
|
||||
/*
|
||||
* Since right_idx <= table->width by precondition, we know
|
||||
* right_idx - rmq_distance(level) <= table->width - rmq_distance(level)
|
||||
* right_idx - rmq_distance(level) < table->width - rmq_distance(level) + 1
|
||||
* which means that the read for `right` is in bounds.
|
||||
*
|
||||
* The read for `left` is then in bounds because
|
||||
* left_idx == right_idx - width <= right_idx - rmq_distance(level)
|
||||
*/
|
||||
uint32_t *const row = table->table + table->width * level;
|
||||
uint32_t left = row[left_idx];
|
||||
uint32_t right = row[right_idx - rmq_distance(level)];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue