#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/DwarfWriter.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
class VISIBILITY_HIDDEN SelectionDAGLegalize {
TargetLowering &TLI;
SelectionDAG &DAG;
+ bool TypesNeedLegalizing;
// Libcall insertion helpers.
void AddPromotedOperand(SDValue From, SDValue To) {
bool isNew = PromotedNodes.insert(std::make_pair(From, To)).second;
assert(isNew && "Got into the map somehow?");
+ isNew = isNew;
// If someone requests legalization of the new node, return itself.
LegalizedNodes.insert(std::make_pair(To, To));
}
void AddWidenedOperand(SDValue From, SDValue To) {
bool isNew = WidenNodes.insert(std::make_pair(From, To)).second;
assert(isNew && "Got into the map somehow?");
+ isNew = isNew;
// If someone requests legalization of the new node, return itself.
LegalizedNodes.insert(std::make_pair(To, To));
}
public:
- explicit SelectionDAGLegalize(SelectionDAG &DAG);
+ explicit SelectionDAGLegalize(SelectionDAG &DAG, bool TypesNeedLegalizing);
/// getTypeAction - Return how we should legalize values of this type, either
/// it is already legal or we need to expand it into multiple registers of
SDValue ExpandEXTRACT_SUBVECTOR(SDValue Op);
SDValue ExpandEXTRACT_VECTOR_ELT(SDValue Op);
+
+ // Returns the legalized (truncated or extended) shift amount.
+ SDValue LegalizeShiftAmount(SDValue ShiftAmt);
};
}
return TLI.isShuffleMaskLegal(Mask, VT) ? Mask.getNode() : 0;
}
-SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag)
- : TLI(dag.getTargetLoweringInfo()), DAG(dag),
+SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag, bool types)
+ : TLI(dag.getTargetLoweringInfo()), DAG(dag), TypesNeedLegalizing(types),
ValueTypeActions(TLI.getValueTypeActions()) {
assert(MVT::LAST_VALUETYPE <= 32 &&
"Too many value types for ValueTypeActions to hold!");
/// appropriate for its type.
void SelectionDAGLegalize::HandleOp(SDValue Op) {
MVT VT = Op.getValueType();
+ // If the type legalizer was run then we should never see any illegal result
+ // types here except for target constants (the type legalizer does not touch
+ // those) or for build vector used as a mask for a vector shuffle.
+ // FIXME: We can removed the BUILD_VECTOR case when we fix PR2957.
+ assert((TypesNeedLegalizing || getTypeAction(VT) == Legal ||
+ Op.getOpcode() == ISD::TargetConstant ||
+ Op.getOpcode() == ISD::BUILD_VECTOR) &&
+ "Illegal type introduced after type legalization?");
switch (getTypeAction(VT)) {
default: assert(0 && "Bad type action!");
case Legal: (void)LegalizeOp(Op); break;
/// ExpandConstantFP - Expands the ConstantFP node to an integer constant or
/// a load from the constant pool.
static SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
- SelectionDAG &DAG, TargetLowering &TLI) {
+ SelectionDAG &DAG, const TargetLowering &TLI) {
bool Extend = false;
// If a FP immediate is precise when represented as a float and if the
/// operations.
static
SDValue ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT NVT,
- SelectionDAG &DAG, TargetLowering &TLI) {
+ SelectionDAG &DAG,
+ const TargetLowering &TLI) {
MVT VT = Node->getValueType(0);
MVT SrcVT = Node->getOperand(1).getValueType();
assert((SrcVT == MVT::f32 || SrcVT == MVT::f64) &&
/// ExpandUnalignedStore - Expands an unaligned store to 2 half-size stores.
static
SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
- TargetLowering &TLI) {
+ const TargetLowering &TLI) {
SDValue Chain = ST->getChain();
SDValue Ptr = ST->getBasePtr();
SDValue Val = ST->getValue();
int SVOffset = ST->getSrcValueOffset();
if (ST->getMemoryVT().isFloatingPoint() ||
ST->getMemoryVT().isVector()) {
- // Expand to a bitconvert of the value to the integer type of the
- // same size, then a (misaligned) int store.
- MVT intVT;
- if (VT.is128BitVector() || VT == MVT::ppcf128 || VT == MVT::f128)
- intVT = MVT::i128;
- else if (VT.is64BitVector() || VT==MVT::f64)
- intVT = MVT::i64;
- else if (VT==MVT::f32)
- intVT = MVT::i32;
- else
- assert(0 && "Unaligned store of unsupported type");
+ MVT intVT = MVT::getIntegerVT(VT.getSizeInBits());
+ if (TLI.isTypeLegal(intVT)) {
+ // Expand to a bitconvert of the value to the integer type of the
+ // same size, then a (misaligned) int store.
+ // FIXME: Does not handle truncating floating point stores!
+ SDValue Result = DAG.getNode(ISD::BIT_CONVERT, intVT, Val);
+ return DAG.getStore(Chain, Result, Ptr, ST->getSrcValue(),
+ SVOffset, ST->isVolatile(), Alignment);
+ } else {
+ // Do a (aligned) store to a stack slot, then copy from the stack slot
+ // to the final destination using (unaligned) integer loads and stores.
+ MVT StoredVT = ST->getMemoryVT();
+ MVT RegVT =
+ TLI.getRegisterType(MVT::getIntegerVT(StoredVT.getSizeInBits()));
+ unsigned StoredBytes = StoredVT.getSizeInBits() / 8;
+ unsigned RegBytes = RegVT.getSizeInBits() / 8;
+ unsigned NumRegs = (StoredBytes + RegBytes - 1) / RegBytes;
+
+ // Make sure the stack slot is also aligned for the register type.
+ SDValue StackPtr = DAG.CreateStackTemporary(StoredVT, RegVT);
+
+ // Perform the original store, only redirected to the stack slot.
+ SDValue Store = DAG.getTruncStore(Chain, Val, StackPtr, NULL, 0,StoredVT);
+ SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy());
+ SmallVector<SDValue, 8> Stores;
+ unsigned Offset = 0;
+
+ // Do all but one copies using the full register width.
+ for (unsigned i = 1; i < NumRegs; i++) {
+ // Load one integer register's worth from the stack slot.
+ SDValue Load = DAG.getLoad(RegVT, Store, StackPtr, NULL, 0);
+ // Store it to the final location. Remember the store.
+ Stores.push_back(DAG.getStore(Load.getValue(1), Load, Ptr,
+ ST->getSrcValue(), SVOffset + Offset,
+ ST->isVolatile(),
+ MinAlign(ST->getAlignment(), Offset)));
+ // Increment the pointers.
+ Offset += RegBytes;
+ StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr,
+ Increment);
+ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, Increment);
+ }
- SDValue Result = DAG.getNode(ISD::BIT_CONVERT, intVT, Val);
- return DAG.getStore(Chain, Result, Ptr, ST->getSrcValue(),
- SVOffset, ST->isVolatile(), Alignment);
+ // The last store may be partial. Do a truncating store. On big-endian
+ // machines this requires an extending load from the stack slot to ensure
+ // that the bits are in the right place.
+ MVT MemVT = MVT::getIntegerVT(8 * (StoredBytes - Offset));
+
+ // Load from the stack slot.
+ SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, RegVT, Store, StackPtr,
+ NULL, 0, MemVT);
+
+ Stores.push_back(DAG.getTruncStore(Load.getValue(1), Load, Ptr,
+ ST->getSrcValue(), SVOffset + Offset,
+ MemVT, ST->isVolatile(),
+ MinAlign(ST->getAlignment(), Offset)));
+ // The order of the stores doesn't matter - say it with a TokenFactor.
+ return DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0],
+ Stores.size());
+ }
}
assert(ST->getMemoryVT().isInteger() &&
!ST->getMemoryVT().isVector() &&
/// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads.
static
SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
- TargetLowering &TLI) {
+ const TargetLowering &TLI) {
int SVOffset = LD->getSrcValueOffset();
SDValue Chain = LD->getChain();
SDValue Ptr = LD->getBasePtr();
MVT VT = LD->getValueType(0);
MVT LoadedVT = LD->getMemoryVT();
if (VT.isFloatingPoint() || VT.isVector()) {
- // Expand to a (misaligned) integer load of the same size,
- // then bitconvert to floating point or vector.
- MVT intVT;
- if (LoadedVT.is128BitVector() ||
- LoadedVT == MVT::ppcf128 || LoadedVT == MVT::f128)
- intVT = MVT::i128;
- else if (LoadedVT.is64BitVector() || LoadedVT == MVT::f64)
- intVT = MVT::i64;
- else if (LoadedVT == MVT::f32)
- intVT = MVT::i32;
- else
- assert(0 && "Unaligned load of unsupported type");
-
- SDValue newLoad = DAG.getLoad(intVT, Chain, Ptr, LD->getSrcValue(),
- SVOffset, LD->isVolatile(),
+ MVT intVT = MVT::getIntegerVT(LoadedVT.getSizeInBits());
+ if (TLI.isTypeLegal(intVT)) {
+ // Expand to a (misaligned) integer load of the same size,
+ // then bitconvert to floating point or vector.
+ SDValue newLoad = DAG.getLoad(intVT, Chain, Ptr, LD->getSrcValue(),
+ SVOffset, LD->isVolatile(),
LD->getAlignment());
- SDValue Result = DAG.getNode(ISD::BIT_CONVERT, LoadedVT, newLoad);
- if (VT.isFloatingPoint() && LoadedVT != VT)
- Result = DAG.getNode(ISD::FP_EXTEND, VT, Result);
+ SDValue Result = DAG.getNode(ISD::BIT_CONVERT, LoadedVT, newLoad);
+ if (VT.isFloatingPoint() && LoadedVT != VT)
+ Result = DAG.getNode(ISD::FP_EXTEND, VT, Result);
+
+ SDValue Ops[] = { Result, Chain };
+ return DAG.getMergeValues(Ops, 2);
+ } else {
+ // Copy the value to a (aligned) stack slot using (unaligned) integer
+ // loads and stores, then do a (aligned) load from the stack slot.
+ MVT RegVT = TLI.getRegisterType(intVT);
+ unsigned LoadedBytes = LoadedVT.getSizeInBits() / 8;
+ unsigned RegBytes = RegVT.getSizeInBits() / 8;
+ unsigned NumRegs = (LoadedBytes + RegBytes - 1) / RegBytes;
+
+ // Make sure the stack slot is also aligned for the register type.
+ SDValue StackBase = DAG.CreateStackTemporary(LoadedVT, RegVT);
+
+ SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy());
+ SmallVector<SDValue, 8> Stores;
+ SDValue StackPtr = StackBase;
+ unsigned Offset = 0;
+
+ // Do all but one copies using the full register width.
+ for (unsigned i = 1; i < NumRegs; i++) {
+ // Load one integer register's worth from the original location.
+ SDValue Load = DAG.getLoad(RegVT, Chain, Ptr, LD->getSrcValue(),
+ SVOffset + Offset, LD->isVolatile(),
+ MinAlign(LD->getAlignment(), Offset));
+ // Follow the load with a store to the stack slot. Remember the store.
+ Stores.push_back(DAG.getStore(Load.getValue(1), Load, StackPtr,
+ NULL, 0));
+ // Increment the pointers.
+ Offset += RegBytes;
+ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, Increment);
+ StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr,
+ Increment);
+ }
+
+ // The last copy may be partial. Do an extending load.
+ MVT MemVT = MVT::getIntegerVT(8 * (LoadedBytes - Offset));
+ SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, RegVT, Chain, Ptr,
+ LD->getSrcValue(), SVOffset + Offset,
+ MemVT, LD->isVolatile(),
+ MinAlign(LD->getAlignment(), Offset));
+ // Follow the load with a store to the stack slot. Remember the store.
+ // On big-endian machines this requires a truncating store to ensure
+ // that the bits end up in the right place.
+ Stores.push_back(DAG.getTruncStore(Load.getValue(1), Load, StackPtr,
+ NULL, 0, MemVT));
+
+ // The order of the stores doesn't matter - say it with a TokenFactor.
+ SDValue TF = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0],
+ Stores.size());
- SDValue Ops[] = { Result, Chain };
- return DAG.getMergeValues(Ops, 2);
+ // Finally, perform the original load only redirected to the stack slot.
+ Load = DAG.getExtLoad(LD->getExtensionType(), VT, TF, StackBase,
+ NULL, 0, LoadedVT);
+
+ // Callers expect a MERGE_VALUES node.
+ SDValue Ops[] = { Load, TF };
+ return DAG.getMergeValues(Ops, 2);
+ }
}
assert(LoadedVT.isInteger() && !LoadedVT.isVector() &&
"Unaligned load of unsupported type.");
Operands[j] = Operand;
}
}
- Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT,
- &Operands[0], Operands.size()));
+
+ switch (Op.getOpcode()) {
+ default:
+ Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT,
+ &Operands[0], Operands.size()));
+ break;
+ case ISD::SHL:
+ case ISD::SRA:
+ case ISD::SRL:
+ Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT, Operands[0],
+ LegalizeShiftAmount(Operands[1])));
+ break;
+ }
}
return DAG.getNode(ISD::BUILD_VECTOR, VT, &Scalars[0], Scalars.size());
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
/// is legal, recursively ensuring that the operands' operations remain
case TargetLowering::Promote:
default: assert(0 && "This action is not supported yet!");
case TargetLowering::Expand: {
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
- bool useDEBUG_LOC = TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other);
- bool useLABEL = TLI.isOperationLegal(ISD::DBG_LABEL, MVT::Other);
+ DwarfWriter *DW = DAG.getDwarfWriter();
+ bool useDEBUG_LOC = TLI.isOperationLegalOrCustom(ISD::DEBUG_LOC,
+ MVT::Other);
+ bool useLABEL = TLI.isOperationLegalOrCustom(ISD::DBG_LABEL, MVT::Other);
const DbgStopPointSDNode *DSP = cast<DbgStopPointSDNode>(Node);
- if (MMI && (useDEBUG_LOC || useLABEL)) {
- const CompileUnitDesc *CompileUnit = DSP->getCompileUnit();
- unsigned SrcFile = MMI->RecordSource(CompileUnit);
-
+ GlobalVariable *CU_GV = cast<GlobalVariable>(DSP->getCompileUnit());
+ if (DW && (useDEBUG_LOC || useLABEL) && !CU_GV->isDeclaration()) {
+ DICompileUnit CU(cast<GlobalVariable>(DSP->getCompileUnit()));
+ unsigned SrcFile = DW->RecordSource(CU.getDirectory(),
+ CU.getFilename());
+
unsigned Line = DSP->getLine();
unsigned Col = DSP->getColumn();
DAG.getConstant(SrcFile, MVT::i32) };
Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops, 4);
} else {
- unsigned ID = MMI->RecordSourceLine(Line, Col, SrcFile);
+ unsigned ID = DW->RecordSourceLine(Line, Col, SrcFile);
Result = DAG.getLabel(ISD::DBG_LABEL, Tmp1, ID);
}
} else {
break;
}
- case ISD::ATOMIC_CMP_SWAP_8:
- case ISD::ATOMIC_CMP_SWAP_16:
- case ISD::ATOMIC_CMP_SWAP_32:
- case ISD::ATOMIC_CMP_SWAP_64: {
+ case ISD::ATOMIC_CMP_SWAP: {
unsigned int num_operands = 4;
assert(Node->getNumOperands() == num_operands && "Invalid Atomic node!");
SDValue Ops[4];
AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1));
return Result.getValue(Op.getResNo());
}
- case ISD::ATOMIC_LOAD_ADD_8:
- case ISD::ATOMIC_LOAD_SUB_8:
- case ISD::ATOMIC_LOAD_AND_8:
- case ISD::ATOMIC_LOAD_OR_8:
- case ISD::ATOMIC_LOAD_XOR_8:
- case ISD::ATOMIC_LOAD_NAND_8:
- case ISD::ATOMIC_LOAD_MIN_8:
- case ISD::ATOMIC_LOAD_MAX_8:
- case ISD::ATOMIC_LOAD_UMIN_8:
- case ISD::ATOMIC_LOAD_UMAX_8:
- case ISD::ATOMIC_SWAP_8:
- case ISD::ATOMIC_LOAD_ADD_16:
- case ISD::ATOMIC_LOAD_SUB_16:
- case ISD::ATOMIC_LOAD_AND_16:
- case ISD::ATOMIC_LOAD_OR_16:
- case ISD::ATOMIC_LOAD_XOR_16:
- case ISD::ATOMIC_LOAD_NAND_16:
- case ISD::ATOMIC_LOAD_MIN_16:
- case ISD::ATOMIC_LOAD_MAX_16:
- case ISD::ATOMIC_LOAD_UMIN_16:
- case ISD::ATOMIC_LOAD_UMAX_16:
- case ISD::ATOMIC_SWAP_16:
- case ISD::ATOMIC_LOAD_ADD_32:
- case ISD::ATOMIC_LOAD_SUB_32:
- case ISD::ATOMIC_LOAD_AND_32:
- case ISD::ATOMIC_LOAD_OR_32:
- case ISD::ATOMIC_LOAD_XOR_32:
- case ISD::ATOMIC_LOAD_NAND_32:
- case ISD::ATOMIC_LOAD_MIN_32:
- case ISD::ATOMIC_LOAD_MAX_32:
- case ISD::ATOMIC_LOAD_UMIN_32:
- case ISD::ATOMIC_LOAD_UMAX_32:
- case ISD::ATOMIC_SWAP_32:
- case ISD::ATOMIC_LOAD_ADD_64:
- case ISD::ATOMIC_LOAD_SUB_64:
- case ISD::ATOMIC_LOAD_AND_64:
- case ISD::ATOMIC_LOAD_OR_64:
- case ISD::ATOMIC_LOAD_XOR_64:
- case ISD::ATOMIC_LOAD_NAND_64:
- case ISD::ATOMIC_LOAD_MIN_64:
- case ISD::ATOMIC_LOAD_MAX_64:
- case ISD::ATOMIC_LOAD_UMIN_64:
- case ISD::ATOMIC_LOAD_UMAX_64:
- case ISD::ATOMIC_SWAP_64: {
+ case ISD::ATOMIC_LOAD_ADD:
+ case ISD::ATOMIC_LOAD_SUB:
+ case ISD::ATOMIC_LOAD_AND:
+ case ISD::ATOMIC_LOAD_OR:
+ case ISD::ATOMIC_LOAD_XOR:
+ case ISD::ATOMIC_LOAD_NAND:
+ case ISD::ATOMIC_LOAD_MIN:
+ case ISD::ATOMIC_LOAD_MAX:
+ case ISD::ATOMIC_LOAD_UMIN:
+ case ISD::ATOMIC_LOAD_UMAX:
+ case ISD::ATOMIC_SWAP: {
unsigned int num_operands = 3;
assert(Node->getNumOperands() == num_operands && "Invalid Atomic node!");
SDValue Ops[3];
unsigned EntrySize = MF.getJumpTableInfo()->getEntrySize();
Index= DAG.getNode(ISD::MUL, PTy, Index, DAG.getConstant(EntrySize, PTy));
SDValue Addr = DAG.getNode(ISD::ADD, PTy, Index, Table);
-
- SDValue LD;
- switch (EntrySize) {
- default: assert(0 && "Size of jump table not supported yet."); break;
- case 4: LD = DAG.getLoad(MVT::i32, Chain, Addr,
- PseudoSourceValue::getJumpTable(), 0); break;
- case 8: LD = DAG.getLoad(MVT::i64, Chain, Addr,
- PseudoSourceValue::getJumpTable(), 0); break;
- }
+ MVT MemVT = MVT::getIntegerVT(EntrySize * 8);
+ SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, PTy, Chain, Addr,
+ PseudoSourceValue::getJumpTable(), 0, MemVT);
Addr = LD;
if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) {
// For PIC, the sequence is:
// BRIND(load(Jumptable + index) + RelocBase)
// RelocBase can be JumpTable, GOT or some sort of global base.
- if (PTy != MVT::i32)
- Addr = DAG.getNode(ISD::SIGN_EXTEND, PTy, Addr);
Addr = DAG.getNode(ISD::ADD, PTy, Addr,
TLI.getPICJumpTableRelocBase(Table, DAG));
}
Tmp3 = Node->getOperand(3); // RHS
Tmp4 = Node->getOperand(1); // CC
- LegalizeSetCC(TLI.getSetCCResultType(Tmp2), Tmp2, Tmp3, Tmp4);
+ LegalizeSetCC(TLI.getSetCCResultType(Tmp2.getValueType()), Tmp2, Tmp3,Tmp4);
LastCALLSEQ_END = DAG.getEntryNode();
// If we didn't get both a LHS and RHS back from LegalizeSetCC,
Tmp4 = LegalizeOp(Node->getOperand(3)); // False
SDValue CC = Node->getOperand(4);
- LegalizeSetCC(TLI.getSetCCResultType(Tmp1), Tmp1, Tmp2, CC);
+ LegalizeSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC);
// If we didn't get both a LHS and RHS back from LegalizeSetCC,
// the LHS is a legal SETCC itself. In this case, we need to compare
"Fell off of the edge of the floating point world");
// If the target supports SETCC of this type, use it.
- if (TLI.isOperationLegal(ISD::SETCC, NewInTy))
+ if (TLI.isOperationLegalOrCustom(ISD::SETCC, NewInTy))
break;
}
if (NewInTy.isInteger())
Tmp1 = TLI.LowerOperation(Result, DAG);
if (Tmp1.getNode()) Result = Tmp1;
break;
+ case TargetLowering::Expand: {
+ // Unroll into a nasty set of scalar code for now.
+ MVT VT = Node->getValueType(0);
+ unsigned NumElems = VT.getVectorNumElements();
+ MVT EltVT = VT.getVectorElementType();
+ MVT TmpEltVT = Tmp1.getValueType().getVectorElementType();
+ SmallVector<SDValue, 8> Ops(NumElems);
+ for (unsigned i = 0; i < NumElems; ++i) {
+ SDValue In1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, TmpEltVT,
+ Tmp1, DAG.getIntPtrConstant(i));
+ Ops[i] = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(TmpEltVT), In1,
+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, TmpEltVT,
+ Tmp2, DAG.getIntPtrConstant(i)),
+ CC);
+ Ops[i] = DAG.getNode(ISD::SELECT, EltVT, Ops[i],
+ DAG.getConstant(EltVT.getIntegerVTBitMask(),EltVT),
+ DAG.getConstant(0, EltVT));
+ }
+ Result = DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElems);
+ break;
+ }
}
break;
}
Node->getOpcode() == ISD::SRL ||
Node->getOpcode() == ISD::SRA) &&
!Node->getValueType(0).isVector()) {
- if (TLI.getShiftAmountTy().bitsLT(Tmp2.getValueType()))
- Tmp2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Tmp2);
- else if (TLI.getShiftAmountTy().bitsGT(Tmp2.getValueType()))
- Tmp2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Tmp2);
+ Tmp2 = LegalizeShiftAmount(Tmp2);
}
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
// and unsigned forms. If the target supports both SMUL_LOHI and
// UMUL_LOHI, form a preference by checking which forms of plain
// MULH it supports.
- bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, VT);
- bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, VT);
- bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, VT);
- bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, VT);
+ bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT);
+ bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT);
+ bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT);
+ bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT);
unsigned OpToUse = 0;
if (HasSMUL_LOHI && !HasMULHS) {
OpToUse = ISD::SMUL_LOHI;
}
}
if (Node->getOpcode() == ISD::MULHS &&
- TLI.isOperationLegal(ISD::SMUL_LOHI, VT)) {
+ TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) {
Result = SDValue(DAG.getNode(ISD::SMUL_LOHI, VTs, Tmp1, Tmp2).getNode(),
1);
break;
}
if (Node->getOpcode() == ISD::MULHU &&
- TLI.isOperationLegal(ISD::UMUL_LOHI, VT)) {
+ TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) {
Result = SDValue(DAG.getNode(ISD::UMUL_LOHI, VTs, Tmp1, Tmp2).getNode(),
1);
break;
}
if (Node->getOpcode() == ISD::SDIV &&
- TLI.isOperationLegal(ISD::SDIVREM, VT)) {
+ TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) {
Result = SDValue(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).getNode(),
0);
break;
}
if (Node->getOpcode() == ISD::UDIV &&
- TLI.isOperationLegal(ISD::UDIVREM, VT)) {
+ TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) {
Result = SDValue(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).getNode(),
0);
break;
}
-
+
// Check to see if we have a libcall for this operator.
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
bool isSigned = false;
case ISD::MUL:
if (VT == MVT::i32)
LC = RTLIB::MUL_I32;
+ else if (VT == MVT::i64)
+ LC = RTLIB::MUL_I64;
break;
case ISD::FPOW:
LC = GetFPLibCall(VT, RTLIB::POW_F32, RTLIB::POW_F64, RTLIB::POW_F80,
RTLIB::POW_PPCF128);
break;
+ case ISD::FDIV:
+ LC = GetFPLibCall(VT, RTLIB::DIV_F32, RTLIB::DIV_F64, RTLIB::DIV_F80,
+ RTLIB::DIV_PPCF128);
+ break;
default: break;
}
if (LC != RTLIB::UNKNOWN_LIBCALL) {
MVT IVT =
Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64;
SDValue SignBit = DAG.getNode(ISD::BIT_CONVERT, IVT, Tmp2);
- SignBit = DAG.getSetCC(TLI.getSetCCResultType(SignBit),
+ SignBit = DAG.getSetCC(TLI.getSetCCResultType(IVT),
SignBit, DAG.getConstant(0, IVT), ISD::SETLT);
// Get the absolute value of the result.
SDValue AbsVal = DAG.getNode(ISD::FABS, Tmp1.getValueType(), Tmp1);
Tmp1 = LegalizeOp(Node->getOperand(0));
Tmp2 = LegalizeOp(Node->getOperand(1));
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+ Tmp3 = Result.getValue(0);
+ Tmp4 = Result.getValue(1);
+
+ switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Legal:
+ break;
+ case TargetLowering::Custom:
+ Tmp1 = TLI.LowerOperation(Tmp3, DAG);
+ if (Tmp1.getNode() != NULL) {
+ Tmp3 = LegalizeOp(Tmp1);
+ Tmp4 = LegalizeOp(Tmp1.getValue(1));
+ }
+ break;
+ }
// Since this produces two values, make sure to remember that we legalized
// both of them.
- AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0));
- AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1));
- return Result;
+ AddLegalizedOperand(SDValue(Node, 0), Tmp3);
+ AddLegalizedOperand(SDValue(Node, 1), Tmp4);
+ return Op.getResNo() ? Tmp4 : Tmp3;
case ISD::ADDE:
case ISD::SUBE:
Tmp2 = LegalizeOp(Node->getOperand(1));
Tmp3 = LegalizeOp(Node->getOperand(2));
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
+ Tmp3 = Result.getValue(0);
+ Tmp4 = Result.getValue(1);
+
+ switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Legal:
+ break;
+ case TargetLowering::Custom:
+ Tmp1 = TLI.LowerOperation(Tmp3, DAG);
+ if (Tmp1.getNode() != NULL) {
+ Tmp3 = LegalizeOp(Tmp1);
+ Tmp4 = LegalizeOp(Tmp1.getValue(1));
+ }
+ break;
+ }
// Since this produces two values, make sure to remember that we legalized
// both of them.
- AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0));
- AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1));
- return Result;
+ AddLegalizedOperand(SDValue(Node, 0), Tmp3);
+ AddLegalizedOperand(SDValue(Node, 1), Tmp4);
+ return Op.getResNo() ? Tmp4 : Tmp3;
case ISD::BUILD_PAIR: {
MVT PairTy = Node->getValueType(0);
// See if remainder can be lowered using two-result operations.
SDVTList VTs = DAG.getVTList(VT, VT);
if (Node->getOpcode() == ISD::SREM &&
- TLI.isOperationLegal(ISD::SDIVREM, VT)) {
+ TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) {
Result = SDValue(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).getNode(), 1);
break;
}
if (Node->getOpcode() == ISD::UREM &&
- TLI.isOperationLegal(ISD::UDIVREM, VT)) {
+ TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) {
Result = SDValue(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).getNode(), 1);
break;
}
SDValue VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, V, 0);
// Increment the pointer, VAList, to the next vaarg
Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList,
- DAG.getConstant(TLI.getTargetData()->getABITypeSize(VT.getTypeForMVT()),
- TLI.getPointerTy()));
+ DAG.getConstant(TLI.getTargetData()->
+ getTypePaddedSize(VT.getTypeForMVT()),
+ TLI.getPointerTy()));
// Store the incremented VAList to the legalized pointer
Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, V, 0);
// Load the actual argument out of the pointer VAList
break;
case ISD::CTTZ:
//if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1), Tmp1,
+ Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1,
DAG.getConstant(NVT.getSizeInBits(), NVT),
ISD::SETEQ);
Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
// Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X).
MVT VT = Node->getValueType(0);
Tmp2 = DAG.getConstantFP(0.0, VT);
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1), Tmp1, Tmp2,
- ISD::SETUGT);
+ Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1.getValueType()),
+ Tmp1, Tmp2, ISD::SETUGT);
Tmp3 = DAG.getNode(ISD::FNEG, VT, Tmp1);
Result = DAG.getNode(ISD::SELECT, VT, Tmp2, Tmp1, Tmp3);
break;
default: assert(0 && "Unknown cvt code!");
case ISD::CVT_SF:
case ISD::CVT_UF:
- break;
case ISD::CVT_FF:
+ break;
case ISD::CVT_FS:
case ISD::CVT_FU:
case ISD::CVT_SS:
Result = PromoteOp(Node->getOperand(0));
// For FP, make Op1 a i32
- Result = DAG.getConvertRndSat(Result.getValueType(), Result,
+ Result = DAG.getConvertRndSat(Op.getValueType(), Result,
DTyOp, STyOp, RndOp, SatOp, CvtCode);
break;
}
switch (getTypeAction(Node->getOperand(0).getValueType())) {
case Legal:
Tmp1 = LegalizeOp(Node->getOperand(0));
- Result = DAG.UpdateNodeOperands(Result, Tmp1);
+ switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+ default: assert(0 && "Unknown TRUNCATE legalization operation action!");
+ case TargetLowering::Custom:
+ isCustom = true;
+ // FALLTHROUGH
+ case TargetLowering::Legal:
+ Result = DAG.UpdateNodeOperands(Result, Tmp1);
+ if (isCustom) {
+ Tmp1 = TLI.LowerOperation(Result, DAG);
+ if (Tmp1.getNode()) Result = Tmp1;
+ }
+ break;
+ case TargetLowering::Expand:
+ assert(Result.getValueType().isVector() && "must be vector type");
+ // Unroll the truncate. We should do better.
+ Result = LegalizeOp(UnrollVectorOp(Result));
+ }
break;
case Expand:
ExpandOp(Node->getOperand(0), Tmp1, Tmp2);
APInt x = APInt::getSignBit(NVT.getSizeInBits());
(void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven);
Tmp2 = DAG.getConstantFP(apf, VT);
- Tmp3 = DAG.getSetCC(TLI.getSetCCResultType(Node->getOperand(0)),
- Node->getOperand(0), Tmp2, ISD::SETLT);
+ Tmp3 = DAG.getSetCC(TLI.getSetCCResultType(VT), Node->getOperand(0),
+ Tmp2, ISD::SETLT);
True = DAG.getNode(ISD::FP_TO_SINT, NVT, Node->getOperand(0));
False = DAG.getNode(ISD::FP_TO_SINT, NVT,
DAG.getNode(ISD::FSUB, VT, Node->getOperand(0),
break;
}
- case ISD::SADDO: {
- SDValue LHS = LegalizeOp(Node->getOperand(0));
- SDValue RHS = LegalizeOp(Node->getOperand(1));
+ case ISD::SADDO:
+ case ISD::SSUBO: {
+ MVT VT = Node->getValueType(0);
+ switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
+ default: assert(0 && "This action not supported for this op yet!");
+ case TargetLowering::Custom:
+ Result = TLI.LowerOperation(Op, DAG);
+ if (Result.getNode()) break;
+ // FALLTHROUGH
+ case TargetLowering::Legal: {
+ SDValue LHS = LegalizeOp(Node->getOperand(0));
+ SDValue RHS = LegalizeOp(Node->getOperand(1));
+
+ SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
+ ISD::ADD : ISD::SUB, LHS.getValueType(),
+ LHS, RHS);
+ MVT OType = Node->getValueType(1);
+
+ SDValue Zero = DAG.getConstant(0, LHS.getValueType());
+
+ // LHSSign -> LHS >= 0
+ // RHSSign -> RHS >= 0
+ // SumSign -> Sum >= 0
+ //
+ // Add:
+ // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
+ // Sub:
+ // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
+ //
+ SDValue LHSSign = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE);
+ SDValue RHSSign = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE);
+ SDValue SignsMatch = DAG.getSetCC(OType, LHSSign, RHSSign,
+ Node->getOpcode() == ISD::SADDO ?
+ ISD::SETEQ : ISD::SETNE);
- SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS);
- MVT OType = SDValue(Node, 1).getValueType();
- SDValue Cmp = DAG.getSetCC(OType, Sum, LHS, ISD::SETLT);
+ SDValue SumSign = DAG.getSetCC(OType, Sum, Zero, ISD::SETGE);
+ SDValue SumSignNE = DAG.getSetCC(OType, LHSSign, SumSign, ISD::SETNE);
- MVT ValueVTs[] = { LHS.getValueType(), OType };
- SDValue Ops[] = { Sum, Cmp };
+ SDValue Cmp = DAG.getNode(ISD::AND, OType, SignsMatch, SumSignNE);
+
+ MVT ValueVTs[] = { LHS.getValueType(), OType };
+ SDValue Ops[] = { Sum, Cmp };
+
+ Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(&ValueVTs[0], 2),
+ &Ops[0], 2);
+ SDNode *RNode = Result.getNode();
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0));
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1));
+ break;
+ }
+ }
- Result = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
- SDNode *RNode = Result.getNode();
- DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0));
- DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1));
break;
}
- case ISD::UADDO: {
+ case ISD::UADDO:
+ case ISD::USUBO: {
+ MVT VT = Node->getValueType(0);
+ switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
+ default: assert(0 && "This action not supported for this op yet!");
+ case TargetLowering::Custom:
+ Result = TLI.LowerOperation(Op, DAG);
+ if (Result.getNode()) break;
+ // FALLTHROUGH
+ case TargetLowering::Legal: {
+ SDValue LHS = LegalizeOp(Node->getOperand(0));
+ SDValue RHS = LegalizeOp(Node->getOperand(1));
+
+ SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::UADDO ?
+ ISD::ADD : ISD::SUB, LHS.getValueType(),
+ LHS, RHS);
+ MVT OType = Node->getValueType(1);
+ SDValue Cmp = DAG.getSetCC(OType, Sum, LHS,
+ Node->getOpcode () == ISD::UADDO ?
+ ISD::SETULT : ISD::SETUGT);
+
+ MVT ValueVTs[] = { LHS.getValueType(), OType };
+ SDValue Ops[] = { Sum, Cmp };
+
+ Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(&ValueVTs[0], 2),
+ &Ops[0], 2);
+ SDNode *RNode = Result.getNode();
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0));
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1));
+ break;
+ }
+ }
+
+ break;
+ }
+ case ISD::SMULO:
+ case ISD::UMULO: {
+ MVT VT = Node->getValueType(0);
+ switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
+ default: assert(0 && "This action is not supported at all!");
+ case TargetLowering::Custom:
+ Result = TLI.LowerOperation(Op, DAG);
+ if (Result.getNode()) break;
+ // Fall Thru
+ case TargetLowering::Legal:
+ // FIXME: According to Hacker's Delight, this can be implemented in
+ // target independent lowering, but it would be inefficient, since it
+ // requires a division + a branch.
+ assert(0 && "Target independent lowering is not supported for SMULO/UMULO!");
+ break;
+ }
break;
}
+
}
assert(Result.getValueType() == Op.getValueType() &&
assert(isa<ConstantFPSDNode>(Result) && "Didn't constant fold fp_extend?");
break;
- case ISD::SETCC:
- assert(isTypeLegal(TLI.getSetCCResultType(Node->getOperand(0)))
+ case ISD::SETCC: {
+ MVT VT0 = Node->getOperand(0).getValueType();
+ assert(isTypeLegal(TLI.getSetCCResultType(VT0))
&& "SetCC type is not legal??");
- Result = DAG.getNode(ISD::SETCC,
- TLI.getSetCCResultType(Node->getOperand(0)),
+ Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(VT0),
Node->getOperand(0), Node->getOperand(1),
Node->getOperand(2));
break;
-
+ }
case ISD::TRUNCATE:
switch (getTypeAction(Node->getOperand(0).getValueType())) {
case Legal:
// FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not
// legal, such as PowerPC.
if (Node->getOpcode() == ISD::FP_TO_UINT &&
- !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
- (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) ||
+ !TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NVT) &&
+ (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT) ||
TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)){
Result = DAG.getNode(ISD::FP_TO_SINT, NVT, Tmp1);
} else {
break;
}
- case ISD::ATOMIC_CMP_SWAP_8:
- case ISD::ATOMIC_CMP_SWAP_16:
- case ISD::ATOMIC_CMP_SWAP_32:
- case ISD::ATOMIC_CMP_SWAP_64: {
+ case ISD::ATOMIC_CMP_SWAP: {
AtomicSDNode* AtomNode = cast<AtomicSDNode>(Node);
Tmp2 = PromoteOp(Node->getOperand(2));
Tmp3 = PromoteOp(Node->getOperand(3));
- Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getChain(),
+ Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getMemoryVT(),
+ AtomNode->getChain(),
AtomNode->getBasePtr(), Tmp2, Tmp3,
AtomNode->getSrcValue(),
AtomNode->getAlignment());
AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
break;
}
- case ISD::ATOMIC_LOAD_ADD_8:
- case ISD::ATOMIC_LOAD_SUB_8:
- case ISD::ATOMIC_LOAD_AND_8:
- case ISD::ATOMIC_LOAD_OR_8:
- case ISD::ATOMIC_LOAD_XOR_8:
- case ISD::ATOMIC_LOAD_NAND_8:
- case ISD::ATOMIC_LOAD_MIN_8:
- case ISD::ATOMIC_LOAD_MAX_8:
- case ISD::ATOMIC_LOAD_UMIN_8:
- case ISD::ATOMIC_LOAD_UMAX_8:
- case ISD::ATOMIC_SWAP_8:
- case ISD::ATOMIC_LOAD_ADD_16:
- case ISD::ATOMIC_LOAD_SUB_16:
- case ISD::ATOMIC_LOAD_AND_16:
- case ISD::ATOMIC_LOAD_OR_16:
- case ISD::ATOMIC_LOAD_XOR_16:
- case ISD::ATOMIC_LOAD_NAND_16:
- case ISD::ATOMIC_LOAD_MIN_16:
- case ISD::ATOMIC_LOAD_MAX_16:
- case ISD::ATOMIC_LOAD_UMIN_16:
- case ISD::ATOMIC_LOAD_UMAX_16:
- case ISD::ATOMIC_SWAP_16:
- case ISD::ATOMIC_LOAD_ADD_32:
- case ISD::ATOMIC_LOAD_SUB_32:
- case ISD::ATOMIC_LOAD_AND_32:
- case ISD::ATOMIC_LOAD_OR_32:
- case ISD::ATOMIC_LOAD_XOR_32:
- case ISD::ATOMIC_LOAD_NAND_32:
- case ISD::ATOMIC_LOAD_MIN_32:
- case ISD::ATOMIC_LOAD_MAX_32:
- case ISD::ATOMIC_LOAD_UMIN_32:
- case ISD::ATOMIC_LOAD_UMAX_32:
- case ISD::ATOMIC_SWAP_32:
- case ISD::ATOMIC_LOAD_ADD_64:
- case ISD::ATOMIC_LOAD_SUB_64:
- case ISD::ATOMIC_LOAD_AND_64:
- case ISD::ATOMIC_LOAD_OR_64:
- case ISD::ATOMIC_LOAD_XOR_64:
- case ISD::ATOMIC_LOAD_NAND_64:
- case ISD::ATOMIC_LOAD_MIN_64:
- case ISD::ATOMIC_LOAD_MAX_64:
- case ISD::ATOMIC_LOAD_UMIN_64:
- case ISD::ATOMIC_LOAD_UMAX_64:
- case ISD::ATOMIC_SWAP_64: {
+ case ISD::ATOMIC_LOAD_ADD:
+ case ISD::ATOMIC_LOAD_SUB:
+ case ISD::ATOMIC_LOAD_AND:
+ case ISD::ATOMIC_LOAD_OR:
+ case ISD::ATOMIC_LOAD_XOR:
+ case ISD::ATOMIC_LOAD_NAND:
+ case ISD::ATOMIC_LOAD_MIN:
+ case ISD::ATOMIC_LOAD_MAX:
+ case ISD::ATOMIC_LOAD_UMIN:
+ case ISD::ATOMIC_LOAD_UMAX:
+ case ISD::ATOMIC_SWAP: {
AtomicSDNode* AtomNode = cast<AtomicSDNode>(Node);
Tmp2 = PromoteOp(Node->getOperand(2));
- Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getChain(),
+ Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getMemoryVT(),
+ AtomNode->getChain(),
AtomNode->getBasePtr(), Tmp2,
AtomNode->getSrcValue(),
AtomNode->getAlignment());
break;
case ISD::CTTZ:
// if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1), Tmp1,
+ Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1,
DAG.getConstant(NVT.getSizeInBits(), NVT),
ISD::SETEQ);
Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
Tmp2 = DAG.getConstant(0, MVT::i32);
CC = DAG.getCondCode(TLI.getCmpLibcallCC(LC1));
if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
- Tmp1 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(Tmp1), Tmp1, Tmp2,
- CC);
+ Tmp1 = DAG.getNode(ISD::SETCC,
+ TLI.getSetCCResultType(Tmp1.getValueType()),
+ Tmp1, Tmp2, CC);
LHS = ExpandLibCall(LC2, DAG.getMergeValues(Ops, 2).getNode(),
false /*sign irrelevant*/, Dummy);
- Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(LHS), LHS, Tmp2,
- DAG.getCondCode(TLI.getCmpLibcallCC(LC2)));
+ Tmp2 = DAG.getNode(ISD::SETCC,
+ TLI.getSetCCResultType(LHS.getValueType()), LHS,
+ Tmp2, DAG.getCondCode(TLI.getCmpLibcallCC(LC2)));
Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2);
Tmp2 = SDValue();
}
// BNE crN, L:
// FCMPU crN, lo1, lo2
// The following can be improved, but not that much.
- Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
- ISD::SETOEQ);
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, CCCode);
+ Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ LHSHi, RHSHi, ISD::SETOEQ);
+ Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
+ LHSLo, RHSLo, CCCode);
Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
- Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
- ISD::SETUNE);
- Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, CCCode);
+ Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ LHSHi, RHSHi, ISD::SETUNE);
+ Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ LHSHi, RHSHi, CCCode);
Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
Tmp2 = SDValue();
// NOTE: on targets without efficient SELECT of bools, we can always use
// this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL);
- Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo,
- LowCC, false, DagCombineInfo);
+ Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
+ LHSLo, RHSLo, LowCC, false, DagCombineInfo);
if (!Tmp1.getNode())
- Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, LowCC);
- Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
- CCCode, false, DagCombineInfo);
+ Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
+ LHSLo, RHSLo, LowCC);
+ Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ LHSHi, RHSHi, CCCode, false, DagCombineInfo);
if (!Tmp2.getNode())
- Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(LHSHi), LHSHi,
- RHSHi,CC);
+ Tmp2 = DAG.getNode(ISD::SETCC,
+ TLI.getSetCCResultType(LHSHi.getValueType()),
+ LHSHi, RHSHi,CC);
ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.getNode());
ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.getNode());
Tmp1 = Tmp2;
Tmp2 = SDValue();
} else {
- Result = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
- ISD::SETEQ, false, DagCombineInfo);
+ Result = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ LHSHi, RHSHi, ISD::SETEQ, false,
+ DagCombineInfo);
if (!Result.getNode())
- Result=DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
- ISD::SETEQ);
+ Result=DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+ LHSHi, RHSHi, ISD::SETEQ);
Result = LegalizeOp(DAG.getNode(ISD::SELECT, Tmp1.getValueType(),
Result, Tmp1, Tmp2));
Tmp1 = Result;
FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(FIPtr);
int SPFI = StackPtrFI->getIndex();
-
+ const Value *SV = PseudoSourceValue::getFixedStack(SPFI);
+
unsigned SrcSize = SrcOp.getValueType().getSizeInBits();
unsigned SlotSize = SlotVT.getSizeInBits();
unsigned DestSize = DestVT.getSizeInBits();
if (SrcSize > SlotSize)
Store = DAG.getTruncStore(DAG.getEntryNode(), SrcOp, FIPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0,
- SlotVT, false, SrcAlign);
+ SV, 0, SlotVT, false, SrcAlign);
else {
assert(SrcSize == SlotSize && "Invalid store");
Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr,
- PseudoSourceValue::getFixedStack(SPFI), 0,
- false, SrcAlign);
+ SV, 0, false, SrcAlign);
}
// Result is a load from the stack slot.
if (SlotSize == DestSize)
- return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0, false, DestAlign);
+ return DAG.getLoad(DestVT, Store, FIPtr, SV, 0, false, DestAlign);
assert(SlotSize < DestSize && "Unknown extension!");
- return DAG.getExtLoad(ISD::EXTLOAD, DestVT, Store, FIPtr, NULL, 0, SlotVT,
+ return DAG.getExtLoad(ISD::EXTLOAD, DestVT, Store, FIPtr, SV, 0, SlotVT,
false, DestAlign);
}
&MaskVec[0], MaskVec.size());
// If the target supports SCALAR_TO_VECTOR and this shuffle mask, use it.
- if (TLI.isOperationLegal(ISD::SCALAR_TO_VECTOR, Node->getValueType(0)) &&
+ if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR,
+ Node->getValueType(0)) &&
isShuffleLegal(Node->getValueType(0), ShuffleMask)) {
Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), Val1);
Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), Val2);
MVT VT = Node->getValueType(0);
// Create the stack frame object.
SDValue FIPtr = DAG.CreateStackTemporary(VT);
-
+ int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();
+ const Value *SV = PseudoSourceValue::getFixedStack(FI);
+
// Emit a store of each element to the stack slot.
SmallVector<SDValue, 8> Stores;
unsigned TypeByteSize = Node->getOperand(0).getValueType().getSizeInBits()/8;
Idx = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr, Idx);
Stores.push_back(DAG.getStore(DAG.getEntryNode(), Node->getOperand(i), Idx,
- NULL, 0));
+ SV, Offset));
}
SDValue StoreChain;
StoreChain = DAG.getEntryNode();
// Result is a load from the stack slot.
- return DAG.getLoad(VT, StoreChain, FIPtr, NULL, 0);
+ return DAG.getLoad(VT, StoreChain, FIPtr, SV, 0);
}
void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp,
// signed, then adjust the result if the sign bit is set.
SDValue SignedConv = ExpandIntToFP(true, DestTy, Source);
- SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
- DAG.getConstant(0, Hi.getValueType()),
- ISD::SETLT);
+ SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi.getValueType()),
+ Hi, DAG.getConstant(0, Hi.getValueType()),
+ ISD::SETLT);
SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
SDValue CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
SignSet, Four, Zero);
assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet");
SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
- SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Op0), Op0,
- DAG.getConstant(0, Op0.getValueType()),
- ISD::SETLT);
+ SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Op0.getValueType()),
+ Op0, DAG.getConstant(0, Op0.getValueType()),
+ ISD::SETLT);
SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
SDValue CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
SignSet, Four, Zero);
// the target lowering hooks to expand it. Just keep the low part of the
// expanded operation, we know that we're truncating anyway.
if (getTypeAction(NewOutTy) == Expand) {
- Operation = SDValue(TLI.ReplaceNodeResults(Operation.getNode(), DAG), 0);
- assert(Operation.getNode() && "Didn't return anything");
+ SmallVector<SDValue, 2> Results;
+ TLI.ReplaceNodeResults(Operation.getNode(), Results, DAG);
+ assert(Results.size() == 1 && "Incorrect FP_TO_XINT lowering!");
+ Operation = Results[0];
}
// Truncate the result of the extended FP_TO_*INT operation to the desired
unsigned len = VT.getSizeInBits();
for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
//x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8])
- SDValue Tmp2 = DAG.getConstant(mask[i], VT);
+ SDValue Tmp2 = DAG.getConstant(VT.getIntegerVTBitMask() & mask[i], VT);
SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT);
Op = DAG.getNode(ISD::ADD, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2),
DAG.getNode(ISD::AND, VT,
SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT);
Op = DAG.getNode(ISD::OR, VT, Op, DAG.getNode(ISD::SRL, VT, Op, Tmp3));
}
- Op = DAG.getNode(ISD::XOR, VT, Op, DAG.getConstant(~0ULL, VT));
+ Op = DAG.getNOT(Op, VT);
return DAG.getNode(ISD::CTPOP, VT, Op);
}
case ISD::CTTZ: {
// { return 32 - nlz(~x & (x-1)); }
// see also http://www.hackersdelight.org/HDcode/ntz.cc
MVT VT = Op.getValueType();
- SDValue Tmp2 = DAG.getConstant(~0ULL, VT);
- SDValue Tmp3 = DAG.getNode(ISD::AND, VT,
- DAG.getNode(ISD::XOR, VT, Op, Tmp2),
+ SDValue Tmp3 = DAG.getNode(ISD::AND, VT, DAG.getNOT(Op, VT),
DAG.getNode(ISD::SUB, VT, Op, DAG.getConstant(1, VT)));
// If ISD::CTLZ is legal and CTPOP isn't, then do that instead.
- if (!TLI.isOperationLegal(ISD::CTPOP, VT) &&
- TLI.isOperationLegal(ISD::CTLZ, VT))
+ if (!TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) &&
+ TLI.isOperationLegalOrCustom(ISD::CTLZ, VT))
return DAG.getNode(ISD::SUB, VT,
DAG.getConstant(VT.getSizeInBits(), VT),
DAG.getNode(ISD::CTLZ, VT, Tmp3));
ExpandOp(Node->getOperand(0), Lo, Hi);
SDValue BitsC = DAG.getConstant(NVT.getSizeInBits(), NVT);
SDValue HLZ = DAG.getNode(ISD::CTLZ, NVT, Hi);
- SDValue TopNotZero = DAG.getSetCC(TLI.getSetCCResultType(HLZ), HLZ, BitsC,
- ISD::SETNE);
+ SDValue TopNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), HLZ, BitsC,
+ ISD::SETNE);
SDValue LowPart = DAG.getNode(ISD::CTLZ, NVT, Lo);
LowPart = DAG.getNode(ISD::ADD, NVT, LowPart, BitsC);
ExpandOp(Node->getOperand(0), Lo, Hi);
SDValue BitsC = DAG.getConstant(NVT.getSizeInBits(), NVT);
SDValue LTZ = DAG.getNode(ISD::CTTZ, NVT, Lo);
- SDValue BotNotZero = DAG.getSetCC(TLI.getSetCCResultType(LTZ), LTZ, BitsC,
- ISD::SETNE);
+ SDValue BotNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), LTZ, BitsC,
+ ISD::SETNE);
SDValue HiPart = DAG.getNode(ISD::CTTZ, NVT, Hi);
HiPart = DAG.getNode(ISD::ADD, NVT, HiPart, BitsC);
break;
}
- case ISD::ATOMIC_CMP_SWAP_64: {
+ case ISD::ATOMIC_CMP_SWAP: {
// This operation does not need a loop.
SDValue Tmp = TLI.LowerOperation(Op, DAG);
assert(Tmp.getNode() && "Node must be custom expanded!");
break;
}
- case ISD::ATOMIC_LOAD_ADD_64:
- case ISD::ATOMIC_LOAD_SUB_64:
- case ISD::ATOMIC_LOAD_AND_64:
- case ISD::ATOMIC_LOAD_OR_64:
- case ISD::ATOMIC_LOAD_XOR_64:
- case ISD::ATOMIC_LOAD_NAND_64:
- case ISD::ATOMIC_SWAP_64: {
+ case ISD::ATOMIC_LOAD_ADD:
+ case ISD::ATOMIC_LOAD_SUB:
+ case ISD::ATOMIC_LOAD_AND:
+ case ISD::ATOMIC_LOAD_OR:
+ case ISD::ATOMIC_LOAD_XOR:
+ case ISD::ATOMIC_LOAD_NAND:
+ case ISD::ATOMIC_SWAP: {
// These operations require a loop to be generated. We can't do that yet,
// so substitute a target-dependent pseudo and expand that later.
SDValue In2Lo, In2Hi, In2;
In2 = DAG.getNode(ISD::BUILD_PAIR, VT, In2Lo, In2Hi);
AtomicSDNode* Anode = cast<AtomicSDNode>(Node);
SDValue Replace =
- DAG.getAtomic(Op.getOpcode(), Op.getOperand(0), Op.getOperand(1), In2,
+ DAG.getAtomic(Op.getOpcode(), Anode->getMemoryVT(),
+ Op.getOperand(0), Op.getOperand(1), In2,
Anode->getSrcValue(), Anode->getAlignment());
SDValue Result = TLI.LowerOperation(Replace, DAG);
ExpandOp(Result.getValue(0), Lo, Hi);
// If ADDC/ADDE are supported and if the shift amount is a constant 1, emit
// this X << 1 as X+X.
if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(ShiftAmt)) {
- if (ShAmt->getAPIntValue() == 1 && TLI.isOperationLegal(ISD::ADDC, NVT) &&
- TLI.isOperationLegal(ISD::ADDE, NVT)) {
+ if (ShAmt->getAPIntValue() == 1 &&
+ TLI.isOperationLegalOrCustom(ISD::ADDC, NVT) &&
+ TLI.isOperationLegalOrCustom(ISD::ADDE, NVT)) {
SDValue LoOps[2], HiOps[3];
ExpandOp(Node->getOperand(0), LoOps[0], HiOps[0]);
SDVTList VTList = DAG.getVTList(LoOps[0].getValueType(), MVT::Flag);
SDValue LHSL, LHSH, RHSL, RHSH;
ExpandOp(Node->getOperand(0), LHSL, LHSH);
ExpandOp(Node->getOperand(1), RHSL, RHSH);
- SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
SDValue LoOps[2], HiOps[3];
LoOps[0] = LHSL;
LoOps[1] = RHSL;
bool hasCarry = false;
for (unsigned BitSize = NVT.getSizeInBits(); BitSize != 0; BitSize /= 2) {
MVT AVT = MVT::getIntegerVT(BitSize);
- if (TLI.isOperationLegal(OpV, AVT)) {
+ if (TLI.isOperationLegalOrCustom(OpV, AVT)) {
hasCarry = true;
break;
}
}
if(hasCarry) {
+ SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
if (Node->getOpcode() == ISD::ADD) {
Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
HiOps[2] = Lo.getValue(1);
break;
} else {
if (Node->getOpcode() == ISD::ADD) {
- Lo = DAG.getNode(ISD::ADD, VTList, LoOps, 2);
- Hi = DAG.getNode(ISD::ADD, VTList, HiOps, 2);
- SDValue Cmp1 = DAG.getSetCC(TLI.getSetCCResultType(Lo),
+ Lo = DAG.getNode(ISD::ADD, NVT, LoOps, 2);
+ Hi = DAG.getNode(ISD::ADD, NVT, HiOps, 2);
+ SDValue Cmp1 = DAG.getSetCC(TLI.getSetCCResultType(NVT),
Lo, LoOps[0], ISD::SETULT);
SDValue Carry1 = DAG.getNode(ISD::SELECT, NVT, Cmp1,
DAG.getConstant(1, NVT),
DAG.getConstant(0, NVT));
- SDValue Cmp2 = DAG.getSetCC(TLI.getSetCCResultType(Lo),
+ SDValue Cmp2 = DAG.getSetCC(TLI.getSetCCResultType(NVT),
Lo, LoOps[1], ISD::SETULT);
SDValue Carry2 = DAG.getNode(ISD::SELECT, NVT, Cmp2,
DAG.getConstant(1, NVT),
Carry1);
Hi = DAG.getNode(ISD::ADD, NVT, Hi, Carry2);
} else {
- Lo = DAG.getNode(ISD::SUB, VTList, LoOps, 2);
- Hi = DAG.getNode(ISD::SUB, VTList, HiOps, 2);
+ Lo = DAG.getNode(ISD::SUB, NVT, LoOps, 2);
+ Hi = DAG.getNode(ISD::SUB, NVT, HiOps, 2);
SDValue Cmp = DAG.getSetCC(NVT, LoOps[0], LoOps[1], ISD::SETULT);
SDValue Borrow = DAG.getNode(ISD::SELECT, NVT, Cmp,
DAG.getConstant(1, NVT),
}
}
- bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT);
- bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT);
- bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT);
- bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT);
+ bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT);
+ bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT);
+ bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT);
+ bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT);
if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
SDValue LL, LH, RL, RH;
ExpandOp(Node->getOperand(0), LL, LH);
bool isNew =
ExpandedNodes.insert(std::make_pair(Op, std::make_pair(Lo, Hi))).second;
assert(isNew && "Value already expanded?!?");
+ isNew = isNew;
}
/// SplitVectorOp - Given an operand of vector type, break it down into
case ISD::XOR:
case ISD::UREM:
case ISD::SREM:
- case ISD::FREM: {
+ case ISD::FREM:
+ case ISD::SHL:
+ case ISD::SRA:
+ case ISD::SRL: {
SDValue LL, LH, RL, RH;
SplitVectorOp(Node->getOperand(0), LL, LH);
SplitVectorOp(Node->getOperand(1), RL, RH);
bool isNew =
SplitNodes.insert(std::make_pair(Op, std::make_pair(Lo, Hi))).second;
assert(isNew && "Value already split?!?");
+ isNew = isNew;
}
case ISD::VSETCC: {
SDValue Op0 = ScalarizeVectorOp(Op.getOperand(0));
SDValue Op1 = ScalarizeVectorOp(Op.getOperand(1));
- Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(Op0), Op0, Op1,
- Op.getOperand(2));
+ Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(Op0.getValueType()),
+ Op0, Op1, Op.getOperand(2));
Result = DAG.getNode(ISD::SELECT, NewVT, Result,
DAG.getConstant(-1ULL, NewVT),
DAG.getConstant(0ULL, NewVT));
Result = LegalizeOp(Result);
bool isNew = ScalarizedNodes.insert(std::make_pair(Op, Result)).second;
assert(isNew && "Value already scalarized?");
+ isNew = isNew;
return Result;
}
NewOps.push_back(PermOp.getOperand(i));
} else {
unsigned Idx =
- cast<ConstantSDNode>(PermOp.getOperand(i))->getZExtValue();
+ cast<ConstantSDNode>(PermOp.getOperand(i))->getZExtValue();
if (Idx < NumElts) {
NewOps.push_back(PermOp.getOperand(i));
}
SDValue Tmp1 = Node->getOperand(0);
// Converts between two different types so we need to determine
// the correct widen type for the input operand.
- MVT TVT = Tmp1.getValueType();
- assert(TVT.isVector() && "can not widen non vector type");
- MVT TEVT = TVT.getVectorElementType();
- assert(WidenVT.getSizeInBits() % EVT.getSizeInBits() == 0 &&
- "can not widen bit bit convert that are not multiple of element type");
- MVT TWidenVT = MVT::getVectorVT(TEVT,
- WidenVT.getSizeInBits()/EVT.getSizeInBits());
- Tmp1 = WidenVectorOp(Tmp1, TWidenVT);
- assert(Tmp1.getValueType().getSizeInBits() == WidenVT.getSizeInBits());
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1);
+ MVT InVT = Tmp1.getValueType();
+ unsigned WidenSize = WidenVT.getSizeInBits();
+ if (InVT.isVector()) {
+ MVT InEltVT = InVT.getVectorElementType();
+ unsigned InEltSize = InEltVT.getSizeInBits();
+ assert(WidenSize % InEltSize == 0 &&
+ "can not widen bit convert that are not multiple of element type");
+ MVT NewInWidenVT = MVT::getVectorVT(InEltVT, WidenSize / InEltSize);
+ Tmp1 = WidenVectorOp(Tmp1, NewInWidenVT);
+ assert(Tmp1.getValueType().getSizeInBits() == WidenVT.getSizeInBits());
+ Result = DAG.getNode(ISD::BIT_CONVERT, WidenVT, Tmp1);
+ } else {
+ // If the result size is a multiple of the input size, widen the input
+ // and then convert.
+ unsigned InSize = InVT.getSizeInBits();
+ assert(WidenSize % InSize == 0 &&
+ "can not widen bit convert that are not multiple of element type");
+ unsigned NewNumElts = WidenSize / InSize;
+ SmallVector<SDValue, 16> Ops(NewNumElts);
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT);
+ Ops[0] = Tmp1;
+ for (unsigned i = 1; i < NewNumElts; ++i)
+ Ops[i] = UndefVal;
- TargetLowering::LegalizeAction action =
- TLI.getOperationAction(Node->getOpcode(), WidenVT);
- switch (action) {
- default: assert(0 && "action not supported");
- case TargetLowering::Legal:
- break;
- case TargetLowering::Promote:
- // We defer the promotion to when we legalize the op
- break;
- case TargetLowering::Expand:
- // Expand the operation into a bunch of nasty scalar code.
- Result = LegalizeOp(UnrollVectorOp(Result));
- break;
+ MVT NewInVT = MVT::getVectorVT(InVT, NewNumElts);
+ Result = DAG.getNode(ISD::BUILD_VECTOR, NewInVT, &Ops[0], NewNumElts);
+ Result = DAG.getNode(ISD::BIT_CONVERT, WidenVT, Result);
}
break;
}
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP:
case ISD::FP_TO_SINT:
- case ISD::FP_TO_UINT: {
+ case ISD::FP_TO_UINT:
+ case ISD::FP_ROUND: {
SDValue Tmp1 = Node->getOperand(0);
// Converts between two different types so we need to determine
// the correct widen type for the input operand.
Tmp1 = WidenVectorOp(Tmp1, TWidenVT);
assert(Tmp1.getValueType().getVectorNumElements() == NewNumElts);
Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1);
-
- TargetLowering::LegalizeAction action =
- TLI.getOperationAction(Node->getOpcode(), WidenVT);
- switch (action) {
- default: assert(0 && "action not supported");
- case TargetLowering::Legal:
- break;
- case TargetLowering::Promote:
- // We defer the promotion to when we legalize the op
- break;
- case TargetLowering::Expand:
- // Expand the operation into a bunch of nasty scalar code.
- Result = LegalizeOp(UnrollVectorOp(Result));
- break;
- }
break;
}
case ISD::SIGN_EXTEND:
case ISD::ZERO_EXTEND:
case ISD::ANY_EXTEND:
- case ISD::FP_ROUND:
case ISD::SIGN_EXTEND_INREG:
case ISD::FABS:
case ISD::FNEG:
case ISD::CTTZ:
case ISD::CTLZ: {
// Unary op widening
- SDValue Tmp1;
- TargetLowering::LegalizeAction action =
- TLI.getOperationAction(Node->getOpcode(), WidenVT);
-
+ SDValue Tmp1;
Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT);
assert(Tmp1.getValueType() == WidenVT);
Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1);
- switch (action) {
- default: assert(0 && "action not supported");
- case TargetLowering::Legal:
- break;
- case TargetLowering::Promote:
- // We defer the promotion to when we legalize the op
- break;
- case TargetLowering::Expand:
- // Expand the operation into a bunch of nasty scalar code.
- Result = LegalizeOp(UnrollVectorOp(Result));
- break;
- }
break;
}
case ISD::CONVERT_RNDSAT: {
SDValue RndOp = Node->getOperand(3);
SDValue SatOp = Node->getOperand(4);
-
- TargetLowering::LegalizeAction action =
- TLI.getOperationAction(Node->getOpcode(), WidenVT);
-
SDValue SrcOp = Node->getOperand(0);
// Converts between two different types so we need to determine
Result = DAG.getConvertRndSat(WidenVT, SrcOp, DTyOp, STyOp,
RndOp, SatOp, CvtCode);
- switch (action) {
- default: assert(0 && "action not supported");
- case TargetLowering::Legal:
- break;
- case TargetLowering::Promote:
- // We defer the promotion to when we legalize the op
- break;
- case TargetLowering::Expand:
- // Expand the operation into a bunch of nasty scalar code.
- Result = LegalizeOp(UnrollVectorOp(Result));
- break;
- }
break;
}
case ISD::FPOW:
case ISD::UREM:
case ISD::BSWAP: {
// Binary op widening
- TargetLowering::LegalizeAction action =
- TLI.getOperationAction(Node->getOpcode(), WidenVT);
-
SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT);
SDValue Tmp2 = WidenVectorOp(Node->getOperand(1), WidenVT);
assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT);
Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Tmp2);
- switch (action) {
- default: assert(0 && "action not supported");
- case TargetLowering::Legal:
- break;
- case TargetLowering::Promote:
- // We defer the promotion to when we legalize the op
- break;
- case TargetLowering::Expand:
- // Expand the operation into a bunch of nasty scalar code by first
- // Widening to the right type and then unroll the beast.
- Result = LegalizeOp(UnrollVectorOp(Result));
- break;
- }
break;
}
case ISD::SHL:
case ISD::SRA:
case ISD::SRL: {
- // Binary op with one non vector operand
- TargetLowering::LegalizeAction action =
- TLI.getOperationAction(Node->getOpcode(), WidenVT);
-
SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT);
assert(Tmp1.getValueType() == WidenVT);
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Node->getOperand(1));
- switch (action) {
- default: assert(0 && "action not supported");
- case TargetLowering::Legal:
- break;
- case TargetLowering::Promote:
- // We defer the promotion to when we legalize the op
- break;
- case TargetLowering::Expand:
- // Expand the operation into a bunch of nasty scalar code.
- Result = LegalizeOp(UnrollVectorOp(Result));
- break;
- }
+ SDValue ShOp = Node->getOperand(1);
+ MVT ShVT = ShOp.getValueType();
+ MVT NewShVT = MVT::getVectorVT(ShVT.getVectorElementType(),
+ WidenVT.getVectorNumElements());
+ ShOp = WidenVectorOp(ShOp, NewShVT);
+ assert(ShOp.getValueType() == NewShVT);
+ Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, ShOp);
break;
}
+
case ISD::EXTRACT_VECTOR_ELT: {
SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT);
assert(Tmp1.getValueType() == WidenVT);
// We could widen on a multiple of the incoming operand if necessary.
unsigned NumConcat = NewNumElts / NumElts;
assert(NewNumElts % NumElts == 0 && "Can widen only a multiple of vector");
- std::vector<SDValue> UnOps(NumElts, DAG.getNode(ISD::UNDEF,
- VT.getVectorElementType()));
- SDValue UndefVal = DAG.getNode(ISD::BUILD_VECTOR, VT,
- &UnOps[0], UnOps.size());
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, VT);
SmallVector<SDValue, 8> MOps;
MOps.push_back(Op);
for (unsigned i = 1; i != NumConcat; ++i) {
}
case ISD::SELECT: {
- TargetLowering::LegalizeAction action =
- TLI.getOperationAction(Node->getOpcode(), WidenVT);
-
// Determine new condition widen type and widen
SDValue Cond1 = Node->getOperand(0);
MVT CondVT = Cond1.getValueType();
SDValue Tmp2 = WidenVectorOp(Node->getOperand(2), WidenVT);
assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT);
Result = DAG.getNode(Node->getOpcode(), WidenVT, Cond1, Tmp1, Tmp2);
- switch (action) {
- default: assert(0 && "action not supported");
- case TargetLowering::Legal:
- break;
- case TargetLowering::Promote:
- // We defer the promotion to when we legalize the op
- break;
- case TargetLowering::Expand:
- // Expand the operation into a bunch of nasty scalar code by first
- // Widening to the right type and then unroll the beast.
- Result = LegalizeOp(UnrollVectorOp(Result));
- break;
- }
break;
}
case ISD::SELECT_CC: {
- TargetLowering::LegalizeAction action =
- TLI.getOperationAction(Node->getOpcode(), WidenVT);
-
// Determine new condition widen type and widen
SDValue Cond1 = Node->getOperand(0);
SDValue Cond2 = Node->getOperand(1);
"operands not widen");
Result = DAG.getNode(Node->getOpcode(), WidenVT, Cond1, Cond2, Tmp1,
Tmp2, Node->getOperand(4));
- switch (action) {
- default: assert(0 && "action not supported");
- case TargetLowering::Legal:
- break;
- case TargetLowering::Promote:
- // We defer the promotion to when we legalize the op
- break;
- case TargetLowering::Expand:
- // Expand the operation into a bunch of nasty scalar code by first
- // Widening to the right type and then unroll the beast.
- Result = LegalizeOp(UnrollVectorOp(Result));
- break;
- }
break;
}
case ISD::VSETCC: {
MVT TmpWidenVT = MVT::getVectorVT(TmpEVT, NewNumElts);
Tmp1 = WidenVectorOp(Tmp1, TmpWidenVT);
SDValue Tmp2 = WidenVectorOp(Node->getOperand(1), TmpWidenVT);
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Tmp2,
+ Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Tmp2,
Node->getOperand(2));
break;
}
- case ISD::ATOMIC_CMP_SWAP_8:
- case ISD::ATOMIC_CMP_SWAP_16:
- case ISD::ATOMIC_CMP_SWAP_32:
- case ISD::ATOMIC_CMP_SWAP_64:
- case ISD::ATOMIC_LOAD_ADD_8:
- case ISD::ATOMIC_LOAD_SUB_8:
- case ISD::ATOMIC_LOAD_AND_8:
- case ISD::ATOMIC_LOAD_OR_8:
- case ISD::ATOMIC_LOAD_XOR_8:
- case ISD::ATOMIC_LOAD_NAND_8:
- case ISD::ATOMIC_LOAD_MIN_8:
- case ISD::ATOMIC_LOAD_MAX_8:
- case ISD::ATOMIC_LOAD_UMIN_8:
- case ISD::ATOMIC_LOAD_UMAX_8:
- case ISD::ATOMIC_SWAP_8:
- case ISD::ATOMIC_LOAD_ADD_16:
- case ISD::ATOMIC_LOAD_SUB_16:
- case ISD::ATOMIC_LOAD_AND_16:
- case ISD::ATOMIC_LOAD_OR_16:
- case ISD::ATOMIC_LOAD_XOR_16:
- case ISD::ATOMIC_LOAD_NAND_16:
- case ISD::ATOMIC_LOAD_MIN_16:
- case ISD::ATOMIC_LOAD_MAX_16:
- case ISD::ATOMIC_LOAD_UMIN_16:
- case ISD::ATOMIC_LOAD_UMAX_16:
- case ISD::ATOMIC_SWAP_16:
- case ISD::ATOMIC_LOAD_ADD_32:
- case ISD::ATOMIC_LOAD_SUB_32:
- case ISD::ATOMIC_LOAD_AND_32:
- case ISD::ATOMIC_LOAD_OR_32:
- case ISD::ATOMIC_LOAD_XOR_32:
- case ISD::ATOMIC_LOAD_NAND_32:
- case ISD::ATOMIC_LOAD_MIN_32:
- case ISD::ATOMIC_LOAD_MAX_32:
- case ISD::ATOMIC_LOAD_UMIN_32:
- case ISD::ATOMIC_LOAD_UMAX_32:
- case ISD::ATOMIC_SWAP_32:
- case ISD::ATOMIC_LOAD_ADD_64:
- case ISD::ATOMIC_LOAD_SUB_64:
- case ISD::ATOMIC_LOAD_AND_64:
- case ISD::ATOMIC_LOAD_OR_64:
- case ISD::ATOMIC_LOAD_XOR_64:
- case ISD::ATOMIC_LOAD_NAND_64:
- case ISD::ATOMIC_LOAD_MIN_64:
- case ISD::ATOMIC_LOAD_MAX_64:
- case ISD::ATOMIC_LOAD_UMIN_64:
- case ISD::ATOMIC_LOAD_UMAX_64:
- case ISD::ATOMIC_SWAP_64: {
+ case ISD::ATOMIC_CMP_SWAP:
+ case ISD::ATOMIC_LOAD_ADD:
+ case ISD::ATOMIC_LOAD_SUB:
+ case ISD::ATOMIC_LOAD_AND:
+ case ISD::ATOMIC_LOAD_OR:
+ case ISD::ATOMIC_LOAD_XOR:
+ case ISD::ATOMIC_LOAD_NAND:
+ case ISD::ATOMIC_LOAD_MIN:
+ case ISD::ATOMIC_LOAD_MAX:
+ case ISD::ATOMIC_LOAD_UMIN:
+ case ISD::ATOMIC_LOAD_UMAX:
+ case ISD::ATOMIC_SWAP: {
// For now, we assume that using vectors for these operations don't make
// much sense so we just split it. We return an empty result
SDValue X, Y;
// Width: Preferred width of element type
// VVT: Vector value type whose size we must match.
// Returns VecEVT and EVT - the vector type and its associated element type
-static void FindWidenVecType(TargetLowering &TLI, unsigned Width, MVT VVT,
+static void FindWidenVecType(const TargetLowering &TLI, unsigned Width, MVT VVT,
MVT& EVT, MVT& VecEVT) {
// We start with the preferred width, make it a power of 2 and see if
// we can find a vector type of that width. If not, we reduce it by
// It must be true that we the widen vector type is bigger than where
// we need to store.
assert(StVT.isVector() && VVT.isVector());
- assert(StVT.getSizeInBits() < VVT.getSizeInBits());
+ assert(StVT.bitsLT(VVT));
assert(StVT.getVectorElementType() == VVT.getVectorElementType());
// Store value
// SelectionDAG::Legalize - This is the entry point for the file.
//
-void SelectionDAG::Legalize() {
+void SelectionDAG::Legalize(bool TypesNeedLegalizing) {
/// run - This is the main entry point to this class.
///
- SelectionDAGLegalize(*this).LegalizeDAG();
+ SelectionDAGLegalize(*this, TypesNeedLegalizing).LegalizeDAG();
}