@@ -1027,6 +1027,64 @@ pickOpcodeForVT(MVT::SimpleValueType VT, std::optional<unsigned> Opcode_i16,
10271027 }
10281028}
10291029
1030+ static inline bool isAddLike (const SDValue V) {
1031+ return V.getOpcode () == ISD::ADD ||
1032+ (V->getOpcode () == ISD::OR && V->getFlags ().hasDisjoint ());
1033+ }
1034+
1035+ // selectBaseADDR - Match a dag node which will serve as the base address for an
1036+ // ADDR operand pair.
1037+ static SDValue selectBaseADDR (SDValue N, SelectionDAG *DAG) {
1038+ if (const auto *GA = dyn_cast<GlobalAddressSDNode>(N))
1039+ return DAG->getTargetGlobalAddress (GA->getGlobal (), SDLoc (N),
1040+ GA->getValueType (0 ), GA->getOffset (),
1041+ GA->getTargetFlags ());
1042+ if (const auto *ES = dyn_cast<ExternalSymbolSDNode>(N))
1043+ return DAG->getTargetExternalSymbol (ES->getSymbol (), ES->getValueType (0 ),
1044+ ES->getTargetFlags ());
1045+ if (const auto *FIN = dyn_cast<FrameIndexSDNode>(N))
1046+ return DAG->getTargetFrameIndex (FIN->getIndex (), FIN->getValueType (0 ));
1047+
1048+ return N;
1049+ }
1050+
1051+ static SDValue accumulateOffset (SDValue &Addr, SDLoc DL, SelectionDAG *DAG) {
1052+ APInt AccumulatedOffset (64u , 0 );
1053+ while (isAddLike (Addr)) {
1054+ const auto *CN = dyn_cast<ConstantSDNode>(Addr.getOperand (1 ));
1055+ if (!CN)
1056+ break ;
1057+
1058+ const APInt CI = CN->getAPIntValue ().sext (64 );
1059+ if (!(CI + AccumulatedOffset).isSignedIntN (32 ))
1060+ break ;
1061+
1062+ AccumulatedOffset += CI;
1063+ Addr = Addr->getOperand (0 );
1064+ }
1065+ return DAG->getSignedTargetConstant (AccumulatedOffset.getSExtValue (), DL,
1066+ MVT::i32 );
1067+ }
1068+
1069+ static std::pair<SDValue, SDValue> selectADDR (SDValue Addr, SelectionDAG *DAG) {
1070+ SDValue Offset = accumulateOffset (Addr, SDLoc (Addr), DAG);
1071+ SDValue Base = selectBaseADDR (Addr, DAG);
1072+ return {Base, Offset};
1073+ }
1074+
1075+ // Select a pair of operands which represent a valid PTX address, this could be
1076+ // one of the following things:
1077+ // - [var] - Offset is simply set to 0
1078+ // - [reg] - Offset is simply set to 0
1079+ // - [reg+immOff]
1080+ // - [var+immOff]
1081+ // Note that immOff must fit into a 32-bit signed integer.
1082+ bool NVPTXDAGToDAGISel::SelectADDR (SDValue Addr, SDValue &Base,
1083+ SDValue &Offset) {
1084+ std::tie (Base, Offset) = selectADDR (Addr, CurDAG);
1085+ return true ;
1086+ }
1087+
10301088bool NVPTXDAGToDAGISel::tryLoad (SDNode *N) {
10311089 MemSDNode *LD = cast<MemSDNode>(N);
10321090 assert (LD->readMem () && " Expected load" );
@@ -1062,8 +1120,7 @@ bool NVPTXDAGToDAGISel::tryLoad(SDNode *N) {
10621120 FromTypeWidth <= 128 && " Invalid width for load" );
10631121
10641122 // Create the machine instruction DAG
1065- SDValue Offset, Base;
1066- SelectADDR (N->getOperand (1 ), Base, Offset);
1123+ const auto [Base, Offset] = selectADDR (N->getOperand (1 ), CurDAG);
10671124 SDValue Ops[] = {getI32Imm (Ordering, DL),
10681125 getI32Imm (Scope, DL),
10691126 getI32Imm (CodeAddrSpace, DL),
@@ -1144,8 +1201,7 @@ bool NVPTXDAGToDAGISel::tryLoadVector(SDNode *N) {
11441201 assert (isPowerOf2_32 (FromTypeWidth) && FromTypeWidth >= 8 &&
11451202 FromTypeWidth <= 128 && TotalWidth <= 256 && " Invalid width for load" );
11461203
1147- SDValue Offset, Base;
1148- SelectADDR (N->getOperand (1 ), Base, Offset);
1204+ const auto [Base, Offset] = selectADDR (N->getOperand (1 ), CurDAG);
11491205 SDValue Ops[] = {getI32Imm (Ordering, DL),
11501206 getI32Imm (Scope, DL),
11511207 getI32Imm (CodeAddrSpace, DL),
@@ -1213,8 +1269,7 @@ bool NVPTXDAGToDAGISel::tryLDG(MemSDNode *LD) {
12131269 assert (isPowerOf2_32 (FromTypeWidth) && FromTypeWidth >= 8 &&
12141270 FromTypeWidth <= 128 && TotalWidth <= 256 && " Invalid width for load" );
12151271
1216- SDValue Base, Offset;
1217- SelectADDR (LD->getOperand (1 ), Base, Offset);
1272+ const auto [Base, Offset] = selectADDR (LD->getOperand (1 ), CurDAG);
12181273 SDValue Ops[] = {getI32Imm (FromType, DL), getI32Imm (FromTypeWidth, DL), Base,
12191274 Offset, LD->getChain ()};
12201275
@@ -1278,8 +1333,7 @@ bool NVPTXDAGToDAGISel::tryLDU(SDNode *N) {
12781333 SDValue Addr =
12791334 LD->getOperand (LD->getOpcode () == ISD::INTRINSIC_W_CHAIN ? 2 : 1 );
12801335
1281- SDValue Base, Offset;
1282- SelectADDR (Addr, Base, Offset);
1336+ const auto [Base, Offset] = selectADDR (Addr, CurDAG);
12831337 SDValue Ops[] = {getI32Imm (FromTypeWidth, DL), Base, Offset, LD->getChain ()};
12841338
12851339 std::optional<unsigned > Opcode;
@@ -1339,9 +1393,7 @@ bool NVPTXDAGToDAGISel::tryStore(SDNode *N) {
13391393 assert (isPowerOf2_32 (ToTypeWidth) && ToTypeWidth >= 8 && ToTypeWidth <= 128 &&
13401394 " Invalid width for store" );
13411395
1342- SDValue Offset, Base;
1343- SelectADDR (ST->getBasePtr (), Base, Offset);
1344-
1396+ const auto [Base, Offset] = selectADDR (ST->getBasePtr (), CurDAG);
13451397 SDValue Ops[] = {selectPossiblyImm (Value),
13461398 getI32Imm (Ordering, DL),
13471399 getI32Imm (Scope, DL),
@@ -1399,9 +1451,7 @@ bool NVPTXDAGToDAGISel::tryStoreVector(SDNode *N) {
13991451 assert (isPowerOf2_32 (ToTypeWidth) && ToTypeWidth >= 8 && ToTypeWidth <= 128 &&
14001452 TotalWidth <= 256 && " Invalid width for store" );
14011453
1402- SDValue Offset, Base;
1403- SelectADDR (Addr, Base, Offset);
1404-
1454+ const auto [Base, Offset] = selectADDR (Addr, CurDAG);
14051455 Ops.append ({getI32Imm (Ordering, DL), getI32Imm (Scope, DL),
14061456 getI32Imm (CodeAddrSpace, DL), getI32Imm (ToTypeWidth, DL), Base,
14071457 Offset, Chain});
@@ -1708,59 +1758,6 @@ bool NVPTXDAGToDAGISel::tryBF16ArithToFMA(SDNode *N) {
17081758 return true ;
17091759}
17101760
1711- static inline bool isAddLike (const SDValue V) {
1712- return V.getOpcode () == ISD::ADD ||
1713- (V->getOpcode () == ISD::OR && V->getFlags ().hasDisjoint ());
1714- }
1715-
1716- // selectBaseADDR - Match a dag node which will serve as the base address for an
1717- // ADDR operand pair.
1718- static SDValue selectBaseADDR (SDValue N, SelectionDAG *DAG) {
1719- if (const auto *GA = dyn_cast<GlobalAddressSDNode>(N))
1720- return DAG->getTargetGlobalAddress (GA->getGlobal (), SDLoc (N),
1721- GA->getValueType (0 ), GA->getOffset (),
1722- GA->getTargetFlags ());
1723- if (const auto *ES = dyn_cast<ExternalSymbolSDNode>(N))
1724- return DAG->getTargetExternalSymbol (ES->getSymbol (), ES->getValueType (0 ),
1725- ES->getTargetFlags ());
1726- if (const auto *FIN = dyn_cast<FrameIndexSDNode>(N))
1727- return DAG->getTargetFrameIndex (FIN->getIndex (), FIN->getValueType (0 ));
1728-
1729- return N;
1730- }
1731-
1732- static SDValue accumulateOffset (SDValue &Addr, SDLoc DL, SelectionDAG *DAG) {
1733- APInt AccumulatedOffset (64u , 0 );
1734- while (isAddLike (Addr)) {
1735- const auto *CN = dyn_cast<ConstantSDNode>(Addr.getOperand (1 ));
1736- if (!CN)
1737- break ;
1738-
1739- const APInt CI = CN->getAPIntValue ().sext (64 );
1740- if (!(CI + AccumulatedOffset).isSignedIntN (32 ))
1741- break ;
1742-
1743- AccumulatedOffset += CI;
1744- Addr = Addr->getOperand (0 );
1745- }
1746- return DAG->getSignedTargetConstant (AccumulatedOffset.getSExtValue (), DL,
1747- MVT::i32 );
1748- }
1749-
1750- // Select a pair of operands which represent a valid PTX address, this could be
1751- // one of the following things:
1752- // - [var] - Offset is simply set to 0
1753- // - [reg] - Offset is simply set to 0
1754- // - [reg+immOff]
1755- // - [var+immOff]
1756- // Note that immOff must fit into a 32-bit signed integer.
1757- bool NVPTXDAGToDAGISel::SelectADDR (SDValue Addr, SDValue &Base,
1758- SDValue &Offset) {
1759- Offset = accumulateOffset (Addr, SDLoc (Addr), CurDAG);
1760- Base = selectBaseADDR (Addr, CurDAG);
1761- return true ;
1762- }
1763-
17641761SDValue NVPTXDAGToDAGISel::selectPossiblyImm (SDValue V) {
17651762 if (V.getOpcode () == ISD::BITCAST)
17661763 V = V.getOperand (0 );
@@ -1774,37 +1771,20 @@ SDValue NVPTXDAGToDAGISel::selectPossiblyImm(SDValue V) {
17741771 return V;
17751772}
17761773
1777- bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace (SDNode *N,
1778- unsigned int spN) const {
1779- const Value *Src = nullptr ;
1780- if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
1781- if (spN == 0 && mN ->getMemOperand ()->getPseudoValue ())
1782- return true ;
1783- Src = mN ->getMemOperand ()->getValue ();
1784- }
1785- if (!Src)
1786- return false ;
1787- if (auto *PT = dyn_cast<PointerType>(Src->getType ()))
1788- return (PT->getAddressSpace () == spN);
1789- return false ;
1790- }
1791-
17921774// / SelectInlineAsmMemoryOperand - Implement addressing mode selection for
17931775// / inline asm expressions.
17941776bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand (
17951777 const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
17961778 std::vector<SDValue> &OutOps) {
1797- SDValue Op0, Op1;
17981779 switch (ConstraintID) {
17991780 default :
18001781 return true ;
1801- case InlineAsm::ConstraintCode::m: // memory
1802- if (SelectADDR (Op, Op0, Op1)) {
1803- OutOps.push_back (Op0);
1804- OutOps.push_back (Op1);
1805- return false ;
1806- }
1807- break ;
1782+ case InlineAsm::ConstraintCode::m: { // memory
1783+ const auto [Base, Offset] = selectADDR (Op, CurDAG);
1784+ OutOps.push_back (Base);
1785+ OutOps.push_back (Offset);
1786+ return false ;
1787+ }
18081788 }
18091789 return true ;
18101790}
0 commit comments