Skip to content

Commit e49929e

Browse files
authored
Rollup merge of #134932 - RalfJung:arm-float-abi, r=workingjubilee
explicitly set float ABI for all ARM targets We currently always set the `FloatABIType` field in the LLVM target machine to `Default`, which means LLVM infers the ARM float ABI (hard vs soft) from the LLVM target triple. This causes problems such as having to set the LLVM triple to `*-gnueabi` for our `musleabi` targets to ensure they get correctly inferred as soft-float targets. It also means rustc doesn't really know which float ABI ends up being used, which is a blocker for #134794. So I think we should stop doing that and instead explicitly control that value. That's what this PR implements. See [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/187780-t-compiler.2Fwg-llvm/topic/Softfloat.20ABI.2C.20hardfloat.20instructions) for more context. Best reviewed commit-by-commit. I hope I got all those `llvm_floatabi` values right...
2 parents fa6990c + c3189c5 commit e49929e

File tree

66 files changed

+258
-103
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+258
-103
lines changed

compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ impl OwnedTargetMachine {
2525
model: llvm::CodeModel,
2626
reloc: llvm::RelocModel,
2727
level: llvm::CodeGenOptLevel,
28-
use_soft_fp: bool,
28+
float_abi: llvm::FloatAbi,
2929
function_sections: bool,
3030
data_sections: bool,
3131
unique_section_names: bool,
@@ -57,7 +57,7 @@ impl OwnedTargetMachine {
5757
model,
5858
reloc,
5959
level,
60-
use_soft_fp,
60+
float_abi,
6161
function_sections,
6262
data_sections,
6363
unique_section_names,

compiler/rustc_codegen_llvm/src/back/write.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc_session::config::{
2626
self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath,
2727
};
2828
use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext, sym};
29-
use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
29+
use rustc_target::spec::{CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
3030
use tracing::debug;
3131

3232
use crate::back::lto::ThinBuffer;
@@ -181,6 +181,14 @@ pub(crate) fn to_llvm_code_model(code_model: Option<CodeModel>) -> llvm::CodeMod
181181
}
182182
}
183183

