@@ -655,6 +655,18 @@ 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
+ . emit ( ) ;
668
+ }
669
+
658
670
// Determine if this GEP operation is effectively byte-level addressing.
659
671
// This check is based on the *provided* input type `ty`. If `ty` is i8 or u8,
660
672
// it suggests the caller intends to perform byte-offset calculations,
@@ -1972,6 +1984,21 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
1972
1984
ptr : Self :: Value ,
1973
1985
indices : & [ Self :: Value ] ,
1974
1986
) -> 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
+
1975
2002
self . maybe_inbounds_gep ( ty, ptr, indices, true )
1976
2003
}
1977
2004
0 commit comments