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

[RISCV] Code model other than medium does not work with lto #139479

Open
kxxt opened this issue Apr 7, 2025 · 11 comments
Open

[RISCV] Code model other than medium does not work with lto #139479

kxxt opened this issue Apr 7, 2025 · 11 comments
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-LTO Area: Link-time optimization (LTO) C-bug Category: This is a bug. I-prioritize Issue: Indicates that prioritization has been requested for this issue. O-riscv Target: RISC-V architecture regression-from-stable-to-stable Performance or correctness regression from one stable version to another. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue

Comments

@kxxt
Copy link
Contributor

kxxt commented Apr 7, 2025

I tried this code:

// hello.rs
fn main() {
    println!("Hello, world!");
}
// command on riscv64
rustc -C code-model=large -C lto hello.rs
// command on x86_64
rustc --target riscv64gc-unknown-linux-gnu -C code-model=large -C lto hello.rs

I expected to see this happen: code compiles without error

Instead, this happened: failed to load bitcode of module "addr2line-*"

on riscv64, archrv rust:

$ rustc -C code-model=large -C lto hello.rs
warning: linking module flags 'Code Model': IDs have conflicting values in '' and 'hello.8b1675587fc60370-cgu.0'

error: failed to load bitcode of module "addr2line-4a5a0cf02a84c587.addr2line.d0fbcb35ed0a8d23-cgu.0.rcgu.o": 

error: aborting due to 1 previous error; 1 warning emitted

On x86_64, latest stable from rustup:

rustc --target riscv64gc-unknown-linux-gnu -C code-model=large -C lto hello.rs
warning: linking module flags 'Code Model': IDs have conflicting values in '' and 'hello.eea8546ba018bd24-cgu.0'

error: failed to load bitcode of module "addr2line-28336428312034c6.addr2line.134ee917f0cf37e1-cgu.0.rcgu.o": 

error: aborting due to 1 previous error; 1 warning emitted

On x86_64, Nightly:

rustc +nightly --target riscv64gc-unknown-linux-gnu -C code-model=large -C lto hello.rs
warning: linking module flags 'Code Model': IDs have conflicting values: 'i32 3' from , and 'i32 4' from hello.4a3c48060548947b-cgu.0

error: failed to load bitcode of module "addr2line-62ef9fdb0627a182.addr2line.746071221f6a6099-cgu.0.rcgu.o": 

error: aborting due to 1 previous error; 1 warning emitted

Meta

rustc --version --verbose:

rustc 1.85.1 (4eb161250 2025-03-15) (Arch Linux rust 1:1.85.1-1)
binary: rustc
commit-hash: 4eb161250e340c8f48f66e2b929ef4a5bed7c181
commit-date: 2025-03-15
host: riscv64gc-unknown-linux-gnu
release: 1.85.1
LLVM version: 19.1.7
rustc 1.86.0 (05f9846f8 2025-03-31)
binary: rustc
commit-hash: 05f9846f893b09a1be1fc8560e33fc3c815cfecb
commit-date: 2025-03-31
host: x86_64-unknown-linux-gnu
release: 1.86.0
LLVM version: 19.1.7
rustc 1.88.0-nightly (5e17a2a91 2025-04-05)
binary: rustc
commit-hash: 5e17a2a91dd7dbefd8b4a1087c2e42257457deeb
commit-date: 2025-04-05
host: x86_64-unknown-linux-gnu
release: 1.88.0-nightly
LLVM version: 20.1.2

This is specific to RISC-V. The same code works fine for x86_64 and aarch64 target. e.g.

rustc +nightly --target aarch64-unknown-linux-gnu -C code-model=large -C lto hello.rs -C linker=/bin/aarch64-linux-gnu-gcc 
@kxxt kxxt added the C-bug Category: This is a bug. label Apr 7, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 7, 2025
@kxxt
Copy link
Contributor Author

kxxt commented Apr 7, 2025

@rustbot label +O-riscv +A-LTO +A-LLVM +S-has-mcve

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-LTO Area: Link-time optimization (LTO) O-riscv Target: RISC-V architecture S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue labels Apr 7, 2025
@kxxt
Copy link
Contributor Author

kxxt commented Apr 7, 2025

rustc +1.42 --target riscv64gc-unknown-linux-gnu -C code-model=large -C lto hello.rs -C linker=/bin/riscv64-linux-gnu-gcc works. This is a regression.

@rustbot label +regression-from-stable-to-stable

@rustbot rustbot added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Apr 7, 2025
@kxxt
Copy link
Contributor Author

kxxt commented Apr 7, 2025

This regression is first introduced in 1.52.0.

@kxxt
Copy link
Contributor Author

kxxt commented Apr 7, 2025

cargo-bisect-rustc:

********************************************************************************
Regression in nightly-2021-03-15
********************************************************************************

