rust-lang / rust-lang/rustc_codegen_gcc
[AI] Bunch of bugs found by autonomous scanner
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 1.2k
- Forks
- 105
- Avg merge
- 8h 20m
- Merged PRs (30d)
- 14
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 |
c92f0540 |
| 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 | faebf739 |
| 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 | fac57d9a |
| 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 | afae271d |
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Unpack the attached archive and choose one candidate from the table, starting with the named file such as back/write.rs, builder.rs, type_of.rs, intrinsic/simd.rs, int.rs, or intrinsic/llvm.rs. Reproduce the reported behavior on the affected path and verify that the candidate's stated failure is resolved without introducing the described crash, incorrect result, or memory-safety issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend, compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100