Skip to content
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

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

Open
plugwash opened this issue Aug 16, 2022 · 18 comments
Open

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

plugwash opened this issue Aug 16, 2022 · 18 comments
Labels
A-atomic Area: Atomics, barriers, and sync primitives A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@plugwash
Copy link

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
@plugwash plugwash added the C-bug Category: This is a bug. label Aug 16, 2022
@workingjubilee workingjubilee added O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state O-MIPS Target: MIPS processors O-PowerPC Target: PowerPC processors A-atomic Area: Atomics, barriers, and sync primitives labels Aug 17, 2022
@workingjubilee
Copy link
Member

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: #99668

@workingjubilee
Copy link
Member

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
Copy link
Member

Amanieu commented Apr 1, 2023

LLVM bug: llvm/llvm-project#61880

@Amanieu
Copy link
Member

Amanieu commented Apr 1, 2023

@Amanieu Amanieu added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Apr 1, 2023
@Noratrieb Noratrieb added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Apr 5, 2023
@yingopq
Copy link

yingopq commented Dec 12, 2023

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
Copy link
Member

Amanieu commented Dec 12, 2023

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

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

@urosbericsyrmia
Copy link

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
Copy link
Member

Amanieu commented Mar 8, 2024

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

@urosbericsyrmia
Copy link

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

@Amanieu Amanieu removed O-MIPS Target: MIPS processors O-PowerPC Target: PowerPC processors labels Mar 25, 2024
@Amanieu
Copy link
Member

Amanieu commented Mar 25, 2024

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

*EDIT: MIPS is fixed, not ARM.

@brad0
Copy link

brad0 commented Mar 30, 2024

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

llvm/llvm-project#86424

@brad0
Copy link

brad0 commented Apr 5, 2024

LLVM 18.1.3 has been released.

@DianQK
Copy link
Member

DianQK commented Apr 12, 2024

@rustbot label llvm-fixed-upstream

@rustbot rustbot added the llvm-fixed-upstream Issue expected to be fixed by the next major LLVM upgrade, or backported fixes label Apr 12, 2024
@DianQK
Copy link
Member

DianQK commented Apr 12, 2024

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

@DianQK
Copy link
Member

DianQK commented Apr 12, 2024

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
Copy link
Member

Amanieu commented Apr 13, 2024

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

@DianQK
Copy link
Member

DianQK commented Apr 13, 2024

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

@rustbot rustbot removed the llvm-fixed-upstream Issue expected to be fixed by the next major LLVM upgrade, or backported fixes label Apr 13, 2024
jdmitrovic-syrmia added a commit to jdmitrovic-syrmia/llvm-project that referenced this issue Apr 18, 2024
In order for the following `SLT` instruction to work properly,
we need to sign-extend appropriate subwords.

In addition, subwords must remain in the same position from
before sign-extension.

Resolves llvm#61881. Also, downstream bugs rust-lang/rust#100650 and
rust-lang/rust#123772 are fixed.
jdmitrovic-syrmia added a commit to jdmitrovic-syrmia/llvm-project that referenced this issue Apr 19, 2024
In order for the following `SLT` instruction to work properly,
we need to sign-extend appropriate subwords.

In addition, subwords must remain in the same position from
before sign-extension.

Resolves llvm#61881. Also, downstream bugs rust-lang/rust#100650 and
rust-lang/rust#123772 are fixed.
@brad0
Copy link

brad0 commented Apr 24, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-atomic Area: Atomics, barriers, and sync primitives A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants