Testing the optimization capabilities of the compiler


#1

I made a quick tool to test some simple optimizations that I would expect the compiler to be able to perform. These were picked such that they all look very simple, and “obviously” do nothing, but the compiler has some trouble reducing them down.

I thought (perhaps with a few more test cases) this could be a good benchmark for how far along compiler optimizations are. Maybe it is too LLVM-dependent though!

Already from stable -> nightly it goes from 1 success, 15 failures to 5 successes, 11 failures, so we’re making progress


#2

Do you have a list of the ones that are “failing” on Nightly?


#3

Current nightly (rustc 1.23.0-nightly (d762b1d6c 2017-11-04)) tests are as follows:

test out/nullary/reverse.s failed - test output:
reverse:
	movl	$4104, %eax
	callq	__rust_probestack
	subq	%rax, %rsp
	leaq	8(%rsp), %rdi
	xorl	%esi, %esi
	movl	$4096, %edx
	callq	memset@PLT
	leaq	36(%rsp), %rax
	movl	$1023, %ecx
	.p2align	4, 0x90
.LBB0_1:
	movl	-28(%rax), %edx
	movl	8(%rsp,%rcx,4), %esi
	movl	%esi, -28(%rax)
	movl	%edx, 8(%rsp,%rcx,4)
	movl	-24(%rax), %edx
	movl	4(%rsp,%rcx,4), %esi
	movl	%esi, -24(%rax)
	movl	%edx, 4(%rsp,%rcx,4)
	movl	-20(%rax), %edx
	movl	(%rsp,%rcx,4), %esi
	movl	%esi, -20(%rax)
	movl	%edx, (%rsp,%rcx,4)
	movl	-16(%rax), %edx
	movl	-4(%rsp,%rcx,4), %esi
	movl	%esi, -16(%rax)
	movl	%edx, -4(%rsp,%rcx,4)
	movl	-12(%rax), %edx
	movl	-8(%rsp,%rcx,4), %esi
	movl	%esi, -12(%rax)
	movl	%edx, -8(%rsp,%rcx,4)
	movl	-8(%rax), %edx
	movl	-12(%rsp,%rcx,4), %esi
	movl	%esi, -8(%rax)
	movl	%edx, -12(%rsp,%rcx,4)
	movl	-4(%rax), %edx
	movl	-16(%rsp,%rcx,4), %esi
	movl	%esi, -4(%rax)
	movl	%edx, -16(%rsp,%rcx,4)
	movl	(%rax), %edx
	movl	-20(%rsp,%rcx,4), %esi
	movl	%esi, (%rax)
	movl	%edx, -20(%rsp,%rcx,4)
	addq	$32, %rax
	addq	$-8, %rcx
	cmpq	$511, %rcx
	jne	.LBB0_1
	addq	$4104, %rsp
	retq
test out/nullary/parse_int.s failed - test output:
parse_int:
	pushq	%rax
	leaq	str.7(%rip), %rdi
	movl	$5, %esi
	callq	_ZN4core3num52_$LT$impl$u20$core..str..FromStr$u20$for$u20$i32$GT$8from_str17h1a7d3d2071c6afc1E@PLT
	testb	%al, %al
	jne	.LBB2_2
	popq	%rax
	retq
test out/nullary/flat_map_loop.s passed
test out/nullary/split_whitespace.s failed - test output:
split_whitespace:
	pushq	%r14
	pushq	%rbx
	subq	$88, %rsp
	movl	$18, %eax
	vmovq	%rax, %xmm0
	vpslldq	$8, %xmm0, %xmm1
	vmovdqa	%xmm1, 16(%rsp)
	leaq	str.0(%rip), %rax
	movq	%rax, 32(%rsp)
	vmovdqu	%xmm0, 40(%rsp)
	leaq	str.0+18(%rip), %rcx
	vmovq	%rcx, %xmm0
	vmovq	%rax, %xmm1
	vpunpcklqdq	%xmm0, %xmm1, %xmm0
	vmovdqu	%xmm0, 56(%rsp)
	movb	$0, 72(%rsp)
	movb	$1, 80(%rsp)
	movb	$0, 81(%rsp)
	movq	%rsp, %r14
	leaq	16(%rsp), %rbx
	.p2align	4, 0x90
