-
Notifications
You must be signed in to change notification settings - Fork 234
Float CmpResult seems to be of the wrong type #919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
That's interesting, agreed that it should be a Out of curiosity, how did you notice the difference here? I guess if LLVM only reads the lower bits of the return but GCC checks the whole register, that would be visible. |
In cg_gcc, I saw the following instruction to check the result: test rax, rax while cg_llvm had: test eax, eax
From a quick glance, this is a target hook that can be overwritten by the backend (see here for Aarch64 for instance). Thanks! |
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
Oh, so I guess my searches just didn't find anything because GH doesn't index the 30k line GCC target files :) Posted a fix in #920, would you mind reviewing? |
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
Inconsistent with the compilers, the GCC docs list |
For completeness, I checked for other overrides. Doesn't seem like anything other than aarch64 uses anything different: // src/gcc/gcc/targhooks.cc
scalar_int_mode
default_libgcc_cmp_return_mode (void)
{
return word_mode;
} // src/gcc/gcc/config/aarch64/aarch64.cc
#undef TARGET_LIBGCC_CMP_RETURN_MODE
#define TARGET_LIBGCC_CMP_RETURN_MODE aarch64_libgcc_cmp_return_mode
static scalar_int_mode
aarch64_libgcc_cmp_return_mode (void)
{
return SImode;
} // src/gcc/gcc/config/rs6000/rs6000.cc
#undef TARGET_LIBGCC_CMP_RETURN_MODE
#define TARGET_LIBGCC_CMP_RETURN_MODE rs6000_abi_word_mode
static scalar_int_mode
rs6000_abi_word_mode (void)
{
return TARGET_32BIT ? SImode : DImode;
} // src/gcc/gcc/config/s390/s390.cc
#undef TARGET_LIBGCC_CMP_RETURN_MODE
#define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
static scalar_int_mode
s390_libgcc_cmp_return_mode (void)
{
return TARGET_64BIT ? DImode : SImode;
} // libgcc/config/avr/avr-lib.h
#ifdef FLOAT
#define CMPtype QItype
|
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
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
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
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
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
Yes, I'll test this with cg_gcc when the CI passes. |
Submitted https://gcc.gnu.org/pipermail/gcc-patches/2025-May/684626.html |
I think you should be able to test it whenever, the remaining failures are testing against the version we’re currently shipping (I don’t think I’ll get to that before tomorrow) |
I just ran the core tests and they now pass with this fix. |
Uh oh!
There was an error while loading. Please reload this page.
Hi.
I'm currently trying to make some new f128 tests pass for cg_gcc and I believe I found out the issue: it seems the
CmpResult
type is aliased wrongly toi32
while it should be aliased toi64
(or at leastlong
) on x86-64.The type is defined here as a
i32
while the comment just above point to this that mentions that it should be along
.Could you please double-check that it indeed should be a
long
and not ai32
?It seems like it should be a
int
on Aarch64, according to the LLVM code linked above.Thanks.
The text was updated successfully, but these errors were encountered: