Skip to content

The panic branch of Some(x).unwrap() is not removed for some types #93011

Closed
@saethlin

Description

@saethlin

Demos: https://godbolt.org/z/TMh3Krfc5

The motivating example is:

pub fn bad_vec(s: Vec<u8>) -> Vec<u8> {
    Some(s).expect("bad_vec")
}
example::bad_myvec:
        push    rax
        mov     rax, qword ptr [rsi]
        test    rax, rax
        je      .LBB5_1
        mov     qword ptr [rdi], rax
        movups  xmm0, xmmword ptr [rsi + 8]
        movups  xmmword ptr [rdi + 8], xmm0
        mov     rax, rdi
        pop     rcx
        ret
.LBB5_1:
        lea     rdi, [rip + .L__unnamed_5]
        lea     rdx, [rip + .L__unnamed_6]
        mov     esi, 9
        call    qword ptr [rip + core::option::expect_failed@GOTPCREL]
        ud2

It looks to me like the problem with Vec is that specifically the nonnull attribute does not survive being wrapped in two structs that each contain a second member. If either of RawVec or Vec is missing a usize member, the optimization works.

There is a missed NonZero* optimization in here that I found looking for types that fail to optimize. It's unclear to me if this was reported previously in #49572, or if whatever fixes the problem with Vec will also fix the NonZero* example.


I think this is similar but not the same problem as seen in #71257

Metadata

Metadata

Assignees

No one assigned

    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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions