Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 9,368 Lines • ▼ Show 20 Lines | assert(TopHalf && BottomHalf && | ||||
"One half of the selector was all UNDEFs and the other was all the " | "One half of the selector was all UNDEFs and the other was all the " | ||||
"same value. This should have been addressed before this function."); | "same value. This should have been addressed before this function."); | ||||
return DAG.getNode( | return DAG.getNode( | ||||
ISD::CONCAT_VECTORS, DL, VT, | ISD::CONCAT_VECTORS, DL, VT, | ||||
BottomHalf->isNullValue() ? RHS->getOperand(0) : LHS->getOperand(0), | BottomHalf->isNullValue() ? RHS->getOperand(0) : LHS->getOperand(0), | ||||
TopHalf->isNullValue() ? RHS->getOperand(1) : LHS->getOperand(1)); | TopHalf->isNullValue() ? RHS->getOperand(1) : LHS->getOperand(1)); | ||||
} | } | ||||
bool refineUniformBase(SDValue &BasePtr, SDValue &Index) { | |||||
if (!isNullConstant(BasePtr) || Index.getOpcode() != ISD::ADD) | |||||
return false; | |||||
// For now we check only the LHS of the add. | |||||
SDValue LHS = Index.getOperand(0); | |||||
if (LHS.getOpcode() != ISD::SPLAT_VECTOR) | |||||
return false; | |||||
SDValue SplatValue = LHS.getOperand(0); | |||||
if (SplatValue.getSimpleValueType() != MVT::i64) | |||||
sdesmalen: This seems specific to AArch64 which has 64bit pointers. But I'd think this check is not needed… | |||||
return false; | |||||
BasePtr = SplatValue; | |||||
Index = Index.getOperand(1); | |||||
return true; | |||||
} | |||||
// Fold sext/zext of index into index type. | |||||
bool refineIndexType(MaskedScatterSDNode *MSC, SDValue &Index, | |||||
bool Scaled, SelectionDAG &DAG) { | |||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo(); | |||||
SDValue Op = Index.getOperand(0); | |||||
if (Index.getOpcode() == ISD::ZERO_EXTEND) { | |||||
MSC->setIndexType(Scaled ? ISD::UNSIGNED_SCALED : ISD::UNSIGNED_UNSCALED); | |||||
This condition isn't correct, I think you want to always set the index type to unsigned when the index is zero-extended. Only the setting of Index to be the source operand of the zero-extend needs to be guarded by TLI.isLegalMaskedGSIndexType. (same for the sign-extend case below). sdesmalen: This condition isn't correct, I think you want to always set the index type to unsigned when… | |||||
if (TLI.isLegalMaskedGSIndexType(Op.getValueType())) { | |||||
Index = Op; | |||||
return true; | |||||
} | |||||
} | |||||
if (Index.getOpcode() == ISD::SIGN_EXTEND) { | |||||
MSC->setIndexType(Scaled ? ISD::SIGNED_SCALED : ISD::SIGNED_UNSCALED); | |||||
if (TLI.isLegalMaskedGSIndexType(Op.getValueType())) { | |||||
Index = Op; | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
SDValue DAGCombiner::visitMSCATTER(SDNode *N) { | SDValue DAGCombiner::visitMSCATTER(SDNode *N) { | ||||
MaskedScatterSDNode *MSC = cast<MaskedScatterSDNode>(N); | MaskedScatterSDNode *MSC = cast<MaskedScatterSDNode>(N); | ||||
SDValue Mask = MSC->getMask(); | SDValue Mask = MSC->getMask(); | ||||
SDValue Chain = MSC->getChain(); | SDValue Chain = MSC->getChain(); | ||||
SDValue Index = MSC->getIndex(); | |||||
SDValue Scale = MSC->getScale(); | |||||
SDValue StoreVal = MSC->getValue(); | |||||
SDValue BasePtr = MSC->getBasePtr(); | |||||
SDLoc DL(N); | SDLoc DL(N); | ||||
// Zap scatters with a zero mask. | // Zap scatters with a zero mask. | ||||
if (ISD::isBuildVectorAllZeros(Mask.getNode())) | if (ISD::isBuildVectorAllZeros(Mask.getNode())) | ||||
return Chain; | return Chain; | ||||
if (refineUniformBase(BasePtr, Index)) { | |||||
SDValue Ops[] = {Chain, StoreVal, Mask, BasePtr, Index, Scale}; | |||||
return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), | |||||
StoreVal.getValueType(), DL, Ops, | |||||
MSC->getMemOperand(), | |||||
MSC->getIndexType(), MSC->isTruncatingStore()); | |||||
} | |||||
if (refineIndexType(MSC, Index, MSC->isIndexScaled(), DAG)) { | |||||
SDValue Ops[] = {Chain, StoreVal, Mask, BasePtr, Index, Scale}; | |||||
return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), | |||||
StoreVal.getValueType(), DL, Ops, | |||||
MSC->getMemOperand(), | |||||
MSC->getIndexType(), MSC->isTruncatingStore()); | |||||
} | |||||
return SDValue(); | return SDValue(); | ||||
} | } | ||||
SDValue DAGCombiner::visitMSTORE(SDNode *N) { | SDValue DAGCombiner::visitMSTORE(SDNode *N) { | ||||
MaskedStoreSDNode *MST = cast<MaskedStoreSDNode>(N); | MaskedStoreSDNode *MST = cast<MaskedStoreSDNode>(N); | ||||
SDValue Mask = MST->getMask(); | SDValue Mask = MST->getMask(); | ||||
SDValue Chain = MST->getChain(); | SDValue Chain = MST->getChain(); | ||||
SDLoc DL(N); | SDLoc DL(N); | ||||
▲ Show 20 Lines • Show All 13,029 Lines • Show Last 20 Lines |
This seems specific to AArch64 which has 64bit pointers. But I'd think this check is not needed to begin with, because the MaskedGS BasePtr must be a scalar pointer, or a vector of pointers, so the splat value would always be a pointer type (which I assume this code is checking).