.LBB0_1:
	movq	%r14, %rdi
	movq	%rbx, %rsi
	callq	_ZN100_$LT$std_unicode..u_str..SplitWhitespace$LT$$u27$a$GT$$u20$as$u20$core..iter..iterator..Iterator$GT$4next17h769e8a80a6cb4191E@PLT
	cmpq	$0, (%rsp)
	jne	.LBB0_1
	addq	$88, %rsp
	popq	%rbx
	popq	%r14
	retq
test out/nullary/simple_loop.s passed
test out/nullary/hashmap_new.s failed - test output:
hashmap_new:
	pushq	%r15
	pushq	%r14
	pushq	%rbx
	subq	$64, %rsp
	callq	_ZN3std11collections4hash3map11RandomState3new4KEYS7__getit17h5f9ad682990b9885E@PLT
	movq	%rax, %r14
	testq	%r14, %r14
	je	.LBB3_9
	cmpq	$0, (%r14)
	je	.LBB3_3
	movq	%r14, %rax
	addq	$8, %rax
	movq	8(%r14), %rbx
	jmp	.LBB3_7
.LBB3_3:
	leaq	40(%rsp), %rdi
	callq	_ZN3std4rand5OsRng3new17hb06ff12d0ce51b98E@PLT
	movq	44(%rsp), %rax
	cmpl	$0, 40(%rsp)
	movl	60(%rsp), %ecx
	movl	%ecx, 32(%rsp)
	movq	52(%rsp), %rcx
	movq	%rcx, 24(%rsp)
	jne	.LBB3_8
	movq	%rax, 8(%rsp)
	leaq	8(%rsp), %r15
	movq	%r15, %rdi
	callq	_ZN61_$LT$std..sys..imp..rand..imp..OsRng$u20$as$u20$rand..Rng$GT$8next_u6417h4c128250c95d2a92E@PLT
	movq	%rax, %rbx
	movq	%r15, %rdi
	callq	_ZN61_$LT$std..sys..imp..rand..imp..OsRng$u20$as$u20$rand..Rng$GT$8next_u6417h4c128250c95d2a92E@PLT
	movq	%rax, %r15
	cmpl	$0, 8(%rsp)
	je	.LBB3_6
	leaq	12(%rsp), %rdi
	callq	_ZN69_$LT$std..sys..imp..fd..FileDesc$u20$as$u20$core..ops..drop..Drop$GT$4drop17hb5e0f9c50772fa63E@PLT
.LBB3_6:
	movq	%r14, %rax
	addq	$8, %rax
	movq	$1, (%r14)
	movq	%rbx, 8(%r14)
	movq	%r15, 16(%r14)
.LBB3_7:
	addq	$1, %rbx
	movq	%rbx, (%rax)
	callq	_ZN3std11collections4hash3map19DefaultResizePolicy3new17hce5ffecdfe2fca83E@PLT
	addq	$64, %rsp
	popq	%rbx
	popq	%r14
	popq	%r15
	retq
test out/nullary/push_vec.s failed - test output:
push_vec:
	subq	$24, %rsp
	movq	$4, (%rsp)
	vxorps	%xmm0, %xmm0, %xmm0
	vmovups	%xmm0, 8(%rsp)
	movq	%rsp, %rdi
	callq	_ZN49_$LT$alloc..raw_vec..RawVec$LT$T$C$$u20$A$GT$$GT$6double17hf2fa367e245430a3E
	movq	(%rsp), %rdi
	movq	16(%rsp), %rax
	movl	$1, (%rdi,%rax,4)
	addq	$1, %rax
	movq	%rax, 16(%rsp)
	movq	8(%rsp), %rsi
	testq	%rsi, %rsi
	je	.LBB1_2
	shlq	$2, %rsi
	movl	$4, %edx
	callq	__rust_dealloc@PLT
.LBB1_2:
	addq	$24, %rsp
	retq
test out/nullary/chained_loop.s passed
test out/nullary/from_utf8.s failed - test output:
from_utf8:
	subq	$40, %rsp
	leaq	byte_str.7(%rip), %rsi
	leaq	16(%rsp), %rdi
	movl	$13, %edx
	callq	_ZN4core3str9from_utf817h242bddfb4644550cE@PLT
	cmpq	$0, 16(%rsp)
	jne	.LBB2_2
	addq	$40, %rsp
	retq
