Skip to content
Draft
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
6 changes: 6 additions & 0 deletions compiler/rustc_codegen_llvm/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ pub(crate) struct FixedX18InvalidArch<'a> {
pub arch: &'a str,
}

#[derive(Diagnostic)]
#[diag("the `-Zmips-nan2008` flag is not supported on the `{$arch}` architecture")]
pub(crate) struct MipsNan2008InvalidArch<'a> {
pub arch: &'a str,
}

#[derive(Diagnostic)]
#[diag("`-Zpacked-stack` is incompatible with `backchain` target feature")]
#[note(
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,19 @@ fn llvm_features_by_flags(sess: &Session, features: &mut Vec<String>) {
features.push("+reserve-x18".into());
}
}

// -Zmips-nan2008
if sess.opts.unstable_opts.mips_nan2008 {
match sess.target.arch {
Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => {
features.push("+nan2008".into());
}
_ => {
sess.dcx()
.emit_fatal(errors::MipsNan2008InvalidArch { arch: sess.target.arch.desc() });
}
}
}
}

/// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(min_function_alignment, Some(Align::EIGHT));
tracked!(min_recursion_limit, Some(256));
tracked!(mips_nan2008, true);
tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]);
tracked!(mir_opt_level, Some(4));
tracked!(mir_preserve_ub, true);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2579,6 +2579,8 @@ options! {
"align all functions to at least this many bytes. Must be a power of 2"),
min_recursion_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
"set a minimum recursion limit (final limit = max(this, recursion_limit_from_crate))"),
mips_nan2008: bool = (false, parse_bool, [TRACKED] { TARGET_MODIFIER: MipsNan2008 },
"enable the nan2008 target feature (IEEE 754-2008 NaN encoding) on MIPS targets (default: no)"),
mir_enable_passes: Vec<(String, bool)> = (Vec::new(), parse_list_with_polarity, [TRACKED],
"use like `-Zmir-enable-passes=+DestinationPropagation,-InstSimplify`. Forces the \
specified passes to be enabled, overriding all other checks. In particular, this will \
Expand Down
24 changes: 24 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/mips-nan2008.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# `mips-nan2008`

This option enables the LLVM `nan2008` subtarget feature on MIPS targets. It is
only supported on `mips`, `mips32r6`, `mips64`, and `mips64r6` architectures.
Using this flag on other targets is an error.

When enabled, this flag causes the compiler to select the IEEE 754-2008 NaN
encoding for MIPS targets, as opposed to the legacy MIPS NaN encoding. This is
useful when linking against C libraries and toolchains built with GCC's
`-mnan=2008` flag, or when the system ABI mandates the 2008 NaN encoding.

This flag is a target modifier. All crates in the crate graph must agree on
whether the `mips-nan2008` flag is used. The compiler will emit an error if
crates with conflicting settings are linked together. This error can be bypassed
at your own risk using the `-Cunsafe-allow-abi-mismatch=mips-nan2008` flag,
though this may cause runtime failures if the ABIs are truly incompatible.

## Example

To compile code for MIPS with the 2008 NaN encoding:

```sh
rustc -Zmips-nan2008 --target mips-unknown-linux-gnu example.rs
```
23 changes: 23 additions & 0 deletions tests/codegen-llvm/mips-nan2008.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Test that the `nan2008` target feature is (not) emitted when
// the `-Zmips-nan2008` flag is (not) set.

//@ add-minicore
//@ revisions: unset set
//@ needs-llvm-components: mips
//@ compile-flags: --target mips-unknown-linux-gnu
//@ [set] compile-flags: -Zmips-nan2008

#![crate_type = "lib"]
#![feature(no_core, lang_items)]
#![no_core]

extern crate minicore;
use minicore::*;

#[no_mangle]
pub fn foo() {
// CHECK: @foo() unnamed_addr #0

// unset-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+nan2008{{.*}} }
// set: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+nan2008{{.*}} }
}
7 changes: 7 additions & 0 deletions tests/ui/target_modifiers/auxiliary/mips_nan2008.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//@ no-prefer-dynamic
//@ compile-flags: --target mips-unknown-linux-gnu -Zmips-nan2008
//@ needs-llvm-components: mips

#![feature(no_core)]
#![crate_type = "rlib"]
#![no_core]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: mixing `-Zmips-nan2008` will cause an ABI mismatch in crate `incompatible_mips_nan2008`
--> $DIR/incompatible_mips_nan2008.rs:13:1
|
LL | #![feature(no_core)]
| ^
|
= help: the `-Zmips-nan2008` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
= note: unset `-Zmips-nan2008` in this crate is incompatible with `-Zmips-nan2008=` in dependency `mips_nan2008`
= help: set `-Zmips-nan2008=` in this crate or unset `-Zmips-nan2008` in `mips_nan2008`
= help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=mips-nan2008` to silence this error

error: aborting due to 1 previous error

18 changes: 18 additions & 0 deletions tests/ui/target_modifiers/incompatible_mips_nan2008.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ aux-build:mips_nan2008.rs
//@ compile-flags: --target mips-unknown-linux-gnu
//@ needs-llvm-components: mips

//@ revisions:allow_match allow_mismatch error_generated
//@[allow_match] compile-flags: -Zmips-nan2008
//@[allow_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=mips-nan2008
// [error_generated] no extra compile-flags
//@[allow_mismatch] check-pass
//@[allow_match] check-pass
//@ ignore-backends: gcc

#![feature(no_core)]
//[error_generated]~^ ERROR mixing `-Zmips-nan2008` will cause an ABI mismatch in crate `incompatible_mips_nan2008`
#![crate_type = "rlib"]
#![no_core]

extern crate mips_nan2008;
Loading