rust-lang / rust-lang/rust

`lto=fat` results in compressed RV64 instructions even when they are explicitly disabled

Open
#154,436 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug needs-triage
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried to compile a shared library with the following custom target:

{
  "arch": "riscv64",
  "code-model": "medium",
  "cpu": "generic-rv64",
  "crt-objects-fallback": "false",
  "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
  "only-cdylib": true,
  "eh-frame-header": false,
  "emit-debug-gdb-scripts": false,
  "features": "+m,+b,+zbc,+zknh,+unaligned-scalar-mem",
  "linker": "rust-lld",
  "linker-flavor": "ld.lld",
  "llvm-abiname": "lp64",
  "llvm-target": "riscv64",
  "max-atomic-width": 64,
  "panic-strategy": "immediate-abort",
  "position-independent-executables": true,
  "relro-level": "full",
  "static-position-independent-executables": true,
  "target-pointer-width": 64,
  "relocation-model": "pie",
  "singlethread": true,
  "dynamic-linking": true,
  "default-visibility": "hidden",
  "pre-link-args": {
    "ld": [
      "-Bsymbolic"
    ]
  },
  "dll-prefix": "",
  "dll-suffix": ".contract.so",
  "env": "abundance"
}

It works as expected with release profile, producing the code according to the specification, file says:

ELF 64-bit LSB shared object, UCB RISC-V, soft-float ABI, version 1 (GNU/Linux), static-pie linked, not stripped

Things change when I compile it for this custom profile:

[profile.contract]
inherits = "release"
lto = "fat"

I expected to see this happen:

Same kind of shared library is produced.

Instead, this happened:

ELF 64-bit LSB shared object, UCB RISC-V, RVC, soft-float ABI, version 1 (GNU/Linux), static-pie linked, not stripped

RVC is not what I requested though. Moreover, adding -c,-zca,-zcb to features explicitly makes no difference, I still see compressed instructions like c.or, c.sd, c.li, etc.

Possibly related to https://github.com/rust-lang/rust/issues/147667 ?

Meta

rustc --version --verbose:

rustc 1.96.0-nightly (3b1b0ef4d 2026-03-11)
binary: rustc
commit-hash: 3b1b0ef4d80d3117924d91352c8b6ca528708b3c
commit-date: 2026-03-11
host: x86_64-unknown-linux-gnu
release: 1.96.0-nightly
LLVM version: 22.1.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the custom RISC-V target with the release profile and with profile.contract using lto = "fat"; compare the file output and generated instructions. Start by tracing how the target feature settings are passed through the compiler's LTO/codegen path. Done means compressed instructions are not emitted when the relevant compressed extensions are disabled.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.