184+
fn to_llvm_float_abi(float_abi: Option<FloatAbi>) -> llvm::FloatAbi {
185+
match float_abi {
186+
None => llvm::FloatAbi::Default,
187+
Some(FloatAbi::Soft) => llvm::FloatAbi::Soft,
188+
Some(FloatAbi::Hard) => llvm::FloatAbi::Hard,
189+
}
190+
}
191+
184192
pub(crate) fn target_machine_factory(
185193
sess: &Session,
186194
optlvl: config::OptLevel,
@@ -189,12 +197,12 @@ pub(crate) fn target_machine_factory(
189197
let reloc_model = to_llvm_relocation_model(sess.relocation_model());
190198

191199
let (opt_level, _) = to_llvm_opt_settings(optlvl);
192-
let use_softfp = if sess.target.arch == "arm" {
193-
sess.opts.cg.soft_float
200+
let float_abi = if sess.target.arch == "arm" && sess.opts.cg.soft_float {
201+
llvm::FloatAbi::Soft
194202
} else {
195203
// `validate_commandline_args_with_session_available` has already warned about this being
196204
// ignored. Let's make sure LLVM doesn't suddenly start using this flag on more targets.
197-
false
205+
to_llvm_float_abi(sess.target.llvm_floatabi)
198206
};
199207

200208
let ffunction_sections =
@@ -290,7 +298,7 @@ pub(crate) fn target_machine_factory(
290298
code_model,
291299
reloc_model,
292300
opt_level,
293-
use_softfp,
301+
float_abi,
294302
ffunction_sections,
295303
fdata_sections,
296304
funique_section_names,

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ pub struct SanitizerOptions {
526526
pub sanitize_kernel_address_recover: bool,
527527
}
528528

529-
/// LLVMRelocMode
529+
/// LLVMRustRelocModel
530530
#[derive(Copy, Clone, PartialEq)]
531531
#[repr(C)]
532532
pub enum RelocModel {
@@ -538,6 +538,15 @@ pub enum RelocModel {
538538
ROPI_RWPI,
539539
}
540540

541+
/// LLVMRustFloatABI
542+
#[derive(Copy, Clone, PartialEq)]
543+
#[repr(C)]
544+
pub enum FloatAbi {
545+
Default,
546+
Soft,
547+
Hard,
548+
}
549+
541550
/// LLVMRustCodeModel
542551
#[derive(Copy, Clone)]
543552
#[repr(C)]
@@ -2192,7 +2201,7 @@ unsafe extern "C" {
21922201
Model: CodeModel,
21932202
Reloc: RelocModel,
21942203
Level: CodeGenOptLevel,
2195-
UseSoftFP: bool,
2204+
FloatABIType: FloatAbi,
21962205
FunctionSections: bool,
21972206
DataSections: bool,
21982207
UniqueSectionNames: bool,

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+21-5
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,24 @@ static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
308308
report_fatal_error("Bad RelocModel.");
309309
}
310310

311+
enum class LLVMRustFloatABI {
312+
Default,
313+
Soft,
314+
Hard,
315+
};
316+
317+
static FloatABI::ABIType fromRust(LLVMRustFloatABI RustFloatAbi) {
318+
switch (RustFloatAbi) {
319+
case LLVMRustFloatABI::Default:
320+
return FloatABI::Default;
321+
case LLVMRustFloatABI::Soft:
322+
return FloatABI::Soft;
323+
case LLVMRustFloatABI::Hard:
324+
return FloatABI::Hard;
325+
}
326+
report_fatal_error("Bad FloatABI.");
327+
}
328+
311329
/// getLongestEntryLength - Return the length of the longest entry in the table.
312330
template <typename KV> static size_t getLongestEntryLength(ArrayRef<KV> Table) {
313331
size_t MaxLen = 0;
@@ -358,7 +376,7 @@ extern "C" const char *LLVMRustGetHostCPUName(size_t *OutLen) {
358376
extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
359377
const char *TripleStr, const char *CPU, const char *Feature,
360378
const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
361-
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
379+
LLVMRustCodeGenOptLevel RustOptLevel, LLVMRustFloatABI RustFloatABIType,
362380
bool FunctionSections, bool DataSections, bool UniqueSectionNames,
363381
bool TrapUnreachable, bool Singlethread, bool VerboseAsm,
364382
bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray,
@@ -369,6 +387,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
369387
auto OptLevel = fromRust(RustOptLevel);
370388
auto RM = fromRust(RustReloc);
371389
auto CM = fromRust(RustCM);
390+
auto FloatABIType = fromRust(RustFloatABIType);
372391

373392
std::string Error;
374393
auto Trip = Triple(Triple::normalize(TripleStr));
@@ -381,10 +400,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
381400

382401
TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Trip);
383402

384-
Options.FloatABIType = FloatABI::Default;
385-
if (UseSoftFloat) {
386-
Options.FloatABIType = FloatABI::Soft;
387-
}
403+
Options.FloatABIType = FloatABIType;
388404
Options.DataSections = DataSections;
389405
Options.FunctionSections = FunctionSections;
390406
Options.UniqueSectionNames = UniqueSectionNames;

compiler/rustc_target/src/spec/base/apple/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::borrow::Cow;
22
use std::env;
33

44
use crate::spec::{
5-
Cc, DebuginfoKind, FramePointer, LinkerFlavor, Lld, SplitDebuginfo, StackProbeType, StaticCow,
6-
TargetOptions, cvs,
5+
Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, SplitDebuginfo, StackProbeType,
6+
StaticCow, TargetOptions, cvs,
77
};
88

99
#[cfg(test)]
@@ -105,6 +105,7 @@ pub(crate) fn base(
105105
) -> (TargetOptions, StaticCow<str>, StaticCow<str>) {
106106
let opts = TargetOptions {
107107
abi: abi.target_abi().into(),
108+
llvm_floatabi: Some(FloatAbi::Hard),
108109
os: os.into(),
109110
cpu: arch.target_cpu(abi).into(),
110111
link_env_remove: link_env_remove(os),

compiler/rustc_target/src/spec/json.rs

+14
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,18 @@ impl Target {
116116
Some(Ok(()))
117117
})).unwrap_or(Ok(()))
118118
} );
119+
($key_name:ident, FloatAbi) => ( {
120+
let name = (stringify!($key_name)).replace("_", "-");
121+
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
122+
match s.parse::<super::FloatAbi>() {
123+
Ok(float_abi) => base.$key_name = Some(float_abi),
124+
_ => return Some(Err(format!("'{}' is not a valid value for \
125+
llvm-floatabi. Use 'soft' or 'hard'.",
126+
s))),
127+
}
128+
Some(Ok(()))
129+
})).unwrap_or(Ok(()))
130+
} );
119131
($key_name:ident, RelocModel) => ( {
120132
let name = (stringify!($key_name)).replace("_", "-");
121133
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
@@ -598,6 +610,7 @@ impl Target {
598610
key!(mcount = "target-mcount");
599611
key!(llvm_mcount_intrinsic, optional);
600612
key!(llvm_abiname);
613+
key!(llvm_floatabi, FloatAbi)?;
601614
key!(relax_elf_relocations, bool);
602615
key!(llvm_args, list);
603616
key!(use_ctors_section, bool);
@@ -772,6 +785,7 @@ impl ToJson for Target {
772785
target_option_val!(mcount, "target-mcount");
773786
target_option_val!(llvm_mcount_intrinsic);
774787
target_option_val!(llvm_abiname);
788+
target_option_val!(llvm_floatabi);
775789
target_option_val!(relax_elf_relocations);
776790
target_option_val!(llvm_args);
777791
target_option_val!(use_ctors_section);

compiler/rustc_target/src/spec/mod.rs

+46-1
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,35 @@ impl ToJson for CodeModel {
10851085
}
10861086
}
10871087

1088+
/// The float ABI setting to be configured in the LLVM target machine.
1089+
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
1090+
pub enum FloatAbi {
1091+
Soft,
1092+
Hard,
1093+
}
1094+
1095+
impl FromStr for FloatAbi {
1096+
type Err = ();
1097+
1098+
fn from_str(s: &str) -> Result<FloatAbi, ()> {
1099+
Ok(match s {
1100+
"soft" => FloatAbi::Soft,
1101+
"hard" => FloatAbi::Hard,
1102+
_ => return Err(()),
1103+
})
1104+
}
1105+
}
1106+
1107+
impl ToJson for FloatAbi {
1108+
fn to_json(&self) -> Json {
1109+
match *self {
1110+
FloatAbi::Soft => "soft",
1111+
FloatAbi::Hard => "hard",
1112+
}
1113+
.to_json()
1114+
}
1115+
}
1116+
10881117
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
10891118
pub enum TlsModel {
10901119
GeneralDynamic,
@@ -2150,6 +2179,8 @@ pub struct TargetOptions {
21502179
pub env: StaticCow<str>,
21512180
/// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"`
21522181
/// or `"eabihf"`. Defaults to "".
2182+
/// This field is *not* forwarded directly to LLVM; its primary purpose is `cfg(target_abi)`.
2183+
/// However, parts of the backend do check this field for specific values to enable special behavior.
21532184
pub abi: StaticCow<str>,
21542185
/// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
21552186
pub vendor: StaticCow<str>,
@@ -2446,8 +2477,17 @@ pub struct TargetOptions {
24462477
pub llvm_mcount_intrinsic: Option<StaticCow<str>>,
24472478

24482479
/// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers
2480+
/// and the `-target-abi` flag in llc. In the LLVM API this is `MCOptions.ABIName`.
24492481
pub llvm_abiname: StaticCow<str>,
24502482

2483+
/// Control the float ABI to use, for architectures that support it. The only architecture we
2484+
/// currently use this for is ARM. Corresponds to the `-float-abi` flag in llc. In the LLVM API
2485+
/// this is `FloatABIType`. (clang's `-mfloat-abi` is similar but more complicated since it
2486+
/// can also affect the `soft-float` target feature.)
2487+
///
2488+
/// If not provided, LLVM will infer the float ABI from the target triple (`llvm_target`).
2489+
pub llvm_floatabi: Option<FloatAbi>,
2490+
24512491
/// Whether or not RelaxElfRelocation flag will be passed to the linker
24522492
pub relax_elf_relocations: bool,
24532493

@@ -2719,6 +2759,7 @@ impl Default for TargetOptions {
27192759
mcount: "mcount".into(),
27202760
llvm_mcount_intrinsic: None,
27212761
llvm_abiname: "".into(),
2762+
llvm_floatabi: None,
27222763
relax_elf_relocations: false,
27232764
llvm_args: cvs![],
27242765
use_ctors_section: false,
@@ -3153,7 +3194,8 @@ impl Target {
31533194
);
31543195
}
31553196

3156-
// Check that RISC-V targets always specify which ABI they use.
3197+
// Check that RISC-V targets always specify which ABI they use,
3198+
// and that ARM targets specify their float ABI.
31573199
match &*self.arch {
31583200
"riscv32" => {
31593201
check_matches!(
@@ -3170,6 +3212,9 @@ impl Target {
31703212
"invalid RISC-V ABI name"
31713213
);
31723214
}
3215+
"arm" => {
3216+
check!(self.llvm_floatabi.is_some(), "ARM targets must specify their float ABI",)
3217+
}
31733218
_ => {}
31743219
}
31753220

compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{SanitizerSet, Target, TargetOptions, base};
1+
use crate::spec::{FloatAbi, SanitizerSet, Target, TargetOptions, base};
22

33
pub(crate) fn target() -> Target {
44
Target {
@@ -14,6 +14,7 @@ pub(crate) fn target() -> Target {
1414
arch: "arm".into(),
1515
options: TargetOptions {
1616
abi: "eabi".into(),
17+
llvm_floatabi: Some(FloatAbi::Soft),
1718
// https://developer.android.com/ndk/guides/abis.html#armeabi
1819
features: "+strict-align,+v5te".into(),
1920
supported_sanitizers: SanitizerSet::ADDRESS,

compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{Target, TargetOptions, base};
1+
use crate::spec::{FloatAbi, Target, TargetOptions, base};
22

33
pub(crate) fn target() -> Target {
44
Target {
@@ -14,6 +14,7 @@ pub(crate) fn target() -> Target {
1414
arch: "arm".into(),
1515
options: TargetOptions {
1616
abi: "eabi".into(),
17+
llvm_floatabi: Some(FloatAbi::Soft),
1718
features: "+strict-align,+v6".into(),
1819
max_atomic_width: Some(64),
1920
mcount: "\u{1}__gnu_mcount_nc".into(),

compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{Target, TargetOptions, base};
1+
use crate::spec::{FloatAbi, Target, TargetOptions, base};
22

33
pub(crate) fn target() -> Target {
44
Target {
@@ -14,6 +14,7 @@ pub(crate) fn target() -> Target {
1414
arch: "arm".into(),
1515
options: TargetOptions {
1616
abi: "eabihf".into(),
17+
llvm_floatabi: Some(FloatAbi::Hard),
1718
features: "+strict-align,+v6,+vfp2,-d32".into(),
1819
max_atomic_width: Some(64),
1920
mcount: "\u{1}__gnu_mcount_nc".into(),

compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
use crate::spec::{Target, TargetOptions, base};
1+
use crate::spec::{FloatAbi, Target, TargetOptions, base};
22

33
pub(crate) fn target() -> Target {
44
Target {
5-
// It's important we use "gnueabi" and not "musleabi" here. LLVM uses it
6-
// to determine the calling convention and float ABI, and it doesn't
7-
// support the "musleabi" value.
8-
llvm_target: "arm-unknown-linux-gnueabi".into(),
5+
llvm_target: "arm-unknown-linux-musleabi".into(),
96
metadata: crate::spec::TargetMetadata {
107
description: Some("Armv6 Linux with musl 1.2.3".into()),
118
tier: Some(2),
@@ -17,6 +14,7 @@ pub(crate) fn target() -> Target {
1714
arch: "arm".into(),
1815
options: TargetOptions {
1916
abi: "eabi".into(),
17+
llvm_floatabi: Some(FloatAbi::Soft),
2018
// Most of these settings are copied from the arm_unknown_linux_gnueabi
2119
// target.
2220
features: "+strict-align,+v6".into(),

compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
use crate::spec::{Target, TargetOptions, base};
1+
use crate::spec::{FloatAbi, Target, TargetOptions, base};
22

33
pub(crate) fn target() -> Target {
44
Target {
5-
// It's important we use "gnueabihf" and not "musleabihf" here. LLVM
6-
// uses it to determine the calling convention and float ABI, and it
7-
// doesn't support the "musleabihf" value.
8-
llvm_target: "arm-unknown-linux-gnueabihf".into(),
5+
llvm_target: "arm-unknown-linux-musleabihf".into(),
96
metadata: crate::spec::TargetMetadata {
107
description: Some("Armv6 Linux with musl 1.2.3, hardfloat".into()),
118
tier: Some(2),
@@ -17,6 +14,7 @@ pub(crate) fn target() -> Target {
1714
arch: "arm".into(),
1815
options: TargetOptions {
1916
abi: "eabihf".into(),
17+
llvm_floatabi: Some(FloatAbi::Hard),
2018
// Most of these settings are copied from the arm_unknown_linux_gnueabihf
2119
// target.
2220
features: "+strict-align,+v6,+vfp2,-d32".into(),

0 commit comments

Comments
 (0)