@@ -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