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:
Duncan Sands 2009-01-31 15:50:11 +00:00
parent d1b5e3fad9
commit 92abc62399
12 changed files with 156 additions and 102 deletions

View File

@ -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

View File

@ -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());

View File

@ -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:

View File

@ -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.

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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:

View File

@ -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));
}
}
}

View 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)

View 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
}

View 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
}