#include "LegalizeTypes.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
cerr << "PromoteIntegerResult #" << ResNo << ": ";
N->dump(&DAG); cerr << "\n";
#endif
- assert(0 && "Do not know how to promote this operator!");
- abort();
+ LLVM_UNREACHABLE("Do not know how to promote this operator!");
case ISD::AssertSext: Res = PromoteIntRes_AssertSext(N); break;
case ISD::AssertZext: Res = PromoteIntRes_AssertZext(N); break;
case ISD::BIT_CONVERT: Res = PromoteIntRes_BIT_CONVERT(N); break;
case ISD::USUBO: Res = PromoteIntRes_UADDSUBO(N, ResNo); break;
case ISD::SMULO:
case ISD::UMULO: Res = PromoteIntRes_XMULO(N, ResNo); break;
- case ISD::ADDC:
- case ISD::SUBC: Res = PromoteIntRes_ADDSUBC(N, ResNo); break;
- case ISD::ADDE:
- case ISD::SUBE: Res = PromoteIntRes_ADDSUBE(N, ResNo); break;
case ISD::ATOMIC_LOAD_ADD:
case ISD::ATOMIC_LOAD_SUB:
SetPromotedInteger(SDValue(N, ResNo), Res);
}
-SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBC(SDNode *N, unsigned ResNo) {
- // Only the carry bit result is expected to be promoted.
- assert(ResNo == 1 && "Only carry bit result promotion currently supported!");
- return PromoteIntRes_Overflow(N);
-}
-
-SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBE(SDNode *N, unsigned ResNo) {
- // Only the carry bit result is expected to be promoted.
- assert(ResNo == 1 && "Only carry bit result promotion currently supported!");
- // This is a ternary operator, so clone a slightly modified
- // PromoteIntRes_Overflow here (this is the only client).
- if (ResNo == 1) {
- // Simply change the return type of the boolean result.
- MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
- MVT ValueVTs[] = { N->getValueType(0), NVT };
- SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) };
- SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(),
- DAG.getVTList(ValueVTs, 2), Ops, 3);
-
- // Modified the sum result - switch anything that used the old sum to use
- // the new one.
- ReplaceValueWith(SDValue(N, 0), Res);
-
- return SDValue(Res.getNode(), 1);
- }
- assert(0 && "Do not know how to promote this operator!");
- abort();
-}
-
SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
// Sign-extend the new bits, and continue the assertion.
SDValue Op = SExtPromotedInteger(N->getOperand(0));
return DAG.getNode(ISD::BIT_CONVERT, dl, OutVT, GetWidenedVector(InOp));
}
- // Otherwise, lower the bit-convert to a store/load from the stack.
- // Create the stack frame object. Make sure it is aligned for both
- // the source and destination types.
- SDValue FIPtr = DAG.CreateStackTemporary(InVT, OutVT);
- int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();
- const Value *SV = PseudoSourceValue::getFixedStack(FI);
-
- // Emit a store to the stack slot.
- SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0);
-
- // Result is an extending load from the stack slot.
- return DAG.getExtLoad(ISD::EXTLOAD, dl, NOutVT, Store, FIPtr, SV, 0, OutVT);
+ return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
+ CreateStackStoreLoad(InOp, OutVT));
}
SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
}
SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
- MVT OldVT = N->getValueType(0);
- SDValue OldVec = N->getOperand(0);
- if (getTypeAction(OldVec.getValueType()) == WidenVector)
- OldVec = GetWidenedVector(N->getOperand(0));
- unsigned OldElts = OldVec.getValueType().getVectorNumElements();
DebugLoc dl = N->getDebugLoc();
-
- if (OldElts == 1) {
- assert(!isTypeLegal(OldVec.getValueType()) &&
- "Legal one-element vector of a type needing promotion!");
- // It is tempting to follow GetScalarizedVector by a call to
- // GetPromotedInteger, but this would be wrong because the
- // scalarized value may not yet have been processed.
- return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT),
- GetScalarizedVector(OldVec));
- }
-
- // Convert to a vector half as long with an element type of twice the width,
- // for example <4 x i16> -> <2 x i32>.
- assert(!(OldElts & 1) && "Odd length vectors not supported!");
- MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
- assert(OldVT.isSimple() && NewVT.isSimple());
-
- SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl,
- MVT::getVectorVT(NewVT, OldElts / 2),
- OldVec);
-
- // 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.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,
- // Hi if it was odd.
- SDValue Lo = Elt;
- SDValue Hi = DAG.getNode(ISD::SRL, dl, NewVT, Elt,
- DAG.getConstant(OldVT.getSizeInBits(),
- TLI.getPointerTy()));
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
-
- // Extend to the promoted type.
- SDValue Odd = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, OldIdx);
- SDValue Res = DAG.getNode(ISD::SELECT, dl, NewVT, Odd, Hi, Lo);
- return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT), Res);
+ MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NVT, N->getOperand(0),
+ N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
unsigned NewOpc = N->getOpcode();
DebugLoc dl = N->getDebugLoc();
- // If we're promoting a UINT to a larger size, check to see if the new node
- // will be legal. If it isn't, check to see if FP_TO_SINT is legal, since
- // we can use that instead. This allows us to generate better code for
- // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not
- // legal, such as PowerPC.
+ // If we're promoting a UINT to a larger size and the larger FP_TO_UINT is
+ // not Legal, check to see if we can use FP_TO_SINT instead. (If both UINT
+ // and SINT conversions are Custom, there is no way to tell which is preferable.
+ // We choose SINT because that's the right thing on PPC.)
if (N->getOpcode() == ISD::FP_TO_UINT &&
- !TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NVT) &&
+ !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT))
NewOpc = ISD::FP_TO_SINT;
return Res;
}
-/// Promote the overflow or carry result of an overflowing arithmetic node.
+/// Promote the overflow flag of an overflowing arithmetic node.
SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
// Simply change the return type of the boolean result.
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
cerr << "PromoteIntegerOperand Op #" << OpNo << ": ";
N->dump(&DAG); cerr << "\n";
#endif
- assert(0 && "Do not know how to promote this operator's operand!");
- abort();
+ LLVM_UNREACHABLE("Do not know how to promote this operator's operand!");
- case ISD::ADDE:
- case ISD::SUBE: Res = PromoteIntOp_ADDSUBE(N, OpNo); break;
case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break;
case ISD::BIT_CONVERT: Res = PromoteIntOp_BIT_CONVERT(N); break;
case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break;
}
}
-SDValue DAGTypeLegalizer::PromoteIntOp_ADDSUBE(SDNode *N, unsigned OpNo) {
- assert(OpNo == 2 && "Don't know how to promote this operand!");
- return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
- N->getOperand(1),
- GetPromotedInteger(N->getOperand(2)));
-}
-
SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
SDValue Op = GetPromotedInteger(N->getOperand(0));
return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op);
cerr << "ExpandIntegerResult #" << ResNo << ": ";
N->dump(&DAG); cerr << "\n";
#endif
- assert(0 && "Do not know how to expand the result of this operator!");
- abort();
+ LLVM_UNREACHABLE("Do not know how to expand the result of this operator!");
case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
TLI.isOperationLegalOrCustom(ISD::ADDC,
TLI.getTypeToExpandTo(NVT))) {
// Emit this X << 1 as X+X.
- SDVTList VTList = DAG.getVTList(NVT, MVT::i1);
+ SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
SDValue LoOps[2] = { InL, InL };
Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
SDValue HiOps[3] = { InH, InH, Lo.getValue(1) };
TLI.getTypeToExpandTo(NVT));
if (hasCarry) {
- SDVTList VTList = DAG.getVTList(NVT, MVT::i1);
+ SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
if (N->getOpcode() == ISD::ADD) {
Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
DebugLoc dl = N->getDebugLoc();
GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
- SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1);
+ SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
SDValue LoOps[2] = { LHSL, RHSL };
SDValue HiOps[3] = { LHSH, RHSH };
Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
}
- // Legalized the second result (carry bit) - switch anything that used the
- // result to use the new one.
+ // Legalized the flag result - switch anything that used the old flag to
+ // use the new one.
ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
}
DebugLoc dl = N->getDebugLoc();
GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
- SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1);
+ SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
SDValue HiOps[3] = { LHSH, RHSH };
HiOps[2] = Lo.getValue(1);
Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3);
- // Legalized the second result (carry bit) - switch anything that used the
- // result to use the new one.
+ // Legalized the flag result - switch anything that used the old flag to
+ // use the new one.
ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
}
DebugLoc dl = N->getDebugLoc();
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- if (VT == MVT::i32)
+ if (VT == MVT::i16)
+ LC = RTLIB::SDIV_I16;
+ else if (VT == MVT::i32)
LC = RTLIB::SDIV_I32;
else if (VT == MVT::i64)
LC = RTLIB::SDIV_I64;
else if (VT == MVT::i128)
LC = RTLIB::SRA_I128;
}
-
+
if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) {
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned, dl), Lo, Hi);
DebugLoc dl = N->getDebugLoc();
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- if (VT == MVT::i32)
+ if (VT == MVT::i16)
+ LC = RTLIB::SREM_I16;
+ else if (VT == MVT::i32)
LC = RTLIB::SREM_I32;
else if (VT == MVT::i64)
LC = RTLIB::SREM_I64;
DebugLoc dl = N->getDebugLoc();
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- if (VT == MVT::i32)
+ if (VT == MVT::i16)
+ LC = RTLIB::UDIV_I16;
+ else if (VT == MVT::i32)
LC = RTLIB::UDIV_I32;
else if (VT == MVT::i64)
LC = RTLIB::UDIV_I64;
DebugLoc dl = N->getDebugLoc();
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- if (VT == MVT::i32)
+ if (VT == MVT::i16)
+ LC = RTLIB::UREM_I16;
+ else if (VT == MVT::i32)
LC = RTLIB::UREM_I32;
else if (VT == MVT::i64)
LC = RTLIB::UREM_I64;
cerr << "ExpandIntegerOperand Op #" << OpNo << ": ";
N->dump(&DAG); cerr << "\n";
#endif
- assert(0 && "Do not know how to expand this operator's operand!");
- abort();
+ LLVM_UNREACHABLE("Do not know how to expand this operator's operand!");
case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break;
case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;