[llvm] [clang] [SystemZ] Add backchain target-feature (PR #71668)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 8 04:11:28 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Ilya Leoshkevich (iii-i)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/71668.diff


5 Files Affected:

- (added) clang/test/CodeGen/SystemZ/mbackchain-4.c (+11) 
- (modified) llvm/lib/Target/SystemZ/SystemZFeatures.td (+5) 
- (modified) llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp (+11-9) 
- (modified) llvm/lib/Target/SystemZ/SystemZISelLowering.cpp (+4-4) 
- (modified) llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp (+5-3) 


``````````diff
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) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/71668


More information about the llvm-commits mailing list