-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SystemZ] Add backchain target-feature #71668
Conversation
GCC supports building individual functions with backchain using the __attribute__((target("backchain"))) syntax, and Clang should too. Clang translates this into the "target-features"="+backchain" attribute, and the -mbackchain command-line option into the "backchain" attribute. The backend currently checks only the latter; furthermore, the backchain target feature is not defined. Handle backchain like soft-float. Define a target feature, convert function attribute into it in getSubtargetImpl(), and check for target feature instead of function attribute everywhere. Add an end-to-end test to the Clang testsuite.
@llvm/pr-subscribers-clang Author: Ilya Leoshkevich (iii-i) ChangesGCC supports building individual functions with backchain using the attribute((target("backchain"))) syntax, and Clang should too. Clang translates this into the "target-features"="+backchain" attribute, and the -mbackchain command-line option into the "backchain" attribute. The backend currently checks only the latter; furthermore, the backchain target feature is not defined. Handle backchain like soft-float. Define a target feature, convert function attribute into it in getSubtargetImpl(), and check for target feature instead of function attribute everywhere. Add an end-to-end test to the Clang testsuite. Full diff: https://github.com/llvm/llvm-project/pull/71668.diff 5 Files Affected:
diff --git a/clang/test/CodeGen/SystemZ/mbackchain-4.c b/clang/test/CodeGen/SystemZ/mbackchain-4.c
new file mode 100644
index 000000000000000..6e5f4fc5da40084
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/mbackchain-4.c
@@ -0,0 +1,11 @@
+// RUN: %clang --target=s390x-linux -O1 -S -o - %s | FileCheck %s
+
+__attribute__((target("backchain")))
+void *foo(void) {
+ return __builtin_return_address(1);
+}
+
+// CHECK-LABEL: foo:
+// CHECK: lg %r1, 0(%r15)
+// CHECK: lg %r2, 112(%r1)
+// CHECK: br %r14
diff --git a/llvm/lib/Target/SystemZ/SystemZFeatures.td b/llvm/lib/Target/SystemZ/SystemZFeatures.td
index 78b8394d6486522..fdd94206421a418 100644
--- a/llvm/lib/Target/SystemZ/SystemZFeatures.td
+++ b/llvm/lib/Target/SystemZ/SystemZFeatures.td
@@ -32,6 +32,11 @@ def FeatureSoftFloat : SystemZFeature<
"Use software emulation for floating point"
>;
+def FeatureBackChain : SystemZFeature<
+ "backchain", "BackChain", (all_of FeatureBackChain),
+ "Store the address of the caller's frame into the callee's stack frame"
+>;
+
//===----------------------------------------------------------------------===//
//
// New features added in the Ninth Edition of the z/Architecture
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
index bfd31709eb3e0bc..7522998fd06d8e5 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
@@ -443,7 +443,7 @@ void SystemZELFFrameLowering::processFunctionBeforeFrameFinalized(
MachineFrameInfo &MFFrame = MF.getFrameInfo();
SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
MachineRegisterInfo *MRI = &MF.getRegInfo();
- bool BackChain = MF.getFunction().hasFnAttribute("backchain");
+ bool BackChain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
if (!usePackedStack(MF) || BackChain)
// Create the incoming register save area.
@@ -628,7 +628,7 @@ void SystemZELFFrameLowering::emitPrologue(MachineFunction &MF,
.addImm(StackSize);
}
else {
- bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
+ bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
// If we need backchain, save current stack pointer. R1 is free at
// this point.
if (StoreBackchain)
@@ -786,7 +786,7 @@ void SystemZELFFrameLowering::inlineStackProbe(
.addMemOperand(MMO);
};
- bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
+ bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
if (StoreBackchain)
BuildMI(*MBB, MBBI, DL, ZII->get(SystemZ::LGR))
.addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D);
@@ -861,8 +861,9 @@ StackOffset SystemZELFFrameLowering::getFrameIndexReference(
unsigned SystemZELFFrameLowering::getRegSpillOffset(MachineFunction &MF,
Register Reg) const {
bool IsVarArg = MF.getFunction().isVarArg();
- bool BackChain = MF.getFunction().hasFnAttribute("backchain");
- bool SoftFloat = MF.getSubtarget<SystemZSubtarget>().hasSoftFloat();
+ const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
+ bool BackChain = Subtarget.hasBackChain();
+ bool SoftFloat = Subtarget.hasSoftFloat();
unsigned Offset = RegSpillOffsets[Reg];
if (usePackedStack(MF) && !(IsVarArg && !SoftFloat)) {
if (SystemZ::GR64BitRegClass.contains(Reg))
@@ -890,8 +891,9 @@ int SystemZELFFrameLowering::getOrCreateFramePointerSaveIndex(
bool SystemZELFFrameLowering::usePackedStack(MachineFunction &MF) const {
bool HasPackedStackAttr = MF.getFunction().hasFnAttribute("packed-stack");
- bool BackChain = MF.getFunction().hasFnAttribute("backchain");
- bool SoftFloat = MF.getSubtarget<SystemZSubtarget>().hasSoftFloat();
+ const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
+ bool BackChain = Subtarget.hasBackChain();
+ bool SoftFloat = Subtarget.hasSoftFloat();
if (HasPackedStackAttr && BackChain && !SoftFloat)
report_fatal_error("packed-stack + backchain + hard-float is unsupported.");
bool CallConv = MF.getFunction().getCallingConv() != CallingConv::GHC;
@@ -946,7 +948,7 @@ static bool isXPLeafCandidate(const MachineFunction &MF) {
return false;
// If the backchain pointer should be stored, then it is not a XPLeaf routine.
- if (MF.getFunction().hasFnAttribute("backchain"))
+ if (MF.getSubtarget<SystemZSubtarget>().hasBackChain())
return false;
// If function acquires its own stack frame, then it is not a XPLeaf routine.
@@ -989,7 +991,7 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots(
// If the function needs a frame pointer, or if the backchain pointer should
// be stored, then save the stack pointer register R4.
- if (hasFP(MF) || MF.getFunction().hasFnAttribute("backchain"))
+ if (hasFP(MF) || Subtarget.hasBackChain())
CSI.push_back(CalleeSavedInfo(Regs.getStackPointerRegister()));
// Scan the call-saved GPRs and find the bounds of the register spill area.
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index e6ea4205623d31d..4e57986206dc680 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -3631,7 +3631,7 @@ SDValue SystemZTargetLowering::lowerFRAMEADDR(SDValue Op,
if (Depth > 0) {
// FIXME The frontend should detect this case.
- if (!MF.getFunction().hasFnAttribute("backchain"))
+ if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
report_fatal_error("Unsupported stack frame traversal count");
SDValue Offset = DAG.getConstant(TFL->getBackchainOffset(MF), DL, PtrVT);
@@ -3660,7 +3660,7 @@ SDValue SystemZTargetLowering::lowerRETURNADDR(SDValue Op,
if (Depth > 0) {
// FIXME The frontend should detect this case.
- if (!MF.getFunction().hasFnAttribute("backchain"))
+ if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
report_fatal_error("Unsupported stack frame traversal count");
SDValue FrameAddr = lowerFRAMEADDR(Op, DAG);
@@ -3886,7 +3886,7 @@ SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(SDValue Op,
const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
MachineFunction &MF = DAG.getMachineFunction();
bool RealignOpt = !MF.getFunction().hasFnAttribute("no-realign-stack");
- bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
+ bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
SDValue Chain = Op.getOperand(0);
SDValue Size = Op.getOperand(1);
@@ -4563,7 +4563,7 @@ SDValue SystemZTargetLowering::lowerSTACKRESTORE(SDValue Op,
SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
auto *Regs = Subtarget.getSpecialRegisters();
- bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
+ bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
if (MF.getFunction().getCallingConv() == CallingConv::GHC)
report_fatal_error("Variable-sized stack allocations are not supported "
diff --git a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
index 186494ad2ac614c..73e01e3ec184427 100644
--- a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
@@ -169,12 +169,14 @@ SystemZTargetMachine::getSubtargetImpl(const Function &F) const {
FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
// FIXME: This is related to the code below to reset the target options,
- // we need to know whether or not the soft float flag is set on the
- // function, so we can enable it as a subtarget feature.
+ // we need to know whether the soft float and backchain flags are set on the
+ // function, so we can enable them as subtarget features.
bool SoftFloat = F.getFnAttribute("use-soft-float").getValueAsBool();
-
if (SoftFloat)
FS += FS.empty() ? "+soft-float" : ",+soft-float";
+ bool BackChain = F.hasFnAttribute("backchain");
+ if (BackChain)
+ FS += FS.empty() ? "+backchain" : ",+backchain";
auto &I = SubtargetMap[CPU + TuneCPU + FS];
if (!I) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for taking care of this, Ilya!
This is now causing a CI failure: https://lab.llvm.org/buildbot/#/builders/139/builds/53143 |
GCC supports building individual functions with backchain using the attribute((target("backchain"))) syntax, and Clang should too.
Clang translates this into the "target-features"="+backchain" attribute, and the -mbackchain command-line option into the "backchain" attribute. The backend currently checks only the latter; furthermore, the backchain target feature is not defined.
Handle backchain like soft-float. Define a target feature, convert function attribute into it in getSubtargetImpl(), and check for target feature instead of function attribute everywhere. Add an end-to-end test to the Clang testsuite.