forked from OSchip/llvm-project
ARM:
Removed extra stack frame object for fixed byval arguments, VarArgsStyleRegisters invocation was reworked due to some improper usage in past. PR14099 also demonstrates it. llvm-svn: 166273
This commit is contained in:
parent
2e3b716959
commit
dab8043048
|
@ -2554,7 +2554,8 @@ ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
|
|||
DebugLoc dl, SDValue &Chain,
|
||||
const Value *OrigArg,
|
||||
unsigned OffsetFromOrigArg,
|
||||
unsigned ArgOffset) const {
|
||||
unsigned ArgOffset,
|
||||
bool ForceMutable) const {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
|
@ -2603,7 +2604,8 @@ ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
|
|||
&MemOps[0], MemOps.size());
|
||||
} else
|
||||
// This will point to the next argument passed via stack.
|
||||
AFI->setVarArgsFrameIndex(MFI->CreateFixedObject(4, ArgOffset, true));
|
||||
AFI->setVarArgsFrameIndex(
|
||||
MFI->CreateFixedObject(4, ArgOffset, !ForceMutable));
|
||||
}
|
||||
|
||||
SDValue
|
||||
|
@ -2729,15 +2731,20 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
|
|||
// Since they could be overwritten by lowering of arguments in case of
|
||||
// a tail call.
|
||||
if (Flags.isByVal()) {
|
||||
unsigned VARegSize, VARegSaveSize;
|
||||
computeRegArea(CCInfo, MF, VARegSize, VARegSaveSize);
|
||||
VarArgStyleRegisters(CCInfo, DAG,
|
||||
dl, Chain, CurOrigArg, Ins[VA.getValNo()].PartOffset, 0);
|
||||
unsigned Bytes = Flags.getByValSize() - VARegSize;
|
||||
if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects.
|
||||
int FI = MFI->CreateFixedObject(Bytes,
|
||||
VA.getLocMemOffset(), false);
|
||||
InVals.push_back(DAG.getFrameIndex(FI, getPointerTy()));
|
||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
if (!AFI->getVarArgsFrameIndex()) {
|
||||
VarArgStyleRegisters(CCInfo, DAG,
|
||||
dl, Chain, CurOrigArg,
|
||||
Ins[VA.getValNo()].PartOffset,
|
||||
VA.getLocMemOffset(),
|
||||
true /*force mutable frames*/);
|
||||
int VAFrameIndex = AFI->getVarArgsFrameIndex();
|
||||
InVals.push_back(DAG.getFrameIndex(VAFrameIndex, getPointerTy()));
|
||||
} else {
|
||||
int FI = MFI->CreateFixedObject(Flags.getByValSize(),
|
||||
VA.getLocMemOffset(), false);
|
||||
InVals.push_back(DAG.getFrameIndex(FI, getPointerTy()));
|
||||
}
|
||||
} else {
|
||||
int FI = MFI->CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
|
||||
VA.getLocMemOffset(), true);
|
||||
|
|
|
@ -469,7 +469,8 @@ namespace llvm {
|
|||
DebugLoc dl, SDValue &Chain,
|
||||
const Value *OrigArg,
|
||||
unsigned OffsetFromOrigArg,
|
||||
unsigned ArgOffset)
|
||||
unsigned ArgOffset,
|
||||
bool ForceMutable = false)
|
||||
const;
|
||||
|
||||
void computeRegArea(CCState &CCInfo, MachineFunction &MF,
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi | FileCheck %s
|
||||
|
||||
%struct.s = type { [4 x i32] }
|
||||
@v = constant %struct.s zeroinitializer;
|
||||
|
||||
declare void @f(%struct.s* %p);
|
||||
|
||||
; CHECK: t:
|
||||
define void @t(i32 %a, %struct.s* byval %s) nounwind {
|
||||
entry:
|
||||
|
||||
; Here we need to only check proper start address of restored %s argument.
|
||||
; CHECK: sub sp, sp, #16
|
||||
; CHECK: push {r11, lr}
|
||||
; CHECK: add r0, sp, #12
|
||||
; CHECK: stm r0, {r1, r2, r3}
|
||||
; CHECK: add r0, sp, #12
|
||||
; CHECK-NEXT: bl f
|
||||
call void @f(%struct.s* %s)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: caller:
|
||||
define void @caller() {
|
||||
|
||||
; CHECK: ldm r0, {r1, r2, r3}
|
||||
call void @t(i32 0, %struct.s* @v);
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue