LLVM 24.0.0git
NVPTXSubtarget.h
Go to the documentation of this file.
1//=====-- NVPTXSubtarget.h - Define Subtarget for the NVPTX ---*- C++ -*--====//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares the NVPTX specific subclass of TargetSubtarget.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_NVPTX_NVPTXSUBTARGET_H
14#define LLVM_LIB_TARGET_NVPTX_NVPTXSUBTARGET_H
15
16#include "NVPTX.h"
17#include "NVPTXFrameLowering.h"
18#include "NVPTXISelLowering.h"
19#include "NVPTXInstrInfo.h"
20#include "NVPTXRegisterInfo.h"
22#include "llvm/IR/DataLayout.h"
25#include <string>
26
27#define GET_SUBTARGETINFO_HEADER
28#include "NVPTXGenSubtargetInfo.inc"
29
30namespace llvm {
31
33 virtual void anchor();
34 std::string TargetName;
35
36 // PTX version x.y is represented as 10*x+y, e.g. 3.1 == 31
37 unsigned PTXVersion;
38
39 // FullSmVersion encoding: SM * 10 + ArchSuffixOffset
40 // ArchSuffixOffset: 0 (base), 2 ('f'), 3 ('a')
41 // e.g. sm_30 -> 300, sm_90a -> 903, sm_100f -> 1002
42 unsigned FullSmVersion;
43
44 NVPTXInstrInfo InstrInfo;
46 std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
47
48 // NVPTX does not have any call stack frame, but need a NVPTX specific
49 // FrameLowering class because TargetFrameLowering is abstract.
50 NVPTXFrameLowering FrameLowering;
51
52public:
53 /// This constructor initializes the data members to match that
54 /// of the specified module.
55 ///
56 NVPTXSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
57 const NVPTXTargetMachine &TM);
58
59 ~NVPTXSubtarget() override;
60
61 const TargetFrameLowering *getFrameLowering() const override {
62 return &FrameLowering;
63 }
64 const NVPTXInstrInfo *getInstrInfo() const override { return &InstrInfo; }
65 const NVPTXRegisterInfo *getRegisterInfo() const override {
66 return &InstrInfo.getRegisterInfo();
67 }
68 const NVPTXTargetLowering *getTargetLowering() const override {
69 return &TLInfo;
70 }
71
73 return TSInfo.get();
74 }
75
76 // Checks PTX version and family-specific and architecture-specific SM
77 // versions. For example, sm_100{f/a} and any future variants in the same
78 // family will match for any PTX version greater than or equal to
79 // `MinPTXVersion`.
80 bool hasPTXWithFamilySMs(unsigned MinPTXVersion,
81 ArrayRef<unsigned> SMVersions) const;
82 // Checks PTX version and architecture-specific SM versions.
83 // For example, sm_100{a} will match for any PTX version greater than or equal
84 // to `MinPTXVersion`.
85 bool hasPTXWithAccelSMs(unsigned MinPTXVersion,
86 ArrayRef<unsigned> SMVersions) const;
87
88 bool has256BitVectorLoadStore(unsigned AS) const {
89 return getSmVersion() >= 100 && PTXVersion >= 88 &&
91 }
93 return getSmVersion() >= 50 && PTXVersion >= 83;
94 }
95 bool hasAtomAddF64() const { return getSmVersion() >= 60; }
96 bool hasAtomScope() const { return getSmVersion() >= 60; }
97 bool hasAtomBitwise64() const { return getSmVersion() >= 32; }
98 bool hasAtomMinMax64() const { return getSmVersion() >= 32; }
99 bool hasAtomCas16() const { return getSmVersion() >= 70 && PTXVersion >= 63; }
100 bool hasAtomSwap128() const {
101 return getSmVersion() >= 90 && PTXVersion >= 83;
102 }
103 bool hasClusters() const { return getSmVersion() >= 90 && PTXVersion >= 78; }
104 bool hasLDG() const { return getSmVersion() >= 32; }
105 bool hasHWROT32() const { return getSmVersion() >= 32; }
106 bool hasBrx() const { return getSmVersion() >= 30 && PTXVersion >= 60; }
107 bool hasFP16Math() const { return getSmVersion() >= 53; }
108 bool hasBF16Math() const { return getSmVersion() >= 80; }
109 bool allowFP16Math() const;
110 bool hasMaskOperator() const { return PTXVersion >= 71; }
111 bool hasNoReturn() const { return getSmVersion() >= 30 && PTXVersion >= 64; }
112 // Does SM & PTX support memory orderings (weak and atomic: relaxed, acquire,
113 // release, acq_rel, sc) ?
114 bool hasMemoryOrdering() const {
115 return getSmVersion() >= 70 && PTXVersion >= 60;
116 }
117 // Does SM & PTX support .acquire and .release qualifiers for fence?
119 return getSmVersion() >= 90 && PTXVersion >= 86;
120 }
121 // Does SM & PTX support atomic relaxed MMIO operations ?
122 bool hasRelaxedMMIO() const {
123 return getSmVersion() >= 70 && PTXVersion >= 82;
124 }
125 bool hasDotInstructions() const {
126 return getSmVersion() >= 61 && PTXVersion >= 50;
127 }
128
129 // Checks following instructions support:
130 // - tcgen05.ld/st
131 // - tcgen05.alloc/dealloc/relinquish
132 // - tcgen05.cp
133 // - tcgen05.fence/wait
134 // - tcgen05.commit
135 // - tcgen05.mma
137 // sm_101 renamed to sm_110 in PTX 9.0
138 return hasPTXWithFamilySMs(90, {100, 110}) ||
139 hasPTXWithFamilySMs(88, {100, 101}) ||
140 hasPTXWithAccelSMs(86, {100, 101});
141 }
142
143 // Checks tcgen05.shift instruction support.
145 // sm_101 renamed to sm_110 in PTX 9.0
146 return hasPTXWithAccelSMs(90, {100, 110, 103}) ||
147 hasPTXWithAccelSMs(88, {100, 101, 103}) ||
148 hasPTXWithAccelSMs(86, {100, 101});
149 }
150
152 return hasPTXWithFamilySMs(88, {100}) || hasPTXWithAccelSMs(86, {100});
153 }
154
155 bool hasTcgen05MMAI8Kind() const {
156 return hasPTXWithAccelSMs(90, {100, 110}) ||
157 hasPTXWithAccelSMs(86, {100, 101});
158 }
159
161 return hasPTXWithAccelSMs(90, {100, 110, 103}) ||
162 hasPTXWithAccelSMs(87, {100, 101, 103});
163 }
164
166 return hasPTXWithAccelSMs(90, {100, 110, 103}) ||
167 hasPTXWithAccelSMs(86, {100, 101, 103});
168 }
169
171 return hasPTXWithFamilySMs(90, {110, 103}) ||
172 hasPTXWithFamilySMs(88, {101, 103});
173 }
174
175 bool hasReduxSyncF32() const {
176 return hasPTXWithFamilySMs(88, {100}) || hasPTXWithAccelSMs(86, {100});
177 }
178
179 bool hasMMABlockScale() const {
180 return hasPTXWithFamilySMs(88, {120}) || hasPTXWithAccelSMs(87, {120});
181 }
182
184 return hasPTXWithAccelSMs(87, {120, 121});
185 }
186
188 return hasPTXWithFamilySMs(91, {120});
189 }
190
192 return hasPTXWithAccelSMs(91, {120, 121});
193 }
194
195 // f32x2 instructions in Blackwell family
196 bool hasF32x2Instructions() const;
197
198 // Checks support for following in TMA:
199 // - cta_group::1/2 support
200 // - im2col_w/w_128 mode support
201 // - tile_gather4 mode support
202 // - tile_scatter4 mode support
204 return hasPTXWithFamilySMs(90, {100, 110}) ||
205 hasPTXWithFamilySMs(88, {100, 101}) ||
206 hasPTXWithAccelSMs(86, {100, 101});
207 }
208
209 // Checks support for conversions involving e4m3x2 and e5m2x2.
211 if (PTXVersion >= 81)
212 return getSmVersion() >= 89;
213
214 if (PTXVersion >= 78)
215 return getSmVersion() >= 90;
216
217 return false;
218 }
219
220 // Checks support for conversions involving the following types:
221 // - e2m3x2/e3m2x2
222 // - e2m1x2
223 // - ue8m0x2
225 return hasPTXWithFamilySMs(90, {100, 110, 120}) ||
226 hasPTXWithFamilySMs(88, {100, 101, 120}) ||
227 hasPTXWithAccelSMs(86, {100, 101, 120});
228 }
229
230 // Checks support for conversions involving the following types:
231 // - bf16x2 -> f8x2
232 // - f16x2 -> f6x2
233 // - bf16x2 -> f6x2
234 // - f16x2 -> f4x2
235 // - bf16x2 -> f4x2
237 return hasPTXWithFamilySMs(91, {100, 110, 120});
238 }
239
241 return hasPTXWithAccelSMs(91, {100, 103, 110, 120, 121});
242 }
243
244 // Checks support for conversions from narrow FP types to bf16x2.
246 return hasPTXWithFamilySMs(92, {100, 110, 120});
247 }
248
250 return hasPTXWithFamilySMs(90, {90, 100, 110, 120}) ||
251 hasPTXWithFamilySMs(88, {90, 100, 101, 120}) ||
252 hasPTXWithAccelSMs(83, {90, 100, 101, 120});
253 }
254
255 bool hasTensormapReplaceElemtypeSupport(unsigned ElemType) const {
256 if (ElemType >= static_cast<unsigned>(nvvm::TensormapElemType::B4x16))
257 return hasPTXWithFamilySMs(90, {100, 110, 120}) ||
258 hasPTXWithFamilySMs(88, {100, 101, 120}) ||
259 hasPTXWithAccelSMs(87, {100, 101, 120});
260
262 }
263
265 return hasPTXWithFamilySMs(90, {100, 110, 120}) ||
266 hasPTXWithFamilySMs(88, {100, 101, 120}) ||
267 hasPTXWithAccelSMs(87, {100, 101, 120});
268 }
269
270 bool hasTensormapReplaceSwizzleModeSupport(unsigned SwizzleMode) const {
271 if (SwizzleMode ==
272 static_cast<unsigned>(nvvm::TensormapSwizzleMode::SWIZZLE_96B))
273 return hasPTXWithAccelSMs(88, {103});
274
276 }
277
279 return hasPTXWithFamilySMs(90, {100, 110, 120}) ||
280 hasPTXWithFamilySMs(88, {100, 101, 120}) ||
281 hasPTXWithAccelSMs(86, {100, 101, 120});
282 }
283
284 bool hasSetMaxNRegSupport() const {
285 return hasPTXWithFamilySMs(90, {100, 110, 120}) ||
286 hasPTXWithFamilySMs(88, {100, 101, 120}) ||
287 hasPTXWithAccelSMs(86, {100, 101, 120}) ||
288 hasPTXWithAccelSMs(80, {90});
289 }
290
292 return hasPTXWithFamilySMs(90, {100, 110, 120}) ||
293 hasPTXWithFamilySMs(88, {100, 101, 120}) ||
294 hasPTXWithAccelSMs(86, {100, 101, 120});
295 }
296
297 // Prior to CUDA 12.3 ptxas did not recognize that the trap instruction
298 // terminates a basic block. Instead, it would assume that control flow
299 // continued to the next instruction. The next instruction could be in the
300 // block that's lexically below it. This would lead to a phantom CFG edges
301 // being created within ptxas. This issue was fixed in CUDA 12.3. Thus, when
302 // PTX ISA versions 8.3+ we can confidently say that the bug will not be
303 // present.
304 bool hasPTXASUnreachableBug() const { return PTXVersion < 83; }
305 bool hasCvtaParam() const { return getSmVersion() >= 70 && PTXVersion >= 77; }
307 return hasPTXWithAccelSMs(87, {100, 103});
308 }
309 unsigned getFullSmVersion() const { return FullSmVersion; }
310 unsigned getSmVersion() const { return getFullSmVersion() / 10; }
311 unsigned getSmFamilyVersion() const { return getFullSmVersion() / 100; }
312 // GPUs with "a" suffix have architecture-accelerated features that are
313 // supported on the specified architecture only, hence such targets do not
314 // follow the onion layer model. hasArchAccelFeatures() allows distinguishing
315 // such GPU variants from the base GPU architecture.
316 // - false represents non-accelerated architecture.
317 // - true represents architecture-accelerated variant.
318 bool hasArchAccelFeatures() const {
319 return (getFullSmVersion() & 1) && PTXVersion >= 80;
320 }
321 // GPUs with 'f' suffix have architecture-accelerated features which are
322 // portable across all future architectures under same SM major. For example,
323 // sm_100f features will work for sm_10X*f*/sm_10X*a* future architectures.
324 // - false represents non-family-specific architecture.
325 // - true represents family-specific variant.
327 return getFullSmVersion() % 10 == 2 ? PTXVersion >= 88
329 }
330 // If the user did not provide a target we default to the `sm_75` target.
332 return hasTargetName() ? StringRef(TargetName) : "sm_75";
333 }
334 bool hasTargetName() const { return !TargetName.empty(); }
335
336 bool hasNativeBF16Support(unsigned Opcode) const;
337
338 // Get maximum value of required alignments among the supported data types.
339 // From the PTX ISA doc, section 8.2.3:
340 // The memory consistency model relates operations executed on memory
341 // locations with scalar data-types, which have a maximum size and alignment
342 // of 64 bits. Memory operations with a vector data-type are modelled as a
343 // set of equivalent memory operations with a scalar data-type, executed in
344 // an unspecified order on the elements in the vector.
345 unsigned getMaxRequiredAlignment() const { return 8; }
346 // Get the smallest cmpxchg word size that the hardware supports.
347 unsigned getMinCmpXchgSizeInBits() const { return 32; }
348
349 unsigned getPTXVersion() const { return PTXVersion; }
350
353};
354
355} // namespace llvm
356
357#endif
NVPTX address space definition.
This file contains the definitions of the enumerations and flags associated with NVVM Intrinsics,...
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool hasTensormapReplaceElemtypeSupport(unsigned ElemType) const
bool hasMMASparseBlockScaleF4() const
bool hasTcgen05MMASparseMxf4() const
const NVPTXInstrInfo * getInstrInfo() const override
bool hasTensormapReplaceSwizzleModeSupport(unsigned SwizzleMode) const
bool hasPTXWithAccelSMs(unsigned MinPTXVersion, ArrayRef< unsigned > SMVersions) const
bool hasFP16X2ToNarrowFPConversionSupport() const
bool hasTcgen05MMAI8Kind() const
bool hasTMABlackwellSupport() const
StringRef getTargetName() const
bool hasS2F6X2ConversionSupport() const
bool hasTcgen05MMASparseMxf4nvf4() const
const SelectionDAGTargetInfo * getSelectionDAGInfo() const override
unsigned getMaxRequiredAlignment() const
bool hasClusterLaunchControlTryCancelMulticastSupport() const
bool hasAtomMinMax64() const
bool hasTcgen05InstSupport() const
bool hasAtomAddF64() const
bool hasSplitAcquireAndReleaseFences() const
bool hasNativeBF16Support(unsigned Opcode) const
bool hasConvertWithStochasticRounding() const
bool hasMaskOperator() const
bool hasFP8ConversionSupport() const
const NVPTXTargetLowering * getTargetLowering() const override
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
unsigned getMinCmpXchgSizeInBits() const
unsigned getPTXVersion() const
bool hasCvtaParam() const
~NVPTXSubtarget() override
bool hasUsedBytesMaskPragma() const
bool hasPTXWithFamilySMs(unsigned MinPTXVersion, ArrayRef< unsigned > SMVersions) const
const NVPTXRegisterInfo * getRegisterInfo() const override
bool hasTensormapReplaceSupport() const
bool hasDotInstructions() const
bool hasNarrowFPToBF16x2ConversionSupport() const
bool hasTcgen05MMAScaleInputDImm() const
bool hasFamilySpecificFeatures() const
bool hasAtomBitwise64() const
bool hasTcgen05ShiftSupport() const
bool hasRelaxedMMIO() const
bool hasTargetName() const
bool hasSetMaxNRegSupport() const
bool hasMMASparseWithMXF4NVF4Scale4xE8M0() const
bool hasAtomSwap128() const
unsigned getSmFamilyVersion() const
bool hasF32x2Instructions() const
bool hasTcgen05LdRedSupport() const
bool hasReduxSyncF32() const
unsigned getFullSmVersion() const
bool hasMMAWithMXF4NVF4Scale4xE8M0() const
const TargetFrameLowering * getFrameLowering() const override
bool hasAtomScope() const
unsigned getSmVersion() const
bool hasMMABlockScale() const
bool hasLdStmatrixBlackwellSupport() const
bool hasAtomCas16() const
bool hasNarrowFPConversionSupport() const
bool hasMemoryOrdering() const
bool hasArchAccelFeatures() const
NVPTXSubtarget & initializeSubtargetDependencies(StringRef CPU, StringRef FS)
bool has256BitVectorLoadStore(unsigned AS) const
bool hasTensormapReplaceSwizzleAtomicitySupport() const
NVPTXSubtarget(const Triple &TT, StringRef CPU, StringRef FS, const NVPTXTargetMachine &TM)
This constructor initializes the data members to match that of the specified module.
bool hasPTXASUnreachableBug() const
Targets can subclass this to parameterize the SelectionDAG lowering and instruction selection process...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Information about stack frame layout on the target.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
This is an optimization pass for GlobalISel generic memory operations.