Skip to content

Commit 4738965

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

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

crates/rustc_codegen_spirv/src/builder/builder_methods.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,18 @@ 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+
.emit();
668+
}
669+
658670
// Determine if this GEP operation is effectively byte-level addressing.
659671
// This check is based on the *provided* input type `ty`. If `ty` is i8 or u8,
660672
// it suggests the caller intends to perform byte-offset calculations,
@@ -1972,6 +1984,21 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
19721984
ptr: Self::Value,
19731985
indices: &[Self::Value],
19741986
) -> Self::Value {
1987+
// HACK(eddyb) effectively a backport of this `gep [0, i]` -> `gep [i]`
1988+
// PR: https://github.com/rust-lang/rust/pull/134117 to even earlier
1989+
// nightlies - and that PR happens to remove the last GEP that can be
1990+
// emitted with any "structured" (struct/array) indices, beyond the
1991+
// "first index" (which acts as `<*T>::offset` aka "pointer arithmetic").
1992+
if let &[ptr_base_index, structured_index] = indices {
1993+
if self.builder.lookup_const_scalar(ptr_base_index) == Some(0) {
1994+
if let SpirvType::Array { element, .. } | SpirvType::RuntimeArray { element, .. } =
1995+
self.lookup_type(ty)
1996+
{
1997+
return self.maybe_inbounds_gep(element, ptr, &[structured_index], true);
1998+
}
1999+
}
2000+
}
2001+
19752002
self.maybe_inbounds_gep(ty, ptr, indices, true)
19762003
}
19772004

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)