1
1
//@ assembly-output: emit-asm
2
- //@ only-x86
3
- // FIXME(#114479): LLVM miscompiles loading and storing `f32` and `f64` when SSE is disabled.
4
- // There's no compiletest directive to ignore a test on i586 only, so just always explicitly enable
5
- // SSE2.
6
- // Use the same target CPU as `i686` so that LLVM orders the instructions in the same order.
7
- //@ compile-flags: -Ctarget-feature=+sse2 -Ctarget-cpu=pentium4
2
+ //@ revisions: sse nosse
3
+ //@[sse] compile-flags: --target i686-unknown-linux-gnu
4
+ //@[sse] needs-llvm-components: x86
5
+ // We make SSE available but don't use it for the ABI.
6
+ //@[nosse] compile-flags: --target i586-unknown-linux-gnu -Ctarget-feature=+sse2 -Ctarget-cpu=pentium4
7
+ //@[nosse] needs-llvm-components: x86
8
+
8
9
// Force frame pointers to make ASM more consistent between targets
9
10
//@ compile-flags: -O -C force-frame-pointers
10
11
//@ filecheck-flags: --implicit-check-not fld --implicit-check-not fst
11
- //@ revisions: normal win
12
- //@[normal] ignore-windows
13
- //@[win] only-windows
14
12
15
- #![ crate_type = "lib" ]
16
13
#![ feature( f16, f128) ]
14
+ #![ feature( no_core, lang_items, rustc_attrs, repr_simd) ]
15
+ #![ no_core]
16
+ #![ crate_type = "lib" ]
17
+
18
+ #[ lang = "sized" ]
19
+ trait Sized { }
20
+
21
+ #[ lang = "copy" ]
22
+ trait Copy { }
23
+
24
+ impl Copy for f16 { }
25
+ impl Copy for f32 { }
26
+ impl Copy for f64 { }
27
+ impl Copy for f128 { }
28
+ impl Copy for usize { }
17
29
18
30
// Tests that returning `f32` and `f64` with the "Rust" ABI on 32-bit x86 doesn't use the x87
19
31
// floating point stack, as loading and storing `f32`s and `f64`s to and from the x87 stack quietens
24
36
// CHECK-LABEL: return_f32:
25
37
#[ no_mangle]
26
38
pub fn return_f32 ( x : f32 ) -> f32 {
27
- // CHECK: movl {{.*}}(%ebp), %eax
39
+ // sse: movss {{.*}}(%ebp), %xmm0
40
+ // nosse: movl {{.*}}(%ebp), %eax
28
41
// CHECK-NOT: ax
29
42
// CHECK: retl
30
43
x
@@ -33,9 +46,11 @@ pub fn return_f32(x: f32) -> f32 {
33
46
// CHECK-LABEL: return_f64:
34
47
#[ no_mangle]
35
48
pub fn return_f64 ( x : f64 ) -> f64 {
36
- // CHECK: movl [[#%d,OFFSET:]](%ebp), %[[PTR:.*]]
37
- // CHECK-NEXT: movsd [[#%d,OFFSET+4]](%ebp), %[[VAL:.*]]
38
- // CHECK-NEXT: movsd %[[VAL]], (%[[PTR]])
49
+ // nosse: movl [[#%d,OFFSET:]](%ebp), %[[PTR:.*]]
50
+ // nosse-NEXT: movsd [[#%d,OFFSET+4]](%ebp), %[[VAL:.*]]
51
+ // nosse-NEXT: movsd %[[VAL]], (%[[PTR]])
52
+ // sse: movsd {{.*}}(%ebp), %xmm0
53
+ // sse-NOT: ax
39
54
// CHECK: retl
40
55
x
41
56
}
@@ -148,7 +163,8 @@ pub unsafe fn call_f32(x: &mut f32) {
148
163
}
149
164
// CHECK: movl {{.*}}(%ebp), %[[PTR:.*]]
150
165
// CHECK: calll {{()|_}}get_f32
151
- // CHECK-NEXT: movl %eax, (%[[PTR]])
166
+ // sse-NEXT: movss %xmm0, (%[[PTR]])
167
+ // nosse-NEXT: movl %eax, (%[[PTR]])
152
168
* x = get_f32 ( ) ;
153
169
}
154
170
@@ -160,8 +176,9 @@ pub unsafe fn call_f64(x: &mut f64) {
160
176
}
161
177
// CHECK: movl {{.*}}(%ebp), %[[PTR:.*]]
162
178
// CHECK: calll {{()|_}}get_f64
163
- // CHECK: movsd {{.*}}(%{{ebp|esp}}), %[[VAL:.*]]
164
- // CHECK-NEXT: movsd %[[VAL:.*]], (%[[PTR]])
179
+ // sse: movlps %xmm0, (%[[PTR]])
180
+ // nosse: movsd {{.*}}(%{{ebp|esp}}), %[[VAL:.*]]
181
+ // nosse-NEXT: movsd %[[VAL:.*]], (%[[PTR]])
165
182
* x = get_f64 ( ) ;
166
183
}
167
184
@@ -190,10 +207,8 @@ pub unsafe fn call_f64_f64(x: &mut (f64, f64)) {
190
207
}
191
208
// CHECK: movl {{.*}}(%ebp), %[[PTR:.*]]
192
209
// CHECK: calll {{()|_}}get_f64_f64
193
- // normal: movsd [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
194
- // normal-NEXT: movsd [[#%d,OFFSET+8]](%ebp), %[[VAL2:.*]]
195
- // win: movsd (%esp), %[[VAL1:.*]]
196
- // win-NEXT: movsd 8(%esp), %[[VAL2:.*]]
210
+ // CHECK: movsd [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
211
+ // CHECK-NEXT: movsd [[#%d,OFFSET+8]](%ebp), %[[VAL2:.*]]
197
212
// CHECK-NEXT: movsd %[[VAL1]], (%[[PTR]])
198
213
// CHECK-NEXT: movsd %[[VAL2]], 8(%[[PTR]])
199
214
* x = get_f64_f64 ( ) ;
@@ -207,13 +222,10 @@ pub unsafe fn call_f32_f64(x: &mut (f32, f64)) {
207
222
}
208
223
// CHECK: movl {{.*}}(%ebp), %[[PTR:.*]]
209
224
// CHECK: calll {{()|_}}get_f32_f64
210
- // normal: movss [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
211
- // normal-NEXT: movsd [[#%d,OFFSET+4]](%ebp), %[[VAL2:.*]]
212
- // win: movss (%esp), %[[VAL1:.*]]
213
- // win-NEXT: movsd 8(%esp), %[[VAL2:.*]]
225
+ // CHECK: movss [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
226
+ // CHECK-NEXT: movsd [[#%d,OFFSET+4]](%ebp), %[[VAL2:.*]]
214
227
// CHECK-NEXT: movss %[[VAL1]], (%[[PTR]])
215
- // normal-NEXT: movsd %[[VAL2]], 4(%[[PTR]])
216
- // win-NEXT: movsd %[[VAL2]], 8(%[[PTR]])
228
+ // CHECK-NEXT: movsd %[[VAL2]], 4(%[[PTR]])
217
229
* x = get_f32_f64 ( ) ;
218
230
}
219
231
@@ -225,10 +237,8 @@ pub unsafe fn call_f64_f32(x: &mut (f64, f32)) {
225
237
}
226
238
// CHECK: movl {{.*}}(%ebp), %[[PTR:.*]]
227
239
// CHECK: calll {{()|_}}get_f64_f32
228
- // normal: movsd [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
229
- // normal-NEXT: movss [[#%d,OFFSET+8]](%ebp), %[[VAL2:.*]]
230
- // win: movsd (%esp), %[[VAL1:.*]]
231
- // win-NEXT: movss 8(%esp), %[[VAL2:.*]]
240
+ // CHECK: movsd [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
241
+ // CHECK-NEXT: movss [[#%d,OFFSET+8]](%ebp), %[[VAL2:.*]]
232
242
// CHECK-NEXT: movsd %[[VAL1]], (%[[PTR]])
233
243
// CHECK-NEXT: movss %[[VAL2]], 8(%[[PTR]])
234
244
* x = get_f64_f32 ( ) ;
@@ -257,10 +267,8 @@ pub unsafe fn call_f64_other(x: &mut (f64, usize)) {
257
267
}
258
268
// CHECK: movl {{.*}}(%ebp), %[[PTR:.*]]
259
269
// CHECK: calll {{()|_}}get_f64_other
260
- // normal: movsd [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
261
- // normal-NEXT: movl [[#%d,OFFSET+8]](%ebp), %[[VAL2:.*]]
262
- // win: movsd (%esp), %[[VAL1:.*]]
263
- // win-NEXT: movl 8(%esp), %[[VAL2:.*]]
270
+ // CHECK: movsd [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
271
+ // CHECK-NEXT: movl [[#%d,OFFSET+8]](%ebp), %[[VAL2:.*]]
264
272
// CHECK-NEXT: movsd %[[VAL1]], (%[[PTR]])
265
273
// CHECK-NEXT: movl %[[VAL2]], 8(%[[PTR]])
266
274
* x = get_f64_other ( ) ;
@@ -289,13 +297,10 @@ pub unsafe fn call_other_f64(x: &mut (usize, f64)) {
289
297
}
290
298
// CHECK: movl {{.*}}(%ebp), %[[PTR:.*]]
291
299
// CHECK: calll {{()|_}}get_other_f64
292
- // normal: movl [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
293
- // normal-NEXT: movsd [[#%d,OFFSET+4]](%ebp), %[[VAL2:.*]]
294
- // win: movl (%esp), %[[VAL1:.*]]
295
- // win-NEXT: movsd 8(%esp), %[[VAL2:.*]]
300
+ // CHECK: movl [[#%d,OFFSET:]](%ebp), %[[VAL1:.*]]
301
+ // CHECK-NEXT: movsd [[#%d,OFFSET+4]](%ebp), %[[VAL2:.*]]
296
302
// CHECK-NEXT: movl %[[VAL1]], (%[[PTR]])
297
- // normal-NEXT: movsd %[[VAL2]], 4(%[[PTR]])
298
- // win-NEXT: movsd %[[VAL2]], 8(%[[PTR]])
303
+ // CHECK-NEXT: movsd %[[VAL2]], 4(%[[PTR]])
299
304
* x = get_other_f64 ( ) ;
300
305
}
301
306
@@ -307,7 +312,8 @@ pub unsafe fn call_other_f64(x: &mut (usize, f64)) {
307
312
pub fn return_f16 ( x : f16 ) -> f16 {
308
313
// CHECK: pushl %ebp
309
314
// CHECK: movl %esp, %ebp
310
- // CHECK: movzwl 8(%ebp), %eax
315
+ // nosse: movzwl 8(%ebp), %eax
316
+ // sse: pinsrw $0, 8(%ebp), %xmm0
311
317
// CHECK: popl %ebp
312
318
// CHECK: retl
313
319
x
@@ -316,15 +322,18 @@ pub fn return_f16(x: f16) -> f16 {
316
322
// CHECK-LABEL: return_f128:
317
323
#[ no_mangle]
318
324
pub fn return_f128 ( x : f128 ) -> f128 {
319
- // CHECK: movl [[#%d,OFFSET:]](%ebp), %[[PTR:.*]]
320
- // CHECK-NEXT: movl [[#%d,OFFSET+4]](%ebp), %[[VAL1:.*]]
321
- // CHECK-NEXT: movl [[#%d,OFFSET+8]](%ebp), %[[VAL2:.*]]
322
- // CHECK-NEXT: movl [[#%d,OFFSET+12]](%ebp), %[[VAL3:.*]]
323
- // CHECK-NEXT: movl [[#%d,OFFSET+16]](%ebp), %[[VAL4:.*]]
324
- // CHECK-NEXT: movl %[[VAL4:.*]] 12(%[[PTR]])
325
- // CHECK-NEXT: movl %[[VAL3:.*]] 8(%[[PTR]])
326
- // CHECK-NEXT: movl %[[VAL2:.*]] 4(%[[PTR]])
327
- // CHECK-NEXT: movl %[[VAL1:.*]] (%[[PTR]])
325
+ // CHECK: pushl %ebp
326
+ // sse: movaps [[#%d,OFFSET:]](%ebp), %xmm0
327
+ // nosse: movl [[#%d,OFFSET:]](%ebp), %[[PTR:.*]]
328
+ // nosse-NEXT: movl [[#%d,OFFSET+4]](%ebp), %[[VAL1:.*]]
329
+ // nosse-NEXT: movl [[#%d,OFFSET+8]](%ebp), %[[VAL2:.*]]
330
+ // nosse-NEXT: movl [[#%d,OFFSET+12]](%ebp), %[[VAL3:.*]]
331
+ // nosse-NEXT: movl [[#%d,OFFSET+16]](%ebp), %[[VAL4:.*]]
332
+ // nosse-NEXT: movl %[[VAL4:.*]] 12(%[[PTR]])
333
+ // nosse-NEXT: movl %[[VAL3:.*]] 8(%[[PTR]])
334
+ // nosse-NEXT: movl %[[VAL2:.*]] 4(%[[PTR]])
335
+ // nosse-NEXT: movl %[[VAL1:.*]] (%[[PTR]])
336
+ // CHECK: popl %ebp
328
337
// CHECK: retl
329
338
x
330
339
}
0 commit comments