Skip to content

Failure to optimize .reverse() with more than one usage in the same file #85872

Closed
@Mikadore

Description

@Mikadore

I was experimenting with some code on godbolt, when encountering this:

pub fn u16_be_to_arch(mut data: [u8;2]) -> [u8;2] {
    data.reverse();
    data
}

with -C opt-level=3 produces the expected assembly:

example::u16_be_to_arch:
        mov     eax, edi
        rol     ax, 8
        ret

However, when adding (into the same file) this function:

pub fn u32_be_to_arch(mut data: [u8;4]) -> [u8;4] {
    data.reverse();
    data
}

The previous function's codegen changes to

example::u16_be_to_arch:
        sub     rsp, 2
        mov     eax, edi
        rol     ax, 8
        mov     word ptr [rsp], ax
        add     rsp, 2
        ret

https://godbolt.org/z/MWTar9xa3
https://godbolt.org/z/sKTznrKh9

The issue: it stores the result on the stack, and then immediately discards that. (which it didn't do previously)

The second potential issue I'm unsure about is, that here a function's codegen changes by just adding removing seemingly unrelated functions. I was told on discord this is because the two functions use the same reverse, and adding the second one forces reverse to be generalized to [u8;2] and [u8;4] as opposed to just [u8;2]. But I by far don't know enough to judge whether this is a problem or not, or what it's caused by, but I wanted to mention it.

Metadata

Metadata

Assignees

Labels

A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-bugCategory: This is a bug.I-heavyIssue: Problems and improvements with respect to binary size of generated code.I-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions