11// Configuration that is shared between `compiler_builtins` and `builtins_test`.
22
3- use std:: env;
3+ use std:: process:: { Command , Stdio } ;
4+ use std:: { env, str} ;
45
56#[ derive( Debug ) ]
67#[ allow( dead_code) ]
@@ -16,6 +17,8 @@ pub struct Target {
1617 pub pointer_width : u8 ,
1718 pub little_endian : bool ,
1819 pub features : Vec < String > ,
20+ pub reliable_f128 : bool ,
21+ pub reliable_f16 : bool ,
1922}
2023
2124impl Target {
@@ -32,6 +35,26 @@ impl Target {
3235 . map ( |s| s. to_lowercase ( ) . replace ( "_" , "-" ) )
3336 . collect ( ) ;
3437
38+ // Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
39+ // to get consistent output regardless of channel (`f16`/`f128` config options are hidden
40+ // on stable otherwise).
41+ let mut cmd = Command :: new ( env:: var ( "RUSTC" ) . unwrap ( ) ) ;
42+ cmd. args ( [ "--print=cfg" , "--target" , & triple] )
43+ . env ( "RUSTC_BOOTSTRAP" , "1" )
44+ . stderr ( Stdio :: inherit ( ) ) ;
45+ let out = cmd
46+ . output ( )
47+ . unwrap_or_else ( |e| panic ! ( "failed to run `{cmd:?}`: {e}" ) ) ;
48+ let rustc_cfg = str:: from_utf8 ( & out. stdout ) . unwrap ( ) ;
49+
50+ // If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
51+ // choice and leave `f16` and `f128` disabled.
52+ let rustc_output_ok = out. status . success ( ) ;
53+ let reliable_f128 =
54+ rustc_output_ok && rustc_cfg. lines ( ) . any ( |l| l == "target_has_reliable_f128" ) ;
55+ let reliable_f16 =
56+ rustc_output_ok && rustc_cfg. lines ( ) . any ( |l| l == "target_has_reliable_f16" ) ;
57+
3558 Self {
3659 triple,
3760 triple_split,
@@ -51,6 +74,8 @@ impl Target {
5174 . split ( "," )
5275 . map ( ToOwned :: to_owned)
5376 . collect ( ) ,
77+ reliable_f128,
78+ reliable_f16,
5479 }
5580 }
5681
@@ -74,63 +99,24 @@ pub fn configure_aliases(target: &Target) {
7499 if target. triple_split [ 0 ] == "thumbv6m" || target. triple_split [ 0 ] == "thumbv8m.base" {
75100 println ! ( "cargo:rustc-cfg=thumb_1" )
76101 }
77- }
78-
79- /// Configure whether or not `f16` and `f128` support should be enabled.
80- pub fn configure_f16_f128 ( target : & Target ) {
81- // Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
82- // that the backend will not crash when using these types and generates code that can be called
83- // without crashing (no infinite recursion). This does not mean that the platform doesn't have
84- // ABI or other bugs.
85- //
86- // We do this here rather than in `rust-lang/rust` because configuring via cargo features is
87- // not straightforward.
88- //
89- // Original source of this list:
90- // <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
91- let f16_enabled = match target. arch . as_str ( ) {
92- // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
93- "arm64ec" => false ,
94- // Selection failure <https://github.com/llvm/llvm-project/issues/50374>
95- "s390x" => false ,
96- // Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
97- "csky" => false ,
98- "hexagon" => false ,
99- "powerpc" | "powerpc64" => false ,
100- "sparc" | "sparc64" => false ,
101- "wasm32" | "wasm64" => false ,
102- // Most everything else works as of LLVM 19
103- _ => true ,
104- } ;
105102
106- let f128_enabled = match target. arch . as_str ( ) {
107- // Unsupported (libcall is not supported) <https://github.com/llvm/llvm-project/issues/121122>
108- "amdgpu" => false ,
109- // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
110- "arm64ec" => false ,
111- // FIXME(llvm20): fixed by <https://github.com/llvm/llvm-project/pull/117525>
112- "mips64" | "mips64r6" => false ,
113- // Selection failure <https://github.com/llvm/llvm-project/issues/95471>
114- "nvptx64" => false ,
115- // Selection failure <https://github.com/llvm/llvm-project/issues/101545>
116- "powerpc64" if & target. os == "aix" => false ,
117- // Selection failure <https://github.com/llvm/llvm-project/issues/41838>
118- "sparc" => false ,
119- // Most everything else works as of LLVM 19
120- _ => true ,
121- } ;
103+ /* Not all backends support `f16` and `f128` to the same level on all architectures, so we
104+ * need to disable things if the compiler may crash. See configuration at:
105+ * * https://github.com/rust-lang/rust/blob/c65dccabacdfd6c8a7f7439eba13422fdd89b91e/compiler/rustc_codegen_llvm/src/llvm_util.rs#L367-L432
106+ * * https://github.com/rust-lang/rustc_codegen_gcc/blob/4b5c44b14166083eef8d71f15f5ea1f53fc976a0/src/lib.rs#L496-L507
107+ * * https://github.com/rust-lang/rustc_codegen_cranelift/blob/c713ffab3c6e28ab4b4dd4e392330f786ea657ad/src/lib.rs#L196-L226
108+ */
122109
123- // If the feature is set, disable these types.
124- let disable_both = env :: var_os ( "CARGO_FEATURE_NO_F16_F128" ) . is_some ( ) ;
110+ // If the feature is set, disable both of these types.
111+ let no_f16_f128 = target . cargo_features . iter ( ) . any ( |s| s == "no-f16-f128" ) ;
125112
126113 println ! ( "cargo::rustc-check-cfg=cfg(f16_enabled)" ) ;
127- println ! ( "cargo::rustc-check-cfg=cfg(f128_enabled)" ) ;
128-
129- if f16_enabled && !disable_both {
114+ if target. reliable_f16 && !no_f16_f128 {
130115 println ! ( "cargo::rustc-cfg=f16_enabled" ) ;
131116 }
132117
133- if f128_enabled && !disable_both {
118+ println ! ( "cargo::rustc-check-cfg=cfg(f128_enabled)" ) ;
119+ if target. reliable_f128 && !no_f16_f128 {
134120 println ! ( "cargo::rustc-cfg=f128_enabled" ) ;
135121 }
136122}
0 commit comments