@@ -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
0 commit comments