1
1
// Configuration that is shared between `compiler_builtins` and `builtins_test`.
2
2
3
- use std:: env;
3
+ use std:: process:: { Command , Stdio } ;
4
+ use std:: { env, str} ;
4
5
5
6
#[ derive( Debug ) ]
6
7
#[ allow( dead_code) ]
@@ -16,6 +17,8 @@ pub struct Target {
16
17
pub pointer_width : u8 ,
17
18
pub little_endian : bool ,
18
19
pub features : Vec < String > ,
20
+ pub reliable_f128 : bool ,
21
+ pub reliable_f16 : bool ,
19
22
}
20
23
21
24
impl Target {
@@ -32,6 +35,26 @@ impl Target {
32
35
. map ( |s| s. to_lowercase ( ) . replace ( "_" , "-" ) )
33
36
. collect ( ) ;
34
37
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
+
35
58
Self {
36
59
triple,
37
60
triple_split,
@@ -51,6 +74,8 @@ impl Target {
51
74
. split ( "," )
52
75
. map ( ToOwned :: to_owned)
53
76
. collect ( ) ,
77
+ reliable_f128,
78
+ reliable_f16,
54
79
}
55
80
}
56
81
@@ -74,63 +99,24 @@ pub fn configure_aliases(target: &Target) {
74
99
if target. triple_split [ 0 ] == "thumbv6m" || target. triple_split [ 0 ] == "thumbv8m.base" {
75
100
println ! ( "cargo:rustc-cfg=thumb_1" )
76
101
}
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
- } ;
105
102
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
+ */
122
109
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" ) ;
125
112
126
113
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 {
130
115
println ! ( "cargo::rustc-cfg=f16_enabled" ) ;
131
116
}
132
117
133
- if f128_enabled && !disable_both {
118
+ println ! ( "cargo::rustc-check-cfg=cfg(f128_enabled)" ) ;
119
+ if target. reliable_f128 && !no_f16_f128 {
134
120
println ! ( "cargo::rustc-cfg=f128_enabled" ) ;
135
121
}
136
122
}
0 commit comments