-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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 <jtitor@2k36.org>
Add regression test for rust-lang#86106 Closes rust-lang#86106 r? `@nikic` Signed-off-by: Yuki Okushi <jtitor@2k36.org>
Signed-off-by: Yuki Okushi <jtitor@2k36.org>
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: