Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't assert on this, it's not invalid IR. Langref states it returns "zero if it cannot be identified"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. I hope that I understand correctly your comment,

"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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason to use this variable (but it should be Register/MCRegister)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for comments. Fixed.

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);
Expand Down Expand Up @@ -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) &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected

"Frame address can only be determined for current frame.");

MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
MachineFrameInfo &MFI = MF.getFrameInfo();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

MFI.setFrameAddressIsTaken(true);
EVT VT = Op.getValueType();
SDLoc DL(Op);

unsigned FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Register

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected

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.
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 22 additions & 0 deletions llvm/test/CodeGen/Xtensa/frameaddr-returnaddr.ll
Original file line number Diff line number Diff line change
@@ -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 \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need -verify-machineinstrs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected

; 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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use named values in tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected

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
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test the non-0 cases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added new tests