[naga spv-out] Let BoundsCheckResult supply the index value.

Let `BoundsCheckResult::Conditional` provide both the condition to
check before carrying out the access, and the index to use for that
access. The `Conditional` variant indicates that we generated a
runtime bounds check, which implies we must have had a SPIR-V id for
the index to pass to that check, so there's no reason not to provide
that to the callers - especially if the bounds check code was able to
reduce it to a known constant.

At the moment, this is not much of a refactor, but later commits will
use `GuardedIndex` in more places, at which point this will avoid a
re-matching and assertion.
This commit is contained in:
Jim Blandy 2024-10-01 10:59:30 -07:00
parent 69ab63ca34
commit 5a6b749335
2 changed files with 22 additions and 8 deletions

View File

@ -1935,11 +1935,14 @@ impl<'w> BlockContext<'w> {
Ok(self.writer.get_constant_scalar(scalar))
}
BoundsCheckResult::Computed(computed_index_id) => Ok(computed_index_id),
BoundsCheckResult::Conditional(comparison_id) => {
self.extend_bounds_check_condition_chain(accumulated_checks, comparison_id, block);
BoundsCheckResult::Conditional {
condition_id: condition,
index_id: index,
} => {
self.extend_bounds_check_condition_chain(accumulated_checks, condition, block);
// Use the index from the `Access` expression unchanged.
Ok(self.cached[index])
Ok(index)
}
}
}

View File

@ -40,7 +40,13 @@ pub(super) enum BoundsCheckResult {
///
/// This is returned when [`BoundsCheckPolicy::ReadZeroSkipWrite`]
/// is in force.
Conditional(Word),
Conditional {
/// The access should only be permitted if this value is true.
condition_id: Word,
/// The access should use this index value.
index_id: Word,
},
}
/// A value that we either know at translation time, or need to compute at runtime.
@ -431,7 +437,10 @@ impl<'w> BlockContext<'w> {
));
// Indicate that we did generate the check.
Ok(BoundsCheckResult::Conditional(condition_id))
Ok(BoundsCheckResult::Conditional {
condition_id,
index_id,
})
}
/// Emit a conditional load for `BoundsCheckPolicy::ReadZeroSkipWrite`.
@ -537,7 +546,6 @@ impl<'w> BlockContext<'w> {
let result_type_id = self.get_expression_type_id(&self.fun_info[expr_handle].ty);
let base_id = self.cached[base];
let index_id = self.cached[index];
let result_id = match self.write_bounds_check(base, index, block)? {
BoundsCheckResult::KnownInBounds(known_index) => {
@ -560,12 +568,15 @@ impl<'w> BlockContext<'w> {
));
result_id
}
BoundsCheckResult::Conditional(comparison_id) => {
BoundsCheckResult::Conditional {
condition_id,
index_id,
} => {
// Run-time bounds checks were required. Emit
// conditional load.
self.write_conditional_indexed_load(
result_type_id,
comparison_id,
condition_id,
block,
|id_gen, block| {
// The in-bounds path. Generate the access.