Skip to content

Commit 3be0f11

Browse files
committed
Update CmpResult to use a pointer-sized return type
As seen at [1], LLVM uses `long long` on LLP64 (to get a 64-bit integer matching pointer size) and `long` on everything else, with exceptions for AArch64 and AVR. Our current logic always uses an `i32`. This happens to work because LLVM uses 32-bit instructions to check the output on x86-64, but the GCC checks the full 64-bit register so garbage in the upper half leads to incorrect results. Update our return type to be `isize`, with exceptions for AArch64 and AVR. Fixes: rust-lang#919 [1]: https://github.com/llvm/llvm-project/blob/0cf3c437c18ed27d9663d87804a9a15ff6874af2/compiler-rt/lib/builtins/fp_compare_impl.inc#L11-L27
1 parent 157a0b7 commit 3be0f11

File tree

2 files changed

+19
-8
lines changed
  • compiler-builtins/src/float
  • libm/src/math/support

2 files changed

+19
-8
lines changed

compiler-builtins/src/float/cmp.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,23 @@
22

33
use crate::float::Float;
44
use crate::int::MinInt;
5-
6-
// https://github.com/llvm/llvm-project/blob/1e6ba3cd2fe96be00b6ed6ba28b3d9f9271d784d/compiler-rt/lib/builtins/fp_compare_impl.inc#L22
7-
#[cfg(target_arch = "avr")]
8-
pub type CmpResult = i8;
9-
10-
// https://github.com/llvm/llvm-project/blob/1e6ba3cd2fe96be00b6ed6ba28b3d9f9271d784d/compiler-rt/lib/builtins/fp_compare_impl.inc#L25
11-
#[cfg(not(target_arch = "avr"))]
12-
pub type CmpResult = i32;
5+
use crate::support::cfg_if;
6+
7+
// Taken from LLVM config:
8+
// https://github.com/llvm/llvm-project/blob/0cf3c437c18ed27d9663d87804a9a15ff6874af2/compiler-rt/lib/builtins/fp_compare_impl.inc#L11-L27
9+
cfg_if! {
10+
if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] {
11+
// Aarch64 uses `int` rather than a pointer-sized value.
12+
pub type CmpResult = i32;
13+
} else if #[cfg(target_arch = "avr")] {
14+
// AVR uses a single byte.
15+
pub type CmpResult = i8;
16+
} else {
17+
// In compiler-rt, LLP64 ABIs use `long long` and everything else uses `long`. In effect,
18+
// this means the return value is always pointer-sized.
19+
pub type CmpResult = isize;
20+
}
21+
}
1322

1423
#[derive(Clone, Copy)]
1524
enum Result {

libm/src/math/support/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ mod int_traits;
1111

1212
#[allow(unused_imports)]
1313
pub use big::{i256, u256};
14+
#[allow(unused_imports)]
15+
pub(crate) use cfg_if;
1416
pub use env::{FpResult, Round, Status};
1517
#[allow(unused_imports)]
1618
pub use float_traits::{DFloat, Float, HFloat, IntTy};

0 commit comments

Comments
 (0)