Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ pub(crate) fn target_machine_factory(
let triple = SmallCStr::new(&versioned_llvm_target(sess));
let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
let features = CString::new(sess.global_backend_features.join(",")).unwrap();
let abi = SmallCStr::new(sess.target.llvm_abiname.desc());
let abi = SmallCStr::new(llvm_util::target_abi(sess));
let trap_unreachable =
sess.opts.unstable_opts.trap_unreachable.unwrap_or(sess.target.trap_unreachable);
let emit_stack_size_section = sess.opts.unstable_opts.emit_stack_sizes;
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,13 +563,12 @@ pub(crate) unsafe fn create_module<'ll>(
// to workaround lld as the LTO plugin not
// correctly setting target-abi for the LTO object
// FIXME: https://github.com/llvm/llvm-project/issues/50591
let llvm_abiname = &sess.target.options.llvm_abiname;
if matches!(sess.target.arch, Arch::RiscV32 | Arch::RiscV64) {
llvm::add_module_flag_str(
llmod,
llvm::ModuleFlagMergeBehavior::Error,
"target-abi",
llvm_abiname.desc(),
llvm_util::target_abi(sess),
);
}

Expand Down
35 changes: 33 additions & 2 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use rustc_data_structures::small_c_str::SmallCStr;
use rustc_fs_util::path_to_c_string;
use rustc_session::config::{NATIVE_CPU, PrintKind, PrintRequest};
use rustc_session::{EarlySession, Session};
use rustc_span::bug;
use rustc_span::{Symbol, bug};
use rustc_target::spec::{
Arch, CfgAbi, Env, MergeFunctions, Os, PanicStrategy, SmallDataThresholdSupport, Target,
Arch, CfgAbi, Env, LlvmAbi, MergeFunctions, Os, PanicStrategy, SmallDataThresholdSupport, Target,
};
use smallvec::{SmallVec, smallvec};

Expand Down Expand Up @@ -812,3 +812,34 @@ pub(crate) fn target_has_mnemonic(sess: &Session, mnemonic: &str) -> bool {
let cstr = SmallCStr::new(mnemonic);
unsafe { llvm::LLVMRustTargetHasMnemonic(tm.raw(), cstr.as_ptr()) }
}

pub(crate) fn target_abi(sess: &Session) -> &str {
if get_version().0 >= 24 && matches!(sess.target.arch, Arch::RiscV32 | Arch::RiscV64) {
let has_feature =
|feat: &str| sess.internal_target_features.contains(&Symbol::intern(feat));
match sess.target.llvm_abiname {
// On LLVM 24+, `computeTargetABI()` treats an ABI requiring `d` (or `f`) as a fatal
// error if the feature is disabled (e.g. via `-Ctarget-feature=-d`). Fall back to a
// compatible ABI so that LLVM module asm parsing (e.g. for `.llvmbc`) succeeds.
LlvmAbi::Ilp32d if !has_feature("d") => {
if has_feature("f") {
LlvmAbi::Ilp32f.desc()
} else {
LlvmAbi::Ilp32.desc()
}
}
LlvmAbi::Lp64d if !has_feature("d") => {
if has_feature("f") {
LlvmAbi::Lp64f.desc()
} else {
LlvmAbi::Lp64.desc()
}
}
LlvmAbi::Ilp32f if !has_feature("f") => LlvmAbi::Ilp32.desc(),
LlvmAbi::Lp64f if !has_feature("f") => LlvmAbi::Lp64.desc(),
_ => sess.target.llvm_abiname.desc(),
}
} else {
sess.target.llvm_abiname.desc()
}
}
Loading