From b8cafe3427a168414400e5dfcbea78996792d2c3 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Mon, 10 Mar 2008 02:17:22 +0000 Subject: [PATCH] Increase ISD::ParamFlags to 64 bits. Increase the ByValSize field to 32 bits, thus enabling correct handling of ByVal structs bigger than 0x1ffff. Abstract interface a bit. Fixes gcc.c-torture/execute/pr23135.c and gcc.c-torture/execute/pr28982b.c in gcc testsuite (were ICE'ing on ppc32, quietly producing wrong code on x86-32.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48122 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/CallingConvLower.h | 6 ++- include/llvm/CodeGen/SelectionDAGNodes.h | 44 ++++++++++--------- lib/CodeGen/SelectionDAG/CallingConvLower.cpp | 8 ++-- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 32 ++++++++------ lib/Target/ARM/ARMISelLowering.cpp | 11 ++--- lib/Target/PowerPC/PPCISelLowering.cpp | 20 ++++++--- lib/Target/X86/X86ISelLowering.cpp | 14 +++--- utils/TableGen/CallingConvEmitter.cpp | 4 +- 8 files changed, 81 insertions(+), 58 deletions(-) diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 8fe3b16c1ba..34e20903fa7 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" namespace llvm { class TargetRegisterInfo; @@ -97,7 +98,7 @@ public: /// reflect the change. typedef bool CCAssignFn(unsigned ValNo, MVT::ValueType ValVT, MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo, - unsigned ArgFlags, CCState &State); + ISD::ParamFlags::ParamFlagsTy ArgFlags, CCState &State); /// CCState - This class holds information needed while lowering arguments and @@ -196,7 +197,8 @@ public: // parameter attribute. void HandleByVal(unsigned ValNo, MVT::ValueType ValVT, MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo, - int MinSize, int MinAlign, unsigned ArgFlags); + int MinSize, int MinAlign, + ISD::ParamFlags::ParamFlagsTy ArgFlags); private: /// MarkAllocated - Mark a register and all of its aliases as allocated. diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 0d0158ac3a9..38281340938 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -57,27 +57,29 @@ struct SDVTList { /// namespace ISD { namespace ParamFlags { - enum Flags { - NoFlagSet = 0, - ZExt = 1<<0, ///< Parameter should be zero extended - ZExtOffs = 0, - SExt = 1<<1, ///< Parameter should be sign extended - SExtOffs = 1, - InReg = 1<<2, ///< Parameter should be passed in register - InRegOffs = 2, - StructReturn = 1<<3, ///< Hidden struct-return pointer - StructReturnOffs = 3, - ByVal = 1<<4, ///< Struct passed by value - ByValOffs = 4, - Nest = 1<<5, ///< Parameter is nested function static chain - NestOffs = 5, - ByValAlign = 0xF << 6, //< The alignment of the struct - ByValAlignOffs = 6, - ByValSize = 0x1ffff << 10, //< The size of the struct - ByValSizeOffs = 10, - OrigAlignment = 0x1F<<27, - OrigAlignmentOffs = 27 - }; + typedef unsigned long long ParamFlagsTy; + + const ParamFlagsTy NoFlagSet = 0ULL; + const ParamFlagsTy ZExt = 1ULL<<0; ///< Zero extended + const ParamFlagsTy ZExtOffs = 0; + const ParamFlagsTy SExt = 1ULL<<1; ///< Sign extended + const ParamFlagsTy SExtOffs = 1; + const ParamFlagsTy InReg = 1ULL<<2; ///< Passed in register + const ParamFlagsTy InRegOffs = 2; + const ParamFlagsTy StructReturn = 1ULL<<3; ///< Hidden struct-ret ptr + const ParamFlagsTy StructReturnOffs = 3; + const ParamFlagsTy ByVal = 1ULL<<4; ///< Struct passed by value + const ParamFlagsTy ByValOffs = 4; + const ParamFlagsTy Nest = 1ULL<<5; ///< Nested fn static chain + const ParamFlagsTy NestOffs = 5; + const ParamFlagsTy ByValAlign = 0xFULL << 6; //< Struct alignment + const ParamFlagsTy ByValAlignOffs = 6; + const ParamFlagsTy OrigAlignment = 0x1FULL<<27; + const ParamFlagsTy OrigAlignmentOffs = 27; + const ParamFlagsTy ByValSize = 0xffffffffULL << 32; //< Struct size + const ParamFlagsTy ByValSizeOffs = 32; + + const ParamFlagsTy One = 1LL; //< 1 of this type, for shifts } //===--------------------------------------------------------------------===// diff --git a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp index 591e9aa0eec..6b9b31b548f 100644 --- a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp +++ b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp @@ -35,7 +35,7 @@ CCState::CCState(unsigned CC, bool isVarArg, const TargetMachine &tm, void CCState::HandleByVal(unsigned ValNo, MVT::ValueType ValVT, MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo, int MinSize, int MinAlign, - unsigned ArgFlags) { + ISD::ParamFlags::ParamFlagsTy ArgFlags) { unsigned Align = 1 << ((ArgFlags & ISD::ParamFlags::ByValAlign) >> ISD::ParamFlags::ByValAlignOffs); unsigned Size = (ArgFlags & ISD::ParamFlags::ByValSize) >> @@ -66,7 +66,8 @@ void CCState::AnalyzeFormalArguments(SDNode *TheArgs, CCAssignFn Fn) { for (unsigned i = 0; i != NumArgs; ++i) { MVT::ValueType ArgVT = TheArgs->getValueType(i); SDOperand FlagOp = TheArgs->getOperand(3+i); - unsigned ArgFlags = cast(FlagOp)->getValue(); + ISD::ParamFlags::ParamFlagsTy ArgFlags = + cast(FlagOp)->getValue(); if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { cerr << "Formal argument #" << i << " has unhandled type " << MVT::getValueTypeString(ArgVT) << "\n"; @@ -98,7 +99,8 @@ void CCState::AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn) { for (unsigned i = 0; i != NumOps; ++i) { MVT::ValueType ArgVT = TheCall->getOperand(5+2*i).getValueType(); SDOperand FlagOp = TheCall->getOperand(5+2*i+1); - unsigned ArgFlags =cast(FlagOp)->getValue(); + ISD::ParamFlags::ParamFlagsTy ArgFlags = + cast(FlagOp)->getValue(); if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { cerr << "Call operand #" << i << " has unhandled type " << MVT::getValueTypeString(ArgVT) << "\n"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index a0d18f84f83..85fbb6f5a0f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -4059,7 +4059,7 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I, ++j) { MVT::ValueType VT = getValueType(I->getType()); - unsigned Flags = ISD::ParamFlags::NoFlagSet; + ISD::ParamFlags::ParamFlagsTy Flags = ISD::ParamFlags::NoFlagSet; unsigned OriginalAlignment = getTargetData()->getABITypeAlignment(I->getType()); @@ -4083,12 +4083,15 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { // this info is not there but there are cases it cannot get right. if (F.getParamAlignment(j)) FrameAlign = Log2_32(F.getParamAlignment(j)); - Flags |= (FrameAlign << ISD::ParamFlags::ByValAlignOffs); - Flags |= (FrameSize << ISD::ParamFlags::ByValSizeOffs); + Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameAlign + << ISD::ParamFlags::ByValAlignOffs); + Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameSize + << ISD::ParamFlags::ByValSizeOffs); } if (F.paramHasAttr(j, ParamAttr::Nest)) Flags |= ISD::ParamFlags::Nest; - Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs); + Flags |= ((ISD::ParamFlags::ParamFlagsTy)OriginalAlignment + << ISD::ParamFlags::OrigAlignmentOffs); MVT::ValueType RegisterVT = getRegisterType(VT); unsigned NumRegs = getNumRegisters(VT); @@ -4097,8 +4100,8 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { // if it isn't first piece, alignment must be 1 if (i > 0) Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) | - (1 << ISD::ParamFlags::OrigAlignmentOffs); - Ops.push_back(DAG.getConstant(Flags, MVT::i32)); + (ISD::ParamFlags::One << ISD::ParamFlags::OrigAlignmentOffs); + Ops.push_back(DAG.getConstant(Flags, MVT::i64)); } } @@ -4174,7 +4177,7 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, for (unsigned i = 0, e = Args.size(); i != e; ++i) { MVT::ValueType VT = getValueType(Args[i].Ty); SDOperand Op = Args[i].Node; - unsigned Flags = ISD::ParamFlags::NoFlagSet; + ISD::ParamFlags::ParamFlagsTy Flags = ISD::ParamFlags::NoFlagSet; unsigned OriginalAlignment = getTargetData()->getABITypeAlignment(Args[i].Ty); @@ -4196,12 +4199,15 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, // info is not there but there are cases it cannot get right. if (Args[i].Alignment) FrameAlign = Log2_32(Args[i].Alignment); - Flags |= (FrameAlign << ISD::ParamFlags::ByValAlignOffs); - Flags |= (FrameSize << ISD::ParamFlags::ByValSizeOffs); + Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameAlign + << ISD::ParamFlags::ByValAlignOffs); + Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameSize + << ISD::ParamFlags::ByValSizeOffs); } if (Args[i].isNest) Flags |= ISD::ParamFlags::Nest; - Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs; + Flags |= ((ISD::ParamFlags::ParamFlagsTy)OriginalAlignment) + << ISD::ParamFlags::OrigAlignmentOffs; MVT::ValueType PartVT = getRegisterType(VT); unsigned NumParts = getNumRegisters(VT); @@ -4217,13 +4223,13 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, for (unsigned i = 0; i != NumParts; ++i) { // if it isn't first piece, alignment must be 1 - unsigned MyFlags = Flags; + ISD::ParamFlags::ParamFlagsTy MyFlags = Flags; if (i != 0) MyFlags = (MyFlags & (~ISD::ParamFlags::OrigAlignment)) | - (1 << ISD::ParamFlags::OrigAlignmentOffs); + (ISD::ParamFlags::One << ISD::ParamFlags::OrigAlignmentOffs); Ops.push_back(Parts[i]); - Ops.push_back(DAG.getConstant(MyFlags, MVT::i32)); + Ops.push_back(DAG.getConstant(MyFlags, MVT::i64)); } } diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 2e7d985bf8e..67aeebf57cc 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -368,12 +368,13 @@ static void HowToPassArgument(MVT::ValueType ObjectVT, unsigned NumGPRs, unsigned StackOffset, unsigned &NeededGPRs, unsigned &NeededStackSize, unsigned &GPRPad, - unsigned &StackPad, unsigned Flags) { + unsigned &StackPad, ISD::ParamFlags::ParamFlagsTy Flags) { NeededStackSize = 0; NeededGPRs = 0; StackPad = 0; GPRPad = 0; - unsigned align = (Flags >> ISD::ParamFlags::OrigAlignmentOffs); + unsigned align = ((Flags & ISD::ParamFlags::OrigAlignment) + >> ISD::ParamFlags::OrigAlignmentOffs); GPRPad = NumGPRs % ((align + 3)/4); StackPad = StackOffset % align; unsigned firstGPR = NumGPRs + GPRPad; @@ -422,7 +423,7 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { unsigned StackPad; unsigned GPRPad; MVT::ValueType ObjectVT = Op.getOperand(5+2*i).getValueType(); - unsigned Flags = Op.getConstantOperandVal(5+2*i+1); + ISD::ParamFlags::ParamFlagsTy Flags = Op.getConstantOperandVal(5+2*i+1); HowToPassArgument(ObjectVT, NumGPRs, NumBytes, ObjGPRs, ObjSize, GPRPad, StackPad, Flags); NumBytes += ObjSize + StackPad; @@ -445,7 +446,7 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { std::vector MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { SDOperand Arg = Op.getOperand(5+2*i); - unsigned Flags = Op.getConstantOperandVal(5+2*i+1); + ISD::ParamFlags::ParamFlagsTy Flags = Op.getConstantOperandVal(5+2*i+1); MVT::ValueType ArgVT = Arg.getValueType(); unsigned ObjSize; @@ -924,7 +925,7 @@ static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG, unsigned ObjGPRs; unsigned GPRPad; unsigned StackPad; - unsigned Flags = Op.getConstantOperandVal(ArgNo + 3); + ISD::ParamFlags::ParamFlagsTy Flags = Op.getConstantOperandVal(ArgNo + 3); HowToPassArgument(ObjectVT, NumGPRs, ArgOffset, ObjGPRs, ObjSize, GPRPad, StackPad, Flags); NumGPRs += GPRPad; diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 6b6ec55864d..ea7f25b36b2 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1361,8 +1361,10 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; - unsigned Flags = cast(Op.getOperand(ArgNo+3))->getValue(); - unsigned AlignFlag = 1 << ISD::ParamFlags::OrigAlignmentOffs; + ISD::ParamFlags::ParamFlagsTy Flags = + cast(Op.getOperand(ArgNo+3))->getValue(); + unsigned AlignFlag = ISD::ParamFlags::One + << ISD::ParamFlags::OrigAlignmentOffs; unsigned isByVal = Flags & ISD::ParamFlags::ByVal; // See if next argument requires stack alignment in ELF bool Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 < e) && @@ -1659,8 +1661,9 @@ static SDNode *isBLACompatibleAddress(SDOperand Op, SelectionDAG &DAG) { /// does not fit in registers. static SDOperand CreateCopyOfByValArgument(SDOperand Src, SDOperand Dst, SDOperand Chain, - unsigned Flags, SelectionDAG &DAG, unsigned Size) { - unsigned Align = 1 << + ISD::ParamFlags::ParamFlagsTy Flags, + SelectionDAG &DAG, unsigned Size) { + unsigned Align = ISD::ParamFlags::One << ((Flags & ISD::ParamFlags::ByValAlign) >> ISD::ParamFlags::ByValAlignOffs); SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); @@ -1693,7 +1696,8 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG, // Add up all the space actually used. for (unsigned i = 0; i != NumOps; ++i) { - unsigned Flags = cast(Op.getOperand(5+2*i+1))->getValue(); + ISD::ParamFlags::ParamFlagsTy Flags = + cast(Op.getOperand(5+2*i+1))->getValue(); unsigned ArgSize =MVT::getSizeInBits(Op.getOperand(5+2*i).getValueType())/8; if (Flags & ISD::ParamFlags::ByVal) ArgSize = (Flags & ISD::ParamFlags::ByValSize) >> @@ -1757,8 +1761,10 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG, for (unsigned i = 0; i != NumOps; ++i) { bool inMem = false; SDOperand Arg = Op.getOperand(5+2*i); - unsigned Flags = cast(Op.getOperand(5+2*i+1))->getValue(); - unsigned AlignFlag = 1 << ISD::ParamFlags::OrigAlignmentOffs; + ISD::ParamFlags::ParamFlagsTy Flags = + cast(Op.getOperand(5+2*i+1))->getValue(); + unsigned AlignFlag = ISD::ParamFlags::One << + ISD::ParamFlags::OrigAlignmentOffs; // See if next argument requires stack alignment in ELF unsigned next = 5+2*(i+1)+1; bool Expand = (Arg.getValueType() == MVT::f64) || ((i + 1 < NumOps) && diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index a49418253c1..087c981b03f 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1145,8 +1145,9 @@ CopyTailCallClobberedArgumentsToVRegs(SDOperand Chain, /// parameter. static SDOperand CreateCopyOfByValArgument(SDOperand Src, SDOperand Dst, SDOperand Chain, - unsigned Flags, SelectionDAG &DAG) { - unsigned Align = 1 << + ISD::ParamFlags::ParamFlagsTy Flags, + SelectionDAG &DAG) { + unsigned Align = ISD::ParamFlags::One << ((Flags & ISD::ParamFlags::ByValAlign) >> ISD::ParamFlags::ByValAlignOffs); unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> ISD::ParamFlags::ByValSizeOffs; @@ -1162,7 +1163,8 @@ SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG, unsigned CC, SDOperand Root, unsigned i) { // Create the nodes corresponding to a load from this parameter slot. - unsigned Flags = cast(Op.getOperand(3 + i))->getValue(); + ISD::ParamFlags::ParamFlagsTy Flags = + cast(Op.getOperand(3 + i))->getValue(); bool AlwaysUseMutable = (CC==CallingConv::Fast) && PerformTailCallOpt; bool isByVal = Flags & ISD::ParamFlags::ByVal; bool isImmutable = !AlwaysUseMutable && !isByVal; @@ -1380,7 +1382,8 @@ X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG, SDOperand PtrOff = DAG.getIntPtrConstant(LocMemOffset); PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); - unsigned Flags = cast(FlagsOp)->getValue(); + ISD::ParamFlags::ParamFlagsTy Flags = + cast(FlagsOp)->getValue(); if (Flags & ISD::ParamFlags::ByVal) { return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG); } @@ -1642,7 +1645,8 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { assert(VA.isMemLoc()); SDOperand Arg = Op.getOperand(5+2*VA.getValNo()); SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); - unsigned Flags = cast(FlagsOp)->getValue(); + ISD::ParamFlags::ParamFlagsTy Flags = + cast(FlagsOp)->getValue(); // Create frame index. int32_t Offset = VA.getLocMemOffset()+FPDiff; uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8; diff --git a/utils/TableGen/CallingConvEmitter.cpp b/utils/TableGen/CallingConvEmitter.cpp index 0ffbd683d38..48f7cb33e6e 100644 --- a/utils/TableGen/CallingConvEmitter.cpp +++ b/utils/TableGen/CallingConvEmitter.cpp @@ -30,7 +30,7 @@ void CallingConvEmitter::run(std::ostream &O) { << std::string(CCs[i]->getName().size()+13, ' ') << "MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,\n" << std::string(CCs[i]->getName().size()+13, ' ') - << "unsigned ArgFlags, CCState &State);\n"; + << "ISD::ParamFlags::ParamFlagsTy ArgFlags, CCState &State);\n"; } // Emit each calling convention description in full. @@ -48,7 +48,7 @@ void CallingConvEmitter::EmitCallingConv(Record *CC, std::ostream &O) { << std::string(CC->getName().size()+13, ' ') << "MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,\n" << std::string(CC->getName().size()+13, ' ') - << "unsigned ArgFlags, CCState &State) {\n"; + << "ISD::ParamFlags::ParamFlagsTy ArgFlags, CCState &State) {\n"; // Emit all of the actions, in order. for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) { O << "\n";