Skip to content

Commit c94db24

Browse files
committed
builder: backport rust-lang/rust#134117 ([0, i] -> [i] for array GEPs).
1 parent e3ecc57 commit c94db24

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

crates/rustc_codegen_spirv/src/builder/builder_methods.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
655655
// https://github.com/gpuweb/gpuweb/issues/33
656656
let (&ptr_base_index, indices) = combined_indices.split_first().unwrap();
657657

658+
// HACK(eddyb) this effectively removes any real support for GEPs with
659+
// any `indices` (beyond `ptr_base_index`), which should now be the case
660+
// across `rustc_codegen_ssa` (see also comment inside `inbounds_gep`).
661+
if !indices.is_empty() {
662+
self.fatal(format!(
663+
"[RUST-GPU BUG] `inbounds_gep` or `gep` called \
664+
with {} combined indices (expected only 1)",
665+
combined_indices.len(),
666+
));
667+
}
668+
658669
// Determine if this GEP operation is effectively byte-level addressing.
659670
// This check is based on the *provided* input type `ty`. If `ty` is i8 or u8,
660671
// it suggests the caller intends to perform byte-offset calculations,
@@ -1972,6 +1983,21 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
19721983
ptr: Self::Value,
19731984
indices: &[Self::Value],
19741985
) -> Self::Value {
1986+
// HACK(eddyb) effectively a backport of this `gep [0, i]` -> `gep [i]`
1987+
// PR: https://github.com/rust-lang/rust/pull/134117 to even earlier
1988+
// nightlies - and that PR happens to remove the last GEP that can be
1989+
// emitted with any "structured" (struct/array) indices, beyond the
1990+
// "first index" (which acts as `<*T>::offset` aka "pointer arithmetic").
1991+
if let &[ptr_base_index, structured_index] = indices {
1992+
if self.builder.lookup_const_scalar(ptr_base_index) == Some(0) {
1993+
if let SpirvType::Array { element, .. } | SpirvType::RuntimeArray { element, .. } =
1994+
self.lookup_type(ty)
1995+
{
1996+
return self.maybe_inbounds_gep(element, ptr, &[structured_index], true);
1997+
}
1998+
}
1999+
}
2000+
19752001
self.maybe_inbounds_gep(ty, ptr, indices, true)
19762002
}
19772003

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: error:0:0 - Result type (OpTypeArray) does not match the type that results from indexing into the composite (OpTypeArray).
2+
%67 = OpCompositeExtract %_arr_uint_uint_2 %49 0 0
3+
|
4+
= note: spirv-val failed
5+
= note: module `$TEST_BUILD_DIR/lang/issue-46.spv1.3`
6+
7+
error: aborting due to 1 previous error
8+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: error:0:0 - OpInBoundsAccessChain result type (OpTypeInt) does not match the type that results from indexing into the base <id> (OpTypeArray).
2+
%33 = OpInBoundsAccessChain %_ptr_StorageBuffer_uint %28 %uint_0
3+
|
4+
= note: spirv-val failed
5+
= note: module `$TEST_BUILD_DIR/storage_class/typed-buffer-simple.spv1.3`
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)