[llvm] [X86] Don't save/restore fp/bp around terminator (PR #106462)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 28 15:04:22 PDT 2024


https://github.com/weiguozhi created https://github.com/llvm/llvm-project/pull/106462

In function spillFPBP we already try to skip terminator, but there is a logic error, so when there is only terminator instruction in the MBB, it still tries to save/restore fp/bp around it if the terminator clobbers fp/bp, for example a tail call with ghc calling convention.

Now this patch really skips terminator even if it is the only instruction in the MBB.

>From 9d238f0c47a192cac52cd5ee5d1f3279ed39aede Mon Sep 17 00:00:00 2001
From: Guozhi Wei <carrot at google.com>
Date: Wed, 28 Aug 2024 14:53:11 -0700
Subject: [PATCH] [X86] Don't save/restore fp/bp around terminator

In function spillFPBP we already try to skip terminator, but there is a
logic error, so when there is only terminator instruction in the MBB, it
still tries to save/restore fp/bp around it if the terminator clobbers
fp/bp, for example a tail call with ghc calling convention.

Now this patch really skips terminator even if it is the only
instruction in the MBB.
---
 llvm/lib/Target/X86/X86FrameLowering.cpp   |  5 ++-
 llvm/test/CodeGen/X86/clobber_frame_ptr.ll | 43 ++++++++++++++++++++++
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 43a3219f789c4a..53bf04e6eff25d 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -4502,8 +4502,9 @@ void X86FrameLowering::spillFPBP(MachineFunction &MF) const {
     bool InsideEHLabels = false;
     auto MI = MBB.rbegin(), ME = MBB.rend();
     auto TermMI = MBB.getFirstTerminator();
-    if (TermMI != MBB.begin())
-      MI = *(std::prev(TermMI));
+    if (TermMI == MBB.begin())
+      continue;
+    MI = *(std::prev(TermMI));
 
     while (MI != ME) {
       // Skip frame setup/destroy instructions.
diff --git a/llvm/test/CodeGen/X86/clobber_frame_ptr.ll b/llvm/test/CodeGen/X86/clobber_frame_ptr.ll
index 55c2d791b66e76..f6b38839d13cc2 100644
--- a/llvm/test/CodeGen/X86/clobber_frame_ptr.ll
+++ b/llvm/test/CodeGen/X86/clobber_frame_ptr.ll
@@ -144,3 +144,46 @@ entry:
   call void @llvm.eh.sjlj.longjmp(ptr @buf)
   unreachable
 }
+
+declare ghccc void @tail()
+
+; We should not save/restore fp/bp around terminator.
+define ghccc void @test5() {
+; CHECK-LABEL: test5:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %rbp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    .cfi_offset %rbp, -16
+; CHECK-NEXT:    movq %rsp, %rbp
+; CHECK-NEXT:    .cfi_def_cfa_register %rbp
+; CHECK-NEXT:    andq $-8, %rsp
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    testb %al, %al
+; CHECK-NEXT:    jne .LBB3_2
+; CHECK-NEXT:  # %bb.1: # %then
+; CHECK-NEXT:    movq $0, (%rax)
+; CHECK-NEXT:    movq %rbp, %rsp
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa %rsp, 8
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB3_2: # %else
+; CHECK-NEXT:    .cfi_def_cfa %rbp, 16
+; CHECK-NEXT:    movq %rbp, %rsp
+; CHECK-NEXT:    popq %rbp
+; CHECK-NEXT:    .cfi_def_cfa %rsp, 8
+; CHECK-NEXT:    jmp tail at PLT # TAILCALL
+entry:
+  br i1 undef, label %then, label %else
+
+then:
+  store i64 0, ptr undef
+  br label %exit
+
+else:
+  musttail call ghccc void @tail()
+  ret void
+
+exit:
+  ret void
+}
+



More information about the llvm-commits mailing list