Basically lshr_int
works as expected when called directly, but not when wrapped in a function. I need to understand better the failure to find a proper fix in BitIntegers. Here is a demo:
julia> using BitIntegers; x = rand(UInt256)
0xbe970fced92b8fcef396a1f5b40c63a86071b8f0330f43290f1d5d748262565f
julia> x >> 4
0x0be970fced92b8fcef396a1f5b40c63a86071b8f0330f43290f1d5d748262565
julia> x >> 0x4
0x0000000000000000000000000000000000000000000000000000000000000000
julia> x >> 0x0004
0x0be970fced92b8fcef396a1f5b40c63a86071b8f0330f43290f1d5d748262565
julia> Base.lshr_int(x, 0x4)
0x0be970fced92b8fcef396a1f5b40c63a86071b8f0330f43290f1d5d748262565
julia> f(x, y) = Base.lshr_int(x, y); f(x, 0x04)
0x0000000000000000000000000000000000000000000000000000000000000000
To what extent is it “safe” to use these intrinsics, and is it possible to change Julia to make the example above work?
Interestingly, on nightly, I get this:
julia> using BitIntegers; x = rand(UInt256)
[ Info: Precompiling BitIntegers [c3b6d118-76ef-56ca-8cc7-ebb389d030a1]
0x00000000000000000000000000000000000000000000000000000000000000a1
So everything rand
generates, except for the last 8 bits somehow is always zero.
Edit: It’s not just rand
:
julia> uint256"0xbe970fced92b8fcef396a1f5b40c63a86071b8f0330f43290f1d5d748262565f"
0x000000000000000000000000000000000000000000000000000000000000005f
Actually what you observe is a consequence of the OP, and it’s how I was made aware of it from https://github.com/JuliaLang/julia/pull/36470#issuecomment-703036745:
125/126> rand(UInt256)
0x00000000000000000000000000000000000000000000000000000000000000d2
127> string(big(ans), base=16)
"28fecc917ccc6d1bbf9b54c500c26d0c8dea1d23520b8d4d87e9377ddf6099d2"
2 Likes
It looks like it’s an LLVM bug:
julia> primitive type UInt256 256 end
julia> x = reinterpret(UInt256, rand(UInt128, 2))[]
UInt256(0x48805fdfb72d71fadaf8daa563cf816383f755d9d9e70d703fa348f556c717ad)
julia> f(x) = Base.lshr_int(x, 0x8)
f (generic function with 1 method)
julia> @code_llvm optimize=false f(x)
; @ REPL[22]:1 within `f'
define void @julia_f_392(i256* noalias nocapture sret %0, i256 %1) {
top:
%2 = call {}*** @julia.ptls_states()
%3 = bitcast {}*** %2 to {}**
%4 = getelementptr inbounds {}*, {}** %3, i64 4
%5 = bitcast {}** %4 to i64**
%6 = load i64*, i64** %5
%7 = lshr i256 %1, 8
%8 = select i1 true, i256 0, i256 %7
store i256 %8, i256* %0, align 8
ret void
}
julia> @code_llvm optimize=true f(x)
; @ REPL[22]:1 within `f'
define void @julia_f_394(i256* noalias nocapture sret %0, i256 %1) {
top:
store i256 0, i256* %0, align 8
ret void
}
Would you mind opening an issue on GitHub?
2 Likes
Ah, so it just prints wrong