about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbeetrees <b@beetr.ee>2024-07-30 12:38:06 +0100
committerbeetrees <b@beetr.ee>2024-07-30 20:23:33 +0100
commitfe6478cc539cfe17b4f5fc10f46928c6b16e6ef0 (patch)
treef7d76bf79284d922407118a62199b4b03f332e04
parente69c19ea0b8cf29ab8188a0eb5e899655464a1ff (diff)
downloadrust-fe6478cc539cfe17b4f5fc10f46928c6b16e6ef0.tar.gz
rust-fe6478cc539cfe17b4f5fc10f46928c6b16e6ef0.zip
Match LLVM ABI in `extern "C"` functions for `f128` on Windows
-rw-r--r--compiler/rustc_target/src/abi/call/x86_win64.rs10
-rw-r--r--library/std/build.rs4
-rw-r--r--tests/assembly/x86_64-windows-float-abi.rs39
3 files changed, 49 insertions, 4 deletions
diff --git a/compiler/rustc_target/src/abi/call/x86_win64.rs b/compiler/rustc_target/src/abi/call/x86_win64.rs
index 90de1a42bc0..4e19460bd28 100644
--- a/compiler/rustc_target/src/abi/call/x86_win64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_win64.rs
@@ -1,5 +1,5 @@
 use crate::abi::call::{ArgAbi, FnAbi, Reg};
-use crate::abi::Abi;
+use crate::abi::{Abi, Float, Primitive};
 
 // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
 
@@ -18,8 +18,12 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
                 // FIXME(eddyb) there should be a size cap here
                 // (probably what clang calls "illegal vectors").
             }
-            Abi::Scalar(_) => {
-                if a.layout.size.bytes() > 8 {
+            Abi::Scalar(scalar) => {
+                // Match what LLVM does for `f128` so that `compiler-builtins` builtins match up
+                // with what LLVM expects.
+                if a.layout.size.bytes() > 8
+                    && !matches!(scalar.primitive(), Primitive::Float(Float::F128))
+                {
                     a.make_indirect();
                 } else {
                     a.extend_integer_width_to(32);
diff --git a/library/std/build.rs b/library/std/build.rs
index c542ba81eed..9b58dd53ba2 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -94,7 +94,7 @@ fn main() {
         // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
         ("arm64ec", _) => false,
         // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
-        ("x86", "windows") => false,
+        ("x86_64", "windows") => false,
         // x86 has ABI bugs that show up with optimizations. This should be partially fixed with
         // the compiler-builtins update. <https://github.com/rust-lang/rust/issues/123885>
         ("x86" | "x86_64", _) => false,
@@ -122,6 +122,8 @@ fn main() {
         ("nvptx64", _) => false,
         // ABI unsupported  <https://github.com/llvm/llvm-project/issues/41838>
         ("sparc", _) => false,
+        // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
+        ("x86_64", "windows") => false,
         // 64-bit Linux is about the only platform to have f128 symbols by default
         (_, "linux") if target_pointer_width == 64 => true,
         // Same as for f16, except MacOS is also missing f128 symbols.
diff --git a/tests/assembly/x86_64-windows-float-abi.rs b/tests/assembly/x86_64-windows-float-abi.rs
new file mode 100644
index 00000000000..1381d492fa5
--- /dev/null
+++ b/tests/assembly/x86_64-windows-float-abi.rs
@@ -0,0 +1,39 @@
+//@ assembly-output: emit-asm
+//@ compile-flags: -O
+//@ only-windows
+//@ only-x86_64
+
+#![feature(f16, f128)]
+#![crate_type = "lib"]
+
+// CHECK-LABEL: second_f16
+// CHECK: movaps %xmm1, %xmm0
+// CHECK-NEXT: retq
+#[no_mangle]
+pub extern "C" fn second_f16(_: f16, x: f16) -> f16 {
+    x
+}
+
+// CHECK-LABEL: second_f32
+// CHECK: movaps %xmm1, %xmm0
+// CHECK-NEXT: retq
+#[no_mangle]
+pub extern "C" fn second_f32(_: f32, x: f32) -> f32 {
+    x
+}
+
+// CHECK-LABEL: second_f64
+// CHECK: movaps %xmm1, %xmm0
+// CHECK-NEXT: retq
+#[no_mangle]
+pub extern "C" fn second_f64(_: f64, x: f64) -> f64 {
+    x
+}
+
+// CHECK-LABEL: second_f128
+// CHECK: movaps %xmm1, %xmm0
+// CHECK-NEXT: retq
+#[no_mangle]
+pub extern "C" fn second_f128(_: f128, x: f128) -> f128 {
+    x
+}