44//@ compile-flags: -Copt-level=1
55
66//@ add-core-stubs
7- //@ revisions: MSVC MINGW
7+ //@ revisions: MSVC MINGW softfloat
88//@ [MSVC] needs-llvm-components: x86
9- //@ [MINGW] needs-llvm-components: x86
109//@ [MSVC] compile-flags: --target x86_64-pc-windows-msvc
11- //@ [ MINGW] compile-flags: --target x86_64-pc-windows-gnu
10+ // Use `WIN` as a common prefix for MSVC and MINGW but *not* the softfloat test.
1211//@ [MSVC] filecheck-flags: --check-prefix=WIN
12+ //@ [MINGW] needs-llvm-components: x86
13+ //@ [MINGW] compile-flags: --target x86_64-pc-windows-gnu
1314//@ [MINGW] filecheck-flags: --check-prefix=WIN
15+ // The `x86_64-unknown-uefi` target also uses the Windows calling convention,
16+ // but does not have SSE registers available.
17+ //@ [softfloat] needs-llvm-components: x86
18+ //@ [softfloat] compile-flags: --target x86_64-unknown-uefi
1419
1520#![ crate_type = "lib" ]
1621#![ no_std]
@@ -28,35 +33,34 @@ extern "C" {
2833pub extern "C" fn pass ( _arg0 : u32 , arg1 : i128 ) {
2934 // CHECK-LABEL: @pass(
3035 // i128 is passed indirectly on Windows. It should load the pointer to the stack and pass
31- // a pointer to that allocation.
32- // WIN -SAME: %_arg0, ptr{{.*}} %arg1)
33- // WIN : [[PASS:%[_0-9]+]] = alloca [16 x i8], align 16
34- // WIN : [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
35- // WIN : store i128 [[LOADED]], ptr [[PASS]]
36- // WIN : call void @extern_call
36+ // a pointer to that allocation. The softfloat ABI works the same.
37+ // CHECK -SAME: %_arg0, ptr{{.*}} %arg1)
38+ // CHECK : [[PASS:%[_0-9]+]] = alloca [16 x i8], align 16
39+ // CHECK : [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
40+ // CHECK : store i128 [[LOADED]], ptr [[PASS]]
41+ // CHECK : call void @extern_call
3742 unsafe { extern_call ( arg1) } ;
3843}
3944
4045// Check that we produce the correct return ABI
4146#[ no_mangle]
4247pub extern "C" fn ret ( _arg0 : u32 , arg1 : i128 ) -> i128 {
43- // CHECK-LABEL: @ret(
44- // i128 is returned in xmm0 on Windows
45- // FIXME(#134288): This may change for the `-msvc` targets in the future.
46- // WIN-SAME: i32{{.*}} %_arg0, ptr{{.*}} %arg1)
47- // WIN: [[LOADED:%[_0-9]+]] = load <16 x i8>, ptr %arg1
48- // WIN-NEXT: ret <16 x i8> [[LOADED]]
48+ // we use the LLVM native ABI for the return value
49+ // CHECK-LABEL: i128 @ret(
50+ // CHECK-SAME: i32{{.*}} %_arg0, ptr{{.*}} %arg1)
51+ // CHECK: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
52+ // CHECK-NEXT: ret i128 [[LOADED]]
4953 arg1
5054}
5155
5256// Check that we consume the correct return ABI
5357#[ no_mangle]
5458pub extern "C" fn forward ( dst : * mut i128 ) {
5559 // CHECK-LABEL: @forward
56- // WIN -SAME: ptr{{.*}} %dst)
57- // WIN : [[RETURNED:%[_0-9]+]] = tail call <16 x i8> @extern_ret()
58- // WIN : store <16 x i8> [[RETURNED]], ptr %dst
59- // WIN : ret void
60+ // CHECK -SAME: ptr{{.*}} %dst)
61+ // CHECK : [[RETURNED:%[_0-9]+]] = tail call {{.*}}i128 @extern_ret()
62+ // CHECK : store i128 [[RETURNED]], ptr %dst
63+ // CHECK : ret void
6064 unsafe { * dst = extern_ret ( ) } ;
6165}
6266
@@ -70,10 +74,10 @@ struct RetAggregate {
7074pub extern "C" fn ret_aggregate ( _arg0 : u32 , arg1 : i128 ) -> RetAggregate {
7175 // CHECK-LABEL: @ret_aggregate(
7276 // Aggregates should also be returned indirectly
73- // WIN -SAME: ptr{{.*}}sret([32 x i8]){{.*}}[[RET:%[_0-9]+]], i32{{.*}}%_arg0, ptr{{.*}}%arg1)
74- // WIN : [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
75- // WIN : [[GEP:%[_0-9]+]] = getelementptr{{.*}}, ptr [[RET]]
76- // WIN : store i128 [[LOADED]], ptr [[GEP]]
77- // WIN : ret void
77+ // CHECK -SAME: ptr{{.*}}sret([32 x i8]){{.*}}[[RET:%[_0-9]+]], i32{{.*}}%_arg0, ptr{{.*}}%arg1)
78+ // CHECK : [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
79+ // CHECK : [[GEP:%[_0-9]+]] = getelementptr{{.*}}, ptr [[RET]]
80+ // CHECK : store i128 [[LOADED]], ptr [[GEP]]
81+ // CHECK : ret void
7882 RetAggregate { a : 1 , b : arg1 }
7983}
0 commit comments