test out/nullary/allocate_string.s failed - test output:
allocate_string:
	subq	$24, %rsp
	leaq	str.0(%rip), %rsi
	movq	%rsp, %rdi
	movl	$6, %edx
	callq	_ZN87_$LT$alloc..string..String$u20$as$u20$core..convert..From$LT$$RF$$u27$a$u20$str$GT$$GT$4from17h9ec4e6191d325016E@PLT
	movq	8(%rsp), %rsi
	testq	%rsi, %rsi
	je	.LBB0_1
	movq	(%rsp), %rdi
	movl	$1, %edx
	addq	$24, %rsp
	jmp	__rust_dealloc@PLT
.LBB0_1:
	addq	$24, %rsp
	retq

nullary tests run - 3 successes, 7 failures

test out/unary/add_loop.s failed - test output:
add_loop:
	testq	%rdi, %rdi
	je	.LBB0_1
	leaq	-1(%rdi), %rcx
	movq	%rdi, %rdx
	xorl	%eax, %eax
	andq	$7, %rdx
	je	.LBB0_4
	.p2align	4, 0x90
.LBB0_3:
	addq	$1, %rax
	cmpq	%rax, %rdx
	jne	.LBB0_3
.LBB0_4:
	cmpq	$7, %rcx
	jb	.LBB0_6
	.p2align	4, 0x90
.LBB0_5:
	addq	$8, %rax
	cmpq	%rdi, %rax
	jb	.LBB0_5
.LBB0_6:
	retq
test out/unary/int_vec_len.s failed - test output:
int_vec_len:
	pushq	%rbx
	subq	$48, %rsp
	movq	%rdi, %rbx
	movl	$4, %ecx
	movq	%rbx, %rax
	mulq	%rcx
	jo	.LBB0_7
	testq	%rax, %rax
	je	.LBB0_2
	leaq	8(%rsp), %rdx
	movl	$4, %esi
	movq	%rax, %rdi
	callq	__rust_alloc_zeroed@PLT
	testq	%rax, %rax
	jne	.LBB0_4
	movq	8(%rsp), %rax
	vmovups	16(%rsp), %xmm0
	vmovaps	%xmm0, 32(%rsp)
	movq	%rax, 8(%rsp)
	vmovaps	32(%rsp), %xmm0
	vmovups	%xmm0, 16(%rsp)
	leaq	8(%rsp), %rdi
	callq	__rust_oom@PLT
.LBB0_2:
	movl	$4, %eax
.LBB0_4:
	testq	%rbx, %rbx
	je	.LBB0_6
	leaq	(,%rbx,4), %rsi
	movl	$4, %edx
	movq	%rax, %rdi
	callq	__rust_dealloc@PLT
.LBB0_6:
	movq	%rbx, %rax
	addq	$48, %rsp
	popq	%rbx
	retq
test out/unary/while_loop.s passed
test out/unary/vec_len.s failed - test output:
vec_len:
	cmpq	$1, %rdi
	ja	.LBB0_3
	testq	%rdi, %rdi
	je	.LBB0_4
	movl	$1, %edi
.LBB0_3:
	movq	%rdi, %rax
	retq
test out/unary/allocate_zeroed.s failed - test output:
allocate_zeroed:
	pushq	%rbx
	subq	$48, %rsp
	movq	%rdi, %rbx
	testq	%rbx, %rbx
	je	.LBB0_3
	leaq	8(%rsp), %rdx
	movl	$1, %esi
	movq	%rbx, %rdi
	callq	__rust_alloc_zeroed@PLT
	testq	%rax, %rax
	je	.LBB0_4
	movl	$1, %edx
	movq	%rax, %rdi
	movq	%rbx, %rsi
	callq	__rust_dealloc@PLT
.LBB0_3:
	movq	%rbx, %rax
	addq	$48, %rsp
	popq	%rbx
	retq
test out/unary/allocate.s passed

unary tests run - 2 successes, 4 failures


#4

Nice. You could add these as unary functions (try! and ?-conversions as identity functions). https://github.com/rust-lang/rust/issues/37939#issuecomment-332943803