diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 75f49beee27c6..42a09106b3a3a 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -2915,13 +2915,14 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots( // 1. Use push2 when // a) number of CSR > 1 if no need padding // b) number of CSR > 2 if need padding + // c) stack alignment >= 16 bytes // 2. When the number of CSR push is odd // a. Start to use push2 from the 1st push if stack is 16B aligned. // b. Start to use push2 from the 2nd push if stack is not 16B aligned. // 3. When the number of CSR push is even, start to use push2 from the 1st // push and make the stack 16B aligned before the push unsigned NumRegsForPush2 = 0; - if (STI.hasPush2Pop2()) { + if (STI.hasPush2Pop2() && getStackAlignment() >= 16) { unsigned NumCSGPR = llvm::count_if(CSI, [](const CalleeSavedInfo &I) { return X86::GR64RegClass.contains(I.getReg()); }); diff --git a/llvm/lib/Target/X86/X86MachineFunctionInfo.h b/llvm/lib/Target/X86/X86MachineFunctionInfo.h index 24371369d4a45..5f974e5de9a19 100644 --- a/llvm/lib/Target/X86/X86MachineFunctionInfo.h +++ b/llvm/lib/Target/X86/X86MachineFunctionInfo.h @@ -149,7 +149,7 @@ class X86MachineFunctionInfo : public MachineFunctionInfo { /// other tools to detect the extended record. bool HasSwiftAsyncContext = false; - /// Ajust stack for push2/pop2 + /// Adjust stack for push2/pop2 bool PadForPush2Pop2 = false; /// Candidate registers for push2/pop2 diff --git a/llvm/test/CodeGen/X86/apx/push2-pop2-disabled-with-small-stack-alignment.ll b/llvm/test/CodeGen/X86/apx/push2-pop2-disabled-with-small-stack-alignment.ll new file mode 100644 index 0000000000000..f07e40b442c04 --- /dev/null +++ b/llvm/test/CodeGen/X86/apx/push2-pop2-disabled-with-small-stack-alignment.ll @@ -0,0 +1,117 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2 | FileCheck %s --check-prefix=CHECK + +; This test is used to check no push2/pop2 emitted if stack alignment is set to +; the value less than 16 bytes required by push2/pop2 instruction. Here it's set +; to 8 bytes. + +define void @csr1() nounwind { +; CHECK-LABEL: csr1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rbp +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: popq %rbp +; CHECK-NEXT: retq +entry: + tail call void asm sideeffect "", "~{rbp},~{dirflag},~{fpsr},~{flags}"() + ret void +} + +define void @csr2() nounwind { +; CHECK-LABEL: csr2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rbp +; CHECK-NEXT: pushq %r15 +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: popq %r15 +; CHECK-NEXT: popq %rbp +; CHECK-NEXT: retq +entry: + tail call void asm sideeffect "", "~{rbp},~{r15},~{dirflag},~{fpsr},~{flags}"() + ret void +} + +define void @csr3() nounwind { +; CHECK-LABEL: csr3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rbp +; CHECK-NEXT: pushq %r15 +; CHECK-NEXT: pushq %r14 +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: popq %r14 +; CHECK-NEXT: popq %r15 +; CHECK-NEXT: popq %rbp +; CHECK-NEXT: retq +entry: + tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{dirflag},~{fpsr},~{flags}"() + ret void +} + +define void @csr4() nounwind { +; CHECK-LABEL: csr4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rbp +; CHECK-NEXT: pushq %r15 +; CHECK-NEXT: pushq %r14 +; CHECK-NEXT: pushq %r13 +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: popq %r13 +; CHECK-NEXT: popq %r14 +; CHECK-NEXT: popq %r15 +; CHECK-NEXT: popq %rbp +; CHECK-NEXT: retq +entry: + tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{dirflag},~{fpsr},~{flags}"() + ret void +} + +define void @csr5() nounwind { +; CHECK-LABEL: csr5: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rbp +; CHECK-NEXT: pushq %r15 +; CHECK-NEXT: pushq %r14 +; CHECK-NEXT: pushq %r13 +; CHECK-NEXT: pushq %r12 +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: popq %r12 +; CHECK-NEXT: popq %r13 +; CHECK-NEXT: popq %r14 +; CHECK-NEXT: popq %r15 +; CHECK-NEXT: popq %rbp +; CHECK-NEXT: retq +entry: + tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{dirflag},~{fpsr},~{flags}"() + ret void +} + +define void @csr6() nounwind { +; CHECK-LABEL: csr6: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushq %rbp +; CHECK-NEXT: pushq %r15 +; CHECK-NEXT: pushq %r14 +; CHECK-NEXT: pushq %r13 +; CHECK-NEXT: pushq %r12 +; CHECK-NEXT: pushq %rbx +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: popq %rbx +; CHECK-NEXT: popq %r12 +; CHECK-NEXT: popq %r13 +; CHECK-NEXT: popq %r14 +; CHECK-NEXT: popq %r15 +; CHECK-NEXT: popq %rbp +; CHECK-NEXT: retq +entry: + tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{rbx},~{dirflag},~{fpsr},~{flags}"() + ret void +} + +!llvm.module.flags = !{!0} +!0 = !{i32 1, !"override-stack-alignment", i32 8}