Skip to content

Commit dffaad8

Browse files
authored
Rollup merge of rust-lang#134337 - RalfJung:riscv-target-features, r=workingjubilee
reject unsound toggling of RISCV target features ~~Stacked on top of rust-lang#133417, only the last commit is new.~~ Works towards rust-lang#132618 (but more [remains to be done](rust-lang#134337 (comment))) Part of rust-lang#116344 Cc ``@beetrees`` I hope I got everything. I didn't do anything about "The f and zfinx features are incompatible" and that's not an ABI thing (right?) and I am not sure how to handle it with these ABI checks. r? ``@workingjubilee`` Ideally we'd also reject target specs that disable the `f` feature but set an ABI that requires `f`... but I don't want to duplicate this logic. I have some ideas for how maybe the entire float ABI check logic should be different, now that we have some examples of what these ABI checks look like, but that will be a future PR.
2 parents 86db97e + 934ed85 commit dffaad8

File tree

2 files changed

+72
-5
lines changed

2 files changed

+72
-5
lines changed

compiler/rustc_target/src/spec/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3166,7 +3166,7 @@ impl Target {
31663166
// Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI.
31673167
check_matches!(
31683168
&*self.llvm_abiname,
3169-
"lp64" | "lp64f" | "lp64d" | "lp64q" | "lp64e",
3169+
"lp64" | "lp64f" | "lp64d" | "lp64e",
31703170
"invalid RISC-V ABI name"
31713171
);
31723172
}

compiler/rustc_target/src/target_features.rs

+71-4
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub enum Stability<Toggleability> {
3939
allow_toggle: Toggleability,
4040
},
4141
/// This feature can not be set via `-Ctarget-feature` or `#[target_feature]`, it can only be
42-
/// set in the basic target definition. It is never set in `cfg(target_feature)`. Used in
42+
/// set in the target spec. It is never set in `cfg(target_feature)`. Used in
4343
/// particular for features that change the floating-point ABI.
4444
Forbidden { reason: &'static str },
4545
}
@@ -590,9 +590,76 @@ const RISCV_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
590590
// tidy-alphabetical-start
591591
("a", STABLE, &["zaamo", "zalrsc"]),
592592
("c", STABLE, &[]),
593-
("d", unstable(sym::riscv_target_feature), &["f"]),
594-
("e", unstable(sym::riscv_target_feature), &[]),
595-
("f", unstable(sym::riscv_target_feature), &[]),
593+
(
594+
"d",
595+
Stability::Unstable {
596+
nightly_feature: sym::riscv_target_feature,
597+
allow_toggle: |target, enable| match &*target.llvm_abiname {
598+
"ilp32d" | "lp64d" if !enable => {
599+
// The ABI requires the `d` feature, so it cannot be disabled.
600+
Err("feature is required by ABI")
601+
}
602+
"ilp32e" if enable => {
603+
// ilp32e is incompatible with features that need aligned load/stores > 32 bits,
604+
// like `d`.
605+
Err("feature is incompatible with ABI")
606+
}
607+
_ => Ok(()),
608+
},
609+
},
610+
&["f"],
611+
),
612+
(
613+
"e",
614+
Stability::Unstable {
615+
// Given that this is a negative feature, consider this before stabilizing:
616+
// does it really make sense to enable this feature in an individual
617+
// function with `#[target_feature]`?
618+
nightly_feature: sym::riscv_target_feature,
619+
allow_toggle: |target, enable| {
620+
match &*target.llvm_abiname {
621+
_ if !enable => {
622+
// Disabling this feature means we can use more registers (x16-x31).
623+
// The "e" ABIs treat them as caller-save, so it is safe to use them only
624+
// in some parts of a program while the rest doesn't know they even exist.
625+
// On other ABIs, the feature is already disabled anyway.
626+
Ok(())
627+
}
628+
"ilp32e" | "lp64e" => {
629+
// Embedded ABIs should already have the feature anyway, it's fine to enable
630+
// it again from an ABI perspective.
631+
Ok(())
632+
}
633+
_ => {
634+
// *Not* an embedded ABI. Enabling `e` is invalid.
635+
Err("feature is incompatible with ABI")
636+
}
637+
}
638+
},
639+
},
640+
&[],
641+
),
642+
(
643+
"f",
644+
Stability::Unstable {
645+
nightly_feature: sym::riscv_target_feature,
646+
allow_toggle: |target, enable| {
647+
match &*target.llvm_abiname {
648+
"ilp32f" | "ilp32d" | "lp64f" | "lp64d" if !enable => {
649+
// The ABI requires the `f` feature, so it cannot be disabled.
650+
Err("feature is required by ABI")
651+
}
652+
_ => Ok(()),
653+
}
654+
},
655+
},
656+
&[],
657+
),
658+
(
659+
"forced-atomics",
660+
Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
661+
&[],
662+
),
596663
("m", STABLE, &[]),
597664
("relax", unstable(sym::riscv_target_feature), &[]),
598665
("unaligned-scalar-mem", unstable(sym::riscv_target_feature), &[]),

0 commit comments

Comments
 (0)