[llvm] 3be0593 - [LoongArch] Add support for ISD::FRAMEADDR and ISD::RETURNADDR
Weining Lu via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 24 00:13:02 PDT 2022
Author: gonglingqin
Date: 2022-10-24T15:12:28+08:00
New Revision: 3be059377e4312f8c74da95e6d61ce5849570c0e
URL: https://github.com/llvm/llvm-project/commit/3be059377e4312f8c74da95e6d61ce5849570c0e
DIFF: https://github.com/llvm/llvm-project/commit/3be059377e4312f8c74da95e6d61ce5849570c0e.diff
LOG: [LoongArch] Add support for ISD::FRAMEADDR and ISD::RETURNADDR
For now, only support lowering frame/return address for current frame.
Differential Revision: https://reviews.llvm.org/D136215
Added:
llvm/test/CodeGen/LoongArch/frameaddr-returnaddr-error.ll
llvm/test/CodeGen/LoongArch/frameaddr-returnaddr.ll
Modified:
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
llvm/lib/Target/LoongArch/LoongArchISelLowering.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 2dd677898a88..62923ba0d3c6 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -222,10 +222,60 @@ SDValue LoongArchTargetLowering::LowerOperation(SDValue Op,
return lowerUINT_TO_FP(Op, DAG);
case ISD::VASTART:
return lowerVASTART(Op, DAG);
+ case ISD::FRAMEADDR:
+ return lowerFRAMEADDR(Op, DAG);
+ case ISD::RETURNADDR:
+ return lowerRETURNADDR(Op, DAG);
}
return SDValue();
}
+SDValue LoongArchTargetLowering::lowerFRAMEADDR(SDValue Op,
+ SelectionDAG &DAG) const {
+ if (!isa<ConstantSDNode>(Op.getOperand(0))) {
+ DAG.getContext()->emitError("argument to '__builtin_frame_address' must "
+ "be a constant integer");
+ return SDValue();
+ }
+
+ // Currently only support lowering frame address for current frame.
+ unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
+ assert((Depth == 0) &&
+ "Frame address can only be determined for current frame.");
+ if (Depth != 0)
+ return SDValue();
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ MF.getFrameInfo().setFrameAddressIsTaken(true);
+
+ return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op),
+ Subtarget.getRegisterInfo()->getFrameRegister(MF),
+ Op.getValueType());
+}
+
+SDValue LoongArchTargetLowering::lowerRETURNADDR(SDValue Op,
+ SelectionDAG &DAG) const {
+ if (verifyReturnAddressArgumentIsConstant(Op, DAG))
+ return SDValue();
+
+ // Currently only support lowering return address for current frame.
+ unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
+ assert((Depth == 0) &&
+ "Return address can only be determined for current frame.");
+ if (Depth != 0)
+ return SDValue();
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ MF.getFrameInfo().setReturnAddressIsTaken(true);
+ MVT GRLenVT = Subtarget.getGRLenVT();
+
+ // Return the value of the return address register, marking it an implicit
+ // live-in.
+ Register Reg = MF.addLiveIn(Subtarget.getRegisterInfo()->getRARegister(),
+ getRegClassFor(GRLenVT));
+ return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Reg, GRLenVT);
+}
+
SDValue LoongArchTargetLowering::lowerEH_DWARF_CFA(SDValue Op,
SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index 3d313c12083a..ca6de97a67d0 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -162,6 +162,8 @@ class LoongArchTargetLowering : public TargetLowering {
SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
bool isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const override;
diff --git a/llvm/test/CodeGen/LoongArch/frameaddr-returnaddr-error.ll b/llvm/test/CodeGen/LoongArch/frameaddr-returnaddr-error.ll
new file mode 100644
index 000000000000..6adb2e5b7775
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/frameaddr-returnaddr-error.ll
@@ -0,0 +1,18 @@
+; RUN: not llc --mtriple=loongarch64 --disable-verify < %s 2>&1 | FileCheck %s
+
+declare ptr @llvm.frameaddress(i32)
+declare ptr @llvm.returnaddress(i32)
+
+define ptr @non_const_depth_frameaddress(i32 %x) nounwind {
+; CHECK: argument to '__builtin_frame_address' must be a constant integer
+ %1 = call ptr @llvm.frameaddress(i32 %x)
+ ret ptr %1
+}
+
+
+define ptr @non_const_depth_returnaddress(i32 %x) nounwind {
+; CHECK: argument to '__builtin_return_address' must be a constant integer
+ %1 = call ptr @llvm.returnaddress(i32 %x)
+ ret ptr %1
+}
+
diff --git a/llvm/test/CodeGen/LoongArch/frameaddr-returnaddr.ll b/llvm/test/CodeGen/LoongArch/frameaddr-returnaddr.ll
new file mode 100644
index 000000000000..7b0a4627685a
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/frameaddr-returnaddr.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32
+; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64
+
+declare ptr @llvm.frameaddress(i32)
+declare ptr @llvm.returnaddress(i32)
+
+define ptr @test_frameaddress_0() nounwind {
+; LA32-LABEL: test_frameaddress_0:
+; LA32: # %bb.0:
+; LA32-NEXT: addi.w $sp, $sp, -16
+; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill
+; LA32-NEXT: addi.w $fp, $sp, 16
+; LA32-NEXT: move $a0, $fp
+; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload
+; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32-NEXT: addi.w $sp, $sp, 16
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_frameaddress_0:
+; LA64: # %bb.0:
+; LA64-NEXT: addi.d $sp, $sp, -16
+; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill
+; LA64-NEXT: addi.d $fp, $sp, 16
+; LA64-NEXT: move $a0, $fp
+; LA64-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload
+; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64-NEXT: addi.d $sp, $sp, 16
+; LA64-NEXT: ret
+ %1 = call ptr @llvm.frameaddress(i32 0)
+ ret ptr %1
+}
+
+define ptr @test_returnaddress_0() nounwind {
+; LA32-LABEL: test_returnaddress_0:
+; LA32: # %bb.0:
+; LA32-NEXT: move $a0, $ra
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_returnaddress_0:
+; LA64: # %bb.0:
+; LA64-NEXT: move $a0, $ra
+; LA64-NEXT: ret
+ %1 = call ptr @llvm.returnaddress(i32 0)
+ ret ptr %1
+}
More information about the llvm-commits
mailing list