Skip to content

Commit b6c7942

Browse files
committed
[windows] Always pass fp128 arguments indirectly
LLVM currently expects `__float128` to be both passed and returned in xmm registers on Windows. However, this disagrees with the Windows x86-64 calling convention [1], which indicates values larger than 64 bits should be passed indirectly. Update LLVM's default calling convention to pass `fp128` directly. Returning in xmm0 is unchanged since this seems like a reasonable extrapolation of the ABI. With this patch, the calling convention for `i128` and `f128` is the same. GCC passes `__float128` indirectly, which this also matches. However, it also returns indirectly, which is not done here. I intend to attempt a GCC change to also return in `xmm0` rather than making that change here, given the consistency with `i128`. This corresponds to the frontend change in [2], see more details there. [1]: https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170 [2]: #115052
1 parent c5497d0 commit b6c7942

File tree

6 files changed

+565
-202
lines changed

6 files changed

+565
-202
lines changed

llvm/lib/Target/X86/X86CallingConv.td

+2-1
Original file line numberDiff line numberDiff line change
@@ -639,8 +639,9 @@ def CC_X86_Win64_C : CallingConv<[
639639
// 512 bit vectors are passed by pointer
640640
CCIfType<[v64i8, v32i16, v16i32, v32f16, v32bf16, v16f32, v8f64, v8i64], CCPassIndirect<i64>>,
641641

642-
// Long doubles are passed by pointer
642+
// Float types larger than 64-bits (long double and fp128) are passed by pointer
643643
CCIfType<[f80], CCPassIndirect<i64>>,
644+
CCIfType<[f128], CCPassIndirect<i64>>,
644645

645646
// If SSE was disabled, pass FP values smaller than 64-bits as integers in
646647
// GPRs or on the stack.

llvm/test/CodeGen/X86/fp128-abi.ll

+68-30
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ define fp128 @first_arg(fp128 %x) {
9797
;
9898
; CHECK-MSVC64-LABEL: first_arg:
9999
; CHECK-MSVC64: # %bb.0:
100+
; CHECK-MSVC64-NEXT: movaps (%rcx), %xmm0
100101
; CHECK-MSVC64-NEXT: retq
101102
;
102103
; CHECK-MSVC32-LABEL: first_arg:
@@ -118,6 +119,7 @@ define fp128 @first_arg(fp128 %x) {
118119
;
119120
; CHECK-MINGW-LABEL: first_arg:
120121
; CHECK-MINGW: # %bb.0:
122+
; CHECK-MINGW-NEXT: movaps (%rcx), %xmm0
121123
; CHECK-MINGW-NEXT: retq
122124
ret fp128 %x
123125
}
@@ -152,7 +154,8 @@ define fp128 @leading_args(i64 %_0, i64 %_1, i64 %_2, i64 %_3, fp128 %x) {
152154
;
153155
; CHECK-MSVC64-LABEL: leading_args:
154156
; CHECK-MSVC64: # %bb.0:
155-
; CHECK-MSVC64-NEXT: movaps %xmm4, %xmm0
157+
; CHECK-MSVC64-NEXT: movq {{[0-9]+}}(%rsp), %rax
158+
; CHECK-MSVC64-NEXT: movaps (%rax), %xmm0
156159
; CHECK-MSVC64-NEXT: retq
157160
;
158161
; CHECK-MSVC32-LABEL: leading_args:
@@ -174,7 +177,8 @@ define fp128 @leading_args(i64 %_0, i64 %_1, i64 %_2, i64 %_3, fp128 %x) {
174177
;
175178
; CHECK-MINGW-LABEL: leading_args:
176179
; CHECK-MINGW: # %bb.0:
177-
; CHECK-MINGW-NEXT: movaps %xmm4, %xmm0
180+
; CHECK-MINGW-NEXT: movq {{[0-9]+}}(%rsp), %rax
181+
; CHECK-MINGW-NEXT: movaps (%rax), %xmm0
178182
; CHECK-MINGW-NEXT: retq
179183
ret fp128 %x
180184
}
@@ -210,7 +214,8 @@ define fp128 @many_leading_args(i64 %_0, i64 %_1, i64 %_2, i64 %_3, i64 %_4, fp1
210214
;
211215
; CHECK-MSVC64-LABEL: many_leading_args:
212216
; CHECK-MSVC64: # %bb.0:
213-
; CHECK-MSVC64-NEXT: movaps %xmm5, %xmm0
217+
; CHECK-MSVC64-NEXT: movq {{[0-9]+}}(%rsp), %rax
218+
; CHECK-MSVC64-NEXT: movaps (%rax), %xmm0
214219
; CHECK-MSVC64-NEXT: retq
215220
;
216221
; CHECK-MSVC32-LABEL: many_leading_args:
@@ -232,7 +237,8 @@ define fp128 @many_leading_args(i64 %_0, i64 %_1, i64 %_2, i64 %_3, i64 %_4, fp1
232237
;
233238
; CHECK-MINGW-LABEL: many_leading_args:
234239
; CHECK-MINGW: # %bb.0:
235-
; CHECK-MINGW-NEXT: movaps %xmm5, %xmm0
240+
; CHECK-MINGW-NEXT: movq {{[0-9]+}}(%rsp), %rax
241+
; CHECK-MINGW-NEXT: movaps (%rax), %xmm0
236242
; CHECK-MINGW-NEXT: retq
237243
ret fp128 %x
238244
}
@@ -267,7 +273,8 @@ define fp128 @trailing_arg(i64 %_0, i64 %_1, i64 %_2, i64 %_3, i64 %_4, fp128 %x
267273
;
268274
; CHECK-MSVC64-LABEL: trailing_arg:
269275
; CHECK-MSVC64: # %bb.0:
270-
; CHECK-MSVC64-NEXT: movaps %xmm4, %xmm0
276+
; CHECK-MSVC64-NEXT: movq {{[0-9]+}}(%rsp), %rax
277+
; CHECK-MSVC64-NEXT: movaps (%rax), %xmm0
271278
; CHECK-MSVC64-NEXT: retq
272279
;
273280
; CHECK-MSVC32-LABEL: trailing_arg:
@@ -289,7 +296,8 @@ define fp128 @trailing_arg(i64 %_0, i64 %_1, i64 %_2, i64 %_3, i64 %_4, fp128 %x
289296
;
290297
; CHECK-MINGW-LABEL: trailing_arg:
291298
; CHECK-MINGW: # %bb.0:
292-
; CHECK-MINGW-NEXT: movaps %xmm4, %xmm0
299+
; CHECK-MINGW-NEXT: movq {{[0-9]+}}(%rsp), %rax
300+
; CHECK-MINGW-NEXT: movaps (%rax), %xmm0
293301
; CHECK-MINGW-NEXT: retq
294302
ret fp128 %x
295303
}
@@ -317,9 +325,12 @@ define void @call_first_arg(fp128 %x) nounwind {
317325
;
318326
; CHECK-MSVC64-LABEL: call_first_arg:
319327
; CHECK-MSVC64: # %bb.0:
320-
; CHECK-MSVC64-NEXT: subq $40, %rsp
328+
; CHECK-MSVC64-NEXT: subq $56, %rsp
329+
; CHECK-MSVC64-NEXT: movaps (%rcx), %xmm0
330+
; CHECK-MSVC64-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
331+
; CHECK-MSVC64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
321332
; CHECK-MSVC64-NEXT: callq first_arg
322-
; CHECK-MSVC64-NEXT: addq $40, %rsp
333+
; CHECK-MSVC64-NEXT: addq $56, %rsp
323334
; CHECK-MSVC64-NEXT: retq
324335
;
325336
; CHECK-MSVC32-LABEL: call_first_arg:
@@ -342,9 +353,12 @@ define void @call_first_arg(fp128 %x) nounwind {
342353
;
343354
; CHECK-MINGW-LABEL: call_first_arg:
344355
; CHECK-MINGW: # %bb.0:
345-
; CHECK-MINGW-NEXT: subq $40, %rsp
356+
; CHECK-MINGW-NEXT: subq $56, %rsp
357+
; CHECK-MINGW-NEXT: movaps (%rcx), %xmm0
358+
; CHECK-MINGW-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
359+
; CHECK-MINGW-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
346360
; CHECK-MINGW-NEXT: callq first_arg
347-
; CHECK-MINGW-NEXT: addq $40, %rsp
361+
; CHECK-MINGW-NEXT: addq $56, %rsp
348362
; CHECK-MINGW-NEXT: retq
349363
call i128 @first_arg(fp128 %x)
350364
ret void
@@ -385,14 +399,17 @@ define void @call_leading_args(fp128 %x) nounwind {
385399
;
386400
; CHECK-MSVC64-LABEL: call_leading_args:
387401
; CHECK-MSVC64: # %bb.0:
388-
; CHECK-MSVC64-NEXT: subq $40, %rsp
402+
; CHECK-MSVC64-NEXT: subq $72, %rsp
403+
; CHECK-MSVC64-NEXT: movaps (%rcx), %xmm0
404+
; CHECK-MSVC64-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
405+
; CHECK-MSVC64-NEXT: leaq {{[0-9]+}}(%rsp), %rax
406+
; CHECK-MSVC64-NEXT: movq %rax, {{[0-9]+}}(%rsp)
389407
; CHECK-MSVC64-NEXT: xorl %ecx, %ecx
390408
; CHECK-MSVC64-NEXT: xorl %edx, %edx
391409
; CHECK-MSVC64-NEXT: xorl %r8d, %r8d
392410
; CHECK-MSVC64-NEXT: xorl %r9d, %r9d
393-
; CHECK-MSVC64-NEXT: movaps %xmm0, %xmm4
394411
; CHECK-MSVC64-NEXT: callq leading_args
395-
; CHECK-MSVC64-NEXT: addq $40, %rsp
412+
; CHECK-MSVC64-NEXT: addq $72, %rsp
396413
; CHECK-MSVC64-NEXT: retq
397414
;
398415
; CHECK-MSVC32-LABEL: call_leading_args:
@@ -423,14 +440,17 @@ define void @call_leading_args(fp128 %x) nounwind {
423440
;
424441
; CHECK-MINGW-LABEL: call_leading_args:
425442
; CHECK-MINGW: # %bb.0:
426-
; CHECK-MINGW-NEXT: subq $40, %rsp
443+
; CHECK-MINGW-NEXT: subq $72, %rsp
444+
; CHECK-MINGW-NEXT: movaps (%rcx), %xmm0
445+
; CHECK-MINGW-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
446+
; CHECK-MINGW-NEXT: leaq {{[0-9]+}}(%rsp), %rax
447+
; CHECK-MINGW-NEXT: movq %rax, {{[0-9]+}}(%rsp)
427448
; CHECK-MINGW-NEXT: xorl %ecx, %ecx
428449
; CHECK-MINGW-NEXT: xorl %edx, %edx
429450
; CHECK-MINGW-NEXT: xorl %r8d, %r8d
430451
; CHECK-MINGW-NEXT: xorl %r9d, %r9d
431-
; CHECK-MINGW-NEXT: movaps %xmm0, %xmm4
432452
; CHECK-MINGW-NEXT: callq leading_args
433-
; CHECK-MINGW-NEXT: addq $40, %rsp
453+
; CHECK-MINGW-NEXT: addq $72, %rsp
434454
; CHECK-MINGW-NEXT: retq
435455
call i128 @leading_args(i64 0, i64 0, i64 0, i64 0, fp128 %x)
436456
ret void
@@ -477,15 +497,21 @@ define void @call_many_leading_args(fp128 %x) nounwind {
477497
;
478498
; CHECK-MSVC64-LABEL: call_many_leading_args:
479499
; CHECK-MSVC64: # %bb.0:
480-
; CHECK-MSVC64-NEXT: subq $40, %rsp
481-
; CHECK-MSVC64-NEXT: xorps %xmm4, %xmm4
500+
; CHECK-MSVC64-NEXT: subq $88, %rsp
501+
; CHECK-MSVC64-NEXT: movaps (%rcx), %xmm0
502+
; CHECK-MSVC64-NEXT: xorps %xmm1, %xmm1
503+
; CHECK-MSVC64-NEXT: movaps %xmm1, {{[0-9]+}}(%rsp)
504+
; CHECK-MSVC64-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
505+
; CHECK-MSVC64-NEXT: leaq {{[0-9]+}}(%rsp), %rax
506+
; CHECK-MSVC64-NEXT: movq %rax, {{[0-9]+}}(%rsp)
507+
; CHECK-MSVC64-NEXT: leaq {{[0-9]+}}(%rsp), %rax
508+
; CHECK-MSVC64-NEXT: movq %rax, {{[0-9]+}}(%rsp)
482509
; CHECK-MSVC64-NEXT: xorl %ecx, %ecx
483510
; CHECK-MSVC64-NEXT: xorl %edx, %edx
484511
; CHECK-MSVC64-NEXT: xorl %r8d, %r8d
485512
; CHECK-MSVC64-NEXT: xorl %r9d, %r9d
486-
; CHECK-MSVC64-NEXT: movaps %xmm0, %xmm5
487513
; CHECK-MSVC64-NEXT: callq many_leading_args
488-
; CHECK-MSVC64-NEXT: addq $40, %rsp
514+
; CHECK-MSVC64-NEXT: addq $88, %rsp
489515
; CHECK-MSVC64-NEXT: retq
490516
;
491517
; CHECK-MSVC32-LABEL: call_many_leading_args:
@@ -520,15 +546,21 @@ define void @call_many_leading_args(fp128 %x) nounwind {
520546
;
521547
; CHECK-MINGW-LABEL: call_many_leading_args:
522548
; CHECK-MINGW: # %bb.0:
523-
; CHECK-MINGW-NEXT: subq $40, %rsp
524-
; CHECK-MINGW-NEXT: xorps %xmm4, %xmm4
549+
; CHECK-MINGW-NEXT: subq $88, %rsp
550+
; CHECK-MINGW-NEXT: movaps (%rcx), %xmm0
551+
; CHECK-MINGW-NEXT: xorps %xmm1, %xmm1
552+
; CHECK-MINGW-NEXT: movaps %xmm1, {{[0-9]+}}(%rsp)
553+
; CHECK-MINGW-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
554+
; CHECK-MINGW-NEXT: leaq {{[0-9]+}}(%rsp), %rax
555+
; CHECK-MINGW-NEXT: movq %rax, {{[0-9]+}}(%rsp)
556+
; CHECK-MINGW-NEXT: leaq {{[0-9]+}}(%rsp), %rax
557+
; CHECK-MINGW-NEXT: movq %rax, {{[0-9]+}}(%rsp)
525558
; CHECK-MINGW-NEXT: xorl %ecx, %ecx
526559
; CHECK-MINGW-NEXT: xorl %edx, %edx
527560
; CHECK-MINGW-NEXT: xorl %r8d, %r8d
528561
; CHECK-MINGW-NEXT: xorl %r9d, %r9d
529-
; CHECK-MINGW-NEXT: movaps %xmm0, %xmm5
530562
; CHECK-MINGW-NEXT: callq many_leading_args
531-
; CHECK-MINGW-NEXT: addq $40, %rsp
563+
; CHECK-MINGW-NEXT: addq $88, %rsp
532564
; CHECK-MINGW-NEXT: retq
533565
call i128 @many_leading_args(i64 0, i64 0, i64 0, i64 0, fp128 0xL0, fp128 %x)
534566
ret void
@@ -569,14 +601,17 @@ define void @call_trailing_arg(fp128 %x) nounwind {
569601
;
570602
; CHECK-MSVC64-LABEL: call_trailing_arg:
571603
; CHECK-MSVC64: # %bb.0:
572-
; CHECK-MSVC64-NEXT: subq $40, %rsp
604+
; CHECK-MSVC64-NEXT: subq $72, %rsp
605+
; CHECK-MSVC64-NEXT: movaps (%rcx), %xmm0
606+
; CHECK-MSVC64-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
607+
; CHECK-MSVC64-NEXT: leaq {{[0-9]+}}(%rsp), %rax
608+
; CHECK-MSVC64-NEXT: movq %rax, {{[0-9]+}}(%rsp)
573609
; CHECK-MSVC64-NEXT: xorl %ecx, %ecx
574610
; CHECK-MSVC64-NEXT: xorl %edx, %edx
575611
; CHECK-MSVC64-NEXT: xorl %r8d, %r8d
576612
; CHECK-MSVC64-NEXT: xorl %r9d, %r9d
577-
; CHECK-MSVC64-NEXT: movaps %xmm0, %xmm4
578613
; CHECK-MSVC64-NEXT: callq trailing_arg
579-
; CHECK-MSVC64-NEXT: addq $40, %rsp
614+
; CHECK-MSVC64-NEXT: addq $72, %rsp
580615
; CHECK-MSVC64-NEXT: retq
581616
;
582617
; CHECK-MSVC32-LABEL: call_trailing_arg:
@@ -607,14 +642,17 @@ define void @call_trailing_arg(fp128 %x) nounwind {
607642
;
608643
; CHECK-MINGW-LABEL: call_trailing_arg:
609644
; CHECK-MINGW: # %bb.0:
610-
; CHECK-MINGW-NEXT: subq $40, %rsp
645+
; CHECK-MINGW-NEXT: subq $72, %rsp
646+
; CHECK-MINGW-NEXT: movaps (%rcx), %xmm0
647+
; CHECK-MINGW-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
648+
; CHECK-MINGW-NEXT: leaq {{[0-9]+}}(%rsp), %rax
649+
; CHECK-MINGW-NEXT: movq %rax, {{[0-9]+}}(%rsp)
611650
; CHECK-MINGW-NEXT: xorl %ecx, %ecx
612651
; CHECK-MINGW-NEXT: xorl %edx, %edx
613652
; CHECK-MINGW-NEXT: xorl %r8d, %r8d
614653
; CHECK-MINGW-NEXT: xorl %r9d, %r9d
615-
; CHECK-MINGW-NEXT: movaps %xmm0, %xmm4
616654
; CHECK-MINGW-NEXT: callq trailing_arg
617-
; CHECK-MINGW-NEXT: addq $40, %rsp
655+
; CHECK-MINGW-NEXT: addq $72, %rsp
618656
; CHECK-MINGW-NEXT: retq
619657
call i128 @trailing_arg(i64 0, i64 0, i64 0, i64 0, fp128 %x)
620658
ret void

0 commit comments

Comments
 (0)