[llvm] [Xtensa] Lowering FRAMEADDR/RETURNADDR operations. (PR #107363)
Andrei Safronov via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 13 07:31:49 PDT 2024
https://github.com/andreisfr updated https://github.com/llvm/llvm-project/pull/107363
>From a210ae9ea425993d5961497fbd68867dc91f64f1 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Thu, 5 Sep 2024 10:59:44 +0300
Subject: [PATCH 1/3] [Xtensa] Lowering FRAMEADDR/RETURNADDR operations.
---
llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 42 +++++++++++++++++++
llvm/lib/Target/Xtensa/XtensaISelLowering.h | 4 ++
.../CodeGen/Xtensa/frameaddr-returnaddr.ll | 22 ++++++++++
3 files changed, 68 insertions(+)
create mode 100644 llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index 0d2ce26a942e03..97d9c3e9f9f476 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -594,6 +594,26 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
FalseValue, TargetCC);
}
+SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
+ SelectionDAG &DAG) const {
+ // check the depth
+ // TODO: xtensa-gcc can handle this, by navigating through the stack, we
+ // should be able to do this too
+ assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
+ "Return address can be determined only for current frame.");
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ EVT VT = Op.getValueType();
+ unsigned RA = Xtensa::A0;
+ MFI.setReturnAddressIsTaken(true);
+
+ // Return RA, which contains the return address. Mark it an implicit
+ // live-in.
+ unsigned Register = MF.addLiveIn(RA, getRegClassFor(MVT::i32));
+ return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Register, VT);
+}
+
SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
SelectionDAG &DAG) const {
const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
@@ -722,6 +742,24 @@ SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
Op.getOperand(1));
}
+SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
+ SelectionDAG &DAG) const {
+ // check the depth
+ assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
+ "Frame address can only be determined for current frame.");
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
+ MFI.setFrameAddressIsTaken(true);
+ EVT VT = Op.getValueType();
+ SDLoc DL(Op);
+
+ unsigned 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 +905,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 +923,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..69c22733c107ae
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=xtensa -verify-machineinstrs < %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
+ %1 = call ptr @llvm.frameaddress(i32 0)
+ ret ptr %1
+}
+
+define ptr @test_returnaddress_0() nounwind {
+; CHECK-LABEL: test_returnaddress_0:
+; CHECK: or a2, a0, a0
+; CHECK-NEXT: ret
+ %1 = call ptr @llvm.returnaddress(i32 0)
+ ret ptr %1
+}
>From d06b489b906d21b7ffe63d12e6b2d258a89308bc Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Tue, 10 Sep 2024 00:03:19 +0300
Subject: [PATCH 2/3] [Xtensa] Minor corrections.
---
llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 29 +++++++++++--------
.../CodeGen/Xtensa/frameaddr-returnaddr.ll | 26 +++++++++++++----
2 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index 97d9c3e9f9f476..1de5e2c1961dfa 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -596,22 +596,23 @@ SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
SelectionDAG &DAG) const {
- // check the depth
- // TODO: xtensa-gcc can handle this, by navigating through the stack, we
- // should be able to do this too
- assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
- "Return address can be determined only for current frame.");
+ // 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();
- unsigned RA = Xtensa::A0;
MFI.setReturnAddressIsTaken(true);
// Return RA, which contains the return address. Mark it an implicit
// live-in.
- unsigned Register = MF.addLiveIn(RA, getRegClassFor(MVT::i32));
- return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Register, VT);
+ Register RA = MF.addLiveIn(Xtensa::A0, getRegClassFor(MVT::i32));
+ return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RA, VT);
}
SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
@@ -744,9 +745,13 @@ SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
SelectionDAG &DAG) const {
- // check the depth
- assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
- "Frame address can only be determined for current frame.");
+ // 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 = DAG.getMachineFunction().getFrameInfo();
@@ -754,7 +759,7 @@ SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
EVT VT = Op.getValueType();
SDLoc DL(Op);
- unsigned FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
+ Register FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
SDValue FrameAddr =
DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT);
return FrameAddr;
diff --git a/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll b/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll
index 69c22733c107ae..e7e5094ac9bc4b 100644
--- a/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll
+++ b/llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc -mtriple=xtensa -verify-machineinstrs < %s \
+; RUN: llc -mtriple=xtensa < %s \
; RUN: | FileCheck %s
declare ptr @llvm.frameaddress(i32)
@@ -9,14 +9,30 @@ define ptr @test_frameaddress_0() nounwind {
; CHECK-LABEL: test_frameaddress_0:
; CHECK: or a2, a1, a1
; CHECK-NEXT: ret
- %1 = call ptr @llvm.frameaddress(i32 0)
- ret ptr %1
+ %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
- %1 = call ptr @llvm.returnaddress(i32 0)
- ret ptr %1
+ %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
}
>From 0d70d4bedcfd94ba4a1fbd9e9686d8f855fb08b7 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Fri, 13 Sep 2024 17:29:49 +0300
Subject: [PATCH 3/3] [Xtensa] Minor fixes in code
---
llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index 1de5e2c1961dfa..bc1360e2123075 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -601,7 +601,7 @@ SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
// 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)
+ if (Op.getConstantOperandVal(0) != 0)
return SDValue();
MachineFunction &MF = DAG.getMachineFunction();
@@ -750,11 +750,11 @@ SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
// 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)
+ if (Op.getConstantOperandVal(0) != 0)
return SDValue();
MachineFunction &MF = DAG.getMachineFunction();
- MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
+ MachineFrameInfo &MFI = MF.getFrameInfo();
MFI.setFrameAddressIsTaken(true);
EVT VT = Op.getValueType();
SDLoc DL(Op);
More information about the llvm-commits
mailing list