rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.33k stars 12.72k forks source link

fetch_max broken for atomici8 and atomici16 on some targets. #100650

Open plugwash opened 2 years ago

plugwash commented 2 years ago

The rust atomic crate was recently uploaded to Debian, unfortunately on a number of Debian architectures it's tests failed.

---- tests::atomic_i16 stdout ----
thread 'tests::atomic_i16' panicked at 'assertion failed: `(left == right)`
  left: `-25`,
 right: `30`', src/lib.rs:448:9
---- tests::atomic_i8 stdout ----
thread 'tests::atomic_i8' panicked at 'assertion failed: `(left == right)`
  left: `-25`,
 right: `30`', src/lib.rs:428:9

The debian architectures where it failed and the corresponding rust architectures are listed below.

armel -> armv5te-unknown-linux-gnueabi mips64el -> mips64el-unknown-linux-gnuabi64 mipsel -> mipsel-unknown-linux-gnu powerpc -> powerpc-unknown-linux-gnu

My guess is that this is a bug in fallback code used when the architecture does not natively support 8 and 16 bit atomics.

I produced the following testcase to confirm this was not a problem in the atomic crate, but instead an issue in either the compiler or the standard library. I tested this on Debian armel.

use std::sync::atomic::Ordering::SeqCst;
use std::sync::atomic::AtomicI8;
use std::sync::atomic::AtomicI16;
use std::sync::atomic::AtomicI32;
fn main() {
    let a = AtomicI8::new(30);
    println!("{}",a.fetch_max(-25,SeqCst));
    println!("{}",a.load(SeqCst));
    let a = AtomicI16::new(30);
    println!("{}",a.fetch_max(-25,SeqCst));
    println!("{}",a.load(SeqCst));
    let a = AtomicI32::new(30);
    println!("{}",a.fetch_max(-25,SeqCst));
    println!("{}",a.load(SeqCst));
}

I expected this to print 30 six times, but the second and fourth lines of the output are instead -25, this shows fetch_max is not being implemented correctly for AtomicI8 and AtomicI16 (but is being implemented correctly for AtomicI32).

I've only tested this with Debian's rustc so far, I may try to test with upstream rustc but this is complicated by the fact that I don't think upstream offers binaries for armv5te-unknown-linux-gnueabi

Meta

rustc --version --verbose:

rustc 1.59.0
binary: rustc
commit-hash: unknown
commit-date: unknown
host: armv5te-unknown-linux-gnueabi
release: 1.59.0
LLVM version: 13.0.1
workingjubilee commented 2 years ago

I've only tested this with Debian's rustc so far, I may try to test with upstream rustc but this is complicated by the fact that I don't think upstream offers binaries for armv5te-unknown-linux-gnueabi

Correct, unfortunately. This will likely require building from source. Please feel free to open any issues you run into if you do that. Also, we currently use a version of LLVM 15, recently upgraded from LLVM 14. It would be useful to know if using the old LLVM is what decides the matter.

Unfortunately, LLVM has reduced their support for atomics on some platforms, and Rust attempts to avoid exposing anything but hardware atomics, so there might even be flat-out regressions on some of these: https://github.com/rust-lang/rust/issues/99668

workingjubilee commented 1 year ago

Also:

armv5te-unknown-linux-gnueabi

This is in fact a tier 2 platform, apparently, so we do distribute std for this target and you can cross-compile for it.

Amanieu commented 1 year ago

LLVM bug: https://github.com/llvm/llvm-project/issues/61880

Amanieu commented 1 year ago

And 2 more LLVM bugs in the MIPS and PowerPC backends:

yingopq commented 11 months ago

Hi @plugwash @Amanieu,

I have tested the testcase in my lab, and the results were as expected.

The target environment is mips64el, Debian GNU/Linux 11, gcc version 12.2.0, glibc 2.36-9, kernel version 5.10.0-22-loongson-3.

$ ./test2
30
30
30
30
30
30

And the cross compile environment is x86:

$ ~/rust-test/bin/rustc --version --verbose
rustc 1.76.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.76.0-dev
LLVM version: 17.0.5

$ ~/rust-test/bin/rustc --target mips64el-unknown-linux-gnuabi64 -Clinker=mips64el-linux-gnuabi64-gcc -Ctarget-feature=+crt-static -Clink-arg=-static -o test2 ./src/main.rs
Amanieu commented 11 months ago

LLVM seems to still generate incorrect assembly: https://godbolt.org/z/z9TxWTrzq

I'm not sure why it's working for you.

urosbericsyrmia commented 8 months ago

I have tried to reproduce the issue for mipsel and it is working fine. Can you confirm that you are still seeing the issue?

Amanieu commented 8 months ago

The bug has been fixed in upstream LLVM (https://github.com/llvm/llvm-project/pull/77072) and will be back-ported to the 18.x branch used by rustc.

urosbericsyrmia commented 7 months ago

I suggest we remove the O-MIPS label due to the bug being fixed in upstream LLVM for MIPS targets.

Amanieu commented 7 months ago

I've removed the MIPS and PowerPC label since those are now fixed.

*EDIT: MIPS is fixed, not ARM.

brad0 commented 7 months ago

I had the MIPS fix merged into the 18 branch and will be out for 18.1.3.

https://github.com/llvm/llvm-project/pull/86424

brad0 commented 7 months ago

LLVM 18.1.3 has been released.

DianQK commented 7 months ago

@rustbot label llvm-fixed-upstream

DianQK commented 7 months ago

Hmm, I can confirm that the issue has been fixed in af2525317be950fdae635bcbb46b3e755d14ab49. This is LLVM 18.1.2. However, it's broken in 18.1.3.

DianQK commented 7 months ago

LLVM seems to still generate incorrect assembly: https://godbolt.org/z/z9TxWTrzq

I'm not sure why it's working for you.

I don't know anything with MIPS, but judging from the output, it seems that 18.1.2 has resolved these two issues. I will try to find the relevant commit.

Amanieu commented 7 months ago

Yes, MIPS seems to be fixed. It's just ARM that still has the bug (https://github.com/llvm/llvm-project/issues/61880).

DianQK commented 7 months ago

Yes, MIPS seems to be fixed. It's just ARM that still has the bug (llvm/llvm-project#61880).

Thanks. We still need to fix the ARM issue. @rustbot label -llvm-fixed-upstream

brad0 commented 6 months ago

The MIPS patch set was reverted for the 18 branch. But a proper fixed patch set will be hashed out for the 19 release.