From c548428c5d7328592f4db6f6cd815af18b3152a3 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 4 Oct 2006 00:56:09 +0000 Subject: [PATCH] Combine ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD into ISD::LOADX. Add an extra operand to LOADX to specify the exact value extension type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30714 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 5 +- include/llvm/CodeGen/SelectionDAGNodes.h | 56 +++++++++++-- include/llvm/Target/TargetLowering.h | 32 ++++++++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 67 ++++++++------- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 90 +++++++-------------- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 25 +++--- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 38 ++++++--- lib/Target/Alpha/AlphaISelLowering.cpp | 20 ++--- lib/Target/IA64/IA64ISelDAGToDAG.cpp | 3 +- lib/Target/IA64/IA64ISelLowering.cpp | 18 ++--- lib/Target/PowerPC/PPCISelLowering.cpp | 10 +-- lib/Target/Sparc/SparcISelDAGToDAG.cpp | 8 +- lib/Target/TargetSelectionDAG.td | 24 +++--- lib/Target/X86/X86ISelLowering.cpp | 3 +- 14 files changed, 229 insertions(+), 170 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index c173eb122c3..f7ebbf25fbc 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -303,8 +303,9 @@ public: SDOperand SV); SDOperand getVecLoad(unsigned Count, MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, SDOperand SV); - SDOperand getExtLoad(unsigned Opcode, MVT::ValueType VT, SDOperand Chain, - SDOperand Ptr, SDOperand SV, MVT::ValueType EVT); + SDOperand getExtLoad(ISD::LoadExtType LType, MVT::ValueType VT, + SDOperand Chain, SDOperand Ptr, SDOperand SV, + MVT::ValueType EVT); // getSrcValue - construct a node to track a Value* through the backend SDOperand getSrcValue(const Value* I, int offset = 0); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 99fd5917b7a..8a480a4bd99 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -380,11 +380,11 @@ namespace ISD { // the elements, a token chain, a pointer operand, and a SRCVALUE node. VLOAD, - // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators all load a value from - // memory and extend them to a larger value (e.g. load a byte into a word - // register). All three of these have four operands, a token chain, a - // pointer to load from, a SRCVALUE for alias analysis, and a VALUETYPE node - // indicating the type to load. + // Load a value from memory and extend them to a larger value (e.g. load a + // byte into a word register). All three of these have four operands, a + // token chain, a pointer to load from, a SRCVALUE for alias analysis, a + // VALUETYPE node indicating the type to load, and an enum indicating what + // sub-type of LOADX it is: // // SEXTLOAD loads the integer operand and sign extends it to a larger // integer result type. @@ -393,7 +393,7 @@ namespace ISD { // EXTLOAD is used for three things: floating point extending loads, // integer extending loads [the top bits are undefined], and vector // extending loads [load into low elt]. - EXTLOAD, SEXTLOAD, ZEXTLOAD, + LOADX, // TRUNCSTORE - This operators truncates (for integer) or rounds (for FP) a // value and stores it to memory in one operation. This can be used for @@ -533,6 +533,17 @@ namespace ISD { /// BUILD_VECTOR where all of the elements are 0 or undef. bool isBuildVectorAllZeros(const SDNode *N); + //===--------------------------------------------------------------------===// + /// LoadExtType enum - This enum defines the three variants of LOADEXT + /// (load with extension). + /// + enum LoadExtType { + EXTLOAD, + SEXTLOAD, + ZEXTLOAD, + LAST_LOADX_TYPE + }; + //===--------------------------------------------------------------------===// /// ISD::CondCode enum - These are ordered carefully to make the bitfields /// below work out, when considering SETFALSE (something that never exists @@ -671,6 +682,7 @@ public: inline unsigned getOpcode() const; inline unsigned getNumOperands() const; inline const SDOperand &getOperand(unsigned i) const; + inline uint64_t getConstantOperandVal(unsigned i) const; inline bool isTargetOpcode() const; inline unsigned getTargetOpcode() const; @@ -775,10 +787,15 @@ public: /// unsigned getNumOperands() const { return NumOperands; } + /// getConstantOperandVal - Helper method returns the integer value of a + /// ConstantSDNode operand. + uint64_t getConstantOperandVal(unsigned Num) const; + const SDOperand &getOperand(unsigned Num) const { assert(Num < NumOperands && "Invalid child # of SDNode!"); return OperandList[Num]; } + typedef const SDOperand* op_iterator; op_iterator op_begin() const { return OperandList; } op_iterator op_end() const { return OperandList+NumOperands; } @@ -997,6 +1014,9 @@ inline unsigned SDOperand::getNumOperands() const { inline const SDOperand &SDOperand::getOperand(unsigned i) const { return Val->getOperand(i); } +inline uint64_t SDOperand::getConstantOperandVal(unsigned i) const { + return Val->getConstantOperandVal(i); +} inline bool SDOperand::isTargetOpcode() const { return Val->isTargetOpcode(); } @@ -1399,6 +1419,30 @@ struct ilist_traits { const ilist_iterator &Y) {} }; +namespace ISD { + /// isEXTLoad - Returns true if the specified node is a EXTLOAD. + /// + inline bool isEXTLoad(const SDNode *N) { + return N->getOpcode() == ISD::LOADX && + N->getConstantOperandVal(4) == ISD::EXTLOAD; + } + + /// isSEXTLoad - Returns true if the specified node is a SEXTLOAD. + /// + inline bool isSEXTLoad(const SDNode *N) { + return N->getOpcode() == ISD::LOADX && + N->getConstantOperandVal(4) == ISD::SEXTLOAD; + } + + /// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD. + /// + inline bool isZEXTLoad(const SDNode *N) { + return N->getOpcode() == ISD::LOADX && + N->getConstantOperandVal(4) == ISD::ZEXTLOAD; + } +} + + } // end llvm namespace #endif diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 6cecbbc4e58..8fae7479168 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -215,16 +215,33 @@ public: /// expanded to some other code sequence, or the target has a custom expander /// for it. LegalizeAction getOperationAction(unsigned Op, MVT::ValueType VT) const { + assert(Op != ISD::LOADX && "Should use getLoadXAction instead"); return (LegalizeAction)((OpActions[Op] >> (2*VT)) & 3); } /// isOperationLegal - Return true if the specified operation is legal on this /// target. bool isOperationLegal(unsigned Op, MVT::ValueType VT) const { + assert(Op != ISD::LOADX && "Should use isLoadXLegal instead"); return getOperationAction(Op, VT) == Legal || getOperationAction(Op, VT) == Custom; } + /// getLoadXAction - Return how this load with extension should be treated: + /// either it is legal, needs to be promoted to a larger size, needs to be + /// expanded to some other code sequence, or the target has a custom expander + /// for it. + LegalizeAction getLoadXAction(unsigned LType, MVT::ValueType VT) const { + return (LegalizeAction)((LoadXActions[LType] >> (2*VT)) & 3); + } + + /// isLoadXLegal - Return true if the specified load with extension is legal + /// is legal on this target. + bool isLoadXLegal(unsigned LType, MVT::ValueType VT) const { + return getLoadXAction(LType, VT) == Legal || + getLoadXAction(LType, VT) == Custom; + } + /// getTypeToPromoteTo - If the action for this operation is to promote, this /// method returns the ValueType to promote to. MVT::ValueType getTypeToPromoteTo(unsigned Op, MVT::ValueType VT) const { @@ -521,12 +538,22 @@ protected: /// with the specified type and indicate what to do about it. void setOperationAction(unsigned Op, MVT::ValueType VT, LegalizeAction Action) { + assert(Op != ISD::LOADX && "Should use setLoadXAction instead"); assert(VT < 32 && Op < sizeof(OpActions)/sizeof(OpActions[0]) && "Table isn't big enough!"); OpActions[Op] &= ~(uint64_t(3UL) << VT*2); OpActions[Op] |= (uint64_t)Action << VT*2; } + /// setLoadXAction - Indicate that the specified load with extension does not + /// work with the with specified type and indicate what to do about it. + void setLoadXAction(unsigned LType, MVT::ValueType VT, LegalizeAction Action){ + assert(VT < 32 && LType < sizeof(LoadXActions)/sizeof(LoadXActions[0]) && + "Table isn't big enough!"); + LoadXActions[LType] &= ~(uint64_t(3UL) << VT*2); + LoadXActions[LType] |= (uint64_t)Action << VT*2; + } + /// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the /// promotion code defaults to trying a larger integer/fp until it can find /// one that works. If that default is insufficient, this method can be used @@ -773,6 +800,11 @@ private: /// non-legal value types are not described here. uint64_t OpActions[156]; + /// LoadXActions - For each load of load extension type and each value type, + /// keep a LegalizeAction that indicates how instruction selection should deal + /// with the load. + uint64_t LoadXActions[ISD::LAST_LOADX_TYPE]; + ValueTypeActionImpl ValueTypeActions; std::vector LegalFPImmediates; diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 1fe10019679..5d44cf53860 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -217,7 +217,7 @@ class VISIBILITY_HIDDEN DAGCombiner { SDOperand visitBRCOND(SDNode *N); SDOperand visitBR_CC(SDNode *N); SDOperand visitLOAD(SDNode *N); - SDOperand visitXEXTLOAD(SDNode *N); + SDOperand visitLOADX(SDNode *N); SDOperand visitSTORE(SDNode *N); SDOperand visitINSERT_VECTOR_ELT(SDNode *N); SDOperand visitVINSERT_VECTOR_ELT(SDNode *N); @@ -511,9 +511,7 @@ SDOperand DAGCombiner::visit(SDNode *N) { case ISD::BRCOND: return visitBRCOND(N); case ISD::BR_CC: return visitBR_CC(N); case ISD::LOAD: return visitLOAD(N); - case ISD::EXTLOAD: - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: return visitXEXTLOAD(N); + case ISD::LOADX: return visitLOADX(N); case ISD::STORE: return visitSTORE(N); case ISD::INSERT_VECTOR_ELT: return visitINSERT_VECTOR_ELT(N); case ISD::VINSERT_VECTOR_ELT: return visitVINSERT_VECTOR_ELT(N); @@ -1082,12 +1080,12 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { SimplifyDemandedBits(SDOperand(N, 0))) return SDOperand(N, 0); // fold (zext_inreg (extload x)) -> (zextload x) - if (N0.getOpcode() == ISD::EXTLOAD) { + if (ISD::isEXTLoad(N0.Val)) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); // If we zero all the possible extended bits, then we can turn this into // a zextload if we are running before legalize or the operation is legal. if (TLI.MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT)) && - (!AfterLegalize || TLI.isOperationLegal(ISD::ZEXTLOAD, EVT))) { + (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); @@ -1097,12 +1095,12 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { } } // fold (zext_inreg (sextload x)) -> (zextload x) iff load has one use - if (N0.getOpcode() == ISD::SEXTLOAD && N0.hasOneUse()) { + if (ISD::isSEXTLoad(N0.Val) && N0.hasOneUse()) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); // If we zero all the possible extended bits, then we can turn this into // a zextload if we are running before legalize or the operation is legal. if (TLI.MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT)) && - (!AfterLegalize || TLI.isOperationLegal(ISD::ZEXTLOAD, EVT))) { + (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); @@ -1115,8 +1113,8 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { // fold (and (load x), 255) -> (zextload x, i8) // fold (and (extload x, i16), 255) -> (zextload x, i8) if (N1C && - (N0.getOpcode() == ISD::LOAD || N0.getOpcode() == ISD::EXTLOAD || - N0.getOpcode() == ISD::ZEXTLOAD) && + (N0.getOpcode() == ISD::LOAD || ISD::isEXTLoad(N0.Val) || + ISD::isZEXTLoad(N0.Val)) && N0.hasOneUse()) { MVT::ValueType EVT, LoadedVT; if (N1C->getValue() == 255) @@ -1131,7 +1129,7 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { LoadedVT = N0.getOpcode() == ISD::LOAD ? VT : cast(N0.getOperand(3))->getVT(); if (EVT != MVT::Other && LoadedVT > EVT && - (!AfterLegalize || TLI.isOperationLegal(ISD::ZEXTLOAD, EVT))) { + (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) { MVT::ValueType PtrType = N0.getOperand(1).getValueType(); // For big endian targets, we need to add an offset to the pointer to load // the correct bytes. For little endian systems, we merely need to read @@ -1863,7 +1861,7 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) { // fold (sext (load x)) -> (sext (truncate (sextload x))) if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() && - (!AfterLegalize||TLI.isOperationLegal(ISD::SEXTLOAD, N0.getValueType()))){ + (!AfterLegalize||TLI.isLoadXLegal(ISD::SEXTLOAD, N0.getValueType()))){ SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), N0.getValueType()); @@ -1875,8 +1873,7 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) { // fold (sext (sextload x)) -> (sext (truncate (sextload x))) // fold (sext ( extload x)) -> (sext (truncate (sextload x))) - if ((N0.getOpcode() == ISD::SEXTLOAD || N0.getOpcode() == ISD::EXTLOAD) && - N0.hasOneUse()) { + if ((ISD::isSEXTLoad(N0.Val) || ISD::isEXTLoad(N0.Val)) && N0.hasOneUse()) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); @@ -1929,7 +1926,7 @@ SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) { // fold (zext (load x)) -> (zext (truncate (zextload x))) if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() && - (!AfterLegalize||TLI.isOperationLegal(ISD::ZEXTLOAD, N0.getValueType()))){ + (!AfterLegalize||TLI.isLoadXLegal(ISD::ZEXTLOAD, N0.getValueType()))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), N0.getValueType()); @@ -1941,8 +1938,7 @@ SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) { // fold (zext (zextload x)) -> (zext (truncate (zextload x))) // fold (zext ( extload x)) -> (zext (truncate (zextload x))) - if ((N0.getOpcode() == ISD::ZEXTLOAD || N0.getOpcode() == ISD::EXTLOAD) && - N0.hasOneUse()) { + if ((ISD::isZEXTLoad(N0.Val) || ISD::isEXTLoad(N0.Val)) && N0.hasOneUse()) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); @@ -1995,7 +1991,7 @@ SDOperand DAGCombiner::visitANY_EXTEND(SDNode *N) { // fold (aext (load x)) -> (aext (truncate (extload x))) if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() && - (!AfterLegalize||TLI.isOperationLegal(ISD::EXTLOAD, N0.getValueType()))) { + (!AfterLegalize||TLI.isLoadXLegal(ISD::EXTLOAD, N0.getValueType()))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), N0.getValueType()); @@ -2008,12 +2004,12 @@ SDOperand DAGCombiner::visitANY_EXTEND(SDNode *N) { // fold (aext (zextload x)) -> (aext (truncate (zextload x))) // fold (aext (sextload x)) -> (aext (truncate (sextload x))) // fold (aext ( extload x)) -> (aext (truncate (extload x))) - if ((N0.getOpcode() == ISD::ZEXTLOAD || N0.getOpcode() == ISD::EXTLOAD || - N0.getOpcode() == ISD::SEXTLOAD) && - N0.hasOneUse()) { + if (N0.getOpcode() == ISD::LOADX && N0.hasOneUse()) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); - SDOperand ExtLoad = DAG.getExtLoad(N0.getOpcode(), VT, N0.getOperand(0), - N0.getOperand(1), N0.getOperand(2), EVT); + unsigned LType = N0.getConstantOperandVal(4); + SDOperand ExtLoad = DAG.getExtLoad((ISD::LoadExtType)LType, VT, + N0.getOperand(0), N0.getOperand(1), + N0.getOperand(2), EVT); CombineTo(N, ExtLoad); CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), ExtLoad.getValue(1)); @@ -2063,9 +2059,9 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { } // fold (sext_inreg (extload x)) -> (sextload x) - if (N0.getOpcode() == ISD::EXTLOAD && + if (ISD::isEXTLoad(N0.Val) && EVT == cast(N0.getOperand(3))->getVT() && - (!AfterLegalize || TLI.isOperationLegal(ISD::SEXTLOAD, EVT))) { + (!AfterLegalize || TLI.isLoadXLegal(ISD::SEXTLOAD, EVT))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); @@ -2074,9 +2070,9 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { return SDOperand(N, 0); // Return N so it doesn't get rechecked! } // fold (sext_inreg (zextload x)) -> (sextload x) iff load has one use - if (N0.getOpcode() == ISD::ZEXTLOAD && N0.hasOneUse() && + if (ISD::isZEXTLoad(N0.Val) && N0.hasOneUse() && EVT == cast(N0.getOperand(3))->getVT() && - (!AfterLegalize || TLI.isOperationLegal(ISD::SEXTLOAD, EVT))) { + (!AfterLegalize || TLI.isLoadXLegal(ISD::SEXTLOAD, EVT))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); @@ -2525,7 +2521,7 @@ SDOperand DAGCombiner::visitFP_EXTEND(SDNode *N) { // fold (fpext (load x)) -> (fpext (fpround (extload x))) if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() && - (!AfterLegalize||TLI.isOperationLegal(ISD::EXTLOAD, N0.getValueType()))) { + (!AfterLegalize||TLI.isLoadXLegal(ISD::EXTLOAD, N0.getValueType()))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), N0.getValueType()); @@ -2666,8 +2662,8 @@ SDOperand DAGCombiner::visitLOAD(SDNode *N) { return SDOperand(); } -/// visitXEXTLOAD - Handle EXTLOAD/ZEXTLOAD/SEXTLOAD. -SDOperand DAGCombiner::visitXEXTLOAD(SDNode *N) { +/// visitLOADX - Handle EXTLOAD/ZEXTLOAD/SEXTLOAD. +SDOperand DAGCombiner::visitLOADX(SDNode *N) { SDOperand Chain = N->getOperand(0); SDOperand Ptr = N->getOperand(1); SDOperand SrcValue = N->getOperand(2); @@ -3299,9 +3295,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDOperand LHS, // This triggers in things like "select bool X, 10.0, 123.0" after the FP // constants have been dropped into the constant pool. if ((LHS.getOpcode() == ISD::LOAD || - LHS.getOpcode() == ISD::EXTLOAD || - LHS.getOpcode() == ISD::ZEXTLOAD || - LHS.getOpcode() == ISD::SEXTLOAD) && + LHS.getOpcode() == ISD::LOADX ) && // Token chains must be identical. LHS.getOperand(0) == RHS.getOperand(0) && // If this is an EXTLOAD, the VT's must match. @@ -3326,10 +3320,13 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDOperand LHS, if (LHS.getOpcode() == ISD::LOAD) Load = DAG.getLoad(TheSelect->getValueType(0), LHS.getOperand(0), Addr, LHS.getOperand(2)); - else - Load = DAG.getExtLoad(LHS.getOpcode(), TheSelect->getValueType(0), + else { + unsigned LType = LHS.getConstantOperandVal(4); + Load = DAG.getExtLoad((ISD::LoadExtType)LType, + TheSelect->getValueType(0), LHS.getOperand(0), Addr, LHS.getOperand(2), cast(LHS.getOperand(3))->getVT()); + } // Users of the select now use the result of the load. CombineTo(TheSelect, Load); diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index c97e52a8599..07b72a63729 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -799,7 +799,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { if (isDouble && CFP->isExactlyValue((float)CFP->getValue()) && // Only do this if the target has a native EXTLOAD instruction from // f32. - TLI.isOperationLegal(ISD::EXTLOAD, MVT::f32)) { + TLI.isLoadXLegal(ISD::EXTLOAD, MVT::f32)) { LLVMC = cast(ConstantExpr::getCast(LLVMC, Type::FloatTy)); VT = MVT::f32; Extend = true; @@ -1372,19 +1372,19 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { AddLegalizedOperand(SDOperand(Node, 1), Tmp4); return Op.ResNo ? Tmp4 : Tmp3; } - case ISD::EXTLOAD: - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: { + case ISD::LOADX: { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. MVT::ValueType SrcVT = cast(Node->getOperand(3))->getVT(); - switch (TLI.getOperationAction(Node->getOpcode(), SrcVT)) { + unsigned LType = cast(Node->getOperand(4))->getValue(); + switch (TLI.getLoadXAction(LType, SrcVT)) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Promote: - assert(SrcVT == MVT::i1 && "Can only promote EXTLOAD from i1 -> i8!"); + assert(SrcVT == MVT::i1 && "Can only promote LOADX from i1 -> i8!"); Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2), - DAG.getValueType(MVT::i8)); + DAG.getValueType(MVT::i8), + Node->getOperand(4)); Tmp1 = Result.getValue(0); Tmp2 = Result.getValue(1); break; @@ -1393,7 +1393,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // FALLTHROUGH case TargetLowering::Legal: Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2), - Node->getOperand(3)); + Node->getOperand(3), Node->getOperand(4)); Tmp1 = Result.getValue(0); Tmp2 = Result.getValue(1); @@ -1414,14 +1414,13 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp2 = LegalizeOp(Load.getValue(1)); break; } - assert(Node->getOpcode() != ISD::EXTLOAD && - "EXTLOAD should always be supported!"); + assert(LType != ISD::EXTLOAD && "EXTLOAD should always be supported!"); // Turn the unsupported load into an EXTLOAD followed by an explicit // zero/sign extend inreg. Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0), Tmp1, Tmp2, Node->getOperand(2), SrcVT); SDOperand ValRes; - if (Node->getOpcode() == ISD::SEXTLOAD) + if (LType == ISD::SEXTLOAD) ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), Result, DAG.getValueType(SrcVT)); else @@ -3242,12 +3241,12 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1))); break; - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: - case ISD::EXTLOAD: - Result = DAG.getExtLoad(Node->getOpcode(), NVT, Node->getOperand(0), - Node->getOperand(1), Node->getOperand(2), - cast(Node->getOperand(3))->getVT()); + case ISD::LOADX: + Result = + DAG.getExtLoad((ISD::LoadExtType)Node->getConstantOperandVal(4), + NVT, Node->getOperand(0), Node->getOperand(1), + Node->getOperand(2), + cast(Node->getOperand(3))->getVT()); // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1))); break; @@ -4479,10 +4478,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Node->getOperand(1), TH, FH, Node->getOperand(4)); break; } - case ISD::SEXTLOAD: { + case ISD::LOADX: { SDOperand Chain = Node->getOperand(0); SDOperand Ptr = Node->getOperand(1); MVT::ValueType EVT = cast(Node->getOperand(3))->getVT(); + unsigned LType = Node->getConstantOperandVal(4); if (EVT == NVT) Lo = DAG.getLoad(NVT, Chain, Ptr, Node->getOperand(2)); @@ -4492,48 +4492,20 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ // Remember that we legalized the chain. AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Lo.getValue(1))); - - // The high part is obtained by SRA'ing all but one of the bits of the lo - // part. - unsigned LoSize = MVT::getSizeInBits(Lo.getValueType()); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, DAG.getConstant(LoSize-1, - TLI.getShiftAmountTy())); - break; - } - case ISD::ZEXTLOAD: { - SDOperand Chain = Node->getOperand(0); - SDOperand Ptr = Node->getOperand(1); - MVT::ValueType EVT = cast(Node->getOperand(3))->getVT(); - - if (EVT == NVT) - Lo = DAG.getLoad(NVT, Chain, Ptr, Node->getOperand(2)); - else - Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Chain, Ptr, Node->getOperand(2), - EVT); - - // Remember that we legalized the chain. - AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Lo.getValue(1))); - // The high part is just a zero. - Hi = DAG.getConstant(0, NVT); - break; - } - case ISD::EXTLOAD: { - SDOperand Chain = Node->getOperand(0); - SDOperand Ptr = Node->getOperand(1); - MVT::ValueType EVT = cast(Node->getOperand(3))->getVT(); - - if (EVT == NVT) - Lo = DAG.getLoad(NVT, Chain, Ptr, Node->getOperand(2)); - else - Lo = DAG.getExtLoad(ISD::EXTLOAD, NVT, Chain, Ptr, Node->getOperand(2), - EVT); - - // Remember that we legalized the chain. - AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Lo.getValue(1))); - - // The high part is undefined. - Hi = DAG.getNode(ISD::UNDEF, NVT); + if (LType == ISD::SEXTLOAD) { + // The high part is obtained by SRA'ing all but one of the bits of the lo + // part. + unsigned LoSize = MVT::getSizeInBits(Lo.getValueType()); + Hi = DAG.getNode(ISD::SRA, NVT, Lo, DAG.getConstant(LoSize-1, + TLI.getShiftAmountTy())); + } else if (LType == ISD::ZEXTLOAD) { + // The high part is just a zero. + Hi = DAG.getConstant(0, NVT); + } else /* if (LType == ISD::EXTLOAD) */ { + // The high part is undefined. + Hi = DAG.getNode(ISD::UNDEF, NVT); + } break; } case ISD::ANY_EXTEND: diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index c47852b0f36..dc0d00f47e3 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1482,11 +1482,12 @@ SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT, return getNode(ISD::VLOAD, getVTList(MVT::Vector, MVT::Other), Ops, 5); } -SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT, +SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType LType, MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, SDOperand SV, MVT::ValueType EVT) { - SDOperand Ops[] = { Chain, Ptr, SV, getValueType(EVT) }; - return getNode(Opcode, getVTList(VT, MVT::Other), Ops, 4); + SDOperand Ops[] = { Chain, Ptr, SV, getValueType(EVT), + getConstant(LType, MVT::i32) }; + return getNode(ISD::LOADX, getVTList(VT, MVT::Other), Ops, 5); } SDOperand SelectionDAG::getVAArg(MVT::ValueType VT, @@ -1586,11 +1587,10 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList, return getNode(Opcode, VTList.VTs[0], Ops, NumOps); switch (Opcode) { - case ISD::EXTLOAD: - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: { + case ISD::LOADX: { MVT::ValueType EVT = cast(Ops[3])->getVT(); - assert(NumOps == 4 && VTList.NumVTs == 2 && "Bad *EXTLOAD!"); + unsigned LType = cast(Ops[4])->getValue(); + assert(NumOps == 5 && VTList.NumVTs == 2 && "Bad *EXTLOAD!"); // If they are asking for an extending load from/to the same thing, return a // normal load. if (VTList.VTs[0] == EVT) @@ -1602,7 +1602,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList, assert(EVT < VTList.VTs[0] && "Should only be an extending load, not truncating!"); } - assert((Opcode == ISD::EXTLOAD || MVT::isInteger(VTList.VTs[0])) && + assert((LType == ISD::EXTLOAD || MVT::isInteger(VTList.VTs[0])) && "Cannot sign/zero extend a FP/Vector load!"); assert(MVT::isInteger(VTList.VTs[0]) == MVT::isInteger(EVT) && "Cannot convert from FP to Int or Int -> FP!"); @@ -2365,6 +2365,11 @@ bool SDNode::isOperand(SDNode *N) const { return false; } +uint64_t SDNode::getConstantOperandVal(unsigned Num) const { + assert(Num < NumOperands && "Invalid child # of SDNode!"); + return cast(OperandList[Num])->getValue(); +} + const char *SDNode::getOperationName(const SelectionDAG *G) const { switch (getOpcode()) { default: @@ -2525,9 +2530,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const { case ISD::LOAD: return "load"; case ISD::STORE: return "store"; case ISD::VLOAD: return "vload"; - case ISD::EXTLOAD: return "extload"; - case ISD::SEXTLOAD: return "sextload"; - case ISD::ZEXTLOAD: return "zextload"; + case ISD::LOADX: return "loadx"; case ISD::TRUNCSTORE: return "truncstore"; case ISD::VAARG: return "vaarg"; case ISD::VACOPY: return "vacopy"; diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 10c3a04a101..d9d7e3ebed1 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -27,6 +27,7 @@ TargetLowering::TargetLowering(TargetMachine &tm) "Fixed size array in TargetLowering is not large enough!"); // All operations default to being supported. memset(OpActions, 0, sizeof(OpActions)); + memset(LoadXActions, 0, sizeof(LoadXActions)); IsLittleEndian = TD->isLittleEndian(); ShiftAmountTy = SetCCResultTy = PointerTy = getValueType(TD->getIntPtrType()); @@ -550,9 +551,11 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask, KnownOne = 0; break; } - case ISD::ZEXTLOAD: { - MVT::ValueType VT = cast(Op.getOperand(3))->getVT(); - KnownZero |= ~MVT::getIntVTBitMask(VT) & DemandedMask; + case ISD::LOADX: { + if (ISD::isZEXTLoad(Op.Val)) { + MVT::ValueType VT = cast(Op.getOperand(3))->getVT(); + KnownZero |= ~MVT::getIntVTBitMask(VT) & DemandedMask; + } break; } case ISD::ZERO_EXTEND: { @@ -888,9 +891,11 @@ void TargetLowering::ComputeMaskedBits(SDOperand Op, uint64_t Mask, KnownOne = 0; return; } - case ISD::ZEXTLOAD: { - MVT::ValueType VT = cast(Op.getOperand(3))->getVT(); - KnownZero |= ~MVT::getIntVTBitMask(VT) & Mask; + case ISD::LOADX: { + if (ISD::isZEXTLoad(Op.Val)) { + MVT::ValueType VT = cast(Op.getOperand(3))->getVT(); + KnownZero |= ~MVT::getIntVTBitMask(VT) & Mask; + } return; } case ISD::ZERO_EXTEND: { @@ -1047,13 +1052,6 @@ unsigned TargetLowering::ComputeNumSignBits(SDOperand Op, unsigned Depth) const{ case ISD::AssertZext: Tmp = MVT::getSizeInBits(cast(Op.getOperand(1))->getVT()); return VTBits-Tmp; - - case ISD::SEXTLOAD: // '17' bits known - Tmp = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); - return VTBits-Tmp+1; - case ISD::ZEXTLOAD: // '16' bits known - Tmp = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); - return VTBits-Tmp; case ISD::Constant: { uint64_t Val = cast(Op)->getValue(); @@ -1197,6 +1195,20 @@ unsigned TargetLowering::ComputeNumSignBits(SDOperand Op, unsigned Depth) const{ break; } + // Handle LOADX separately here. EXTLOAD case will fallthrough. + if (Op.getOpcode() == ISD::LOADX) { + unsigned LType = Op.getConstantOperandVal(4); + switch (LType) { + default: break; + case ISD::SEXTLOAD: // '17' bits known + Tmp = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); + return VTBits-Tmp+1; + case ISD::ZEXTLOAD: // '16' bits known + Tmp = MVT::getSizeInBits(cast(Op.getOperand(3))->getVT()); + return VTBits-Tmp; + } + } + // Allow the target to implement this method for its nodes. if (Op.getOpcode() >= ISD::BUILTIN_OP_END || Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN || diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index cbbad532855..f94cfd1d421 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -48,20 +48,20 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass); addRegisterClass(MVT::f32, Alpha::F4RCRegisterClass); + setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote); + setLoadXAction(ISD::EXTLOAD, MVT::f32, Expand); + + setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote); + setLoadXAction(ISD::ZEXTLOAD, MVT::i32, Expand); + + setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote); + setLoadXAction(ISD::SEXTLOAD, MVT::i8, Expand); + setLoadXAction(ISD::SEXTLOAD, MVT::i16, Expand); + // setOperationAction(ISD::BRIND, MVT::i64, Expand); setOperationAction(ISD::BR_CC, MVT::Other, Expand); setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); - setOperationAction(ISD::EXTLOAD, MVT::i1, Promote); - setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); - - setOperationAction(ISD::ZEXTLOAD, MVT::i1, Promote); - setOperationAction(ISD::ZEXTLOAD, MVT::i32, Expand); - - setOperationAction(ISD::SEXTLOAD, MVT::i1, Promote); - setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); - setOperationAction(ISD::SEXTLOAD, MVT::i16, Expand); - setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); diff --git a/lib/Target/IA64/IA64ISelDAGToDAG.cpp b/lib/Target/IA64/IA64ISelDAGToDAG.cpp index 8367d245cf1..5add5d6ed5f 100644 --- a/lib/Target/IA64/IA64ISelDAGToDAG.cpp +++ b/lib/Target/IA64/IA64ISelDAGToDAG.cpp @@ -454,8 +454,7 @@ SDNode *IA64DAGToDAGISel::Select(SDOperand Op) { */ case ISD::LOAD: - case ISD::EXTLOAD: // FIXME: load -1, not 1, for bools? - case ISD::ZEXTLOAD: { + case ISD::LOADX: { // FIXME: load -1, not 1, for bools? SDOperand Chain = N->getOperand(0); SDOperand Address = N->getOperand(1); AddToISelQueue(Chain); diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp index 859530e409a..f832ea214f4 100644 --- a/lib/Target/IA64/IA64ISelLowering.cpp +++ b/lib/Target/IA64/IA64ISelLowering.cpp @@ -35,6 +35,15 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM) // register class for predicate registers addRegisterClass(MVT::i1, IA64::PRRegisterClass); + setLoadXAction(ISD::EXTLOAD , MVT::i1 , Promote); + + setLoadXAction(ISD::ZEXTLOAD , MVT::i1 , Expand); + + setLoadXAction(ISD::SEXTLOAD , MVT::i1 , Expand); + setLoadXAction(ISD::SEXTLOAD , MVT::i8 , Expand); + setLoadXAction(ISD::SEXTLOAD , MVT::i16 , Expand); + setLoadXAction(ISD::SEXTLOAD , MVT::i32 , Expand); + setOperationAction(ISD::BRIND , MVT::i64, Expand); setOperationAction(ISD::BR_CC , MVT::Other, Expand); setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); @@ -50,15 +59,6 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM) setSetCCResultType(MVT::i1); setShiftAmountType(MVT::i64); - setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote); - - setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand); - - setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); - setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand); - setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand); - setOperationAction(ISD::SEXTLOAD , MVT::i32 , Expand); - setOperationAction(ISD::FREM , MVT::f32 , Expand); setOperationAction(ISD::FREM , MVT::f64 , Expand); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index ffb4617d3c5..e96982dcf0d 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -43,6 +43,10 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) addRegisterClass(MVT::f32, PPC::F4RCRegisterClass); addRegisterClass(MVT::f64, PPC::F8RCRegisterClass); + // PowerPC has an i16 but no i8 (or i1) SEXTLOAD + setLoadXAction(ISD::SEXTLOAD, MVT::i1, Expand); + setLoadXAction(ISD::SEXTLOAD, MVT::i8, Expand); + setOperationAction(ISD::ConstantFP, MVT::f64, Expand); setOperationAction(ISD::ConstantFP, MVT::f32, Expand); @@ -51,10 +55,6 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) setOperationAction(ISD::MEMSET, MVT::Other, Expand); setOperationAction(ISD::MEMCPY, MVT::Other, Expand); - // PowerPC has an i16 but no i8 (or i1) SEXTLOAD - setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); - setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); - // PowerPC has no SREM/UREM instructions setOperationAction(ISD::SREM, MVT::i32, Expand); setOperationAction(ISD::UREM, MVT::i32, Expand); @@ -311,7 +311,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { static bool isFloatingPointZero(SDOperand Op) { if (ConstantFPSDNode *CFP = dyn_cast(Op)) return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); - else if (Op.getOpcode() == ISD::EXTLOAD || Op.getOpcode() == ISD::LOAD) { + else if (ISD::isEXTLoad(Op.Val) || Op.getOpcode() == ISD::LOAD) { // Maybe this has already been legalized into the constant pool? if (ConstantPoolSDNode *CP = dyn_cast(Op.getOperand(1))) if (ConstantFP *CFP = dyn_cast(CP->getConstVal())) diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 1d1b595743c..801cf4ec9bf 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -137,6 +137,9 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM) addRegisterClass(MVT::f32, SP::FPRegsRegisterClass); addRegisterClass(MVT::f64, SP::DFPRegsRegisterClass); + // Turn FP extload into load/fextend + setLoadXAction(ISD::EXTLOAD, MVT::f32, Expand); + // Custom legalize GlobalAddress nodes into LO/HI parts. setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool , MVT::i32, Custom); @@ -161,9 +164,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM) setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand); setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand); - // Turn FP extload into load/fextend - setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); - // Sparc has no select or setcc: expand to SELECT_CC. setOperationAction(ISD::SELECT, MVT::i32, Expand); setOperationAction(ISD::SELECT, MVT::f32, Expand); @@ -332,7 +332,7 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { if (ObjectVT == MVT::i32) { Load = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0)); } else { - unsigned LoadOp = + ISD::LoadExtType LoadOp = I->getType()->isSigned() ? ISD::SEXTLOAD : ISD::ZEXTLOAD; // Sparc is big endian, so add an offset based on the ObjectVT. diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td index f6d4cd5cdf2..2a2bd17bcf3 100644 --- a/lib/Target/TargetSelectionDAG.td +++ b/lib/Target/TargetSelectionDAG.td @@ -164,10 +164,10 @@ def SDTStore : SDTypeProfile<0, 2, [ // store SDTCisPtrTy<1> ]>; -def SDTExtLoad : SDTypeProfile<1, 3, [ // extload - SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT> +def SDTLoadX : SDTypeProfile<1, 4, [ // loadX + SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisVT<4, i32> ]>; -def SDTIntExtLoad : SDTypeProfile<1, 3, [ // sextload, zextload +def SDTIntExtLoad : SDTypeProfile<1, 3, [ // extload, sextload, zextload SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT> ]>; def SDTTruncStore : SDTypeProfile<0, 4, [ // truncstore @@ -308,11 +308,9 @@ def ret : SDNode<"ISD::RET" , SDTRet, [SDNPHasChain]>; def load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>; def store : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>; -// Do not use sextld and zextld directly. Use sextload and zextload (see -// below) which pass in a dummy srcvalue node which tblgen will skip over. -def sextld : SDNode<"ISD::SEXTLOAD" , SDTIntExtLoad, [SDNPHasChain]>; -def zextld : SDNode<"ISD::ZEXTLOAD" , SDTIntExtLoad, [SDNPHasChain]>; -def extld : SDNode<"ISD::EXTLOAD" , SDTExtLoad, [SDNPHasChain]>; +// Do not use loadx directly. Use extload, sextload and zextload (see below) +// which pass in a dummy srcvalue node which tblgen will skip over. +def loadx : SDNode<"ISD::LOADX" , SDTLoadX, [SDNPHasChain]>; def truncst : SDNode<"ISD::TRUNCSTORE" , SDTTruncStore, [SDNPHasChain]>; def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>; @@ -415,12 +413,12 @@ def vnot_conv : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV_bc)>; def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>; // extending load & truncstore fragments. -def sextload : PatFrag<(ops node:$ptr, node:$vt), - (sextld node:$ptr, srcvalue:$dummy, node:$vt)>; -def zextload : PatFrag<(ops node:$ptr, node:$vt), - (zextld node:$ptr, srcvalue:$dummy, node:$vt)>; def extload : PatFrag<(ops node:$ptr, node:$vt), - (extld node:$ptr, srcvalue:$dummy, node:$vt)>; + (loadx node:$ptr, srcvalue:$dummy, node:$vt, 0)>; +def sextload : PatFrag<(ops node:$ptr, node:$vt), + (loadx node:$ptr, srcvalue:$dummy, node:$vt, 1)>; +def zextload : PatFrag<(ops node:$ptr, node:$vt), + (loadx node:$ptr, srcvalue:$dummy, node:$vt, 2)>; def truncstore : PatFrag<(ops node:$val, node:$ptr, node:$vt), (truncst node:$val, node:$ptr, srcvalue:$dummy, node:$vt)>; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 24fe64d7988..6ab7c98b4a0 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -75,6 +75,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) if (Subtarget->is64Bit()) addRegisterClass(MVT::i64, X86::GR64RegisterClass); + setLoadXAction(ISD::SEXTLOAD, MVT::i1, Expand); + // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this // operation. setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); @@ -155,7 +157,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); - setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); setOperationAction(ISD::FREM , MVT::f64 , Expand); setOperationAction(ISD::CTPOP , MVT::i8 , Expand);