Skip to content

Removing useless small array initializations #48293

Closed
@leonardo-m

Description

@leonardo-m

Rustc should detect and remove useless small array intializations.

This is C++ code:

#include <stdint.h>

typedef struct { int32_t arr[16]; } V;

V test(V a, V b) {
    V res;
    for (int i = 0; i < 16; i++)
        res.arr[i] = a.arr[i] + b.arr[i];
    return res;
}

Compiling it with Clang v.5
g++ -O3 -march=skylake-avx512


test(V, V): # @test(V, V)
  vmovdqu32 zmm0, zmmword ptr [rsp + 72]
  vpaddd zmm0, zmm0, zmmword ptr [rsp + 8]
  vmovdqu32 zmmword ptr [rdi], zmm0
  mov rax, rdi
  vzeroupper
  ret


Similar Rustc code:

pub struct V { arr: [i32; 16] }

pub fn test(a: V, b: V) -> V {
    let mut res = V { arr: [0; 16] };
    for i in 0 .. 16 {
        res.arr[i] = a.arr[i] + b.arr[i];
    }
    res
}
rustc 1.25.0-nightly (3ec5a99aa 2018-02-14)
--crate-type lib -C opt-level=3 -C target-cpu=skylake-avx512 --emit asm

_ZN4test4test17hf0a28b117be5fee8E:
	subq	$64, %rsp
	vmovdqu	(%r8), %ymm0
	vpaddd	(%rdx), %ymm0, %ymm0
	movq	$0, 56(%rsp)
	vmovdqu	%ymm0, (%rsp)
	movl	32(%r8), %eax
	addl	32(%rdx), %eax
	movl	%eax, 32(%rsp)
	movl	36(%r8), %eax
	addl	36(%rdx), %eax
	movl	%eax, 36(%rsp)
	movl	40(%r8), %eax
	addl	40(%rdx), %eax
	movl	%eax, 40(%rsp)
	movl	44(%r8), %eax
	addl	44(%rdx), %eax
	movl	%eax, 44(%rsp)
	movl	48(%r8), %eax
	addl	48(%rdx), %eax
	movl	%eax, 48(%rsp)
	movl	52(%r8), %eax
	addl	52(%rdx), %eax
	movl	%eax, 52(%rsp)
	movl	56(%r8), %eax
	addl	56(%rdx), %eax
	movl	%eax, 56(%rsp)
	movl	60(%r8), %eax
	addl	60(%rdx), %eax
	movl	%eax, 60(%rsp)
	vmovups	(%rsp), %zmm0
	vmovups	%zmm0, (%rcx)
	movq	%rcx, %rax
	addq	$64, %rsp
	vzeroupper
	retq

Not initializing the small result array:

rustc 1.25.0-nightly (3ec5a99aa 2018-02-14)
--crate-type lib -C opt-level=3 -C target-cpu=skylake-avx512 --emit asm


pub struct V { arr: [i32; 16] }

pub fn test(a: V, b: V) -> V {
    let mut res: V = unsafe { std::mem::uninitialized() };
    for i in 0 .. 16 {
        res.arr[i] = a.arr[i] + b.arr[i];
    }
    res
}

_ZN4test4test17hf0a28b117be5fee8E:
    pushq   %rbp
    subq    $112, %rsp
    leaq    112(%rsp), %rbp
    andq    $-64, %rsp
    vmovdqu32   (%r8), %zmm0
    vpaddd  (%rdx), %zmm0, %zmm0
    vmovdqa32   %zmm0, (%rsp)
    vmovaps (%rsp), %zmm0
    vmovups %zmm0, (%rcx)
    movq    %rcx, %rax
    movq    %rbp, %rsp
    popq    %rbp
    vzeroupper
    retq

Rust should remove the need to use mem::uninitialized() in such situations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions