[llvm] 0ba8b24 - [Xtensa] Lowering FRAMEADDR/RETURNADDR operations. (#107363)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 13 11:33:57 PDT 2024


Author: Andrei Safronov
Date: 2024-09-13T21:33:54+03:00
New Revision: 0ba8b247dd63042528850af8cc572dc73225a04c

URL: https://github.com/llvm/llvm-project/commit/0ba8b247dd63042528850af8cc572dc73225a04c
DIFF: https://github.com/llvm/llvm-project/commit/0ba8b247dd63042528850af8cc572dc73225a04c.diff

LOG: [Xtensa] Lowering FRAMEADDR/RETURNADDR operations. (#107363)

Added: 
    llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll

Modified: 
    llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
    llvm/lib/Target/Xtensa/XtensaISelLowering.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index 0d2ce26a942e03..bc1360e2123075 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -594,6 +594,27 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
                      FalseValue, TargetCC);
 }
 
+SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
+                                              SelectionDAG &DAG) const {
+  // This nodes represent llvm.returnaddress on the DAG.
+  // It takes one operand, the index of the return address to return.
+  // An index of zero corresponds to the current function's return address.
+  // An index of one to the parent's return address, and so on.
+  // Depths > 0 not supported yet!
+  if (Op.getConstantOperandVal(0) != 0)
+    return SDValue();
+
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  EVT VT = Op.getValueType();
+  MFI.setReturnAddressIsTaken(true);
+
+  // Return RA, which contains the return address. Mark it an implicit
+  // live-in.
+  Register RA = MF.addLiveIn(Xtensa::A0, getRegClassFor(MVT::i32));
+  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RA, VT);
+}
+
 SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
                                              SelectionDAG &DAG) const {
   const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
@@ -722,6 +743,28 @@ SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
                           Op.getOperand(1));
 }
 
+SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
+                                             SelectionDAG &DAG) const {
+  // This nodes represent llvm.frameaddress on the DAG.
+  // It takes one operand, the index of the frame address to return.
+  // An index of zero corresponds to the current function's frame address.
+  // An index of one to the parent's frame address, and so on.
+  // Depths > 0 not supported yet!
+  if (Op.getConstantOperandVal(0) != 0)
+    return SDValue();
+
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  MFI.setFrameAddressIsTaken(true);
+  EVT VT = Op.getValueType();
+  SDLoc DL(Op);
+
+  Register FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
+  SDValue FrameAddr =
+      DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT);
+  return FrameAddr;
+}
+
 SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
                                                       SelectionDAG &DAG) const {
   SDValue Chain = Op.getOperand(0); // Legalize the chain.
@@ -867,6 +910,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
     return LowerBR_JT(Op, DAG);
   case ISD::Constant:
     return LowerImmediate(Op, DAG);
+  case ISD::RETURNADDR:
+    return LowerRETURNADDR(Op, DAG);
   case ISD::GlobalAddress:
     return LowerGlobalAddress(Op, DAG);
   case ISD::BlockAddress:
@@ -883,6 +928,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
     return LowerSTACKSAVE(Op, DAG);
   case ISD::STACKRESTORE:
     return LowerSTACKRESTORE(Op, DAG);
+  case ISD::FRAMEADDR:
+    return LowerFRAMEADDR(Op, DAG);
   case ISD::DYNAMIC_STACKALLOC:
     return LowerDYNAMIC_STACKALLOC(Op, DAG);
   case ISD::SHL_PARTS:

diff  --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
index 8e7346b40dfe59..2a878e45047d21 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
@@ -125,12 +125,16 @@ class XtensaTargetLowering : public TargetLowering {
 
   SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
 
+  SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
+
   SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
 
   SDValue LowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
 
   SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
 
+  SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
+
   SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
 
   SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;

diff  --git a/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll b/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll
new file mode 100644
index 00000000000000..e7e5094ac9bc4b
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=xtensa < %s \
+; RUN:   | FileCheck %s
+
+declare ptr @llvm.frameaddress(i32)
+declare ptr @llvm.returnaddress(i32)
+
+define ptr @test_frameaddress_0() nounwind {
+; CHECK-LABEL: test_frameaddress_0:
+; CHECK:         or a2, a1, a1
+; CHECK-NEXT:    ret
+  %frameaddr = call ptr @llvm.frameaddress(i32 0)
+  ret ptr %frameaddr
+}
+
+define ptr @test_returnaddress_0() nounwind {
+; CHECK-LABEL: test_returnaddress_0:
+; CHECK:         or a2, a0, a0
+; CHECK-NEXT:    ret
+  %retaddr = call ptr @llvm.returnaddress(i32 0)
+  ret ptr %retaddr
+}
+
+define ptr @test_frameaddress_1() nounwind {
+; CHECK-LABEL: test_frameaddress_1:
+; CHECK:         movi a2, 0
+; CHECK-NEXT:    ret
+  %frameaddr = call ptr @llvm.frameaddress(i32 1)
+  ret ptr %frameaddr
+}
+
+define ptr @test_returnaddress_1() nounwind {
+; CHECK-LABEL: test_returnaddress_1:
+; CHECK:         movi a2, 0
+; CHECK-NEXT:    ret
+  %retaddr = call ptr @llvm.returnaddress(i32 1)
+  ret ptr %retaddr
+}


        


More information about the llvm-commits mailing list