Closed
Description
This small program solves the Euler problem n.97:
#[inline(never)]
fn e97() -> u64 {
// Input.
const BASE: f64 = 28_433.0;
const EXP: u64 = 7_830_457;
const BIG: f64 = 1e10;
let mut b = 1;
while b < EXP { b <<= 1; }
let mut n = 1.0;
while b > 0 {
if EXP & b != 0 {
n = (n * n * 2.0) % BIG;
} else {
n = (n * n) % BIG;
}
b >>= 1;
}
((n * BASE + 1.0) % BIG) as u64
}
fn main() {
assert_eq!(e97(), 8_739_992_577);
}
If I compile it with normal compilation arguments like this it works correctly:
rustc -C lto -O -C target-cpu=haswell e97.rs
If I compile it with -C target-cpu=native or like this, it asserts at run time:
rustc -C lto -O -C target-cpu=haswell e97.rs
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `9246255105`,
right: `8739992577`', e97.rs:27:4
The asm compiling with:
rustc -C lto -O --emit asm e97.rs
_ZN3e973e9717h3d13175579ebef2eE:
pushq %rsi
subq $48, %rsp
movaps %xmm6, 32(%rsp)
movsd .LCPI1_0(%rip), %xmm0
movl $8388608, %esi
movsd .LCPI1_1(%rip), %xmm6
.p2align 4, 0x90
.LBB1_1:
testl $7830457, %esi
mulsd %xmm0, %xmm0
je .LBB1_3
addsd %xmm0, %xmm0
.LBB1_3:
movaps %xmm6, %xmm1
callq fmod
testl $15660914, %esi
mulsd %xmm0, %xmm0
je .LBB1_5
addsd %xmm0, %xmm0
.LBB1_5:
movaps %xmm6, %xmm1
callq fmod
shrq $2, %rsi
jne .LBB1_1
mulsd .LCPI1_2(%rip), %xmm0
addsd .LCPI1_0(%rip), %xmm0
movsd .LCPI1_1(%rip), %xmm1
callq fmod
movsd .LCPI1_3(%rip), %xmm1
movapd %xmm0, %xmm2
subsd %xmm1, %xmm2
cvttsd2si %xmm2, %rax
movabsq $-9223372036854775808, %rcx
xorq %rax, %rcx
cvttsd2si %xmm0, %rax
ucomisd %xmm1, %xmm0
cmovaeq %rcx, %rax
movaps 32(%rsp), %xmm6
addq $48, %rsp
popq %rsi
retq
The asm compiling with:
rustc -C lto -O -C target-cpu=haswell --emit asm e97.rs
_ZN3e973e9717h3d13175579ebef2eE:
.loc 24 0 0 is_stmt 0
movabsq $9246255105, %rax
retq