-
-
Notifications
You must be signed in to change notification settings - Fork 924
avm2: Convert float values representable as ints to Value::Integer
#21907
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
This fixes some previously failing tests.
This test verifies whether floats that are representable as ints are converted to ints.
Value::Integer
If I was knowledgeable about AVM2 internals at all, I would submit an approval, but I wouldn't say that I am... |
FWIW I benchmarked several condition expression and this was the fastest |
How much does this increase the size of the code generated for |
Old: movsd qword, ptr, [rdi, +, 8], xmm0
mov qword, ptr, [rdi], 48
ret New (3.7x slower): maxsd xmm1, qword, ptr, [rip, +, .LCPI5792_0]
minsd xmm1, qword, ptr, [rip, +, .LCPI5792_1]
cvttsd2si edx, xmm1
xor ecx, ecx
ucomisd xmm0, xmm0
mov rax, rdi
cmovnp ecx, edx
movq rdx, xmm0
xorps xmm1, xmm1
cvtsi2sd xmm1, ecx
movq rsi, xmm1
cmp rdx, rsi
jne .LBB5792_1
mov dword, ptr, [rax, +, 8], ecx
mov ecx, 49
mov qword, ptr, [rax], rcx
ret
.LBB5792_1:
movsd qword, ptr, [rax, +, 8], xmm0
mov ecx, 48
mov qword, ptr, [rax], rcx
ret That's a lot of instructions sadly, but I think I can get rid of range and NaN checks with unsafe stuff. |
Using the following code reduces the number of instructions (gets rid of range and NaN checks), but it's 2-6x slower :/ I don't know why let value_i = unsafe { value.to_int_unchecked() };
if value.to_bits() == (value_i as f64).to_bits() {
Value::Integer(value_i)
} else {
Value::Number(value)
} movq rcx, xmm0
cvttpd2dq xmm1, xmm0
cvtdq2pd xmm1, xmm1
movq rdx, xmm1
cmp rcx, rdx
jne .LBB5793_1
cvttsd2si ecx, xmm0
mov dword, ptr, [rax, +, 8], ecx
mov ecx, 49
mov qword, ptr, [rax], rcx
ret
.LBB5793_1:
movsd qword, ptr, [rax, +, 8], xmm0
mov ecx, 48
mov qword, ptr, [rax], rcx
ret (testing on x86_64) Looks like for some reason rustc emits nonoptimal instructions (packed instead of scalar conversions) |
Filed rust-lang/rust#147650 |
Sorry, I didn't do my benchmarks properly. Using the unchecked version prevents inlining. When always inlining we have the checked version 3.6x slower, the unchecked is only 2.6x slower. But unfortunately the doc says it's UB, so we shouldn't use it anyway. |
So benchmarking shows that this PR can in some cases improve performance by 25% but in other cases worsen it by over 50%. (See https://github.com/joelgwebber/bench2d/tree/master/as3) I'll change this to a draft, and we can think about revisiting it in the future, but for now we should focus on covering observable behaviors resulting from this PR instead of doing it like Flash Player. |
This fixes some previously failing tests.
(A new test is included too.)