mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
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
This commit is contained in:
parent
faf1daeb92
commit
c548428c5d
@ -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);
|
||||
|
@ -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<SDNode> {
|
||||
const ilist_iterator<SDNode> &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
|
||||
|
@ -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<double> LegalFPImmediates;
|
||||
|
@ -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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(LHS.getOperand(3))->getVT());
|
||||
}
|
||||
// Users of the select now use the result of the load.
|
||||
CombineTo(TheSelect, Load);
|
||||
|
||||
|
@ -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<ConstantFP>(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<VTSDNode>(Node->getOperand(3))->getVT();
|
||||
switch (TLI.getOperationAction(Node->getOpcode(), SrcVT)) {
|
||||
unsigned LType = cast<ConstantSDNode>(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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(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<VTSDNode>(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:
|
||||
|
@ -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<VTSDNode>(Ops[3])->getVT();
|
||||
assert(NumOps == 4 && VTList.NumVTs == 2 && "Bad *EXTLOAD!");
|
||||
unsigned LType = cast<ConstantSDNode>(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<ConstantSDNode>(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";
|
||||
|
@ -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<VTSDNode>(Op.getOperand(3))->getVT();
|
||||
KnownZero |= ~MVT::getIntVTBitMask(VT) & DemandedMask;
|
||||
case ISD::LOADX: {
|
||||
if (ISD::isZEXTLoad(Op.Val)) {
|
||||
MVT::ValueType VT = cast<VTSDNode>(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<VTSDNode>(Op.getOperand(3))->getVT();
|
||||
KnownZero |= ~MVT::getIntVTBitMask(VT) & Mask;
|
||||
case ISD::LOADX: {
|
||||
if (ISD::isZEXTLoad(Op.Val)) {
|
||||
MVT::ValueType VT = cast<VTSDNode>(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<VTSDNode>(Op.getOperand(1))->getVT());
|
||||
return VTBits-Tmp;
|
||||
|
||||
case ISD::SEXTLOAD: // '17' bits known
|
||||
Tmp = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(3))->getVT());
|
||||
return VTBits-Tmp+1;
|
||||
case ISD::ZEXTLOAD: // '16' bits known
|
||||
Tmp = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(3))->getVT());
|
||||
return VTBits-Tmp;
|
||||
|
||||
case ISD::Constant: {
|
||||
uint64_t Val = cast<ConstantSDNode>(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<VTSDNode>(Op.getOperand(3))->getVT());
|
||||
return VTBits-Tmp+1;
|
||||
case ISD::ZEXTLOAD: // '16' bits known
|
||||
Tmp = MVT::getSizeInBits(cast<VTSDNode>(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 ||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<ConstantFPSDNode>(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<ConstantPoolSDNode>(Op.getOperand(1)))
|
||||
if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
|
||||
|
@ -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.
|
||||
|
@ -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)>;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user