@@ -655,6 +655,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
655
655
// https://github.com/gpuweb/gpuweb/issues/33
656
656
let ( & ptr_base_index, indices) = combined_indices. split_first ( ) . unwrap ( ) ;
657
657
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
+
658
669
// Determine if this GEP operation is effectively byte-level addressing.
659
670
// This check is based on the *provided* input type `ty`. If `ty` is i8 or u8,
660
671
// it suggests the caller intends to perform byte-offset calculations,
@@ -1972,6 +1983,21 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
1972
1983
ptr : Self :: Value ,
1973
1984
indices : & [ Self :: Value ] ,
1974
1985
) -> 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
+
1975
2001
self . maybe_inbounds_gep ( ty, ptr, indices, true )
1976
2002
}
1977
2003
0 commit comments