Почему неиспользуемые векторы с нулевой инициализацией не удаляются при оптимизации?

#rust #compilation

Вопрос:

Если я напишу метод, который инициализирует a Vec с ненулевым значением и вызовет его пару раз из main() , то при сборке с --release помощью ( -O3 ) компилятор оптимизирует все до эффективного отказа от операции:

Код

 fn allocate() {
    let _a = vec![1; 100];
}

pub fn main() {
    allocate();
    allocate();
}
 

Выходной сигнал

 example::main:
        ret
 

Ссылка на Godbolt

Однако, если я вместо этого инициализирую его нулем, результат будет кардинально отличаться:

Код

 fn allocate() {
    let _a = vec![0; 100];
}

pub fn main() {
    allocate();
    allocate();
}
 

Выходной сигнал

 example::main:
        push    rax
        mov     edi, 400
        mov     esi, 4
        call    qword ptr [rip   __rust_alloc_zeroed@GOTPCREL]
        test    rax, rax
        je      .LBB0_2
        mov     esi, 400
        mov     edx, 4
        mov     rdi, rax
        call    qword ptr [rip   __rust_dealloc@GOTPCREL]
        mov     edi, 400
        mov     esi, 4
        call    qword ptr [rip   __rust_alloc_zeroed@GOTPCREL]
        test    rax, rax
        je      .LBB0_2
        mov     esi, 400
        mov     edx, 4
        mov     rdi, rax
        pop     rax
        jmp     qword ptr [rip   __rust_dealloc@GOTPCREL]
.LBB0_2:
        mov     edi, 400
        mov     esi, 4
        call    qword ptr [rip   alloc::alloc::handle_alloc_error@GOTPCREL]
        ud2
 

Ссылка на Godbolt

Почему компилятор сохраняет инструкции нулевой инициализации, даже если он буквально выделяет их и немедленно освобождает, но оптимизирует все, если вы инициализируете что-нибудь еще?

Комментарии:

1. Похоже на ошибку пропущенной оптимизации. Вы могли бы сообщить об этом.

2. @NateEldredge Хороший момент, я предполагал, что это было задумано. Я открыл проблему для этого на случай, если это действительно ошибка.

3. Для справки: проблема .