@@ -1027,6 +1027,64 @@ pickOpcodeForVT(MVT::SimpleValueType VT, std::optional<unsigned> Opcode_i16,
1027
1027
}
1028
1028
}
1029
1029
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
+
1030
1088
bool NVPTXDAGToDAGISel::tryLoad (SDNode *N) {
1031
1089
MemSDNode *LD = cast<MemSDNode>(N);
1032
1090
assert (LD->readMem () && " Expected load" );
@@ -1062,8 +1120,7 @@ bool NVPTXDAGToDAGISel::tryLoad(SDNode *N) {
1062
1120
FromTypeWidth <= 128 && " Invalid width for load" );
1063
1121
1064
1122
// 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);
1067
1124
SDValue Ops[] = {getI32Imm (Ordering, DL),
1068
1125
getI32Imm (Scope, DL),
1069
1126
getI32Imm (CodeAddrSpace, DL),
@@ -1144,8 +1201,7 @@ bool NVPTXDAGToDAGISel::tryLoadVector(SDNode *N) {
1144
1201
assert (isPowerOf2_32 (FromTypeWidth) && FromTypeWidth >= 8 &&
1145
1202
FromTypeWidth <= 128 && TotalWidth <= 256 && " Invalid width for load" );
1146
1203
1147
- SDValue Offset, Base;
1148
- SelectADDR (N->getOperand (1 ), Base, Offset);
1204
+ const auto [Base, Offset] = selectADDR (N->getOperand (1 ), CurDAG);
1149
1205
SDValue Ops[] = {getI32Imm (Ordering, DL),
1150
1206
getI32Imm (Scope, DL),
1151
1207
getI32Imm (CodeAddrSpace, DL),
@@ -1213,8 +1269,7 @@ bool NVPTXDAGToDAGISel::tryLDG(MemSDNode *LD) {
1213
1269
assert (isPowerOf2_32 (FromTypeWidth) && FromTypeWidth >= 8 &&
1214
1270
FromTypeWidth <= 128 && TotalWidth <= 256 && " Invalid width for load" );
1215
1271
1216
- SDValue Base, Offset;
1217
- SelectADDR (LD->getOperand (1 ), Base, Offset);
1272
+ const auto [Base, Offset] = selectADDR (LD->getOperand (1 ), CurDAG);
1218
1273
SDValue Ops[] = {getI32Imm (FromType, DL), getI32Imm (FromTypeWidth, DL), Base,
1219
1274
Offset, LD->getChain ()};
1220
1275
@@ -1278,8 +1333,7 @@ bool NVPTXDAGToDAGISel::tryLDU(SDNode *N) {
1278
1333
SDValue Addr =
1279
1334
LD->getOperand (LD->getOpcode () == ISD::INTRINSIC_W_CHAIN ? 2 : 1 );
1280
1335
1281
- SDValue Base, Offset;
1282
- SelectADDR (Addr, Base, Offset);
1336
+ const auto [Base, Offset] = selectADDR (Addr, CurDAG);
1283
1337
SDValue Ops[] = {getI32Imm (FromTypeWidth, DL), Base, Offset, LD->getChain ()};
1284
1338
1285
1339
std::optional<unsigned > Opcode;
@@ -1339,9 +1393,7 @@ bool NVPTXDAGToDAGISel::tryStore(SDNode *N) {
1339
1393
assert (isPowerOf2_32 (ToTypeWidth) && ToTypeWidth >= 8 && ToTypeWidth <= 128 &&
1340
1394
" Invalid width for store" );
1341
1395
1342
- SDValue Offset, Base;
1343
- SelectADDR (ST->getBasePtr (), Base, Offset);
1344
-
1396
+ const auto [Base, Offset] = selectADDR (ST->getBasePtr (), CurDAG);
1345
1397
SDValue Ops[] = {selectPossiblyImm (Value),
1346
1398
getI32Imm (Ordering, DL),
1347
1399
getI32Imm (Scope, DL),
@@ -1399,9 +1451,7 @@ bool NVPTXDAGToDAGISel::tryStoreVector(SDNode *N) {
1399
1451
assert (isPowerOf2_32 (ToTypeWidth) && ToTypeWidth >= 8 && ToTypeWidth <= 128 &&
1400
1452
TotalWidth <= 256 && " Invalid width for store" );
1401
1453
1402
- SDValue Offset, Base;
1403
- SelectADDR (Addr, Base, Offset);
1404
-
1454
+ const auto [Base, Offset] = selectADDR (Addr, CurDAG);
1405
1455
Ops.append ({getI32Imm (Ordering, DL), getI32Imm (Scope, DL),
1406
1456
getI32Imm (CodeAddrSpace, DL), getI32Imm (ToTypeWidth, DL), Base,
1407
1457
Offset, Chain});
@@ -1708,59 +1758,6 @@ bool NVPTXDAGToDAGISel::tryBF16ArithToFMA(SDNode *N) {
1708
1758
return true ;
1709
1759
}
1710
1760
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
-
1764
1761
SDValue NVPTXDAGToDAGISel::selectPossiblyImm (SDValue V) {
1765
1762
if (V.getOpcode () == ISD::BITCAST)
1766
1763
V = V.getOperand (0 );
@@ -1774,37 +1771,20 @@ SDValue NVPTXDAGToDAGISel::selectPossiblyImm(SDValue V) {
1774
1771
return V;
1775
1772
}
1776
1773
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
-
1792
1774
// / SelectInlineAsmMemoryOperand - Implement addressing mode selection for
1793
1775
// / inline asm expressions.
1794
1776
bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand (
1795
1777
const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
1796
1778
std::vector<SDValue> &OutOps) {
1797
- SDValue Op0, Op1;
1798
1779
switch (ConstraintID) {
1799
1780
default :
1800
1781
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
+ }
1808
1788
}
1809
1789
return true ;
1810
1790
}
0 commit comments