[llvm] [X86] Don't save/restore fp around longjmp instructions (PR #102556)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 16 10:43:21 PDT 2024
https://github.com/weiguozhi updated https://github.com/llvm/llvm-project/pull/102556
>From 9cae8fbc5792b59026a48cffdc182eae32982206 Mon Sep 17 00:00:00 2001
From: Guozhi Wei <carrot at google.com>
Date: Thu, 8 Aug 2024 17:47:33 -0700
Subject: [PATCH 1/2] [X86] Don't save/restore fp around longjmp instructions
Longjmp instructions can also modify fp register, it is expected
behavior. We should not save/restore fp around these instructions.
---
llvm/lib/Target/X86/X86FrameLowering.cpp | 6 +++
llvm/lib/Target/X86/X86ISelLowering.cpp | 2 +
llvm/lib/Target/X86/X86MachineFunctionInfo.h | 11 +++++
llvm/test/CodeGen/X86/clobber_frame_ptr.ll | 43 ++++++++++++++++++++
4 files changed, 62 insertions(+)
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 8404f2231680d6..8760e97e684e35 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -4389,6 +4389,12 @@ bool X86FrameLowering::skipSpillFPBP(
++MI;
return true;
}
+
+ // FP clobbered by longjmp is expected.
+ X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
+ if (X86FI->containLongJmpMIClobberFP(&*MI))
+ return true;
+
return false;
}
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index f69606783f25c8..6974d18814eb75 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -36205,6 +36205,8 @@ X86TargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
MIB.add(MO);
}
MIB.setMemRefs(MMOs);
+ auto *MFI = MF->getInfo<X86MachineFunctionInfo>();
+ MFI->insertLongJmpMIClobberFP(MIB.getInstr());
// Reload IP
MIB = BuildMI(*thisMBB, MI, MIMD, TII->get(PtrLoadOpc), Tmp);
diff --git a/llvm/lib/Target/X86/X86MachineFunctionInfo.h b/llvm/lib/Target/X86/X86MachineFunctionInfo.h
index 13d57c2fa9dfbc..bf3ffdc8677bf3 100644
--- a/llvm/lib/Target/X86/X86MachineFunctionInfo.h
+++ b/llvm/lib/Target/X86/X86MachineFunctionInfo.h
@@ -14,6 +14,7 @@
#define LLVM_LIB_TARGET_X86_X86MACHINEFUNCTIONINFO_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
@@ -174,6 +175,9 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
bool FPClobberedByCall = false;
bool BPClobberedByCall = false;
+ // A set of instructions clobber FP generated from longjmp.
+ SmallSet<MachineInstr *, 2> LongJmpMIClobberFP;
+
private:
/// ForwardedMustTailRegParms - A list of virtual and physical registers
/// that must be forwarded to every musttail call.
@@ -338,6 +342,13 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
bool getBPClobberedByCall() const { return BPClobberedByCall; }
void setBPClobberedByCall(bool C) { BPClobberedByCall = C; }
+
+ bool containLongJmpMIClobberFP(MachineInstr *MI) const {
+ return LongJmpMIClobberFP.contains(MI);
+ }
+ void insertLongJmpMIClobberFP(MachineInstr *MI) {
+ LongJmpMIClobberFP.insert(MI);
+ }
};
} // End llvm namespace
diff --git a/llvm/test/CodeGen/X86/clobber_frame_ptr.ll b/llvm/test/CodeGen/X86/clobber_frame_ptr.ll
index 6209e1a85e9e19..fd8ba7feb9f48f 100644
--- a/llvm/test/CodeGen/X86/clobber_frame_ptr.ll
+++ b/llvm/test/CodeGen/X86/clobber_frame_ptr.ll
@@ -157,3 +157,46 @@ define i64 @test3(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6,
%x = call cc 11 i64 @hipe2(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7)
ret i64 %x
}
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 16
+
+; longjmp modifies fp, it is expected behavior, wo should not save/restore fp
+; around it.
+define void @test4() {
+; CHECK-LABEL: test4:
+; 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: pushq %r15
+; CHECK-NEXT: pushq %r14
+; CHECK-NEXT: pushq %r13
+; CHECK-NEXT: pushq %r12
+; CHECK-NEXT: pushq %rbx
+; CHECK-NEXT: andq $-16, %rsp
+; CHECK-NEXT: subq $16, %rsp
+; CHECK-NEXT: .cfi_offset %rbx, -56
+; CHECK-NEXT: .cfi_offset %r12, -48
+; CHECK-NEXT: .cfi_offset %r13, -40
+; CHECK-NEXT: .cfi_offset %r14, -32
+; CHECK-NEXT: .cfi_offset %r15, -24
+; CHECK-NEXT: pushq %rbp
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: .cfi_remember_state
+; CHECK-NEXT: .cfi_escape 0x0f, 0x06, 0x77, 0x08, 0x06, 0x11, 0x10, 0x22 #
+; CHECK-NEXT: xorl %r13d, %r13d
+; CHECK-NEXT: callq external at PLT
+; CHECK-NEXT: addq $8, %rsp
+; CHECK-NEXT: popq %rbp
+; CHECK-NEXT: .cfi_restore_state
+; CHECK-NEXT: movq buf(%rip), %rbp
+; CHECK-NEXT: movq buf+8(%rip), %rax
+; CHECK-NEXT: movq buf+16(%rip), %rsp
+; CHECK-NEXT: jmpq *%rax
+entry:
+ %x = call ghccc i32 @external(i32 0)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf)
+ unreachable
+}
>From 76d8f76a0ea627bc079ca78a3b5438d91f19b351 Mon Sep 17 00:00:00 2001
From: Guozhi Wei <carrot at google.com>
Date: Fri, 16 Aug 2024 10:39:33 -0700
Subject: [PATCH 2/2] Set FrameDestroy flag for longjmp instructions
Longjmp generated instructions modify fp and sp, they can be treated as
epilog and destroy current stack frame. Set FrameDestroy flag for these
instructions, and later spillFPBP will ignore them.
---
llvm/lib/Target/X86/X86FrameLowering.cpp | 6 ------
llvm/lib/Target/X86/X86ISelLowering.cpp | 4 ++--
llvm/lib/Target/X86/X86MachineFunctionInfo.h | 11 -----------
3 files changed, 2 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 8760e97e684e35..8404f2231680d6 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -4389,12 +4389,6 @@ bool X86FrameLowering::skipSpillFPBP(
++MI;
return true;
}
-
- // FP clobbered by longjmp is expected.
- X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
- if (X86FI->containLongJmpMIClobberFP(&*MI))
- return true;
-
return false;
}
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6974d18814eb75..0866a7439bb8a6 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -36205,8 +36205,7 @@ X86TargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
MIB.add(MO);
}
MIB.setMemRefs(MMOs);
- auto *MFI = MF->getInfo<X86MachineFunctionInfo>();
- MFI->insertLongJmpMIClobberFP(MIB.getInstr());
+ MIB.setMIFlag(MachineInstr::FrameDestroy);
// Reload IP
MIB = BuildMI(*thisMBB, MI, MIMD, TII->get(PtrLoadOpc), Tmp);
@@ -36232,6 +36231,7 @@ X86TargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
// the last instruction of the expansion.
}
MIB.setMemRefs(MMOs);
+ MIB.setMIFlag(MachineInstr::FrameDestroy);
// Jump
BuildMI(*thisMBB, MI, MIMD, TII->get(IJmpOpc)).addReg(Tmp);
diff --git a/llvm/lib/Target/X86/X86MachineFunctionInfo.h b/llvm/lib/Target/X86/X86MachineFunctionInfo.h
index bf3ffdc8677bf3..13d57c2fa9dfbc 100644
--- a/llvm/lib/Target/X86/X86MachineFunctionInfo.h
+++ b/llvm/lib/Target/X86/X86MachineFunctionInfo.h
@@ -14,7 +14,6 @@
#define LLVM_LIB_TARGET_X86_X86MACHINEFUNCTIONINFO_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
@@ -175,9 +174,6 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
bool FPClobberedByCall = false;
bool BPClobberedByCall = false;
- // A set of instructions clobber FP generated from longjmp.
- SmallSet<MachineInstr *, 2> LongJmpMIClobberFP;
-
private:
/// ForwardedMustTailRegParms - A list of virtual and physical registers
/// that must be forwarded to every musttail call.
@@ -342,13 +338,6 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
bool getBPClobberedByCall() const { return BPClobberedByCall; }
void setBPClobberedByCall(bool C) { BPClobberedByCall = C; }
-
- bool containLongJmpMIClobberFP(MachineInstr *MI) const {
- return LongJmpMIClobberFP.contains(MI);
- }
- void insertLongJmpMIClobberFP(MachineInstr *MI) {
- LongJmpMIClobberFP.insert(MI);
- }
};
} // End llvm namespace
More information about the llvm-commits
mailing list