Repository navigation
Open
Labels
bugSomething isn't workingSomething isn't working
Description
I’m developing a project locally that verifies whether a given CPU correctly handles AVX/SSE and other SIMD operations, and it contains a table of reference results generated on my own CPU (hopefully without any errors), which can then be used to validate the results obtained on other hardware.
I thought that testing against these reference results might be useful for this project, as it could help increase the test coverage.
With the help of AI, I automatically generated a list of potential issues from such tool, along with test code, bug explanations and possible solutions, and I hope that this can be useful and help with the project - rustc_codegen_gcc_bughunt_20260902_142949.zip
| # | Class | Candidate | Fix lines | Root cause | Introduced by |
|---|---|---|---|---|---|
| 001 | crash | back/write.rs fat-LTO codegen path SIGSEGVs instead of erroring when liblto_plugin.so is missing | n/a | -fuse-linker-plugin added unconditionally for fat LTO with no check the plugin is available; GCC's driver fails cleanly but rustc then SIGSEGVs inside libgccjit |
c92f054 |
| 004 | logic | builder.rs atomic_extremum CAS-loop comparison has no signed/unsigned variant | +18/-6 | atomic_rmw routes both signed and unsigned fetch_max/fetch_min through one comparison typed by atomic_load's fixed builtin return type, so unsigned compares silently run as signed across the sign bit | afae271 |
| 005 | memory-safety | builder.rs shuffle_vector mask-padding branch reads v2 past its length | +18/-9 | broadcasting a short vector to more than double its lanes reads v2 out of bounds in the padding loop; harmless since the mask never selects the overrun slots, but a genuine UBSan-flagged OOB read | faebf73 |
| 006 | crash | type_of.rs type_uint_from_ty returns signed GCC types for unsigned Rust types | +6/-6 | every UintTy variant mapped to the signed GCC type instead of unsigned, so simd_scatter's pointer-cast target mismatches its stored value's sign and libgccjit hard-rejects the assignment at compile time | fac57d9 |
| 008 | memory-safety | intrinsic/simd.rs gather() touches every SIMD lane's pointer even when masked off | +51/-36 | gather() dereferenced/wrote through every lane's pointer unconditionally before masking the result via shuffle_vector, so a disabled lane's null/dangling pointer got touched anyway in simd_gather and simd_scatter | not determined |
| 010 | logic | int.rs u128-to-f32 cast via __floatuntisf gets miscompiled by GCC's optimizer under a black_box barrier | n/a | u128 as f32 computes the correct runtime result via the extern __floatuntisf call, but GCC's optimizer (-O, opt-level>=1) statically folds away the assert_eq check against f32::INFINITY - an upstream GCC optimizer bug, not a backend cast-lowering bug | not determined |
| 018 | logic | builder.rs lshr/ashr share gcc_lshr's native >> with no sign-forcing cast |
+26/-4 | a value whose GCC-declared type ends up wrongly signed (e.g. via ptrtoint bridging a pointer-to-usize transmute through a signed isize) gets an arithmetic shift where a logical one (or vice versa) was required | afae271 |
| 025 | logic | intrinsic/simd.rs simd_saturating_sub negates rhs to reuse the saturating-add algorithm | +14/-11 | negating the element type's minimum value (e.g. i8::MIN) overflows and wraps back to itself instead of its true negation, corrupting the sum the borrowed saturating-add overflow check is based on, so a MIN-valued rhs lane returns a wrong, non-saturated result | d725cfb |
| 026 | logic | int.rs int_to_float_cast native branch casts using the operand's own declared sign instead of the caller-requested one | +12/-0 | uitofp/sitofp share a native-type cast with no sign-forcing cast, so a value whose GCC type ends up wrongly signed (e.g. via a pointer-to-usize transmute) converts to float using the wrong sign interpretation | 41f20fa |
| 030 | logic | std::arch::x86_64 _mm_subs_epi8/_mm_subs_epi16 return wrong values for i8::MIN/i16::MIN operands | +14/-11 (candidate 025's patch) | the pinned toolchain's stdarch implements these intrinsics via simd_saturating_sub, so this is candidate 025's negate-of-MIN saturating-sub bug reached through a different Rust API surface, not a separate libgccjit-builtin dispatch bug as originally hypothesized | d725cfb |
| 031 | crash | intrinsic/llvm.rs intrinsic() missing explicit mappings for 5 of 6 rdrand/rdseed builtins | +25/-2 | only llvm.x86.rdrand.64 had an explicit override + out-parameter repacking; its five siblings fell through to archs.rs's generated unimplemented!() catch-all and panicked instead of compiling | 68ac3a4 |
| 032 | crash | builder.rs atomic lowering always emits a _atomic*_16 libcall with no -latomic link flag | +395/-1 | every atomic op (including 16-byte cmpxchg/RMW) unconditionally calls the sized _atomic*_{size} GCC builtin instead of inlining cmpxchg16b when the feature is enabled, and the backend never adds -latomic at link time, leaving the libcall reference dangling | afae271 |
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
bjorn3 commentedon Sep 2, 2026
Atomics are not exposed on targets where libatomic is necessary because Rust guarantees that atomic operations are lock free. libatomic is not guaranteed to be lock free and thus never used. I presume the
__atomic_*_16libcalls are emitted by cg_gcc because that is the only way to tell GCC to emit atomic operations. On all targets where Rust supports atomics in the first place, this should always lower to atomic instructions and never result in calls to libatomic.antoyo commentedon Sep 2, 2026
I don't think this is always the case for GCC: I've seen some cases on Aarch64 where LSE/LSE2 is not enabled lower to a libatomic call and enabling LSE does not seem to allow GCC to drop that call.
bjorn3 commentedon Sep 2, 2026
The outlined atomics for when LSE is not known to be supported should be the
__sync_*functions which are guaranteed to be lock free, not the__atomic_*functions which may use a mutex internally. The__sync_*functions are provided by libgcc, compiler-rt and compiler_builtins rather than by libatomic.antoyo commentedon Sep 2, 2026
Can we specify the ordering with
__sync_*functions?bjorn3 commentedon Sep 2, 2026
Looks like I misremembered what functions
-moutline-atomicsproduces on arm64. It uses__aarch64_*functions: https://rust.godbolt.org/z/fnvhv4sn1