Changeset View
Changeset View
Standalone View
Standalone View
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Show First 20 Lines • Show All 3,893 Lines • ▼ Show 20 Lines | for (unsigned Idx = 0; Idx < NumElem; Idx++) { | ||||
Scalars.push_back(DAG.getNode(Node->getOpcode(), dl, | Scalars.push_back(DAG.getNode(Node->getOpcode(), dl, | ||||
VT.getScalarType(), Ex, Sh)); | VT.getScalarType(), Ex, Sh)); | ||||
} | } | ||||
SDValue Result = DAG.getBuildVector(Node->getValueType(0), dl, Scalars); | SDValue Result = DAG.getBuildVector(Node->getValueType(0), dl, Scalars); | ||||
ReplaceNode(SDValue(Node, 0), Result); | ReplaceNode(SDValue(Node, 0), Result); | ||||
break; | break; | ||||
} | } | ||||
case ISD::ROTL: | |||||
case ISD::ROTR: { | |||||
bool IsLeft = Node->getOpcode() == ISD::ROTL; | |||||
SDValue Op0 = Node->getOperand(0), Op1 = Node->getOperand(1); | |||||
EVT ResVT = Node->getValueType(0); | |||||
EVT OpVT = Op0.getValueType(); | |||||
assert(OpVT == ResVT && | |||||
"The result and the operand types of rotate should match"); | |||||
EVT ShVT = Op1.getValueType(); | |||||
SDValue Width = DAG.getConstant(OpVT.getScalarSizeInBits(), dl, ShVT); | |||||
RKSimon: Use OpVT.getScalarSizeInBits() - hopefully we might be able to use this for vector cases as… | |||||
// If a rotate in the other direction is legal, use it. | |||||
unsigned RevRot = IsLeft ? ISD::ROTR : ISD::ROTL; | |||||
if (TLI.isOperationLegal(RevRot, ResVT)) { | |||||
SDValue Sub = DAG.getNode(ISD::SUB, dl, ShVT, Width, Op1); | |||||
Results.push_back(DAG.getNode(RevRot, dl, ResVT, Op0, Sub)); | |||||
Move the Sub = DAG.getNode into the if() case? I don't think its used anywhere else. RKSimon: Move the Sub = DAG.getNode into the if() case? I don't think its used anywhere else. | |||||
break; | |||||
} | |||||
// Otherwise, | |||||
// (rotl x, c) -> (or (shl x, (and c, w-1)), (srl x, (and -c, w-1))) | |||||
// (rotr x, c) -> (or (srl x, (and c, w-1)), (shl x, (and -c, w-1))) | |||||
Is there any way that we can get here with a bit width that isn't power-of-two? In which case we'd have to adjust this and use UREM not AND........ RKSimon: Is there any way that we can get here with a bit width that isn't power-of-two? In which case… | |||||
// | |||||
assert(isPowerOf2_32(OpVT.getScalarSizeInBits()) && | |||||
"Expecting the type bitwidth to be a power of 2"); | |||||
unsigned ShOpc = IsLeft ? ISD::SHL : ISD::SRL; | |||||
unsigned HsOpc = IsLeft ? ISD::SRL : ISD::SHL; | |||||
This lowering is wrong (consider c==0, c==64). Maybe (or (shl x, (and c, w-1), (srl x, (and (sub 0, c), w-1)) instead? efriedma: This lowering is wrong (consider c==0, c==64). Maybe `(or (shl x, (and c, w-1), (srl x, (and… | |||||
SDValue Width1 = DAG.getNode(ISD::SUB, dl, ShVT, | |||||
Width, DAG.getConstant(1, dl, ShVT)); | |||||
SDValue NegOp1 = DAG.getNode(ISD::SUB, dl, ShVT, | |||||
DAG.getConstant(0, dl, ShVT), Op1); | |||||
SDValue And0 = DAG.getNode(ISD::AND, dl, ShVT, Op1, Width1); | |||||
SDValue And1 = DAG.getNode(ISD::AND, dl, ShVT, NegOp1, Width1); | |||||
SDValue Or = DAG.getNode(ISD::OR, dl, ResVT, | |||||
DAG.getNode(ShOpc, dl, ResVT, Op0, And0), | |||||
DAG.getNode(HsOpc, dl, ResVT, Op0, And1)); | |||||
Results.push_back(Or); | |||||
break; | |||||
} | |||||
case ISD::GLOBAL_OFFSET_TABLE: | case ISD::GLOBAL_OFFSET_TABLE: | ||||
case ISD::GlobalAddress: | case ISD::GlobalAddress: | ||||
case ISD::GlobalTLSAddress: | case ISD::GlobalTLSAddress: | ||||
case ISD::ExternalSymbol: | case ISD::ExternalSymbol: | ||||
case ISD::ConstantPool: | case ISD::ConstantPool: | ||||
case ISD::JumpTable: | case ISD::JumpTable: | ||||
case ISD::INTRINSIC_W_CHAIN: | case ISD::INTRINSIC_W_CHAIN: | ||||
case ISD::INTRINSIC_WO_CHAIN: | case ISD::INTRINSIC_WO_CHAIN: | ||||
▲ Show 20 Lines • Show All 840 Lines • Show Last 20 Lines |
Use OpVT.getScalarSizeInBits() - hopefully we might be able to use this for vector cases as well at some point soon.