mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
Fix PR3401: when using large integers, the type
returned by getShiftAmountTy may be too small to hold shift values (it is an i8 on x86-32). Before and during type legalization, use a large but legal type for shift amounts: getPointerTy; afterwards use getShiftAmountTy, fixing up any shift amounts with a big type during operation legalization. Thanks to Dan for writing the original patch (which I shamelessly pillaged). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63482 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d1b5e3fad9
commit
92abc62399
@ -636,6 +636,10 @@ public:
|
||||
/// through the backend.
|
||||
SDValue getMemOperand(const MachineMemOperand &MO);
|
||||
|
||||
/// getShiftAmountOperand - Return the specified value casted to
|
||||
/// the target's desired shift amount type.
|
||||
SDValue getShiftAmountOperand(SDValue Op);
|
||||
|
||||
/// UpdateNodeOperands - *Mutate* the specified node in-place to have the
|
||||
/// specified operands. If the resultant node already exists in the DAG,
|
||||
/// this does not modify the specified node, instead it returns the node that
|
||||
|
@ -240,7 +240,13 @@ namespace {
|
||||
/// FindBetterChain - Walk up chain skipping non-aliasing memory nodes,
|
||||
/// looking for a better chain (aliasing node.)
|
||||
SDValue FindBetterChain(SDNode *N, SDValue Chain);
|
||||
|
||||
|
||||
/// getShiftAmountTy - Returns a type large enough to hold any valid
|
||||
/// shift amount - before type legalization these can be huge.
|
||||
MVT getShiftAmountTy() {
|
||||
return LegalTypes ? TLI.getShiftAmountTy() : TLI.getPointerTy();
|
||||
}
|
||||
|
||||
public:
|
||||
DAGCombiner(SelectionDAG &D, AliasAnalysis &A, bool fast)
|
||||
: DAG(D),
|
||||
@ -1301,7 +1307,7 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
|
||||
if (N1C && N1C->getAPIntValue().isPowerOf2())
|
||||
return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0,
|
||||
DAG.getConstant(N1C->getAPIntValue().logBase2(),
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
// fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c
|
||||
if (N1C && isPowerOf2_64(-N1C->getSExtValue()))
|
||||
// FIXME: If the input is something that is easily negated (e.g. a
|
||||
@ -1310,7 +1316,7 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
|
||||
DAG.getConstant(0, VT),
|
||||
DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0,
|
||||
DAG.getConstant(Log2_64(-N1C->getSExtValue()),
|
||||
TLI.getShiftAmountTy())));
|
||||
getShiftAmountTy())));
|
||||
// (mul (shl X, c1), c2) -> (mul X, c2 << c1)
|
||||
if (N1C && N0.getOpcode() == ISD::SHL &&
|
||||
isa<ConstantSDNode>(N0.getOperand(1))) {
|
||||
@ -1406,18 +1412,18 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
|
||||
// Splat the sign bit into the register
|
||||
SDValue SGN = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0,
|
||||
DAG.getConstant(VT.getSizeInBits()-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
AddToWorkList(SGN.getNode());
|
||||
|
||||
// Add (N0 < 0) ? abs2 - 1 : 0;
|
||||
SDValue SRL = DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, SGN,
|
||||
DAG.getConstant(VT.getSizeInBits() - lg2,
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
SDValue ADD = DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N0, SRL);
|
||||
AddToWorkList(SRL.getNode());
|
||||
AddToWorkList(ADD.getNode()); // Divide by pow2
|
||||
SDValue SRA = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, ADD,
|
||||
DAG.getConstant(lg2, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(lg2, getShiftAmountTy()));
|
||||
|
||||
// If we're dividing by a positive value, we're done. Otherwise, we must
|
||||
// negate the result.
|
||||
@ -1467,7 +1473,7 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) {
|
||||
if (N1C && N1C->getAPIntValue().isPowerOf2())
|
||||
return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0,
|
||||
DAG.getConstant(N1C->getAPIntValue().logBase2(),
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
// fold (udiv x, (shl c, y)) -> x >>u (log2(c)+y) iff c is power of 2
|
||||
if (N1.getOpcode() == ISD::SHL) {
|
||||
if (ConstantSDNode *SHC = dyn_cast<ConstantSDNode>(N1.getOperand(0))) {
|
||||
@ -1607,7 +1613,7 @@ SDValue DAGCombiner::visitMULHS(SDNode *N) {
|
||||
if (N1C && N1C->getAPIntValue() == 1)
|
||||
return DAG.getNode(ISD::SRA, N->getDebugLoc(), N0.getValueType(), N0,
|
||||
DAG.getConstant(N0.getValueType().getSizeInBits() - 1,
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
// fold (mulhs x, undef) -> 0
|
||||
if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
|
||||
return DAG.getConstant(0, VT);
|
||||
@ -2613,7 +2619,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) {
|
||||
TLI.isOperationLegalOrCustom(ISD::TRUNCATE, VT) &&
|
||||
TLI.isTruncateFree(VT, TruncVT)) {
|
||||
|
||||
SDValue Amt = DAG.getConstant(ShiftAmt, TLI.getShiftAmountTy());
|
||||
SDValue Amt = DAG.getConstant(ShiftAmt, getShiftAmountTy());
|
||||
SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT,
|
||||
N0.getOperand(0), Amt);
|
||||
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), TruncVT,
|
||||
@ -2740,7 +2746,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
|
||||
|
||||
if (ShAmt) {
|
||||
Op = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT, Op,
|
||||
DAG.getConstant(ShAmt, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(ShAmt, getShiftAmountTy()));
|
||||
AddToWorkList(Op.getNode());
|
||||
}
|
||||
|
||||
@ -5722,7 +5728,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
|
||||
if (N2C && ((N2C->getAPIntValue() & (N2C->getAPIntValue()-1)) == 0)) {
|
||||
unsigned ShCtV = N2C->getAPIntValue().logBase2();
|
||||
ShCtV = XType.getSizeInBits()-ShCtV-1;
|
||||
SDValue ShCt = DAG.getConstant(ShCtV, TLI.getShiftAmountTy());
|
||||
SDValue ShCt = DAG.getConstant(ShCtV, getShiftAmountTy());
|
||||
SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(),
|
||||
XType, N0, ShCt);
|
||||
AddToWorkList(Shift.getNode());
|
||||
@ -5738,7 +5744,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
|
||||
SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(),
|
||||
XType, N0,
|
||||
DAG.getConstant(XType.getSizeInBits()-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
AddToWorkList(Shift.getNode());
|
||||
|
||||
if (XType.bitsGT(AType)) {
|
||||
@ -5787,7 +5793,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
|
||||
// shl setcc result by log2 n2c
|
||||
return DAG.getNode(ISD::SHL, DL, N2.getValueType(), Temp,
|
||||
DAG.getConstant(N2C->getAPIntValue().logBase2(),
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
}
|
||||
|
||||
// Check to see if this is the equivalent of setcc
|
||||
@ -5810,7 +5816,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
|
||||
SDValue Ctlz = DAG.getNode(ISD::CTLZ, N0.getDebugLoc(), XType, N0);
|
||||
return DAG.getNode(ISD::SRL, DL, XType, Ctlz,
|
||||
DAG.getConstant(Log2_32(XType.getSizeInBits()),
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
}
|
||||
// fold (setgt X, 0) -> (srl (and (-X, ~X), size(X)-1))
|
||||
if (N1C && N1C->isNullValue() && CC == ISD::SETGT) {
|
||||
@ -5820,13 +5826,13 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
|
||||
return DAG.getNode(ISD::SRL, DL, XType,
|
||||
DAG.getNode(ISD::AND, XType, NegN0, NotN0),
|
||||
DAG.getConstant(XType.getSizeInBits()-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
}
|
||||
// fold (setgt X, -1) -> (xor (srl (X, size(X)-1), 1))
|
||||
if (N1C && N1C->isAllOnesValue() && CC == ISD::SETGT) {
|
||||
SDValue Sign = DAG.getNode(ISD::SRL, N0.getDebugLoc(), XType, N0,
|
||||
DAG.getConstant(XType.getSizeInBits()-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
return DAG.getNode(ISD::XOR, DL, XType, Sign, DAG.getConstant(1, XType));
|
||||
}
|
||||
}
|
||||
@ -5839,7 +5845,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
|
||||
MVT XType = N0.getValueType();
|
||||
SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0,
|
||||
DAG.getConstant(XType.getSizeInBits()-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
SDValue Add = DAG.getNode(ISD::ADD, N0.getDebugLoc(), XType,
|
||||
N0, Shift);
|
||||
AddToWorkList(Shift.getNode());
|
||||
@ -5856,7 +5862,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
|
||||
SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType,
|
||||
N0,
|
||||
DAG.getConstant(XType.getSizeInBits()-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
getShiftAmountTy()));
|
||||
SDValue Add = DAG.getNode(ISD::ADD, N0.getDebugLoc(),
|
||||
XType, N0, Shift);
|
||||
AddToWorkList(Shift.getNode());
|
||||
|
@ -301,9 +301,6 @@ private:
|
||||
|
||||
SDValue ExpandEXTRACT_SUBVECTOR(SDValue Op);
|
||||
SDValue ExpandEXTRACT_VECTOR_ELT(SDValue Op);
|
||||
|
||||
// Returns the legalized (truncated or extended) shift amount.
|
||||
SDValue LegalizeShiftAmount(SDValue ShiftAmt);
|
||||
};
|
||||
}
|
||||
|
||||
@ -903,8 +900,10 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) {
|
||||
case ISD::SHL:
|
||||
case ISD::SRA:
|
||||
case ISD::SRL:
|
||||
case ISD::ROTL:
|
||||
case ISD::ROTR:
|
||||
Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT, Operands[0],
|
||||
LegalizeShiftAmount(Operands[1])));
|
||||
DAG.getShiftAmountOperand(Operands[1])));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -969,16 +968,6 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx) {
|
||||
PseudoSourceValue::getFixedStack(SPFI), 0);
|
||||
}
|
||||
|
||||
SDValue SelectionDAGLegalize::LegalizeShiftAmount(SDValue ShiftAmt) {
|
||||
if (TLI.getShiftAmountTy().bitsLT(ShiftAmt.getValueType()))
|
||||
return DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), ShiftAmt);
|
||||
|
||||
if (TLI.getShiftAmountTy().bitsGT(ShiftAmt.getValueType()))
|
||||
return DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), ShiftAmt);
|
||||
|
||||
return ShiftAmt;
|
||||
}
|
||||
|
||||
|
||||
/// LegalizeOp - We know that the specified value has a legal type, and
|
||||
/// that its operands are legal. Now ensure that the operation itself
|
||||
@ -3137,10 +3126,13 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
|
||||
case ISD::SRL_PARTS: {
|
||||
SmallVector<SDValue, 8> Ops;
|
||||
bool Changed = false;
|
||||
for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
|
||||
unsigned N = Node->getNumOperands();
|
||||
for (unsigned i = 0; i + 1 < N; ++i) {
|
||||
Ops.push_back(LegalizeOp(Node->getOperand(i)));
|
||||
Changed |= Ops.back() != Node->getOperand(i);
|
||||
}
|
||||
Ops.push_back(LegalizeOp(DAG.getShiftAmountOperand(Node->getOperand(N-1))));
|
||||
Changed |= Ops.back() != Node->getOperand(N-1);
|
||||
if (Changed)
|
||||
Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size());
|
||||
|
||||
@ -3191,21 +3183,22 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
|
||||
case ISD::FDIV:
|
||||
case ISD::FPOW:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
|
||||
switch (getTypeAction(Node->getOperand(1).getValueType())) {
|
||||
case Expand: assert(0 && "Not possible");
|
||||
case Legal:
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS.
|
||||
break;
|
||||
case Promote:
|
||||
Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the RHS.
|
||||
break;
|
||||
}
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS
|
||||
|
||||
if ((Node->getOpcode() == ISD::SHL ||
|
||||
Node->getOpcode() == ISD::SRL ||
|
||||
Node->getOpcode() == ISD::SRA) &&
|
||||
!Node->getValueType(0).isVector()) {
|
||||
Tmp2 = LegalizeShiftAmount(Tmp2);
|
||||
!Node->getValueType(0).isVector())
|
||||
Tmp2 = DAG.getShiftAmountOperand(Tmp2);
|
||||
|
||||
switch (getTypeAction(Tmp2.getValueType())) {
|
||||
case Expand: assert(0 && "Not possible");
|
||||
case Legal:
|
||||
Tmp2 = LegalizeOp(Tmp2); // Legalize the RHS.
|
||||
break;
|
||||
case Promote:
|
||||
Tmp2 = PromoteOp(Tmp2); // Promote the RHS.
|
||||
break;
|
||||
}
|
||||
|
||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
|
||||
@ -3673,7 +3666,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
|
||||
case ISD::ROTL:
|
||||
case ISD::ROTR:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS
|
||||
Tmp2 = LegalizeOp(DAG.getShiftAmountOperand(Node->getOperand(1))); // RHS
|
||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
|
||||
switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
|
||||
default:
|
||||
|
@ -230,7 +230,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
|
||||
|
||||
unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits();
|
||||
return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op),
|
||||
DAG.getConstant(DiffBits, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(DiffBits, TLI.getPointerTy()));
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) {
|
||||
@ -327,7 +327,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
|
||||
// Extract the element at OldIdx / 2 from the new vector.
|
||||
SDValue OldIdx = N->getOperand(1);
|
||||
SDValue NewIdx = DAG.getNode(ISD::SRL, dl, OldIdx.getValueType(), OldIdx,
|
||||
DAG.getConstant(1, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(1, TLI.getPointerTy()));
|
||||
SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, NewIdx);
|
||||
|
||||
// Select the appropriate half of the element: Lo if OldIdx was even,
|
||||
@ -335,7 +335,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
|
||||
SDValue Lo = Elt;
|
||||
SDValue Hi = DAG.getNode(ISD::SRL, dl, NewVT, Elt,
|
||||
DAG.getConstant(OldVT.getSizeInBits(),
|
||||
TLI.getShiftAmountTy()));
|
||||
TLI.getPointerTy()));
|
||||
if (TLI.isBigEndian())
|
||||
std::swap(Lo, Hi);
|
||||
|
||||
@ -621,7 +621,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
|
||||
// Shift it to the right position and "or" it in.
|
||||
Part = DAG.getNode(ISD::SHL, dl, NVT, Part,
|
||||
DAG.getConstant(i * RegVT.getSizeInBits(),
|
||||
TLI.getShiftAmountTy()));
|
||||
TLI.getPointerTy()));
|
||||
Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part);
|
||||
}
|
||||
|
||||
@ -768,8 +768,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
|
||||
Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi,
|
||||
DAG.getConstant(OVT.getSizeInBits(),
|
||||
TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(OVT.getSizeInBits(), TLI.getPointerTy()));
|
||||
return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi);
|
||||
}
|
||||
|
||||
@ -1329,7 +1328,7 @@ void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N,
|
||||
Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT));
|
||||
// The high part replicates the sign bit of Lo, make it explicit.
|
||||
Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
|
||||
DAG.getConstant(NVTBits-1, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(NVTBits-1, TLI.getPointerTy()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1473,7 +1472,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
|
||||
// lo part.
|
||||
unsigned LoSize = Lo.getValueType().getSizeInBits();
|
||||
Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
|
||||
DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(LoSize-1, TLI.getPointerTy()));
|
||||
} else if (ExtType == ISD::ZEXTLOAD) {
|
||||
// The high part is just a zero.
|
||||
Hi = DAG.getConstant(0, NVT);
|
||||
@ -1535,12 +1534,12 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
|
||||
Lo = DAG.getNode(ISD::OR, dl, NVT, Lo,
|
||||
DAG.getNode(ISD::SHL, dl, NVT, Hi,
|
||||
DAG.getConstant(ExcessBits,
|
||||
TLI.getShiftAmountTy())));
|
||||
TLI.getPointerTy())));
|
||||
// Move high bits to the right position in Hi.
|
||||
Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl,
|
||||
NVT, Hi,
|
||||
DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
|
||||
TLI.getShiftAmountTy()));
|
||||
TLI.getPointerTy()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1762,7 +1761,7 @@ void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
|
||||
// The high part is obtained by SRA'ing all but one of the bits of low part.
|
||||
unsigned LoSize = NVT.getSizeInBits();
|
||||
Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
|
||||
DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(LoSize-1, TLI.getPointerTy()));
|
||||
} else {
|
||||
// For example, extension of an i48 to an i64. The operand type necessarily
|
||||
// promotes to the result type, so will end up being expanded too.
|
||||
@ -1795,7 +1794,7 @@ ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
|
||||
// things like sextinreg V:i64 from i8.
|
||||
Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo,
|
||||
DAG.getConstant(Hi.getValueType().getSizeInBits()-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
TLI.getPointerTy()));
|
||||
} else {
|
||||
// For example, extension of an i48 to an i64. Leave the low part alone,
|
||||
// sext_inreg the high part.
|
||||
@ -1831,8 +1830,7 @@ void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
|
||||
Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0));
|
||||
Hi = DAG.getNode(ISD::SRL, dl,
|
||||
N->getOperand(0).getValueType(), N->getOperand(0),
|
||||
DAG.getConstant(NVT.getSizeInBits(),
|
||||
TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(NVT.getSizeInBits(), TLI.getPointerTy()));
|
||||
Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi);
|
||||
}
|
||||
|
||||
@ -1922,20 +1920,18 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
|
||||
assert(0 && "Do not know how to expand this operator's operand!");
|
||||
abort();
|
||||
|
||||
case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
|
||||
case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break;
|
||||
case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
|
||||
case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
|
||||
case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
|
||||
case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
|
||||
case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
|
||||
|
||||
case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
|
||||
case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
|
||||
case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
|
||||
case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break;
|
||||
case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo);
|
||||
break;
|
||||
case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
|
||||
case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break;
|
||||
case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
|
||||
case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
|
||||
case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break;
|
||||
case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
|
||||
case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
|
||||
case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break;
|
||||
}
|
||||
|
||||
// If the result is null, the sub-method took care of registering results etc.
|
||||
@ -2175,11 +2171,11 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
|
||||
// Transfer high bits from the top of Lo to the bottom of Hi.
|
||||
Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi,
|
||||
DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
|
||||
TLI.getShiftAmountTy()));
|
||||
TLI.getPointerTy()));
|
||||
Hi = DAG.getNode(ISD::OR, dl, NVT, Hi,
|
||||
DAG.getNode(ISD::SRL, NVT, Lo,
|
||||
DAG.getConstant(ExcessBits,
|
||||
TLI.getShiftAmountTy())));
|
||||
TLI.getPointerTy())));
|
||||
}
|
||||
|
||||
// Store both the high bits and maybe some of the low bits.
|
||||
|
@ -942,8 +942,8 @@ SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) {
|
||||
|
||||
Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, Lo);
|
||||
Hi = DAG.getNode(ISD::ANY_EXTEND, NVT, Hi);
|
||||
Hi = DAG.getNode(ISD::SHL, NVT, Hi, DAG.getConstant(LVT.getSizeInBits(),
|
||||
TLI.getShiftAmountTy()));
|
||||
Hi = DAG.getNode(ISD::SHL, NVT, Hi,
|
||||
DAG.getConstant(LVT.getSizeInBits(), TLI.getPointerTy()));
|
||||
return DAG.getNode(ISD::OR, NVT, Lo, Hi);
|
||||
}
|
||||
|
||||
@ -1028,8 +1028,7 @@ void DAGTypeLegalizer::SplitInteger(SDValue Op,
|
||||
Op.getValueType().getSizeInBits() && "Invalid integer splitting!");
|
||||
Lo = DAG.getNode(ISD::TRUNCATE, LoVT, Op);
|
||||
Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op,
|
||||
DAG.getConstant(LoVT.getSizeInBits(),
|
||||
TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(LoVT.getSizeInBits(), TLI.getPointerTy()));
|
||||
Hi = DAG.getNode(ISD::TRUNCATE, HiVT, Hi);
|
||||
}
|
||||
|
||||
|
@ -111,11 +111,6 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) {
|
||||
SDValue DAGTypeLegalizer::ScalarizeVecRes_ShiftOp(SDNode *N) {
|
||||
SDValue LHS = GetScalarizedVector(N->getOperand(0));
|
||||
SDValue ShiftAmt = GetScalarizedVector(N->getOperand(1));
|
||||
if (TLI.getShiftAmountTy().bitsLT(ShiftAmt.getValueType()))
|
||||
ShiftAmt = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), ShiftAmt);
|
||||
else if (TLI.getShiftAmountTy().bitsGT(ShiftAmt.getValueType()))
|
||||
ShiftAmt = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), ShiftAmt);
|
||||
|
||||
return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, ShiftAmt);
|
||||
}
|
||||
|
||||
|
@ -1287,6 +1287,17 @@ SDValue SelectionDAG::getMemOperand(const MachineMemOperand &MO) {
|
||||
return SDValue(N, 0);
|
||||
}
|
||||
|
||||
/// getShiftAmountOperand - Return the specified value casted to
|
||||
/// the target's desired shift amount type.
|
||||
SDValue SelectionDAG::getShiftAmountOperand(SDValue Op) {
|
||||
MVT OpTy = Op.getValueType();
|
||||
MVT ShTy = TLI.getShiftAmountTy();
|
||||
if (OpTy == ShTy || OpTy.isVector()) return Op;
|
||||
|
||||
ISD::NodeType Opcode = OpTy.bitsGT(ShTy) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
|
||||
return getNode(Opcode, ShTy, Op);
|
||||
}
|
||||
|
||||
/// CreateStackTemporary - Create a stack temporary, suitable for holding the
|
||||
/// specified value type.
|
||||
SDValue SelectionDAG::CreateStackTemporary(MVT VT, unsigned minAlign) {
|
||||
@ -2529,9 +2540,6 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
|
||||
"Shift operators return type must be the same as their first arg");
|
||||
assert(VT.isInteger() && N2.getValueType().isInteger() &&
|
||||
"Shifts only work on integers");
|
||||
assert((N2.getValueType() == TLI.getShiftAmountTy() ||
|
||||
(N2.getValueType().isVector() && N2.getValueType().isInteger())) &&
|
||||
"Wrong type for shift amount");
|
||||
|
||||
// Always fold shifts of i1 values so the code generator doesn't need to
|
||||
// handle them. Since we know the size of the shift has to be less than the
|
||||
|
@ -427,7 +427,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl,
|
||||
Hi = DAG.getNode(ISD::ANY_EXTEND, dl, TotalVT, Hi);
|
||||
Hi = DAG.getNode(ISD::SHL, dl, TotalVT, Hi,
|
||||
DAG.getConstant(Lo.getValueType().getSizeInBits(),
|
||||
TLI.getShiftAmountTy()));
|
||||
TLI.getPointerTy()));
|
||||
Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, TotalVT, Lo);
|
||||
Val = DAG.getNode(ISD::OR, dl, TotalVT, Lo, Hi);
|
||||
}
|
||||
@ -587,7 +587,7 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, SDValue Val,
|
||||
unsigned OddParts = NumParts - RoundParts;
|
||||
SDValue OddVal = DAG.getNode(ISD::SRL, dl, ValueVT, Val,
|
||||
DAG.getConstant(RoundBits,
|
||||
TLI.getShiftAmountTy()));
|
||||
TLI.getPointerTy()));
|
||||
getCopyToParts(DAG, dl, OddVal, Parts + RoundParts, OddParts, PartVT);
|
||||
if (TLI.isBigEndian())
|
||||
// The odd parts were reversed by getCopyToParts - unreverse them.
|
||||
@ -1424,14 +1424,14 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) {
|
||||
ISD::SETUGT);
|
||||
|
||||
SDValue ShiftOp;
|
||||
if (VT.bitsGT(TLI.getShiftAmountTy()))
|
||||
if (VT.bitsGT(TLI.getPointerTy()))
|
||||
ShiftOp = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(),
|
||||
TLI.getShiftAmountTy(), SUB);
|
||||
TLI.getPointerTy(), SUB);
|
||||
else
|
||||
ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(),
|
||||
TLI.getShiftAmountTy(), SUB);
|
||||
TLI.getPointerTy(), SUB);
|
||||
|
||||
B.Reg = FuncInfo.MakeReg(TLI.getShiftAmountTy());
|
||||
B.Reg = FuncInfo.MakeReg(TLI.getPointerTy());
|
||||
SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), B.Reg, ShiftOp);
|
||||
|
||||
// Set NextBlock to be the MBB immediately after the current one, if any.
|
||||
@ -1463,7 +1463,7 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
|
||||
BitTestCase &B) {
|
||||
// Make desired shift
|
||||
SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), Reg,
|
||||
TLI.getShiftAmountTy());
|
||||
TLI.getPointerTy());
|
||||
SDValue SwitchVal = DAG.getNode(ISD::SHL, getCurDebugLoc(),
|
||||
TLI.getPointerTy(),
|
||||
DAG.getConstant(1, TLI.getPointerTy()),
|
||||
@ -2121,12 +2121,12 @@ void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
|
||||
SDValue Op1 = getValue(I.getOperand(0));
|
||||
SDValue Op2 = getValue(I.getOperand(1));
|
||||
if (!isa<VectorType>(I.getType())) {
|
||||
if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType()))
|
||||
if (TLI.getPointerTy().bitsLT(Op2.getValueType()))
|
||||
Op2 = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(),
|
||||
TLI.getShiftAmountTy(), Op2);
|
||||
else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType()))
|
||||
TLI.getPointerTy(), Op2);
|
||||
else if (TLI.getPointerTy().bitsGT(Op2.getValueType()))
|
||||
Op2 = DAG.getNode(ISD::ANY_EXTEND, getCurDebugLoc(),
|
||||
TLI.getShiftAmountTy(), Op2);
|
||||
TLI.getPointerTy(), Op2);
|
||||
}
|
||||
|
||||
setValue(&I, DAG.getNode(Opcode, getCurDebugLoc(),
|
||||
@ -2673,7 +2673,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) {
|
||||
unsigned Amt = Log2_64(ElementSize);
|
||||
IdxN = DAG.getNode(ISD::SHL, getCurDebugLoc(),
|
||||
N.getValueType(), IdxN,
|
||||
DAG.getConstant(Amt, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(Amt, TLI.getPointerTy()));
|
||||
} else {
|
||||
SDValue Scale = DAG.getIntPtrConstant(ElementSize);
|
||||
IdxN = DAG.getNode(ISD::MUL, getCurDebugLoc(),
|
||||
@ -3023,7 +3023,7 @@ GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI,
|
||||
SDValue t0 = DAG.getNode(ISD::AND, dl, MVT::i32, Op,
|
||||
DAG.getConstant(0x7f800000, MVT::i32));
|
||||
SDValue t1 = DAG.getNode(ISD::SRL, dl, MVT::i32, t0,
|
||||
DAG.getConstant(23, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(23, TLI.getPointerTy()));
|
||||
SDValue t2 = DAG.getNode(ISD::SUB, dl, MVT::i32, t1,
|
||||
DAG.getConstant(127, MVT::i32));
|
||||
return DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2);
|
||||
@ -3095,7 +3095,7 @@ SelectionDAGLowering::visitExp(CallInst &I) {
|
||||
|
||||
// IntegerPartOfX <<= 23;
|
||||
IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
|
||||
DAG.getConstant(23, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(23, TLI.getPointerTy()));
|
||||
|
||||
if (LimitFloatPrecision <= 6) {
|
||||
// For floating-point precision of 6:
|
||||
@ -3535,7 +3535,7 @@ SelectionDAGLowering::visitExp2(CallInst &I) {
|
||||
|
||||
// IntegerPartOfX <<= 23;
|
||||
IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
|
||||
DAG.getConstant(23, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(23, TLI.getPointerTy()));
|
||||
|
||||
if (LimitFloatPrecision <= 6) {
|
||||
// For floating-point precision of 6:
|
||||
@ -3668,7 +3668,7 @@ SelectionDAGLowering::visitPow(CallInst &I) {
|
||||
|
||||
// IntegerPartOfX <<= 23;
|
||||
IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
|
||||
DAG.getConstant(23, TLI.getShiftAmountTy()));
|
||||
DAG.getConstant(23, TLI.getPointerTy()));
|
||||
|
||||
if (LimitFloatPrecision <= 6) {
|
||||
// For floating-point precision of 6:
|
||||
|
@ -1651,19 +1651,21 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
|
||||
VT == N0.getValueType() && N0.getOpcode() == ISD::AND)
|
||||
if (ConstantSDNode *AndRHS =
|
||||
dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
|
||||
MVT ShiftTy = DCI.isBeforeLegalize() ?
|
||||
getPointerTy() : getShiftAmountTy();
|
||||
if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0 --> (X & 8) >> 3
|
||||
// Perform the xform if the AND RHS is a single bit.
|
||||
if (isPowerOf2_64(AndRHS->getZExtValue())) {
|
||||
return DAG.getNode(ISD::SRL, VT, N0,
|
||||
DAG.getConstant(Log2_64(AndRHS->getZExtValue()),
|
||||
getShiftAmountTy()));
|
||||
DAG.getConstant(Log2_64(AndRHS->getZExtValue()),
|
||||
ShiftTy));
|
||||
}
|
||||
} else if (Cond == ISD::SETEQ && C1 == AndRHS->getZExtValue()) {
|
||||
// (X & 8) == 8 --> (X & 8) >> 3
|
||||
// Perform the xform if C1 is a single bit.
|
||||
if (C1.isPowerOf2()) {
|
||||
return DAG.getNode(ISD::SRL, VT, N0,
|
||||
DAG.getConstant(C1.logBase2(), getShiftAmountTy()));
|
||||
DAG.getConstant(C1.logBase2(), ShiftTy));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
test/CodeGen/X86/2009-01-31-BigShift.ll
Normal file
9
test/CodeGen/X86/2009-01-31-BigShift.ll
Normal file
@ -0,0 +1,9 @@
|
||||
; RUN: llvm-as < %s | llc -march=x86 | not grep and
|
||||
; PR3401
|
||||
|
||||
define void @x(i288 %i) nounwind {
|
||||
call void @add(i288 %i)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @add(i288)
|
11
test/CodeGen/X86/2009-01-31-BigShift2.ll
Normal file
11
test/CodeGen/X86/2009-01-31-BigShift2.ll
Normal file
@ -0,0 +1,11 @@
|
||||
; RUN: llvm-as < %s | llc -march=x86 | grep {mov.*56}
|
||||
; PR3449
|
||||
|
||||
define void @test(<8 x double>* %P, i64* %Q) nounwind {
|
||||
%A = load <8 x double>* %P ; <<8 x double>> [#uses=1]
|
||||
%B = bitcast <8 x double> %A to i512 ; <i512> [#uses=1]
|
||||
%C = lshr i512 %B, 448 ; <i512> [#uses=1]
|
||||
%D = trunc i512 %C to i64 ; <i64> [#uses=1]
|
||||
volatile store i64 %D, i64* %Q
|
||||
ret void
|
||||
}
|
31
test/CodeGen/X86/2009-01-31-BigShift3.ll
Normal file
31
test/CodeGen/X86/2009-01-31-BigShift3.ll
Normal file
@ -0,0 +1,31 @@
|
||||
; RUN: llvm-as < %s | llc -march=x86
|
||||
; PR3450
|
||||
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i386-apple-darwin7"
|
||||
%struct.BitMap = type { i8* }
|
||||
%struct.BitMapListStruct = type { %struct.BitMap, %struct.BitMapListStruct*, %struct.BitMapListStruct* }
|
||||
%struct.Material = type { float, float, float, %struct.Material*, %struct.Material* }
|
||||
%struct.ObjPoint = type { double, double, double, double, double, double }
|
||||
%struct.ObjectStruct = type { [57 x i8], %struct.PointListStruct*, %struct.Poly3Struct*, %struct.Poly4Struct*, %struct.Texture*, %struct.Material*, %struct.Point, i32, i32, %struct.Point, %struct.Point, %struct.Point, %struct.ObjectStruct*, %struct.ObjectStruct*, i32, i32, i32, i32, i32, i32, i32, %struct.ObjectStruct*, %struct.ObjectStruct* }
|
||||
%struct.Point = type { double, double, double }
|
||||
%struct.PointListStruct = type { %struct.ObjPoint*, %struct.PointListStruct*, %struct.PointListStruct* }
|
||||
%struct.Poly3Struct = type { [3 x %struct.ObjPoint*], %struct.Material*, %struct.Texture*, %struct.Poly3Struct*, %struct.Poly3Struct* }
|
||||
%struct.Poly4Struct = type { [4 x %struct.ObjPoint*], %struct.Material*, %struct.Texture*, %struct.Poly4Struct*, %struct.Poly4Struct* }
|
||||
%struct.Texture = type { %struct.Point, %struct.BitMapListStruct*, %struct.Point, %struct.Point, %struct.Point, %struct.Texture*, %struct.Texture* }
|
||||
|
||||
define fastcc void @ScaleObjectAdd(%struct.ObjectStruct* %o, double %sx, double %sy, double %sz) nounwind {
|
||||
entry:
|
||||
%sz101112.ins = or i960 0, 0 ; <i960> [#uses=1]
|
||||
br i1 false, label %return, label %bb1.preheader
|
||||
|
||||
bb1.preheader: ; preds = %entry
|
||||
%0 = lshr i960 %sz101112.ins, 640 ; <i960> [#uses=0]
|
||||
br label %bb1
|
||||
|
||||
bb1: ; preds = %bb1, %bb1.preheader
|
||||
br label %bb1
|
||||
|
||||
return: ; preds = %entry
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user