Closed
Description
I am using armhf build from http://luqman.ca/rust-builds/rust-0.9-pre-3b0d486-arm-unknown-linux-gnueabihf.zip released 2013-11-12. That generates broken code with the following program:
enum Test {
A(f64),
B
}
impl Test {
fn draw(&self) {
match *self {
A(x) => println!("A {}", x),
B => println!("B")
}
}
}
fn main() {
let s = A(0.1);
s.draw();
}
When running on armhf (Samsung ARM Chromebook) the program just goes into infinite loop instead of printing A 0.1.
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
ibukanov commentedon Nov 14, 2013
http://pastebin.mozilla.org/3601836 is the asm output of compiling the above file with rustc -S source.rs
ibukanov commentedon Nov 14, 2013
Apparently it is the call to println with a floating point to blame. The following test case is enough to show the problem:
It inters oo loop after printing a=1
alexcrichton commentedon Nov 14, 2013
Are you able to get a stack trace when the program is infinite looping? Printing is actually a very large amount of machinery, so it may be helpful to reduce this down even further.
ibukanov commentedon Nov 14, 2013
Given the program:
The stack trace of the looping thread looks like oo recursion:
ibukanov commentedon Nov 14, 2013
A variation of the example without format:
also leads to oo recursion:
It is
ibukanov commentedon Nov 14, 2013
More direct test case:
So something breaks code in the float_to_str_common implementation.
chris-morgan commentedon Dec 23, 2013
I ran into this this very issue this evening (when rust-http tests were inexplicably not completing), and pinpointed the cause of failure more accurately. (I may say that after that, I was a little disappointed to find it had already been filed!)
f32
is not affected.std::num::cmath::c_double_utils::trunc
, which providesf64.trunc()
, is unsound:0f64.trunc() != 0f64
. A little transmutation (unsafe { std::cast::transmute::<f64, u64>(0f64) }.to_str_radix(2)
) consistently shows it is yielding the bits 1111111111111111111111000000000100000000000000000000000000000000 (the last 32 bits are zero) rather than 0, the expected value. (I'm not certain of the f64 layout on this architecture, but sign, exponent and mantissa should certainly all be zero.)This is as far as I have gone at present.
I suggest that this be escalated to (at the least!) high priority. It also needs more tags added.
Could someone please update this issue's title and main body to reflect the underlying problem?
emberian commentedon Dec 23, 2013
Nominating for 1.0.
chris-morgan commentedon Jan 2, 2014
@ibukanov: BTW, the stack traces showing recursion is actually bogus; I've experienced it myself on armel also, that it simply doesn't work. The backtraces are broken. But that's a separate issue (#5934, I think).
itdaniher commentedon Jan 2, 2014
Hangs indefinitely, as expected.
Prints
-00000000000000000000000000000000000000000000f32
.Any operations upon the result of 'i2f' are printed as NaN.
This is using:
rustc 0.9-pre (d5d5c50 2013-12-20 12:41:33 -0800)
host: arm-unknown-linux-gnueabihf
Any idea if this issue is related? @chris-morgan suggested f32 to not be impacted, but something's definitely wonky here.
itdaniher commentedon Jan 2, 2014
I got bored and wrote an implementation of ftoa in rust. It works fine on x86, fails miserably on armhf.
Prints
-0.123099
on x86,-0.
on ARMHF. Some combination of 'pow', 'floor', or 'log10' are seriously mucked up. (edit: to_str_radix isn't culpable)itdaniher commentedon Jan 2, 2014
This seems as if it ought to be high priority, with even fairly simple code failing to behave as expected.
@luqmana - have you encountered any related floating point weirdness on ARM? Any insights?
itdaniher commentedon Jan 3, 2014
It looks like the call to the llvm intrinsics for log10 are at least partially culpable.
prints
0
.prints
100
.itdaniher commentedon Jan 4, 2014
Minimal test case:
With optimizations on, it prints 1000000000000000000000000000000 aka 2.0, as expected, as an intrinsic function of a constant is optimized to a constant. Without optimizations, it prints 0 (wrong) as expected.
pnkfelix commentedon Jan 6, 2014
cc me
24 remaining items