about summary refs log tree commit diff
path: root/src/test/run-pass/thinlto
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-06-10 09:11:36 +0000
committerbors <bors@rust-lang.org>2017-06-10 09:11:36 +0000
commit995f741a0e3a57d4142c0590b3266514fa0a0e29 (patch)
treef1f259211c1e5dd2635b06d03d511121c6571101 /src/test/run-pass/thinlto
parente1480499b484d142dfa704ae20bd33eae518c1d0 (diff)
parent6d86f0c018b57fcb9ca12c801939130b7f8e441e (diff)
downloadrust-995f741a0e3a57d4142c0590b3266514fa0a0e29.tar.gz
rust-995f741a0e3a57d4142c0590b3266514fa0a0e29.zip
Auto merge of #42556 - scottmcm:ctz-nz, r=BurntSushi
Get LLVM to stop generating dead assembly in next_power_of_two

It turns out that LLVM can turn `@llvm.ctlz.i64(_, true)` into `@llvm.ctlz.i64(_, false)` ([`ctlz`](http://llvm.org/docs/LangRef.html#llvm-ctlz-intrinsic)) where valuable, but never does the opposite.  That leads to some silly assembly getting generated in certain cases.

A contrived-but-clear example https://is.gd/VAIKuC:
```rust
fn foo(x:u64) -> u32 {
    if x == 0 { return !0; }
    x.leading_zeros()
}
```
Generates
```asm
	testq	%rdi, %rdi
	je	.LBB0_1
	je	.LBB0_3    ; <-- wha?
	bsrq	%rdi, %rax
	xorq	$63, %rax
	retq
.LBB0_1:
	movl	$-1, %eax
	retq
.LBB0_3:
	movl	$64, %eax  ; <-- dead
	retq
```

I noticed this in `next_power_of_two`, which without this PR generates the following:
```asm
	cmpq	$2, %rcx
	jae	.LBB1_2
	movl	$1, %eax
	retq
.LBB1_2:
	decq	%rcx
	je	.LBB1_3
	bsrq	%rcx, %rcx
	xorq	$63, %rcx
	jmp	.LBB1_5
.LBB1_3:
	movl	$64, %ecx  ; <-- dead
.LBB1_5:
	movq	$-1, %rax
	shrq	%cl, %rax
	incq	%rax
	retq
```

And with this PR becomes
```asm
	cmpq	$2, %rcx
	jae	.LBB0_2
	movl	$1, %eax
	retq
.LBB0_2:
	decq	%rcx
	bsrq	%rcx, %rcx
	xorl	$63, %ecx
	movq	$-1, %rax
	shrq	%cl, %rax
	incq	%rax
	retq
```
Diffstat (limited to 'src/test/run-pass/thinlto')
0 files changed, 0 insertions, 0 deletions