4
4
//@ compile-flags: -Copt-level=1
5
5
6
6
//@ add-core-stubs
7
- //@ revisions: MSVC MINGW
7
+ //@ revisions: MSVC MINGW softfloat
8
8
//@ [MSVC] needs-llvm-components: x86
9
- //@ [MINGW] needs-llvm-components: x86
10
9
//@ [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.
12
11
//@ [MSVC] filecheck-flags: --check-prefix=WIN
12
+ //@ [MINGW] needs-llvm-components: x86
13
+ //@ [MINGW] compile-flags: --target x86_64-pc-windows-gnu
13
14
//@ [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
14
19
15
20
#![ crate_type = "lib" ]
16
21
#![ no_std]
@@ -28,35 +33,34 @@ extern "C" {
28
33
pub extern "C" fn pass ( _arg0 : u32 , arg1 : i128 ) {
29
34
// CHECK-LABEL: @pass(
30
35
// 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
37
42
unsafe { extern_call ( arg1) } ;
38
43
}
39
44
40
45
// Check that we produce the correct return ABI
41
46
#[ no_mangle]
42
47
pub 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]]
49
53
arg1
50
54
}
51
55
52
56
// Check that we consume the correct return ABI
53
57
#[ no_mangle]
54
58
pub extern "C" fn forward ( dst : * mut i128 ) {
55
59
// 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
60
64
unsafe { * dst = extern_ret ( ) } ;
61
65
}
62
66
@@ -70,10 +74,10 @@ struct RetAggregate {
70
74
pub extern "C" fn ret_aggregate ( _arg0 : u32 , arg1 : i128 ) -> RetAggregate {
71
75
// CHECK-LABEL: @ret_aggregate(
72
76
// 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
78
82
RetAggregate { a : 1 , b : arg1 }
79
83
}
0 commit comments