Skip to content

Commit fa1b6e6

Browse files
committed
[X86] Fix i128 argument passing under SysV ABI
The x86_64 SysV ABI specifies that __int128 is passed either in two registers (if available) or in a 16 byte aligned stack slot. GCC implements this behavior. However, if only one free register is available, LLVM will instead pass one half of the i128 in a register, and the other on the stack. Make sure that either both are passed in registers or both on the stack. Fixes llvm#41784. The patch is basically what craig.topper proposed to do there. Differential Revision: https://reviews.llvm.org/D158169
1 parent b0af89c commit fa1b6e6

File tree

9 files changed

+68
-53
lines changed

9 files changed

+68
-53
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ C++ Specific Potentially Breaking Changes
4646

4747
ABI Changes in This Version
4848
---------------------------
49+
- Following the SystemV ABI for x86-64, ``__int128`` arguments will no longer
50+
be split between a register and a stack slot.
4951

5052
What's New in Clang |release|?
5153
==============================

llvm/lib/Target/X86/X86CallingConv.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,14 @@ def CC_X86_64_C : CallingConv<[
572572

573573
// The first 6 integer arguments are passed in integer registers.
574574
CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D]>>,
575+
576+
// i128 can be either passed in two i64 registers, or on the stack, but
577+
// not split across register and stack. As such, do not allow using R9
578+
// for a split i64.
579+
CCIfType<[i64],
580+
CCIfSplit<CCAssignToReg<[RDI, RSI, RDX, RCX, R8]>>>,
581+
CCIfType<[i64], CCIfSplit<CCAssignToStackWithShadow<8, 16, [R9]>>>,
582+
575583
CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8 , R9 ]>>,
576584

577585
// The first 8 MMX vector arguments are passed in XMM registers on Darwin.

