diff options
-rw-r--r-- | include/llvm/Target/TargetCallingConv.h | 13 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 5 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 20 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.h | 5 | ||||
-rw-r--r-- | test/CodeGen/ARM/2012-10-04-FixedFrame-vs-byval.ll | 19 |
5 files changed, 50 insertions, 12 deletions
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h index f8cebefb0e..8030d38d73 100644 --- a/include/llvm/Target/TargetCallingConv.h +++ b/include/llvm/Target/TargetCallingConv.h @@ -113,9 +113,18 @@ namespace ISD { MVT VT; bool Used; + /// Index original Function's argument. + unsigned OrigArgIndex; + + /// Offset in bytes of current input value relative to the beginning of + /// original argument. E.g. if argument was splitted into four 32 bit + /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12. + unsigned PartOffset; + InputArg() : VT(MVT::Other), Used(false) {} - InputArg(ArgFlagsTy flags, EVT vt, bool used) - : Flags(flags), Used(used) { + InputArg(ArgFlagsTy flags, EVT vt, bool used, + unsigned origIdx, unsigned partOffs) + : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) { VT = vt.getSimpleVT(); } }; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index dccc2fcf25..cdebff94e5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6681,7 +6681,7 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) { ISD::ArgFlagsTy Flags; Flags.setSRet(); EVT RegisterVT = TLI.getRegisterType(*DAG.getContext(), ValueVTs[0]); - ISD::InputArg RetArg(Flags, RegisterVT, true); + ISD::InputArg RetArg(Flags, RegisterVT, true, 0, 0); Ins.push_back(RetArg); } @@ -6729,7 +6729,8 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) { EVT RegisterVT = TLI.getRegisterType(*CurDAG->getContext(), VT); unsigned NumRegs = TLI.getNumRegisters(*CurDAG->getContext(), VT); for (unsigned i = 0; i != NumRegs; ++i) { - ISD::InputArg MyFlags(Flags, RegisterVT, isArgValueUsed); + ISD::InputArg MyFlags(Flags, RegisterVT, isArgValueUsed, + Idx-1, i*RegisterVT.getStoreSize()); if (NumRegs > 1 && i == 0) MyFlags.Flags.setSplit(); // if it isn't first piece, alignment must be 1 diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index d4d29f57d2..e6f0ef25d8 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -2534,6 +2534,8 @@ ARMTargetLowering::computeRegArea(CCState &CCInfo, MachineFunction &MF, void ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG, DebugLoc dl, SDValue &Chain, + const Value *OrigArg, + unsigned OffsetFromOrigArg, unsigned ArgOffset) const { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -2561,7 +2563,7 @@ ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG, getPointerTy()); SmallVector<SDValue, 4> MemOps; - for (; firstRegToSaveIndex < 4; ++firstRegToSaveIndex) { + for (unsigned i = 0; firstRegToSaveIndex < 4; ++firstRegToSaveIndex, ++i) { const TargetRegisterClass *RC; if (AFI->isThumb1OnlyFunction()) RC = &ARM::tGPRRegClass; @@ -2572,7 +2574,7 @@ ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG, SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, - MachinePointerInfo::getFixedStack(AFI->getVarArgsFrameIndex()), + MachinePointerInfo(OrigArg, OffsetFromOrigArg + 4*i), false, false, 0); MemOps.push_back(Store); FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(), FIN, @@ -2606,14 +2608,16 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain, CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForNode(CallConv, /* Return*/ false, isVarArg)); - + SmallVector<SDValue, 16> ArgValues; int lastInsIndex = -1; - SDValue ArgValue; + Function::const_arg_iterator CurOrigArg = MF.getFunction()->arg_begin(); + unsigned CurArgIdx = 0; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - + std::advance(CurOrigArg, Ins[VA.getValNo()].OrigArgIndex - CurArgIdx); + CurArgIdx = Ins[VA.getValNo()].OrigArgIndex; // Arguments stored in registers. if (VA.isRegLoc()) { EVT RegVT = VA.getLocVT(); @@ -2709,7 +2713,8 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain, if (Flags.isByVal()) { unsigned VARegSize, VARegSaveSize; computeRegArea(CCInfo, MF, VARegSize, VARegSaveSize); - VarArgStyleRegisters(CCInfo, DAG, dl, Chain, 0); + 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, @@ -2732,7 +2737,8 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain, // varargs if (isVarArg) - VarArgStyleRegisters(CCInfo, DAG, dl, Chain, CCInfo.getNextStackOffset()); + VarArgStyleRegisters(CCInfo, DAG, dl, Chain, 0, 0, + CCInfo.getNextStackOffset()); return Chain; } diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 2b8f382c95..b5020c9710 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -466,7 +466,10 @@ namespace llvm { SmallVectorImpl<SDValue> &InVals) const; void VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG, - DebugLoc dl, SDValue &Chain, unsigned ArgOffset) + DebugLoc dl, SDValue &Chain, + const Value *OrigArg, + unsigned OffsetFromOrigArg, + unsigned ArgOffset) const; void computeRegArea(CCState &CCInfo, MachineFunction &MF, diff --git a/test/CodeGen/ARM/2012-10-04-FixedFrame-vs-byval.ll b/test/CodeGen/ARM/2012-10-04-FixedFrame-vs-byval.ll new file mode 100644 index 0000000000..478048d096 --- /dev/null +++ b/test/CodeGen/ARM/2012-10-04-FixedFrame-vs-byval.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi | FileCheck %s + +@.str = private unnamed_addr constant [12 x i8] c"val.a = %f\0A\00" +%struct_t = type { double, double, double } +@static_val = constant %struct_t { double 1.0, double 2.0, double 3.0 } + +declare i32 @printf(i8*, ...) + +; CHECK: test_byval_usage_scheduling: +; CHECK: str r3, [sp, #12] +; CHECK: str r2, [sp, #8] +; CHECK: vldr d16, [sp, #8] +define void @test_byval_usage_scheduling(i32 %n1, i32 %n2, %struct_t* byval %val) nounwind { +entry: + %a = getelementptr inbounds %struct_t* %val, i32 0, i32 0 + %0 = load double* %a + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), double %0) + ret void +} |