fetching https://static.rust-lang.org/dist/2021-03-14/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2021-03-14: 40 B / 40 B [=============================================================================================================================================================================] 100.00 % 1.29 MB/s converted 2021-03-14 to acca818928654807ed3bc1ce0e97df118f8716c8
fetching https://static.rust-lang.org/dist/2021-03-15/channel-rust-nightly-git-commit-hash.txt
nightly manifest 2021-03-15: 40 B / 40 B [=============================================================================================================================================================================] 100.00 % 1.61 MB/s converted 2021-03-15 to d6eaea1c8860adb5302d2fbaad409e36585ab217
looking for regression commit between 2021-03-14 and 2021-03-15
fetching (via remote github) commits from max(acca818928654807ed3bc1ce0e97df118f8716c8, 2021-03-12) to d6eaea1c8860adb5302d2fbaad409e36585ab217
ending github query because we found starting sha: acca818928654807ed3bc1ce0e97df118f8716c8
get_commits_between returning commits, len: 8
  commit[0] 2021-03-13: Auto merge of #83064 - cjgillot:fhash, r=jackh726
  commit[1] 2021-03-14: Auto merge of #83105 - JohnTitor:rollup-tqpm8pb, r=JohnTitor
  commit[2] 2021-03-14: Auto merge of #83028 - GuillaumeGomez:prevent-js-error-if-no-filter, r=Nemo157
  commit[3] 2021-03-14: Auto merge of #83094 - GuillaumeGomez:crates-js-location, r=Nemo157
  commit[4] 2021-03-14: Auto merge of #83044 - kubo39:set-llvm-code-model, r=nikic
  commit[5] 2021-03-14: Auto merge of #83082 - cjgillot:defkey-ii, r=oli-obk
  commit[6] 2021-03-14: Auto merge of #82399 - petrochenkov:modin2, r=Aaron1011
  commit[7] 2021-03-14: Auto merge of #83062 - JohnTitor:improve-reassign-err, r=davidtwco
ERROR: no CI builds available between acca818928654807ed3bc1ce0e97df118f8716c8 and d6eaea1c8860adb5302d2fbaad409e36585ab217 within last 167 days

So it is probably this one: #83044

kxxt added a commit to kxxt/archriscv-packages that referenced this issue Apr 7, 2025
- Use large code model to workaround "relocation truncated to fit"
- Disable LTO because setting code model to anything other than medium
  fails to build with LTO.
  - Bisected and reported as rust-lang/rust#139479
@kxxt
Copy link
Contributor Author

kxxt commented Apr 7, 2025

Probably related to https://github.com/rust-lang/rust/blob/master/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs#L18

riscv is among the architectures with target_options.code_model set.

@apiraino
Copy link
Contributor

apiraino commented Apr 7, 2025

#83044 was a while ago, unsure if something changed for the riscv64gc-unknown-linux-gnu compile target.

cc: riscv maintainers in case they have an opinion (sorry for the mass mention)

@kito-cheng
@michaelmaitland
@robin-randhawa-sifive
@topperc

@saethlin
Copy link
Member

saethlin commented Apr 7, 2025

The code model for that target has always been "medium".

Rust 1.52.0 contains an LLVM upgrade. I bet the "regression" here is actually a fix from llvm/llvm-project#32653

@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 7, 2025
felixonmars pushed a commit to felixonmars/archriscv-packages that referenced this issue Apr 7, 2025
- Use large code model to workaround "relocation truncated to fit"
- Disable LTO because setting code model to anything other than medium
  fails to build with LTO.
  - Bisected and reported as rust-lang/rust#139479
@kxxt
Copy link
Contributor Author

kxxt commented Apr 8, 2025

#83044 probably only reveals this bug instead of causing it.

warning: linking module flags 'Code Model': IDs have conflicting values: 'i32 3' from , and 'i32 4' from hello.4a3c48060548947b-cgu.0

There is an unnamed module carrying the medium code model, which is causing this bug. Any idea on how to find out what it is? The large code model from codegen options seems not applied to it.

@bjorn3
Copy link
Member

bjorn3 commented Apr 8, 2025

Could be the allocator shim:

let module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
let cx =
SimpleCx::new(module_llvm.llmod(), &module_llvm.llcx, tcx.data_layout.pointer_size);
unsafe {
allocator::codegen(tcx, cx, module_name, kind, alloc_error_handler_kind);
}
module_llvm

@kxxt
Copy link
Contributor Author

kxxt commented Apr 8, 2025

I think I get it. When code_model is set in TargetOptions(e.g. riscv64gc-unknown-linux-gnu sets it to Medium),
the generated LLVM bitcode embeded in fat lto object in libadler2-20d8a55a46d89958.rlib contains !2 = !{i32 1, !"Code Model", i32 3}, which then causes the above error when using -C code-model=large option because the prebuilt libadler2 rlib is using Medium code model and LLVM 12 starts to forbid that.

However, when code_model is not set in TargetOptions(e.g. x86_64), the generated LLVM bitcode embeded in fat lto object in libadler2-*.rlib uses the default code model and would not contain the Code Model option. But when we manually set -C code-model=whatever-not-the-default later when building hello.rs, we are still linking modules with different Code Models together. It is just that LLVM is not complaining about it because the prebuilt rlibs does not have Code Model set in their module flags, silently triggering undefined behavior on x86_64.

So I think #83044 is an incomplete fix and thus unfortunately using non-default code model with LTO is not possible in Rust without building std and all dependencies from source again. Session::code_model() should be updated to always return Some(DEFAULT_LLVM_CODE_MODEL_FOR_TARGET) in default case instead of returning None.

@kxxt
Copy link
Contributor Author

kxxt commented Apr 8, 2025

I see that there is a None code model.

If not setting code model does not mean using the default code model and instead bitcode without code model makes sense. I think we should compile target rust sysroot without specifying the code model. Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-LTO Area: Link-time optimization (LTO) C-bug Category: This is a bug. I-prioritize Issue: Indicates that prioritization has been requested for this issue. O-riscv Target: RISC-V architecture regression-from-stable-to-stable Performance or correctness regression from one stable version to another. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue
Projects
None yet
Development

No branches or pull requests

5 participants