llvm/test/CodeGen/X86/addcarry.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ define i256 @add256(i256 %a, i256 %b) nounwind {
4848
; CHECK-LABEL: add256:
4949
; CHECK: # %bb.0: # %entry
5050
; CHECK-NEXT: movq %rdi, %rax
51-
; CHECK-NEXT: addq %r9, %rsi
51+
; CHECK-NEXT: addq {{[0-9]+}}(%rsp), %rsi
5252
; CHECK-NEXT: adcq {{[0-9]+}}(%rsp), %rdx
5353
; CHECK-NEXT: adcq {{[0-9]+}}(%rsp), %rcx
5454
; CHECK-NEXT: adcq {{[0-9]+}}(%rsp), %r8

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ define i128 @in_reg(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i128 %a4) {
1313
define i128 @on_stack(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i128 %a5) {
1414
; CHECK-LABEL: on_stack:
1515
; CHECK: # %bb.0:
16-
; CHECK-NEXT: movq %r9, %rax
17-
; CHECK-NEXT: movq 8(%rsp), %rdx
16+
; CHECK-NEXT: movq 8(%rsp), %rax
17+
; CHECK-NEXT: movq 16(%rsp), %rdx
1818
; CHECK-NEXT: retq
1919
ret i128 %a5
2020
}
2121

2222
define i64 @trailing_arg_on_stack(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i128 %a5, i64 %a6) {
2323
; CHECK-LABEL: trailing_arg_on_stack:
2424
; CHECK: # %bb.0:
25-
; CHECK-NEXT: movq 16(%rsp), %rax
25+
; CHECK-NEXT: movq 24(%rsp), %rax
2626
; CHECK-NEXT: retq
2727
ret i64 %a6
2828
}
@@ -48,14 +48,17 @@ define void @call_on_stack(i128 %x) nounwind {
4848
; CHECK-LABEL: call_on_stack:
4949
; CHECK: # %bb.0:
5050
; CHECK-NEXT: pushq %rax
51+
; CHECK-NEXT: movq %rsi, %rax
5152
; CHECK-NEXT: movq %rdi, %r9
52-
; CHECK-NEXT: movq %rsi, (%rsp)
5353
; CHECK-NEXT: movl $1, %esi
5454
; CHECK-NEXT: movl $2, %edx
5555
; CHECK-NEXT: movl $3, %ecx
5656
; CHECK-NEXT: movl $4, %r8d
5757
; CHECK-NEXT: xorl %edi, %edi
58+
; CHECK-NEXT: pushq %rax
59+
; CHECK-NEXT: pushq %r9
5860
; CHECK-NEXT: callq on_stack@PLT
61+
; CHECK-NEXT: addq $16, %rsp
5962
; CHECK-NEXT: popq %rax
6063
; CHECK-NEXT: retq
6164
call i128 @on_stack(i64 0, i64 1, i64 2, i64 3, i64 4, i128 %x)
@@ -67,17 +70,19 @@ define void @call_trailing_arg_on_stack(i128 %x, i64 %y) nounwind {
6770
; CHECK: # %bb.0:
6871
; CHECK-NEXT: pushq %rax
6972
; CHECK-NEXT: movq %rdx, %rax
70-
; CHECK-NEXT: movq %rsi, %r10
71-
; CHECK-NEXT: movq %rdi, %r9
73+
; CHECK-NEXT: movq %rsi, %r9
74+
; CHECK-NEXT: movq %rdi, %r10
75+
; CHECK-NEXT: subq $8, %rsp
7276
; CHECK-NEXT: movl $1, %esi
7377
; CHECK-NEXT: movl $2, %edx
7478
; CHECK-NEXT: movl $3, %ecx
7579
; CHECK-NEXT: movl $4, %r8d
7680
; CHECK-NEXT: xorl %edi, %edi
7781
; CHECK-NEXT: pushq %rax
82+
; CHECK-NEXT: pushq %r9
7883
; CHECK-NEXT: pushq %r10
7984
; CHECK-NEXT: callq trailing_arg_on_stack@PLT
80-
; CHECK-NEXT: addq $16, %rsp
85+
; CHECK-NEXT: addq $32, %rsp
8186
; CHECK-NEXT: popq %rax
8287
; CHECK-NEXT: retq
8388
call i128 @trailing_arg_on_stack(i64 0, i64 1, i64 2, i64 3, i64 4, i128 %x, i64 %y)

llvm/test/CodeGen/X86/sadd_sat_vec.ll

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,27 +1795,27 @@ define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
17951795
; SSE-NEXT: addq {{[0-9]+}}(%rsp), %rcx
17961796
; SSE-NEXT: adcq {{[0-9]+}}(%rsp), %r8
17971797
; SSE-NEXT: seto %dil
1798-
; SSE-NEXT: movq %r8, %r10
1799-
; SSE-NEXT: sarq $63, %r10
1798+
; SSE-NEXT: movq %r8, %r9
1799+
; SSE-NEXT: sarq $63, %r9
18001800
; SSE-NEXT: testb %dil, %dil
1801-
; SSE-NEXT: cmovneq %r10, %rcx
1802-
; SSE-NEXT: movabsq $-9223372036854775808, %r11 # imm = 0x8000000000000000
1803-
; SSE-NEXT: xorq %r11, %r10
1801+
; SSE-NEXT: cmovneq %r9, %rcx
1802+
; SSE-NEXT: movabsq $-9223372036854775808, %r10 # imm = 0x8000000000000000
1803+
; SSE-NEXT: xorq %r10, %r9
18041804
; SSE-NEXT: testb %dil, %dil
1805-
; SSE-NEXT: cmoveq %r8, %r10
1806-
; SSE-NEXT: addq %r9, %rsi
1805+
; SSE-NEXT: cmoveq %r8, %r9
1806+
; SSE-NEXT: addq {{[0-9]+}}(%rsp), %rsi
18071807
; SSE-NEXT: adcq {{[0-9]+}}(%rsp), %rdx
18081808
; SSE-NEXT: seto %dil
18091809
; SSE-NEXT: movq %rdx, %r8
18101810
; SSE-NEXT: sarq $63, %r8
18111811
; SSE-NEXT: testb %dil, %dil
18121812
; SSE-NEXT: cmovneq %r8, %rsi
1813-
; SSE-NEXT: xorq %r11, %r8
1813+
; SSE-NEXT: xorq %r10, %r8
18141814
; SSE-NEXT: testb %dil, %dil
18151815
; SSE-NEXT: cmoveq %rdx, %r8
18161816
; SSE-NEXT: movq %rcx, 16(%rax)
18171817
; SSE-NEXT: movq %rsi, (%rax)
1818-
; SSE-NEXT: movq %r10, 24(%rax)
1818+
; SSE-NEXT: movq %r9, 24(%rax)
18191819
; SSE-NEXT: movq %r8, 8(%rax)
18201820
; SSE-NEXT: retq
18211821
;
@@ -1825,27 +1825,27 @@ define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
18251825
; AVX-NEXT: addq {{[0-9]+}}(%rsp), %rcx
18261826
; AVX-NEXT: adcq {{[0-9]+}}(%rsp), %r8
18271827
; AVX-NEXT: seto %dil
1828-
; AVX-NEXT: movq %r8, %r10
1829-
; AVX-NEXT: sarq $63, %r10
1828+
; AVX-NEXT: movq %r8, %r9
1829+
; AVX-NEXT: sarq $63, %r9
18301830
; AVX-NEXT: testb %dil, %dil
1831-
; AVX-NEXT: cmovneq %r10, %rcx
1832-
; AVX-NEXT: movabsq $-9223372036854775808, %r11 # imm = 0x8000000000000000
1833-
; AVX-NEXT: xorq %r11, %r10
1831+
; AVX-NEXT: cmovneq %r9, %rcx
1832+
; AVX-NEXT: movabsq $-9223372036854775808, %r10 # imm = 0x8000000000000000
1833+
; AVX-NEXT: xorq %r10, %r9
18341834
; AVX-NEXT: testb %dil, %dil
1835-
; AVX-NEXT: cmoveq %r8, %r10
1836-
; AVX-NEXT: addq %r9, %rsi
1835+
; AVX-NEXT: cmoveq %r8, %r9
1836+
; AVX-NEXT: addq {{[0-9]+}}(%rsp), %rsi
18371837
; AVX-NEXT: adcq {{[0-9]+}}(%rsp), %rdx
18381838
; AVX-NEXT: seto %dil
18391839
; AVX-NEXT: movq %rdx, %r8
18401840
; AVX-NEXT: sarq $63, %r8
18411841
; AVX-NEXT: testb %dil, %dil
18421842
; AVX-NEXT: cmovneq %r8, %rsi
1843-
; AVX-NEXT: xorq %r11, %r8
1843+
; AVX-NEXT: xorq %r10, %r8
18441844
; AVX-NEXT: testb %dil, %dil
18451845
; AVX-NEXT: cmoveq %rdx, %r8
18461846
; AVX-NEXT: movq %rcx, 16(%rax)
18471847
; AVX-NEXT: movq %rsi, (%rax)
1848-
; AVX-NEXT: movq %r10, 24(%rax)
1848+
; AVX-NEXT: movq %r9, 24(%rax)
18491849
; AVX-NEXT: movq %r8, 8(%rax)
18501850
; AVX-NEXT: retq
18511851
%z = call <2 x i128> @llvm.sadd.sat.v2i128(<2 x i128> %x, <2 x i128> %y)

llvm/test/CodeGen/X86/ssub_sat_vec.ll

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,27 +2026,27 @@ define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
20262026
; SSE-NEXT: subq {{[0-9]+}}(%rsp), %rcx
20272027
; SSE-NEXT: sbbq {{[0-9]+}}(%rsp), %r8
20282028
; SSE-NEXT: seto %dil
2029-
; SSE-NEXT: movq %r8, %r10
2030-
; SSE-NEXT: sarq $63, %r10
2029+
; SSE-NEXT: movq %r8, %r9
2030+
; SSE-NEXT: sarq $63, %r9
20312031
; SSE-NEXT: testb %dil, %dil
2032-
; SSE-NEXT: cmovneq %r10, %rcx
2033-
; SSE-NEXT: movabsq $-9223372036854775808, %r11 # imm = 0x8000000000000000
2034-
; SSE-NEXT: xorq %r11, %r10
2032+
; SSE-NEXT: cmovneq %r9, %rcx
2033+
; SSE-NEXT: movabsq $-9223372036854775808, %r10 # imm = 0x8000000000000000
2034+
; SSE-NEXT: xorq %r10, %r9
20352035
; SSE-NEXT: testb %dil, %dil
2036-
; SSE-NEXT: cmoveq %r8, %r10
2037-
; SSE-NEXT: subq %r9, %rsi
2036+
; SSE-NEXT: cmoveq %r8, %r9
2037+
; SSE-NEXT: subq {{[0-9]+}}(%rsp), %rsi
20382038
; SSE-NEXT: sbbq {{[0-9]+}}(%rsp), %rdx
20392039
; SSE-NEXT: seto %dil
20402040
; SSE-NEXT: movq %rdx, %r8
20412041
; SSE-NEXT: sarq $63, %r8
20422042
; SSE-NEXT: testb %dil, %dil
20432043
; SSE-NEXT: cmovneq %r8, %rsi
2044-
; SSE-NEXT: xorq %r11, %r8
2044+
; SSE-NEXT: xorq %r10, %r8
20452045
; SSE-NEXT: testb %dil, %dil
20462046
; SSE-NEXT: cmoveq %rdx, %r8
20472047
; SSE-NEXT: movq %rcx, 16(%rax)
20482048
; SSE-NEXT: movq %rsi, (%rax)
2049-
; SSE-NEXT: movq %r10, 24(%rax)
2049+
; SSE-NEXT: movq %r9, 24(%rax)
20502050
; SSE-NEXT: movq %r8, 8(%rax)
20512051
; SSE-NEXT: retq
20522052
;
@@ -2056,27 +2056,27 @@ define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
20562056
; AVX-NEXT: subq {{[0-9]+}}(%rsp), %rcx
20572057
; AVX-NEXT: sbbq {{[0-9]+}}(%rsp), %r8
20582058
; AVX-NEXT: seto %dil
2059-
; AVX-NEXT: movq %r8, %r10
2060-
; AVX-NEXT: sarq $63, %r10
2059+
; AVX-NEXT: movq %r8, %r9
2060+
; AVX-NEXT: sarq $63, %r9
20612061
; AVX-NEXT: testb %dil, %dil
2062-
; AVX-NEXT: cmovneq %r10, %rcx
2063-
; AVX-NEXT: movabsq $-9223372036854775808, %r11 # imm = 0x8000000000000000
2064-
; AVX-NEXT: xorq %r11, %r10
2062+
; AVX-NEXT: cmovneq %r9, %rcx
2063+
; AVX-NEXT: movabsq $-9223372036854775808, %r10 # imm = 0x8000000000000000
2064+
; AVX-NEXT: xorq %r10, %r9
20652065
; AVX-NEXT: testb %dil, %dil
2066-
; AVX-NEXT: cmoveq %r8, %r10
2067-
; AVX-NEXT: subq %r9, %rsi
2066+
; AVX-NEXT: cmoveq %r8, %r9
2067+
; AVX-NEXT: subq {{[0-9]+}}(%rsp), %rsi
20682068
; AVX-NEXT: sbbq {{[0-9]+}}(%rsp), %rdx
20692069
; AVX-NEXT: seto %dil
20702070
; AVX-NEXT: movq %rdx, %r8
20712071
; AVX-NEXT: sarq $63, %r8
20722072
; AVX-NEXT: testb %dil, %dil
20732073
; AVX-NEXT: cmovneq %r8, %rsi
2074-
; AVX-NEXT: xorq %r11, %r8
2074+
; AVX-NEXT: xorq %r10, %r8
20752075
; AVX-NEXT: testb %dil, %dil
20762076
; AVX-NEXT: cmoveq %rdx, %r8
20772077
; AVX-NEXT: movq %rcx, 16(%rax)
20782078
; AVX-NEXT: movq %rsi, (%rax)
2079-
; AVX-NEXT: movq %r10, 24(%rax)
2079+
; AVX-NEXT: movq %r9, 24(%rax)
20802080
; AVX-NEXT: movq %r8, 8(%rax)
20812081
; AVX-NEXT: retq
20822082
%z = call <2 x i128> @llvm.ssub.sat.v2i128(<2 x i128> %x, <2 x i128> %y)

llvm/test/CodeGen/X86/subcarry.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ define i256 @sub256(i256 %a, i256 %b) nounwind {
2121
; CHECK-LABEL: sub256:
2222
; CHECK: # %bb.0: # %entry
2323
; CHECK-NEXT: movq %rdi, %rax
24-
; CHECK-NEXT: subq %r9, %rsi
24+
; CHECK-NEXT: subq {{[0-9]+}}(%rsp), %rsi
2525
; CHECK-NEXT: sbbq {{[0-9]+}}(%rsp), %rdx
2626
; CHECK-NEXT: sbbq {{[0-9]+}}(%rsp), %rcx
2727
; CHECK-NEXT: sbbq {{[0-9]+}}(%rsp), %r8

llvm/test/CodeGen/X86/uadd_sat_vec.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,11 +1161,11 @@ define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
11611161
; SSE-LABEL: v2i128:
11621162
; SSE: # %bb.0:
11631163
; SSE-NEXT: movq %rdi, %rax
1164-
; SSE-NEXT: addq %r9, %rsi
1164+
; SSE-NEXT: addq {{[0-9]+}}(%rsp), %rsi
11651165
; SSE-NEXT: adcq {{[0-9]+}}(%rsp), %rdx
11661166
; SSE-NEXT: movq $-1, %rdi
1167-
; SSE-NEXT: cmovbq %rdi, %rsi
11681167
; SSE-NEXT: cmovbq %rdi, %rdx
1168+
; SSE-NEXT: cmovbq %rdi, %rsi
11691169
; SSE-NEXT: addq {{[0-9]+}}(%rsp), %rcx
11701170
; SSE-NEXT: adcq {{[0-9]+}}(%rsp), %r8
11711171
; SSE-NEXT: cmovbq %rdi, %r8
@@ -1179,11 +1179,11 @@ define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
11791179
; AVX-LABEL: v2i128:
11801180
; AVX: # %bb.0:
11811181
; AVX-NEXT: movq %rdi, %rax
1182-
; AVX-NEXT: addq %r9, %rsi
1182+
; AVX-NEXT: addq {{[0-9]+}}(%rsp), %rsi
11831183
; AVX-NEXT: adcq {{[0-9]+}}(%rsp), %rdx
11841184
; AVX-NEXT: movq $-1, %rdi
1185-
; AVX-NEXT: cmovbq %rdi, %rsi
11861185
; AVX-NEXT: cmovbq %rdi, %rdx
1186+
; AVX-NEXT: cmovbq %rdi, %rsi
11871187
; AVX-NEXT: addq {{[0-9]+}}(%rsp), %rcx
11881188
; AVX-NEXT: adcq {{[0-9]+}}(%rsp), %r8
11891189
; AVX-NEXT: cmovbq %rdi, %r8

llvm/test/CodeGen/X86/usub_sat_vec.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,10 +1057,10 @@ define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
10571057
; SSE: # %bb.0:
10581058
; SSE-NEXT: movq %rdi, %rax
10591059
; SSE-NEXT: xorl %edi, %edi
1060-
; SSE-NEXT: subq %r9, %rsi
1060+
; SSE-NEXT: subq {{[0-9]+}}(%rsp), %rsi
10611061
; SSE-NEXT: sbbq {{[0-9]+}}(%rsp), %rdx
1062-
; SSE-NEXT: cmovbq %rdi, %rsi
10631062
; SSE-NEXT: cmovbq %rdi, %rdx
1063+
; SSE-NEXT: cmovbq %rdi, %rsi
10641064
; SSE-NEXT: subq {{[0-9]+}}(%rsp), %rcx
10651065
; SSE-NEXT: sbbq {{[0-9]+}}(%rsp), %r8
10661066
; SSE-NEXT: cmovbq %rdi, %r8
@@ -1075,10 +1075,10 @@ define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
10751075
; AVX: # %bb.0:
10761076
; AVX-NEXT: movq %rdi, %rax
10771077
; AVX-NEXT: xorl %edi, %edi
1078-
; AVX-NEXT: subq %r9, %rsi
1078+
; AVX-NEXT: subq {{[0-9]+}}(%rsp), %rsi
10791079
; AVX-NEXT: sbbq {{[0-9]+}}(%rsp), %rdx
1080-
; AVX-NEXT: cmovbq %rdi, %rsi
10811080
; AVX-NEXT: cmovbq %rdi, %rdx
1081+
; AVX-NEXT: cmovbq %rdi, %rsi
10821082
; AVX-NEXT: subq {{[0-9]+}}(%rsp), %rcx
10831083
; AVX-NEXT: sbbq {{[0-9]+}}(%rsp), %r8
10841084
; AVX-NEXT: cmovbq %rdi, %r8

0 commit comments

Comments
 (0)