Closed
Description
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
Labels
No labels