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,24 +33,26 @@ 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(
48+ // WIN -LABEL: @ret(
4449 // i128 is returned in xmm0 on Windows
4550 // FIXME(#134288): This may change for the `-msvc` targets in the future.
4651 // WIN-SAME: i32{{.*}} %_arg0, ptr{{.*}} %arg1)
4752 // WIN: [[LOADED:%[_0-9]+]] = load <16 x i8>, ptr %arg1
4853 // WIN-NEXT: ret <16 x i8> [[LOADED]]
54+ // The softfloat ABI returns this indirectly.
55+ // softfloat-LABEL: i128 @ret(i32{{.*}} %_arg0, ptr{{.*}} %arg1)
4956 arg1
5057}
5158
@@ -57,6 +64,7 @@ pub extern "C" fn forward(dst: *mut i128) {
5764 // WIN: [[RETURNED:%[_0-9]+]] = tail call <16 x i8> @extern_ret()
5865 // WIN: store <16 x i8> [[RETURNED]], ptr %dst
5966 // WIN: ret void
67+ // softfloat: [[RETURNED:%[_0-9]+]] = tail call {{.*}}i128 @extern_ret()
6068 unsafe { * dst = extern_ret ( ) } ;
6169}
6270
@@ -70,10 +78,10 @@ struct RetAggregate {
7078pub extern "C" fn ret_aggregate ( _arg0 : u32 , arg1 : i128 ) -> RetAggregate {
7179 // CHECK-LABEL: @ret_aggregate(
7280 // 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
81+ // CHECK -SAME: ptr{{.*}}sret([32 x i8]){{.*}}[[RET:%[_0-9]+]], i32{{.*}}%_arg0, ptr{{.*}}%arg1)
82+ // CHECK : [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
83+ // CHECK : [[GEP:%[_0-9]+]] = getelementptr{{.*}}, ptr [[RET]]
84+ // CHECK : store i128 [[LOADED]], ptr [[GEP]]
85+ // CHECK : ret void
7886 RetAggregate { a : 1 , b : arg1 }
7987}
0 commit comments