Skip to content

Commit efc7078

Browse files
authored
[X86][APX] Prevent from emitting push2/pop2 if stack alignment<16B (#143076)
push2/pop2 requires 16-byte stack alignment. If the stack alignment is less than that, push2/pop2 should not be emitted. It triggers general protection exception if the data being pushed/popped by push2/pop2 is not 16-byte aligned on the stack.
1 parent bfbf5d5 commit efc7078

File tree

3 files changed

+120
-2
lines changed

3 files changed

+120
-2
lines changed

llvm/lib/Target/X86/X86FrameLowering.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2915,13 +2915,14 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots(
29152915
// 1. Use push2 when
29162916
// a) number of CSR > 1 if no need padding
29172917
// b) number of CSR > 2 if need padding
2918+
// c) stack alignment >= 16 bytes
29182919
// 2. When the number of CSR push is odd
29192920
// a. Start to use push2 from the 1st push if stack is 16B aligned.
29202921
// b. Start to use push2 from the 2nd push if stack is not 16B aligned.
29212922
// 3. When the number of CSR push is even, start to use push2 from the 1st
29222923
// push and make the stack 16B aligned before the push
29232924
unsigned NumRegsForPush2 = 0;
2924-
if (STI.hasPush2Pop2()) {
2925+
if (STI.hasPush2Pop2() && getStackAlignment() >= 16) {
29252926
unsigned NumCSGPR = llvm::count_if(CSI, [](const CalleeSavedInfo &I) {
29262927
return X86::GR64RegClass.contains(I.getReg());
29272928
});

llvm/lib/Target/X86/X86MachineFunctionInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
149149
/// other tools to detect the extended record.
150150
bool HasSwiftAsyncContext = false;
151151

152-
/// Ajust stack for push2/pop2
152+
/// Adjust stack for push2/pop2
153153
bool PadForPush2Pop2 = false;
154154

155155
/// Candidate registers for push2/pop2
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2 | FileCheck %s --check-prefix=CHECK
3+
4+
; This test is used to check no push2/pop2 emitted if stack alignment is set to
5+
; the value less than 16 bytes required by push2/pop2 instruction. Here it's set
6+
; to 8 bytes.
7+
8+
define void @csr1() nounwind {
9+
; CHECK-LABEL: csr1:
10+
; CHECK: # %bb.0: # %entry
11+
; CHECK-NEXT: pushq %rbp
12+
; CHECK-NEXT: #APP
13+
; CHECK-NEXT: #NO_APP
14+
; CHECK-NEXT: popq %rbp
15+
; CHECK-NEXT: retq
16+
entry:
17+
tail call void asm sideeffect "", "~{rbp},~{dirflag},~{fpsr},~{flags}"()
18+
ret void
19+
}
20+
21+
define void @csr2() nounwind {
22+
; CHECK-LABEL: csr2:
23+
; CHECK: # %bb.0: # %entry
24+
; CHECK-NEXT: pushq %rbp
25+
; CHECK-NEXT: pushq %r15
26+
; CHECK-NEXT: #APP
27+
; CHECK-NEXT: #NO_APP
28+
; CHECK-NEXT: popq %r15
29+
; CHECK-NEXT: popq %rbp
30+
; CHECK-NEXT: retq
31+
entry:
32+
tail call void asm sideeffect "", "~{rbp},~{r15},~{dirflag},~{fpsr},~{flags}"()
33+
ret void
34+
}
35+
36+
define void @csr3() nounwind {
37+
; CHECK-LABEL: csr3:
38+
; CHECK: # %bb.0: # %entry
39+
; CHECK-NEXT: pushq %rbp
40+
; CHECK-NEXT: pushq %r15
41+
; CHECK-NEXT: pushq %r14
42+
; CHECK-NEXT: #APP
43+
; CHECK-NEXT: #NO_APP
44+
; CHECK-NEXT: popq %r14
45+
; CHECK-NEXT: popq %r15
46+
; CHECK-NEXT: popq %rbp
47+
; CHECK-NEXT: retq
48+
entry:
49+
tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{dirflag},~{fpsr},~{flags}"()
50+
ret void
51+
}
52+
53+
define void @csr4() nounwind {
54+
; CHECK-LABEL: csr4:
55+
; CHECK: # %bb.0: # %entry
56+
; CHECK-NEXT: pushq %rbp
57+
; CHECK-NEXT: pushq %r15
58+
; CHECK-NEXT: pushq %r14
59+
; CHECK-NEXT: pushq %r13
60+
; CHECK-NEXT: #APP
61+
; CHECK-NEXT: #NO_APP
62+
; CHECK-NEXT: popq %r13
63+
; CHECK-NEXT: popq %r14
64+
; CHECK-NEXT: popq %r15
65+
; CHECK-NEXT: popq %rbp
66+
; CHECK-NEXT: retq
67+
entry:
68+
tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{dirflag},~{fpsr},~{flags}"()
69+
ret void
70+
}
71+
72+
define void @csr5() nounwind {
73+
; CHECK-LABEL: csr5:
74+
; CHECK: # %bb.0: # %entry
75+
; CHECK-NEXT: pushq %rbp
76+
; CHECK-NEXT: pushq %r15
77+
; CHECK-NEXT: pushq %r14
78+
; CHECK-NEXT: pushq %r13
79+
; CHECK-NEXT: pushq %r12
80+
; CHECK-NEXT: #APP
81+
; CHECK-NEXT: #NO_APP
82+
; CHECK-NEXT: popq %r12
83+
; CHECK-NEXT: popq %r13
84+
; CHECK-NEXT: popq %r14
85+
; CHECK-NEXT: popq %r15
86+
; CHECK-NEXT: popq %rbp
87+
; CHECK-NEXT: retq
88+
entry:
89+
tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{dirflag},~{fpsr},~{flags}"()
90+
ret void
91+
}
92+
93+
define void @csr6() nounwind {
94+
; CHECK-LABEL: csr6:
95+
; CHECK: # %bb.0: # %entry
96+
; CHECK-NEXT: pushq %rbp
97+
; CHECK-NEXT: pushq %r15
98+
; CHECK-NEXT: pushq %r14
99+
; CHECK-NEXT: pushq %r13
100+
; CHECK-NEXT: pushq %r12
101+
; CHECK-NEXT: pushq %rbx
102+
; CHECK-NEXT: #APP
103+
; CHECK-NEXT: #NO_APP
104+
; CHECK-NEXT: popq %rbx
105+
; CHECK-NEXT: popq %r12
106+
; CHECK-NEXT: popq %r13
107+
; CHECK-NEXT: popq %r14
108+
; CHECK-NEXT: popq %r15
109+
; CHECK-NEXT: popq %rbp
110+
; CHECK-NEXT: retq
111+
entry:
112+
tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{rbx},~{dirflag},~{fpsr},~{flags}"()
113+
ret void
114+
}
115+
116+
!llvm.module.flags = !{!0}
117+
!0 = !{i32 1, !"override-stack-alignment", i32 8}

0 commit comments

Comments
 (0)