diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -1489,6 +1489,27 @@ return DAG.getMergeValues(Ops, DL); } +static SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, + const VETargetLowering &TLI, + const VESubtarget *Subtarget) { + SDLoc DL(Op); + MachineFunction &MF = DAG.getMachineFunction(); + EVT PtrVT = TLI.getPointerTy(MF.getDataLayout()); + + MachineFrameInfo &MFI = MF.getFrameInfo(); + MFI.setFrameAddressIsTaken(true); + + unsigned Depth = Op.getConstantOperandVal(0); + const VERegisterInfo *RegInfo = Subtarget->getRegisterInfo(); + unsigned FrameReg = RegInfo->getFrameRegister(MF); + SDValue FrameAddr = + DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameReg, PtrVT); + while (Depth--) + FrameAddr = DAG.getLoad(Op.getValueType(), DL, DAG.getEntryNode(), + FrameAddr, MachinePointerInfo()); + return FrameAddr; +} + static SDValue getSplatValue(SDNode *N) { if (auto *BuildVec = dyn_cast(N)) { return BuildVec->getSplatValue(); @@ -1529,6 +1550,8 @@ return lowerConstantPool(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return lowerDYNAMIC_STACKALLOC(Op, DAG); + case ISD::FRAMEADDR: + return lowerFRAMEADDR(Op, DAG, *this, Subtarget); case ISD::GlobalAddress: return lowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: diff --git a/llvm/test/CodeGen/VE/Scalar/frameaddr.ll b/llvm/test/CodeGen/VE/Scalar/frameaddr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/VE/Scalar/frameaddr.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s -mtriple=ve | FileCheck %s + +define i8* @test1() nounwind { +; CHECK-LABEL: test1: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: or %s0, 0, %s9 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %ret = tail call i8* @llvm.frameaddress(i32 0) + ret i8* %ret +} + +define i8* @test2() nounwind { +; CHECK-LABEL: test2: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: ld %s0, (, %s9) +; CHECK-NEXT: ld %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %ret = tail call i8* @llvm.frameaddress(i32 2) + ret i8* %ret +} + +declare i8* @llvm.frameaddress(i32) nounwind readnone