about summary refs log tree commit diff
path: root/tests/codegen
diff options
context:
space:
mode:
authorTrevor Gross <tmgross@umich.edu>2024-12-14 00:32:39 +0000
committerTrevor Gross <tmgross@umich.edu>2025-01-27 12:12:59 +0000
commita44a20ee4ab8fe41ccba2ea3f970f7ee81c61c04 (patch)
tree6defb470714f71607ed2c188fa9aa4cd5eca0525 /tests/codegen
parent581e0ac90c4b3b13c1b5e939b3d7281a6377403e (diff)
downloadrust-a44a20ee4ab8fe41ccba2ea3f970f7ee81c61c04.tar.gz
rust-a44a20ee4ab8fe41ccba2ea3f970f7ee81c61c04.zip
Windows x86: Change `i128` to return via the vector ABI
Clang and GCC both return `i128` in xmm0 on windows-msvc and
windows-gnu. Currently, Rust returns the type on the stack. Add a
calling convention adjustment so we also return scalar `i128`s using the
vector ABI, which makes our `i128` compatible with C.

In the future, Clang may change to return `i128` on the stack for its
`-msvc` targets (more at [1]). If this happens, the change here will
need to be adjusted to only affect MinGW.

Link: https://github.com/rust-lang/rust/issues/134288
Diffstat (limited to 'tests/codegen')
-rw-r--r--tests/codegen/i128-x86-callconv.rs17
1 files changed, 7 insertions, 10 deletions
diff --git a/tests/codegen/i128-x86-callconv.rs b/tests/codegen/i128-x86-callconv.rs
index 0639e95f5c5..9a9c9002fc0 100644
--- a/tests/codegen/i128-x86-callconv.rs
+++ b/tests/codegen/i128-x86-callconv.rs
@@ -41,12 +41,11 @@ pub extern "C" fn pass(_arg0: u32, arg1: i128) {
 #[no_mangle]
 pub extern "C" fn ret(_arg0: u32, arg1: i128) -> i128 {
     // CHECK-LABEL: @ret(
-    // i128 is returned on the stack on Windows.
-    // FIXME: this ABI does not agree with Clang or MinGW GCC
-    // WIN-SAME: ptr{{.*}} sret([16 x i8]){{.*}} [[RET:%_[0-9]+]], i32{{.*}} %_arg0, ptr{{.*}} %arg1)
-    // WIN: [[LOADED:%[0-9]+]] = load i128, ptr %arg1
-    // WIN: store i128 [[LOADED]], ptr [[RET]]
-    // WIN: ret void
+    // i128 is returned in xmm0 on Windows
+    // FIXME(#134288): This may change for the `-msvc` targets in the future.
+    // WIN-SAME: i32{{.*}} %_arg0, ptr{{.*}} %arg1)
+    // WIN: [[LOADED:%[_0-9]+]] = load <16 x i8>, ptr %arg1
+    // WIN-NEXT: ret <16 x i8> [[LOADED]]
     arg1
 }
 
@@ -55,10 +54,8 @@ pub extern "C" fn ret(_arg0: u32, arg1: i128) -> i128 {
 pub extern "C" fn forward(dst: *mut i128) {
     // CHECK-LABEL: @forward
     // WIN-SAME: ptr{{.*}} %dst)
-    // WIN: [[RETURNED:%[_0-9]+]] = alloca [16 x i8], align 16
-    // WIN: call void @extern_ret({{.*}} [[RETURNED]])
-    // WIN: [[TMP:%[_0-9]+]] = load i128, ptr [[RETURNED]]
-    // WIN: store i128 [[TMP]], ptr %dst
+    // WIN: [[RETURNED:%[_0-9]+]] = tail call <16 x i8> @extern_ret()
+    // WIN: store <16 x i8> [[RETURNED]], ptr %dst
     // WIN: ret void
     unsafe { *dst = extern_ret() };
 }