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