[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