Skip to content

Commit 9ae92d7

Browse files
authored
[SelectionDAG] Virtualize isTargetStrictFPOpcode / isTargetMemoryOpcode (#119969)
With this change, targets are no longer required to put memory / strict-fp opcodes after special `ISD::FIRST_TARGET_MEMORY_OPCODE`/`ISD::FIRST_TARGET_STRICTFP_OPCODE` markers. This will also allow autogenerating `isTargetMemoryOpcode`/`isTargetStrictFPOpcode (#119709). Pull Request: #119969
1 parent a7cd660 commit 9ae92d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+234
-122
lines changed

llvm/include/llvm/CodeGen/ISDOpcodes.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,17 +1490,6 @@ enum NodeType {
14901490
BUILTIN_OP_END
14911491
};
14921492

1493-
/// FIRST_TARGET_STRICTFP_OPCODE - Target-specific pre-isel operations
1494-
/// which cannot raise FP exceptions should be less than this value.
1495-
/// Those that do must not be less than this value.
1496-
static const int FIRST_TARGET_STRICTFP_OPCODE = BUILTIN_OP_END + 400;
1497-
1498-
/// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations
1499-
/// which do not reference a specific memory location should be less than
1500-
/// this value. Those that do must not be less than this value, and can
1501-
/// be used with SelectionDAG::getMemIntrinsicNode.
1502-
static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END + 500;
1503-
15041493
/// Whether this is bitwise logic opcode.
15051494
inline bool isBitwiseLogicOp(unsigned Opcode) {
15061495
return Opcode == ISD::AND || Opcode == ISD::OR || Opcode == ISD::XOR;

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,8 +1330,8 @@ class SelectionDAG {
13301330

13311331
/// Creates a MemIntrinsicNode that may produce a
13321332
/// result and takes a list of operands. Opcode may be INTRINSIC_VOID,
1333-
/// INTRINSIC_W_CHAIN, or a target-specific opcode with a value not
1334-
/// less than FIRST_TARGET_MEMORY_OPCODE.
1333+
/// INTRINSIC_W_CHAIN, or a target-specific memory-referencing opcode
1334+
// (see `SelectionDAGTargetInfo::isTargetMemoryOpcode`).
13351335
SDValue getMemIntrinsicNode(
13361336
unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef<SDValue> Ops,
13371337
EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment,

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ class SDValue {
210210
inline const SDValue &getOperand(unsigned i) const;
211211
inline uint64_t getConstantOperandVal(unsigned i) const;
212212
inline const APInt &getConstantOperandAPInt(unsigned i) const;
213-
inline bool isTargetMemoryOpcode() const;
214213
inline bool isTargetOpcode() const;
215214
inline bool isMachineOpcode() const;
216215
inline bool isUndef() const;
@@ -691,22 +690,6 @@ END_TWO_BYTE_PACK()
691690
/// \<target\>ISD namespace).
692691
bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
693692

694-
/// Test if this node has a target-specific opcode that may raise
695-
/// FP exceptions (in the \<target\>ISD namespace and greater than
696-
/// FIRST_TARGET_STRICTFP_OPCODE). Note that all target memory
697-
/// opcode are currently automatically considered to possibly raise
698-
/// FP exceptions as well.
699-
bool isTargetStrictFPOpcode() const {
700-
return NodeType >= ISD::FIRST_TARGET_STRICTFP_OPCODE;
701-
}
702-
703-
/// Test if this node has a target-specific
704-
/// memory-referencing opcode (in the \<target\>ISD namespace and
705-
/// greater than FIRST_TARGET_MEMORY_OPCODE).
706-
bool isTargetMemoryOpcode() const {
707-
return NodeType >= ISD::FIRST_TARGET_MEMORY_OPCODE;
708-
}
709-
710693
/// Return true if the type of the node type undefined.
711694
bool isUndef() const { return NodeType == ISD::UNDEF; }
712695

@@ -1255,10 +1238,6 @@ inline bool SDValue::isTargetOpcode() const {
12551238
return Node->isTargetOpcode();
12561239
}
12571240

1258-
inline bool SDValue::isTargetMemoryOpcode() const {
1259-
return Node->isTargetMemoryOpcode();
1260-
}
1261-
12621241
inline bool SDValue::isMachineOpcode() const {
12631242
return Node->isMachineOpcode();
12641243
}
@@ -1615,10 +1594,10 @@ class AtomicSDNode : public MemSDNode {
16151594
}
16161595
};
16171596

1618-
/// This SDNode is used for target intrinsics that touch
1619-
/// memory and need an associated MachineMemOperand. Its opcode may be
1620-
/// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode
1621-
/// with a value not less than FIRST_TARGET_MEMORY_OPCODE.
1597+
/// This SDNode is used for target intrinsics that touch memory and need
1598+
/// an associated MachineMemOperand. Its opcode may be INTRINSIC_VOID,
1599+
/// INTRINSIC_W_CHAIN, PREFETCH, or a target-specific memory-referencing
1600+
/// opcode (see `SelectionDAGTargetInfo::isTargetMemoryOpcode`).
16221601
class MemIntrinsicSDNode : public MemSDNode {
16231602
public:
16241603
MemIntrinsicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl,

llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ class SelectionDAGTargetInfo {
3535
SelectionDAGTargetInfo &operator=(const SelectionDAGTargetInfo &) = delete;
3636
virtual ~SelectionDAGTargetInfo();
3737

38+
/// Returns true if a node with the given target-specific opcode has
39+
/// a memory operand. Nodes with such opcodes can only be created with
40+
/// `SelectionDAG::getMemIntrinsicNode`.
41+
virtual bool isTargetMemoryOpcode(unsigned Opcode) const { return false; }
42+
43+
/// Returns true if a node with the given target-specific opcode has
44+
/// strict floating-point semantics.
45+
virtual bool isTargetStrictFPOpcode(unsigned Opcode) const { return false; }
46+
47+
/// Returns true if a node with the given target-specific opcode
48+
/// may raise a floating-point exception.
49+
virtual bool mayRaiseFPException(unsigned Opcode) const;
50+
3851
/// Emit target-specific code that performs a memcpy.
3952
/// This can be used by targets to provide code sequences for cases
4053
/// that don't fit the target's parameters for simple loads/stores and can be

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9040,12 +9040,12 @@ SDValue SelectionDAG::getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl,
90409040
SDVTList VTList,
90419041
ArrayRef<SDValue> Ops, EVT MemVT,
90429042
MachineMemOperand *MMO) {
9043-
assert((Opcode == ISD::INTRINSIC_VOID ||
9044-
Opcode == ISD::INTRINSIC_W_CHAIN ||
9045-
Opcode == ISD::PREFETCH ||
9046-
(Opcode <= (unsigned)std::numeric_limits<int>::max() &&
9047-
(int)Opcode >= ISD::FIRST_TARGET_MEMORY_OPCODE)) &&
9048-
"Opcode is not a memory-accessing opcode!");
9043+
assert(
9044+
(Opcode == ISD::INTRINSIC_VOID || Opcode == ISD::INTRINSIC_W_CHAIN ||
9045+
Opcode == ISD::PREFETCH ||
9046+
(Opcode <= (unsigned)std::numeric_limits<int>::max() &&
9047+
Opcode >= ISD::BUILTIN_OP_END && TSI->isTargetMemoryOpcode(Opcode))) &&
9048+
"Opcode is not a memory-accessing opcode!");
90499049

90509050
// Memoize the node unless it returns a glue result.
90519051
MemIntrinsicSDNode *N;

llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "llvm/CodeGen/SchedulerRegistry.h"
5252
#include "llvm/CodeGen/SelectionDAG.h"
5353
#include "llvm/CodeGen/SelectionDAGNodes.h"
54+
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
5455
#include "llvm/CodeGen/StackMaps.h"
5556
#include "llvm/CodeGen/StackProtector.h"
5657
#include "llvm/CodeGen/SwiftErrorValueTracking.h"
@@ -4382,8 +4383,10 @@ bool SelectionDAGISel::mayRaiseFPException(SDNode *N) const {
43824383

43834384
// For ISD opcodes, only StrictFP opcodes may raise an FP
43844385
// exception.
4385-
if (N->isTargetOpcode())
4386-
return N->isTargetStrictFPOpcode();
4386+
if (N->isTargetOpcode()) {
4387+
const SelectionDAGTargetInfo &TSI = CurDAG->getSelectionDAGInfo();
4388+
return TSI.mayRaiseFPException(N->getOpcode());
4389+
}
43874390
return N->isStrictFPOpcode();
43884391
}
43894392

llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@
1515
using namespace llvm;
1616

1717
SelectionDAGTargetInfo::~SelectionDAGTargetInfo() = default;
18+
19+
bool SelectionDAGTargetInfo::mayRaiseFPException(unsigned Opcode) const {
20+
// FIXME: All target memory opcodes are currently automatically considered
21+
// to possibly raise FP exceptions. See rev. 63336795.
22+
return isTargetStrictFPOpcode(Opcode) || isTargetMemoryOpcode(Opcode);
23+
}

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,11 +477,14 @@ enum NodeType : unsigned {
477477
MSRR,
478478

479479
// Strict (exception-raising) floating point comparison
480-
STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
480+
FIRST_STRICTFP_OPCODE,
481+
STRICT_FCMP = FIRST_STRICTFP_OPCODE,
481482
STRICT_FCMPE,
483+
LAST_STRICTFP_OPCODE = STRICT_FCMPE,
482484

483485
// NEON Load/Store with post-increment base updates
484-
LD2post = ISD::FIRST_TARGET_MEMORY_OPCODE,
486+
FIRST_MEMORY_OPCODE,
487+
LD2post = FIRST_MEMORY_OPCODE,
485488
LD3post,
486489
LD4post,
487490
ST2post,
@@ -516,6 +519,7 @@ enum NodeType : unsigned {
516519
STP,
517520
STILP,
518521
STNP,
522+
LAST_MEMORY_OPCODE = STNP,
519523

520524
// SME ZA loads and stores
521525
SME_ZA_LDR,

llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ static cl::opt<bool>
2323
"to lower to librt functions"),
2424
cl::init(true));
2525

26+
bool AArch64SelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
27+
return Opcode >= AArch64ISD::FIRST_MEMORY_OPCODE &&
28+
Opcode <= AArch64ISD::LAST_MEMORY_OPCODE;
29+
}
30+
31+
bool AArch64SelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
32+
return Opcode >= AArch64ISD::FIRST_STRICTFP_OPCODE &&
33+
Opcode <= AArch64ISD::LAST_STRICTFP_OPCODE;
34+
}
35+
2636
SDValue AArch64SelectionDAGInfo::EmitMOPS(unsigned Opcode, SelectionDAG &DAG,
2737
const SDLoc &DL, SDValue Chain,
2838
SDValue Dst, SDValue SrcOrValue,

llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ namespace llvm {
1919

2020
class AArch64SelectionDAGInfo : public SelectionDAGTargetInfo {
2121
public:
22+
bool isTargetMemoryOpcode(unsigned Opcode) const override;
23+
24+
bool isTargetStrictFPOpcode(unsigned Opcode) const override;
25+
2226
SDValue EmitMOPS(unsigned Opcode, SelectionDAG &DAG, const SDLoc &DL,
2327
SDValue Chain, SDValue Dst, SDValue SrcOrValue, SDValue Size,
2428
Align Alignment, bool isVolatile,

llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5555,7 +5555,6 @@ const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const {
55555555
NODE_NAME_CASE(PC_ADD_REL_OFFSET)
55565556
NODE_NAME_CASE(LDS)
55575557
NODE_NAME_CASE(DUMMY_CHAIN)
5558-
case AMDGPUISD::FIRST_MEM_OPCODE_NUMBER: break;
55595558
NODE_NAME_CASE(LOAD_D16_HI)
55605559
NODE_NAME_CASE(LOAD_D16_LO)
55615560
NODE_NAME_CASE(LOAD_D16_HI_I8)

llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,9 @@ enum NodeType : unsigned {
546546
LDS,
547547

548548
DUMMY_CHAIN,
549-
FIRST_MEM_OPCODE_NUMBER = ISD::FIRST_TARGET_MEMORY_OPCODE,
550-
LOAD_D16_HI,
549+
550+
FIRST_MEMORY_OPCODE,
551+
LOAD_D16_HI = FIRST_MEMORY_OPCODE,
551552
LOAD_D16_LO,
552553
LOAD_D16_HI_I8,
553554
LOAD_D16_HI_U8,
@@ -603,6 +604,7 @@ enum NodeType : unsigned {
603604
BUFFER_ATOMIC_FMIN,
604605
BUFFER_ATOMIC_FMAX,
605606
BUFFER_ATOMIC_COND_SUB_U32,
607+
LAST_MEMORY_OPCODE = BUFFER_ATOMIC_COND_SUB_U32,
606608
};
607609

608610
} // End namespace AMDGPUISD

llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "AMDGPUSelectionDAGInfo.h"
10+
#include "AMDGPUISelLowering.h"
1011

1112
using namespace llvm;
1213

1314
AMDGPUSelectionDAGInfo::~AMDGPUSelectionDAGInfo() = default;
15+
16+
bool AMDGPUSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
17+
return Opcode >= AMDGPUISD::FIRST_MEMORY_OPCODE &&
18+
Opcode <= AMDGPUISD::LAST_MEMORY_OPCODE;
19+
}

llvm/lib/Target/AMDGPU/AMDGPUSelectionDAGInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace llvm {
1616
class AMDGPUSelectionDAGInfo : public SelectionDAGTargetInfo {
1717
public:
1818
~AMDGPUSelectionDAGInfo() override;
19+
20+
bool isTargetMemoryOpcode(unsigned Opcode) const override;
1921
};
2022

2123
} // namespace llvm

llvm/lib/Target/ARM/ARMISelLowering.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,8 @@ class VectorType;
321321
CSINC, // Conditional select increment.
322322

323323
// Vector load N-element structure to all lanes:
324-
VLD1DUP = ISD::FIRST_TARGET_MEMORY_OPCODE,
324+
FIRST_MEMORY_OPCODE,
325+
VLD1DUP = FIRST_MEMORY_OPCODE,
325326
VLD2DUP,
326327
VLD3DUP,
327328
VLD4DUP,
@@ -356,7 +357,8 @@ class VectorType;
356357

357358
// Load/Store of dual registers
358359
LDRD,
359-
STRD
360+
STRD,
361+
LAST_MEMORY_OPCODE = STRD,
360362
};
361363

362364
} // end namespace ARMISD

llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ cl::opt<TPLoop::MemTransfer> EnableMemtransferTPLoop(
3030
"Allow (may be subject to certain conditions) "
3131
"conversion of memcpy to TP loop.")));
3232

33+
bool ARMSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
34+
return Opcode >= ARMISD::FIRST_MEMORY_OPCODE &&
35+
Opcode <= ARMISD::LAST_MEMORY_OPCODE;
36+
}
37+
3338
// Emit, if possible, a specialized version of the given Libcall. Typically this
3439
// means selecting the appropriately aligned version, but we also convert memset
3540
// of 0 into memclr.

llvm/lib/Target/ARM/ARMSelectionDAGInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ namespace ARM_AM {
3737

3838
class ARMSelectionDAGInfo : public SelectionDAGTargetInfo {
3939
public:
40+
bool isTargetMemoryOpcode(unsigned Opcode) const override;
41+
4042
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
4143
SDValue Chain, SDValue Dst, SDValue Src,
4244
SDValue Size, Align Alignment,

llvm/lib/Target/Mips/MipsISelLowering.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,14 +247,16 @@ class TargetRegisterClass;
247247
DOUBLE_SELECT_I64,
248248

249249
// Load/Store Left/Right nodes.
250-
LWL = ISD::FIRST_TARGET_MEMORY_OPCODE,
250+
FIRST_MEMORY_OPCODE,
251+
LWL = FIRST_MEMORY_OPCODE,
251252
LWR,
252253
SWL,
253254
SWR,
254255
LDL,
255256
LDR,
256257
SDL,
257-
SDR
258+
SDR,
259+
LAST_MEMORY_OPCODE = SDR,
258260
};
259261

260262
} // ene namespace MipsISD

llvm/lib/Target/Mips/MipsSelectionDAGInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "MipsSelectionDAGInfo.h"
10+
#include "MipsISelLowering.h"
1011

1112
using namespace llvm;
1213

1314
MipsSelectionDAGInfo::~MipsSelectionDAGInfo() = default;
15+
16+
bool MipsSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
17+
return Opcode >= MipsISD::FIRST_MEMORY_OPCODE &&
18+
Opcode <= MipsISD::LAST_MEMORY_OPCODE;
19+
}

llvm/lib/Target/Mips/MipsSelectionDAGInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace llvm {
1616
class MipsSelectionDAGInfo : public SelectionDAGTargetInfo {
1717
public:
1818
~MipsSelectionDAGInfo() override;
19+
20+
bool isTargetMemoryOpcode(unsigned Opcode) const override;
1921
};
2022

2123
} // namespace llvm

llvm/lib/Target/NVPTX/NVPTXISelLowering.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ enum NodeType : unsigned {
7070
BrxEnd,
7171
Dummy,
7272

73-
LoadV2 = ISD::FIRST_TARGET_MEMORY_OPCODE,
73+
FIRST_MEMORY_OPCODE,
74+
LoadV2 = FIRST_MEMORY_OPCODE,
7475
LoadV4,
7576
LDUV2, // LDU.v2
7677
LDUV4, // LDU.v4
@@ -87,6 +88,7 @@ enum NodeType : unsigned {
8788
StoreRetval,
8889
StoreRetvalV2,
8990
StoreRetvalV4,
91+
LAST_MEMORY_OPCODE = StoreRetvalV4,
9092
};
9193
}
9294

llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "NVPTXSelectionDAGInfo.h"
10+
#include "NVPTXISelLowering.h"
1011

1112
using namespace llvm;
1213

1314
NVPTXSelectionDAGInfo::~NVPTXSelectionDAGInfo() = default;
15+
16+
bool NVPTXSelectionDAGInfo::isTargetMemoryOpcode(unsigned Opcode) const {
17+
return Opcode >= NVPTXISD::FIRST_MEMORY_OPCODE &&
18+
Opcode <= NVPTXISD::LAST_MEMORY_OPCODE;
19+
}

llvm/lib/Target/NVPTX/NVPTXSelectionDAGInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace llvm {
1616
class NVPTXSelectionDAGInfo : public SelectionDAGTargetInfo {
1717
public:
1818
~NVPTXSelectionDAGInfo() override;
19+
20+
bool isTargetMemoryOpcode(unsigned Opcode) const override;
1921
};
2022

2123
} // namespace llvm

0 commit comments

Comments
 (0)