Open LilithHafner opened 5 months ago
That's suboptimal. We probably need one more checked mul on the C side.
hmm, we already are doing the multiplication with wide arithmetic: https://github.com/JuliaLang/julia/blob/c88f4e275af866737491290ccb10d9088c0428ff/src/genericmemory.c#L42 I'm very unsure why this check isn't failing. Is wideint_t
somehow being set to uint64?
What does "UB" mean here (the UB bug really bit people...). This is just a bug.
That is how wideint_t
is defined (it depends on the architecture and C-compiler in use)
https://github.com/JuliaLang/julia/blob/e637be11f6fad4e45501138090135e4748a6b60e/src/array.c#L19-L23
UINT128MAX seems to never exist. What is that supposed to be?
It is possible to throw if ((size_t)(-1) >> 1 - 1) / max(elsz + (isunion != 0), 1) + 1 > nel
or similar in array.c
and 2 spots in genericmemory.c
.
Then size_t prod; prod = (elsz + (isunion != 0)) * nel
, without need for wide_t
and MAXINTVAL
.
Ideally we don't need division there, as that is much slower than checking for multiplication overflow
UINT128MAX seems to never exist. What is that supposed to be?
It was introduced by e9be4448fd269bf5915918a2cd272fda03109217 (#5022), but it doesn't seem to be defined/used anywhere else in that revision.
Apparently there is no standards-defined way to avoid this UB in C for multiply. But most compilers have extensions (specifically __builtin_mul_overflow
) to work around that.
Could we move the checking into Julia? Seems we can do this more reliably than C.
Moving the checks to Julia would be a bit dangerous in that anyoen that skips doing the checks could run into weird behavior, but if we give it a bad enough name, it's plausible that people won't try to use it...
What does "UB" mean here
I mean that Array{UInt128}(undef, 2^3, 2^59)[10]
semantically invokes LLVM's undefined behavior.
I think it is unlikely for this to result in incorrect results in user code. It is much more likely to result in crashes/segfaults, and it is also unlikely for a user to allocate an array of this size in the first place.
Related, constructing an array of size 2^61 or 2^62 "works", but not 2^61-1 or 2^62-1:
I'm guessing all this is due to unchecked overflow when multiplying by
sizeof(eltype)
.Much if this behavior is also present on 1.10.
CC @oscardssmith who's been working on this recently.
All examples above are from nightly.