Skip to content
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

Increased code size due to unnecessary memcpy libcall in MaybeUninit::assume_init #96487

Open
piegamesde opened this issue Apr 27, 2022 · 5 comments
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-heavy Issue: Problems and improvements with respect to binary size of generated code. I-slow Issue: Problems and improvements with respect to performance of generated code. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@piegamesde
Copy link
Contributor

piegamesde commented Apr 27, 2022

After updating the compiler toolchain, I noticed that my binary got about 100 bytes larger. In my extremely size constrained environment, this is an increase of 5%. After a lot of minimizing, I tracked the main increase down to MaybeUninit::assume_init. It adds a new call to libc's memcpy. As far as I can tell, the code is moving the value on the stack a few bytes around, which is pointless (alignment should not be the issue here).

This might be related to #61011

Code

Godbolt link

Version it worked on

The last version I got it to run on was nightly-2022-02-01, but it might be working until as late as 2022-02-28 (I had some unrelated compile errors that made bisecting hard).

Version with regression

The older nightly with regression is 2022-03-12

rustc --version --verbose:

rustc 1.61.0-nightly (335ffbfa5 2022-03-11)
binary: rustc
commit-hash: 335ffbfa547df94ac236f5c56130cecf99c8d82b
commit-date: 2022-03-11
host: x86_64-unknown-linux-gnu
release: 1.61.0-nightly
LLVM version: 14.0.0
@piegamesde piegamesde added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Apr 27, 2022
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Apr 27, 2022
@nikic nikic added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-slow Issue: Problems and improvements with respect to performance of generated code. labels Apr 27, 2022
@apiraino apiraino added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Apr 28, 2022
@inquisitivecrystal inquisitivecrystal added the I-heavy Issue: Problems and improvements with respect to binary size of generated code. label Apr 29, 2022
@apiraino
Copy link
Contributor

apiraino commented May 3, 2022

Assigning priority as discussed in the Zulip thread of the Prioritization Working Group.

@piegamesde thanks for the details. Do you happen to have the time to run a bisection on the target platform you're using (riscv32i-unknown-none-elf) and pin the exact commit the regression started? That would help a lot.

@rustbot label -I-prioritize +P-medium

@rustbot rustbot added P-medium Medium priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels May 3, 2022
@piegamesde
Copy link
Contributor Author

I already did a preliminary bisect, hence the date range above. I could not get any closer because my code did not compile during the days in between. This was before minimization though, I will try again with the smaller code and hope that it will keep compiling. However, I due to the tooling I use the best granularity I will be able to provide will be nightly builds and not individual commits.

(btw your Zulip link is broken)

@apiraino
Copy link
Contributor

apiraino commented May 3, 2022

ok thank you so much. being able to single out the nightly is probably enough

(and I have fixed the link, thanks for the notice)

@piegamesde
Copy link
Contributor Author

I tried bisecting with the following one-liner: nix-shell -p 'with (import <nixpkgs> { overlays = [(import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz))]; }); ((rustChannelOf { date = "2022-02-01"; channel = "nightly"; }).rust.override { targets = [ "riscv32i-unknown-none-elf" ]; })' --pure --run 'rustc --version && rm -f bug.s && rustc bug.rs --target=riscv32i-unknown-none-elf -C opt-level=s -C panic=abort -C codegen-units=1 -C lto=fat -C codegen-units=1 --cfg feature=\"panic_immediate_abort\" --crate-type lib --emit asm && cat bug.s. bug.rs is the repro source copied over from the Godbolt link.

The bad news is: I went back until the beginning of 2020 and all versions I tested emitted an additional memcopy for assume_init. So probably this is a case that never worked, and the regression I experienced must have happened on a different level.

@JohnTitor JohnTitor added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. and removed regression-untriaged Untriaged performance or correctness regression. labels May 23, 2022
@workingjubilee workingjubilee changed the title Increased code size due to unneccessary memcpy call in MaybeUninit::assume_init Increased code size due to unnecessary memcpy libcall in MaybeUninit::assume_init Jul 30, 2022
@workingjubilee
Copy link
Member

Passing-by note / reason for editing very, very slightly: the problem is in fact calling out to libc's memcpy, and is not necessarily about the @llvm.memcpy intrinsic nor the assembly-language loop referred to as "memcpy". Also, it generates similar code on x86 too, though there LLVM has inlined the memcmp libcall as vector instructions:
https://godbolt.org/z/dcfcMPdKz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-heavy Issue: Problems and improvements with respect to binary size of generated code. I-slow Issue: Problems and improvements with respect to performance of generated code. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants