Skip to content

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

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

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

# for free to join this conversation on GitHub. Already have an account? # 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