[llvm] 2c12c1e - [X86] Check if an invoked function clobbers fp or bp (#103446)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 14 12:59:41 PDT 2024
Author: weiguozhi
Date: 2024-08-14T12:59:37-07:00
New Revision: 2c12c1e755a1bf453b246027b450b3b8e30fb016
URL: https://github.com/llvm/llvm-project/commit/2c12c1e755a1bf453b246027b450b3b8e30fb016
DIFF: https://github.com/llvm/llvm-project/commit/2c12c1e755a1bf453b246027b450b3b8e30fb016.diff
LOG: [X86] Check if an invoked function clobbers fp or bp (#103446)
In most cases when an instruction or function call clobbers fp and/or bp
register, we can fix it by save/restore the clobbered register. But we
still can't handle it when an invoked function clobbers fp and/or bp
according to its calling convention. This patch detects this case and
reports error instead of silently generating wrong code.
Added:
llvm/test/CodeGen/X86/fp-clobbered-by-eh.ll
Modified:
llvm/lib/Target/X86/X86ISelLoweringCall.cpp
llvm/lib/Target/X86/X86MachineFunctionInfo.h
llvm/lib/Target/X86/X86RegisterInfo.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 1e609a84673a3..ce6b0f9c07dc8 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -2450,10 +2450,16 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
}();
assert(Mask && "Missing call preserved mask for calling convention");
- if (MachineOperand::clobbersPhysReg(Mask, RegInfo->getFrameRegister(MF)))
+ if (MachineOperand::clobbersPhysReg(Mask, RegInfo->getFramePtr())) {
X86Info->setFPClobberedByCall(true);
- if (MachineOperand::clobbersPhysReg(Mask, RegInfo->getBaseRegister()))
+ if (CLI.CB && isa<InvokeInst>(CLI.CB))
+ X86Info->setFPClobberedByInvoke(true);
+ }
+ if (MachineOperand::clobbersPhysReg(Mask, RegInfo->getBaseRegister())) {
X86Info->setBPClobberedByCall(true);
+ if (CLI.CB && isa<InvokeInst>(CLI.CB))
+ X86Info->setBPClobberedByInvoke(true);
+ }
// If this is an invoke in a 32-bit function using a funclet-based
// personality, assume the function clobbers all registers. If an exception
diff --git a/llvm/lib/Target/X86/X86MachineFunctionInfo.h b/llvm/lib/Target/X86/X86MachineFunctionInfo.h
index 13d57c2fa9dfb..24371369d4a45 100644
--- a/llvm/lib/Target/X86/X86MachineFunctionInfo.h
+++ b/llvm/lib/Target/X86/X86MachineFunctionInfo.h
@@ -173,6 +173,8 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
// True if a function clobbers FP/BP according to its calling convention.
bool FPClobberedByCall = false;
bool BPClobberedByCall = false;
+ bool FPClobberedByInvoke = false;
+ bool BPClobberedByInvoke = false;
private:
/// ForwardedMustTailRegParms - A list of virtual and physical registers
@@ -338,6 +340,12 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
bool getBPClobberedByCall() const { return BPClobberedByCall; }
void setBPClobberedByCall(bool C) { BPClobberedByCall = C; }
+
+ bool getFPClobberedByInvoke() const { return FPClobberedByInvoke; }
+ void setFPClobberedByInvoke(bool C) { FPClobberedByInvoke = C; }
+
+ bool getBPClobberedByInvoke() const { return BPClobberedByInvoke; }
+ void setBPClobberedByInvoke(bool C) { BPClobberedByInvoke = C; }
};
} // End llvm namespace
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 3376367cc76b0..638eb1c4f11e4 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -31,6 +31,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetMachine.h"
@@ -565,18 +566,22 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
// Set the frame-pointer register and its aliases as reserved if needed.
if (TFI->hasFP(MF)) {
+ if (MF.getInfo<X86MachineFunctionInfo>()->getFPClobberedByInvoke())
+ MF.getContext().reportError(
+ SMLoc(),
+ "Frame pointer clobbered by function invoke is not supported.");
+
for (const MCPhysReg &SubReg : subregs_inclusive(X86::RBP))
Reserved.set(SubReg);
}
// Set the base-pointer register and its aliases as reserved if needed.
if (hasBasePointer(MF)) {
- CallingConv::ID CC = MF.getFunction().getCallingConv();
- const uint32_t *RegMask = getCallPreservedMask(MF, CC);
- if (MachineOperand::clobbersPhysReg(RegMask, getBaseRegister()))
- report_fatal_error(
- "Stack realignment in presence of dynamic allocas is not supported with"
- "this calling convention.");
+ if (MF.getInfo<X86MachineFunctionInfo>()->getBPClobberedByInvoke())
+ MF.getContext().reportError(SMLoc(),
+ "Stack realignment in presence of dynamic "
+ "allocas is not supported with "
+ "this calling convention.");
Register BasePtr = getX86SubSuperRegister(getBaseRegister(), 64);
for (const MCPhysReg &SubReg : subregs_inclusive(BasePtr))
diff --git a/llvm/test/CodeGen/X86/fp-clobbered-by-eh.ll b/llvm/test/CodeGen/X86/fp-clobbered-by-eh.ll
new file mode 100644
index 0000000000000..03f227a590d5e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fp-clobbered-by-eh.ll
@@ -0,0 +1,27 @@
+; RUN: not llc -mtriple=x86_64-unknown-unknown -stackrealign -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
+
+declare ghccc void @may_throw_or_crash()
+declare i32 @_except_handler3(...)
+
+define internal i64 @catchall_filt() {
+ ret i64 1
+}
+
+; If the invoked function clobbers frame pointer and/or base pointer according
+; to its calling convention, we can't handle it currently, so reports an error
+; message.
+
+; CHECK: <unknown>:0: error: Frame pointer clobbered by function invoke is not supported
+; CHECK: <unknown>:0: error: Stack realignment in presence of dynamic allocas is not supported with this calling convention
+define void @use_except_handler3() personality ptr @_except_handler3 {
+entry:
+ invoke ghccc void @may_throw_or_crash()
+ to label %cont unwind label %lpad
+cont:
+ ret void
+lpad:
+ %cs = catchswitch within none [label %catch] unwind to caller
+catch:
+ %p = catchpad within %cs [ptr @catchall_filt]
+ catchret from %p to label %cont
+}
More information about the llvm-commits
mailing list