-
Notifications
You must be signed in to change notification settings - Fork 61
Backport rust-lang/rust#134117 and allow only <*T>::offset
-like "GEPs".
#327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Builds with my project 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't fully ramped up on this code again, but I can't see anything wrong with it so far.
// HACK(eddyb) this effectively removes any real support for GEPs with | ||
// any `indices` (beyond `ptr_base_index`), which should now be the case | ||
// across `rustc_codegen_ssa` (see also comment inside `inbounds_gep`). | ||
// FIXME(eddyb) are the warning + fallback path even work keeping? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say delete it...this code is already convoluted enough.
(Each commit should be reviewed separately)
LLVM's
GetElementPointer
(akin to SPIR-VOpAccessChain
/OpPtrAccessChain
) was, for a long time, the main way to interact with pointers, as it could perform, in one go, all ofe.g.:
&(*(p: *Foo).add(i)).outer_field3[j].0.inner_field1[k].leaf_field2
, even today:continues to work, even in the "untyped pointer" world (i.e.
%p
having typeptr
instead ofFoo*
).However, both in LLVM itself, and in
rustc_codegen_llvm
, its patterns have been shrinking with time:gep [0 x %Type]
togep %Type
rust-lang/rust#134117encountered in (yet-unlanded) rustup: update to
nightly-2025-05-09
(~1.88) and Rust 2024 edition. #249And they're generally converging on
<*T>::offset
-like pointer arithmetic, whereT
is:[T; N]
or[T]
type<[T]>::get_unchecked(xs, i)
is&*(xs as *const [T] as *const T).add(i)
i8
/u8
for arbitrary byte offsettingstruct
fieldsT
s could go through byte offsetts by multiplying w/ the size ofT
, aka "stride", but having that multiplication in the IR is not (yet) on the table(even SPIR-T
qptr
uses a special "strided offset", even if it erases the specific typeT
)Instead of keeping the increasingly-gnarly
maybe_inbounds_gep
(see also e.g. #233 - a valiant effort at reconciling several of its conflicting needs), this PR moves the core logic to a new method,named
ptr_offset_strided
(suffixed_strided
to hopefully avoid confusion with the byte-orientedptradd
).By only handling
(p: *T).offset(i)
, no more, no less (i.e. no intra-T
offsetting), a lot of the decision logic/correctness subtleties/etc., vanish away, fixing edge cases like #233 (comment) without breaking theissue-46
test (which #233 itself first fixed).Sadly I wasn't able to keep a lot of the comments/
trace!
s added in #233, but I tried to have a bare minimum, combined with the continued existence of#[instrument]
on/trace!
in, several helper methods.EDIT: on top of "future
rustup
PRs", the SPIR-V validation error described in issue #323 appears to disappear on top of this PR (as reported in #323 (comment)) - so it's possible none of this code was ever bug-free.TODO: the last commit still needs some comments to be adjusted, after an unnecessary
pointercast
was removed (it was only ever needed due toformat_args!
).