-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Sema: Improve comptime arithmetic undef handling #24674
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: master
Are you sure you want to change the base?
Conversation
4d42e8e
to
277ad41
Compare
This commit expands on the foundations laid by ziglang#23177 and moves even more `Sema`-only functionality from `Value` to `Sema.arith`. Specifically all shift and bitwise operations, `@truncate`, `@bitReverse` and `@byteSwap` have been moved and adapted to the new rules around `undefined`. Especially the comptime shift operations have been basically rewritten, fixing many open issues in the process. New rules applied to operators: * `<<`, `@shlExact`, `@shlWithOverflow`, `@shrExact`: compile error if any operator is undef * `<<|`, `>>`, all other affected ops: return undef if any operator is undef Additionally this commit canonicalizes the representation of aggregates with all-undefined members in the `InternPool` by disallowing them and enforcing the usage of a single typed `undef` value instead. This reduces the amount of edge cases and fixes a bunch of bugs related to partially undefined vecs. List of operations directly affected by this patch: * `<<`, `<<|`, `@shlExact`, `@shlWithOverflow` * `>>`, `@shrExact` * `&`, `|`, `~`, `^` and their atomic rmw pendants * `@truncate`, `@bitReverse`, `@byteSwap`
277ad41
to
073f1d5
Compare
Just based on the PR description: what's the rationale behind treating |
Oh I think you have a point - I for some reason only paid attention to the bits being shifted out, not the ones being shifted in, but if my mental model is correct this could also cause IB: var x: u7 = 0;
x >>= 1; // bit #7 is undefined/not part of x, so could shift *in* a 1! |
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.
This looks like great work, thank you! I have a few things I'd like you to look over, but this shouldn't be too far from mergeable.
} | ||
/// Given an integer or boolean type, creates an value of that with the bit pattern 0xAA. | ||
/// This is used to convert undef values into 0xAA when performing e.g. bitwise operations. | ||
/// TODO: Eliminate this function and everything it stands for (related: #19634). |
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.
good comment
// :71:17: error: use of undefined value here causes illegal behavior | ||
// :71:17: error: use of undefined value here causes illegal behavior |
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.
It looks like a bunch of errors have disappeared from this test. Do you know why?
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.
Good question - I checked and there are only 4256 errors now compared to 6688 before. Is there maybe some limit on the max line number somewhere? My patch does add lots of error notes for vector indices so maybe some limit is now hit earlier than before?
I'll investigate further
// @as(u8, undefined) | ||
// @as(u8, undefined) | ||
// @as(@Vector(2, u8), [runtime value]) | ||
// @as(@Vector(2, u8), [runtime value]) | ||
// @as(@Vector(2, u8), undefined) |
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.
Ahhh, these changes worried me at first, but actually, this is great! Your undef canonicalization has made .{ undefined, undefined } +% .{ runtime, runtime }
return comptime-known undef. Lovely work!
Thank you for the review! I've added the right shift compile error and a couple of test for now, I'll have a look at all of the other comments tomorrow |
I think you're misunderstanding where the IB comes from here. Shifting any well-defined |
I left the aggregate interns that use byte storage and the ones in the type info logic alone for now. There are also about 100 aggregate interns left outside of Sema I'll deal with those later. |
Benchmarks performed on a MacBook Pro M1 (sadly no poop)
master:
my branch:
So no performance impact or even slightly faster :)
|
I haven't been able to find the cause for the test errors that disaperared yet. I checked all call sites of |
The only remaining usages of |
Benchmarks for x86_64 backend:
Wow I wasn't aware that the x86_64 backend is that much faster than llvm (unless I did something wrong?) can't wait for the aarch64 backend to be ready! |
This commit expands on the foundations laid by #23177
and moves even more
Sema
-only functionality fromValue
to
Sema.arith
. Specifically all shift and bitwise operations,@truncate
,@bitReverse
and@byteSwap
have been moved andadapted to the new rules around
undefined
.Especially the comptime shift operations have been basically
rewritten, fixing many open issues in the process.
New rules applied to operators:
<<
,@shlExact
,@shlWithOverflow
,>>
,@shrExact
: compile error if any operand is undef<<|
,~
,^
,@truncate
,@bitReverse
,@byteSwap
: return undef if any operand is undef&
,|
: Return undef if both operands are undef, turn undef into actual0xAA
bytes otherwiseAdditionally this commit canonicalizes the representation of
aggregates with all-undefined members in the
InternPool
bydisallowing them and enforcing the usage of a single typed
undef
value instead. This reduces the amount of edge casesand fixes a bunch of bugs related to partially undefined vecs.
List of operations directly affected by this patch:
<<
,<<|
,@shlExact
,@shlWithOverflow
>>
,@shrExact
&
,|
,~
,^
and their atomic rmw + reduce pendants@truncate
,@bitReverse
,@byteSwap
Resolves #16466
*
Resolves #21266
Resolves #21943
Resolves #23034
Resolves #24392
*
(was already kind of resolved before this patch I think, but addresses the comment)Most of the LOC in this patch are test cases, but if it's too big to review please let me know and I can try to split it into 2-3 smaller commits