-
Notifications
You must be signed in to change notification settings - Fork 13k
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
String::new()
is slower than "".to_string()
#86106
Comments
@rustbot label regression-untriaged |
Regressed since 1.52.0, between nightly-2021-03-04 and nightly-2021-03-05 so I assume it's caused (revealed?) by #81451. |
Reduced llvm-ir: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%"std::string::String" = type { [0 x i64], %"std::vec::Vec<u8>", [0 x i64] }
%"std::vec::Vec<u8>" = type { [0 x i64], { i8*, i64 }, [0 x i64], i64, [0 x i64] }
@0 = private unnamed_addr constant <{ [16 x i8] }> <{ [16 x i8] c"\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>, align 8
define void @abc(%"std::string::String"* %0) unnamed_addr {
start:
%1 = load i8*, i8** bitcast (<{ [16 x i8] }>* @0 to i8**), align 8
%ptr = bitcast %"std::string::String"* %0 to i8**
store i8* %1, i8** %ptr, align 8
ret void
}
; This works by replacing the pointer type with an integral type
define void @cba(%"std::string::String"* %0) unnamed_addr {
start:
%1 = load i64, i64* bitcast (<{ [16 x i8] }>* @0 to i64*), align 8
%ptr = bitcast %"std::string::String"* %0 to i64*
store i64 %1, i64* %ptr, align 8
ret void
}
LLVM fails to figure out that the load can be replaced with a constant (Probably because of the |
It isn't only in pub fn foo()->Vec<u8>{
vec![]
}
pub fn foo()->Vec<u8>{
vec![].clone()
} example::foo:
mov rax, rdi
mov rcx, qword ptr [rip + .L__unnamed_1]
mov qword ptr [rdi], rcx
xorps xmm0, xmm0
movups xmmword ptr [rdi + 8], xmm0
ret
.L__unnamed_1:
.asciz "\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
example::foo:
mov rax, rdi
mov qword ptr [rdi], 1
xorps xmm0, xmm0
movups xmmword ptr [rdi + 8], xmm0
ret |
Assigning priority as discussed in the Zulip thread of the Prioritization Working Group. @rustbot label -I-prioritize +P-high |
This can be somewhat solved by using pub const fn new() -> Self {
Vec { buf: RawVec::new(), len: 0 }
} instead of pub const fn new() -> Self {
Vec { buf: RawVec::NEW, len: 0 }
} but i been hit by
Tried solving this by placing |
Seems like you hit #75794. |
It could be because these stability changes are seen by the bootstrap compiler and not your own version of There are a few examples of attributes needing to be Depending on whether you need to target the bootstrap compiler, or to "temporarily hide" your changes from it, it can look like |
@lqd #[inline]
#[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(bootstrap)]
pub const fn new() -> Self {
Vec { buf: RawVec::NEW, len: 0 }
}
#[inline]
#[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(bootstrap))]
pub const fn new() -> Self {
Vec { buf: RawVec::new(), len: 0 }
} and RawVec to #[rustc_allow_const_fn_unstable(const_fn)]
#[cfg_attr(not(bootstrap), rustc_const_unstable(feature="rawvec_const_new_fake_stable", issue="99999"))]
pub const fn new() -> Self {
Self::new_in(Global)
} with adding But this clearly wrong (tried few permutations of cfg's), as error the same. |
Asking about how to handle this on zulip, e.g. in the t-libs stream, would probably be best then. |
Found workaround, but this bloats rcgu size a lot, sadly. |
Fixed upstream by llvm/llvm-project@6a19cb8. |
I assume that this will make its way into Rust with LLVM 14? Or will it become a patch release? |
This will be part of the LLVM 14 upgrade. |
Fixed by #93577 https://rust.godbolt.org/z/vMdfPzfT5, but test should be added, to check regressions in future. |
Signed-off-by: Yuki Okushi <[email protected]>
Add regression test for rust-lang#86106 Closes rust-lang#86106 r? `@nikic` Signed-off-by: Yuki Okushi <[email protected]>
Signed-off-by: Yuki Okushi <[email protected]>
I tried this code:
I expected to see this happen: both functions contain identical code.
Instead, this happened: https://rust.godbolt.org/z/P53MMG4W6.
For
String::new()
it does one more instruction:mov rcx, qword ptr [rip + .L__unnamed_1]
. Thisrcx
is then read further below atmov qword ptr [rdi], rcx
.The
"".to_string()
version however does not do this extra step and immediately reads from a constant:mov qword ptr [rdi], 1
.This means that
String::new()
does slightly more work than"".to_string()
but I expect them to be identical.Before 1.52.0 the functions generated identical code: https://rust.godbolt.org/z/8647E6YhY.
oli noted the following:
Meta
This currently happens on nightly.
The text was updated successfully, but these errors were encountered: