core: support odd-bit primitive integers, add Core.bitsizeof#61359
core: support odd-bit primitive integers, add Core.bitsizeof#61359fingolfin wants to merge 19 commits into
Conversation
|
Thanks for working on this, this would be a great feature. |
|
Thanks for starting this initiative. Not sure how useful this is to you, but I went ahead and spun up a bot to explore an implementation for #61361 along with this change: 8a8a6ac That commit also punts on the issue of bit-level padding in |
Allow declaring primitive integer types with non-byte logical widths while keeping their storage byte-rounded. Track the declared bit width in datatype layout metadata, use it in width-sensitive runtime and codegen paths, and add Core.bitsizeof for public introspection. Update bitstring and the manual to reflect logical bit widths, and add coverage for UInt63 and Int63 declarations, conversions, and LLVM lowering. Co-authored-by: Codex <codex@openai.com>
Handle byte extraction in bitstring by logical bit width rather than rounded storage size. Sub-byte primitives need zero-extension to UInt8, while wider odd-bit primitives still truncate to their low byte. Add regression coverage for a 6-bit primitive to keep bitstring working below one byte. Co-authored-by: Codex <codex@openai.com>
Store odd-bit primitive width metadata in an explicit unused_bits field instead of overloading the layout struct padding bits. This keeps the layout description self-documenting while preserving the same packed footprint. Adjust the layout builder and runtime metadata accessors to use the new field name, and update the corresponding runtime_internals bitfield notes. Co-authored-by: Codex <codex@openai.com>
Reject byte-oriented reinterpret helpers for non-byte-aligned primitive types, fix APInt sign, zero-extension, and truncation for sub-byte widths, and use storage width for ABI integer rewrites. Extend the odd-width intrinsics and reinterpret tests. Co-authored-by: Codex <codex@openai.com>
Rewrite the primitive type description to say that the declared bit count is the logical width, while storage remains byte-rounded. This keeps the manual aligned with odd-bit primitive support and Core.bitsizeof. Co-authored-by: Codex <codex@openai.com>
Add regressions for odd-width primitive equality and object identity masking, integer-float conversion round trips, Ref and field loads, and storage-metadata behavior. Extend reinterpret coverage for odd-width primitive layout metadata as well. Co-authored-by: Codex <codex@openai.com>
e8cd519 to
553f547
Compare
|
@topolarity we (Codex and me) substantially revised this, also based on some of the things you did in your PR. Perhaps triage can make a decision on issue #61361 so I know whether to take that into account or not... |
|
BTW there is at least one genuine test failure, I just did not yet have time to look into it: |
I think it might be possible to proceed without the triage decision, at least for a while. If we can make progress making the codebase consistent about allocation vs. storage vs. register (bit) size then accepting #61361 is a small change to make I do think it might be useful to create an "action list" of areas that need non-byte-multiple integer support and to tackle them piece-by-piece. Specifically this piece:
doesn't seem that far out-of-reach to me TBH (not that you have to / should worry about it in this PR). I think the LLVM support should "just work" as long as we add the "cast storage integer type to / from register integer type" on the boundary with memory from 8a8a6ac, and I'd be happy to do an "odd-bit" follow-up to #61399 for this. The improved test coverage from that PR should be a help too. |
|
Can we move this forward? What is missing? |
Port odd-width APInt conflict resolution to APInt.c. Keep datatype unused_bits alongside master layout updates. Co-authored-by: Codex <codex@openai.com>
Allow the local Int63 test constructor to accept signed integers through Int64 so default Int32 literals on 32-bit runners exercise the same truncation path. Co-authored-by: Codex <codex@openai.com>
| if (!dt->layout->nfields && !dt->layout->npointers) | ||
| return NULL; | ||
| return Type::getIntNTy(ctx, jl_datatype_nbits(dt)); | ||
| return Type::getIntNTy(ctx, jl_datatype_size(dt) * 8); |
There was a problem hiding this comment.
For ABIs we need byte store, so here we move away from jl_datatype_nbits
|
I've just resolve the merge conflicts. Had to adapt to the I've asked Codex to summarize what it thinks of the state of this PR -- sorry, I don't mean to be rude by doing this, but I wasn't sure based on the previous comments what might be expected or not, so I thought I'd ask it ... here is what it wrote after I pointed it at the discussion here:
Anyway: there was also a failure on 32bit systems that I hope is fixed now. Of course I (with Codex/ChatGPT) can do more work on this, but right now, I am indeed not quite sure else is expected / necessary? I mean: of course more work is needed, but would it perhaps make sense to get this (or perhaps just parts?) in sooner rather than later to avoid further conflicts caused by code drift, and then we can do follow-up PRs, e.g. to change the storage behavior? |
|
I'm happy with incremental progress, especially for new features, so once CI goes through, I'm happy to get it merged. I'll also take another review pass. |
Mask the partial storage byte when zero-extending odd-bit APInt values, and make reinterpret padding checks inspect isbits union members so odd-width primitives cannot bypass the guard. Add focused coverage for runtime odd-width zero extension and reinterpret rejection through an isbits union field. Co-authored-by: Codex <codex@openai.com>
|
It would definitely be good if others checked this -- while I tried my best to discuss all changes with Codex, we may very well have missed something. |
Resolve the bitstring conflict by preserving odd-bit primitive extraction while adopting master wrapping arithmetic. Co-authored-by: Codex <codex@openai.com>
|
Another merge conflict popped up, should be resolved now. |
Use declared primitive bit widths when modeling bitcast and integer conversion exceptions, so invalid casts remain observable and valid odd-width conversions are recognized. Co-authored-by: Codex <codex@openai.com>
Share size transfer logic with Core.sizeof and register bitsizeof for constant folding, return inference, and builtin effect analysis. Co-authored-by: Codex <codex@openai.com>
|
Realized there are some more issues with this. But now need to attend some talks. Will update PR later tonight |
Pad the leading partial byte to its logical hexadecimal width so low-valued 5-, 6-, and 7-bit primitives keep a stable representation. Co-authored-by: Codex <codex@openai.com>
|
OK pushed three more commits. |
|
One fixed a somewhat serious issue where Another commit improves support in the compiler for |
Make the expected values explicitly Int64 so identity comparisons do not depend on the host-sized Int literal type. CI: https://buildkite.com/julialang/julia-pr/builds/333#019f5038-9b13-473b-9287-582d1b7113b4 Co-authored-by: Codex <codex@openai.com>
0682913 to
4d43c94
Compare
|
I've once again resolved merge conflicts. The repeating build failure on x86_64-apple-darwin seems to be unrelated to this PR (see discussion on Slack) |
|
Yeah, the Darwin builders have been having trouble, fine to ignore for now. |
Allow declaring primitive integer types with non-byte logical widths while keeping their storage byte-rounded. Track the declared bit width in datatype layout metadata, use it in width-sensitive runtime and codegen paths, and add Core.bitsizeof for public introspection.
Update bitstring and the manual to reflect logical bit widths, and add coverage for UInt63 and Int63 declarations, conversions, and LLVM lowering.
Some non-goals for this initial step:
UInt63or similar types anywhere other than the test suiteThis pull request was written with the assistance of generative AI.
Co-authored-by: Codex codex@openai.com
Motivated by discussion on PR #61262.
Also constitutes partial progress on issue #45486 (but no attempts at bit packed arrays, or "arbitrary size" integers, just enabling odd size).