LLVM 24.0.0git
AMDGPURegBankLegalizeRules.cpp
Go to the documentation of this file.
1//===-- AMDGPURegBankLegalizeRules.cpp ------------------------------------===//
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/// Definitions of RegBankLegalize Rules for all opcodes.
10/// Implementation of container for all the Rules and search.
11/// Fast search for most common case when Rule.Predicate checks LLT and
12/// uniformity of register in operand 0.
13//
14//===----------------------------------------------------------------------===//
15
17#include "AMDGPUInstrInfo.h"
18#include "GCNSubtarget.h"
21#include "llvm/IR/IntrinsicsAMDGPU.h"
23
24#define DEBUG_TYPE "amdgpu-regbanklegalize"
25
26using namespace llvm;
27using namespace AMDGPU;
28
29bool AMDGPU::isAnyPtr(LLT Ty, unsigned Width) {
30 return Ty.isPointer() && Ty.getSizeInBits() == Width;
31}
32
34 std::initializer_list<RegBankLLTMappingApplyID> DstOpMappingList,
35 std::initializer_list<RegBankLLTMappingApplyID> SrcOpMappingList,
37 : DstOpMapping(DstOpMappingList), SrcOpMapping(SrcOpMappingList),
39
41 std::initializer_list<UniformityLLTOpPredicateID> OpList,
42 std::function<bool(const MachineInstr &)> TestFunc)
44
46 const MachineUniformityInfo &MUI,
47 const MachineRegisterInfo &MRI) {
48 switch (UniID) {
49 case S1:
50 return MRI.getType(Reg) == LLT::scalar(1);
51 case S16:
52 return MRI.getType(Reg) == LLT::scalar(16);
53 case S32:
54 return MRI.getType(Reg) == LLT::scalar(32);
55 case S64:
56 return MRI.getType(Reg) == LLT::scalar(64);
57 case S128:
58 return MRI.getType(Reg) == LLT::scalar(128);
59 case P0:
60 return MRI.getType(Reg) == LLT::pointer(0, 64);
61 case P1:
62 return MRI.getType(Reg) == LLT::pointer(1, 64);
63 case P2:
64 return MRI.getType(Reg) == LLT::pointer(2, 32);
65 case P3:
66 return MRI.getType(Reg) == LLT::pointer(3, 32);
67 case P4:
68 return MRI.getType(Reg) == LLT::pointer(4, 64);
69 case P5:
70 return MRI.getType(Reg) == LLT::pointer(5, 32);
71 case P8:
72 return MRI.getType(Reg) == LLT::pointer(8, 128);
73 case Ptr32:
74 return isAnyPtr(MRI.getType(Reg), 32);
75 case Ptr64:
76 return isAnyPtr(MRI.getType(Reg), 64);
77 case Ptr128:
78 return isAnyPtr(MRI.getType(Reg), 128);
79 case V2S16:
80 return MRI.getType(Reg) == LLT::fixed_vector(2, 16);
81 case V2S32:
82 return MRI.getType(Reg) == LLT::fixed_vector(2, 32);
83 case V3S32:
84 return MRI.getType(Reg) == LLT::fixed_vector(3, 32);
85 case V4S32:
86 return MRI.getType(Reg) == LLT::fixed_vector(4, 32);
87 case B32:
88 return MRI.getType(Reg).getSizeInBits() == 32;
89 case B64:
90 return MRI.getType(Reg).getSizeInBits() == 64;
91 case B96:
92 return MRI.getType(Reg).getSizeInBits() == 96;
93 case B128:
94 return MRI.getType(Reg).getSizeInBits() == 128;
95 case B160:
96 return MRI.getType(Reg).getSizeInBits() == 160;
97 case B256:
98 return MRI.getType(Reg).getSizeInBits() == 256;
99 case B512:
100 return MRI.getType(Reg).getSizeInBits() == 512;
101 case DivAnyTy:
102 return MUI.isDivergentAtDef(Reg);
103 case UniS1:
104 return MRI.getType(Reg) == LLT::scalar(1) && MUI.isUniformAtDef(Reg);
105 case UniS16:
106 return MRI.getType(Reg) == LLT::scalar(16) && MUI.isUniformAtDef(Reg);
107 case UniS32:
108 return MRI.getType(Reg) == LLT::scalar(32) && MUI.isUniformAtDef(Reg);
109 case UniS64:
110 return MRI.getType(Reg) == LLT::scalar(64) && MUI.isUniformAtDef(Reg);
111 case UniS128:
112 return MRI.getType(Reg) == LLT::scalar(128) && MUI.isUniformAtDef(Reg);
113 case UniP0:
114 return MRI.getType(Reg) == LLT::pointer(0, 64) && MUI.isUniformAtDef(Reg);
115 case UniP1:
116 return MRI.getType(Reg) == LLT::pointer(1, 64) && MUI.isUniformAtDef(Reg);
117 case UniP2:
118 return MRI.getType(Reg) == LLT::pointer(2, 32) && MUI.isUniformAtDef(Reg);
119 case UniP3:
120 return MRI.getType(Reg) == LLT::pointer(3, 32) && MUI.isUniformAtDef(Reg);
121 case UniP4:
122 return MRI.getType(Reg) == LLT::pointer(4, 64) && MUI.isUniformAtDef(Reg);
123 case UniP5:
124 return MRI.getType(Reg) == LLT::pointer(5, 32) && MUI.isUniformAtDef(Reg);
125 case UniP6:
126 return MRI.getType(Reg) == LLT::pointer(6, 32) && MUI.isUniformAtDef(Reg);
127 case UniP8:
128 return MRI.getType(Reg) == LLT::pointer(8, 128) && MUI.isUniformAtDef(Reg);
129 case UniPtr32:
130 return isAnyPtr(MRI.getType(Reg), 32) && MUI.isUniformAtDef(Reg);
131 case UniPtr64:
132 return isAnyPtr(MRI.getType(Reg), 64) && MUI.isUniformAtDef(Reg);
133 case UniPtr128:
134 return isAnyPtr(MRI.getType(Reg), 128) && MUI.isUniformAtDef(Reg);
135 case UniV2S16:
136 return MRI.getType(Reg) == LLT::fixed_vector(2, 16) &&
137 MUI.isUniformAtDef(Reg);
138 case UniV2S32:
139 return MRI.getType(Reg) == LLT::fixed_vector(2, 32) &&
140 MUI.isUniformAtDef(Reg);
141 case UniV3S32:
142 return MRI.getType(Reg) == LLT::fixed_vector(3, 32) &&
143 MUI.isUniformAtDef(Reg);
144 case UniV4S32:
145 return MRI.getType(Reg) == LLT::fixed_vector(4, 32) &&
146 MUI.isUniformAtDef(Reg);
147 case UniV6S32:
148 return MRI.getType(Reg) == LLT::fixed_vector(6, 32) &&
149 MUI.isUniformAtDef(Reg);
150 case UniV8S16:
151 return MRI.getType(Reg) == LLT::fixed_vector(8, 16) &&
152 MUI.isUniformAtDef(Reg);
153 case UniV8S32:
154 return MRI.getType(Reg) == LLT::fixed_vector(8, 32) &&
155 MUI.isUniformAtDef(Reg);
156 case UniV16S16:
157 return MRI.getType(Reg) == LLT::fixed_vector(16, 16) &&
158 MUI.isUniformAtDef(Reg);
159 case UniV16S32:
160 return MRI.getType(Reg) == LLT::fixed_vector(16, 32) &&
161 MUI.isUniformAtDef(Reg);
162 case UniV32S16:
163 return MRI.getType(Reg) == LLT::fixed_vector(32, 16) &&
164 MUI.isUniformAtDef(Reg);
165 case UniV32S32:
166 return MRI.getType(Reg) == LLT::fixed_vector(32, 32) &&
167 MUI.isUniformAtDef(Reg);
168 case UniV2S64:
169 return MRI.getType(Reg) == LLT::fixed_vector(2, 64) &&
170 MUI.isUniformAtDef(Reg);
171 case UniB32:
172 return MRI.getType(Reg).getSizeInBits() == 32 && MUI.isUniformAtDef(Reg);
173 case UniB64:
174 return MRI.getType(Reg).getSizeInBits() == 64 && MUI.isUniformAtDef(Reg);
175 case UniB96:
176 return MRI.getType(Reg).getSizeInBits() == 96 && MUI.isUniformAtDef(Reg);
177 case UniB128:
178 return MRI.getType(Reg).getSizeInBits() == 128 && MUI.isUniformAtDef(Reg);
179 case UniB160:
180 return MRI.getType(Reg).getSizeInBits() == 160 && MUI.isUniformAtDef(Reg);
181 case UniB256:
182 return MRI.getType(Reg).getSizeInBits() == 256 && MUI.isUniformAtDef(Reg);
183 case UniB512:
184 return MRI.getType(Reg).getSizeInBits() == 512 && MUI.isUniformAtDef(Reg);
185 case UniBRC: {
186 if (MUI.isDivergentAtDef(Reg))
187 return false;
188 // Check if there is SGPR register class of same size as the LLT.
189 const SIRegisterInfo *TRI =
190 static_cast<const SIRegisterInfo *>(MRI.getTargetRegisterInfo());
191 // There is no 16 bit SGPR register class. Extra size check is required
192 // since getSGPRClassForBitWidth returns SReg_32RegClass for Size 16.
193 unsigned LLTSize = MRI.getType(Reg).getSizeInBits();
194 return LLTSize >= 32 && TRI->getSGPRClassForBitWidth(LLTSize);
195 }
196 case DivS1:
197 return MRI.getType(Reg) == LLT::scalar(1) && MUI.isDivergentAtDef(Reg);
198 case DivS16:
199 return MRI.getType(Reg) == LLT::scalar(16) && MUI.isDivergentAtDef(Reg);
200 case DivS32:
201 return MRI.getType(Reg) == LLT::scalar(32) && MUI.isDivergentAtDef(Reg);
202 case DivS64:
203 return MRI.getType(Reg) == LLT::scalar(64) && MUI.isDivergentAtDef(Reg);
204 case DivS128:
205 return MRI.getType(Reg) == LLT::scalar(128) && MUI.isDivergentAtDef(Reg);
206 case DivP0:
207 return MRI.getType(Reg) == LLT::pointer(0, 64) && MUI.isDivergentAtDef(Reg);
208 case DivP1:
209 return MRI.getType(Reg) == LLT::pointer(1, 64) && MUI.isDivergentAtDef(Reg);
210 case DivP2:
211 return MRI.getType(Reg) == LLT::pointer(2, 32) && MUI.isDivergentAtDef(Reg);
212 case DivP3:
213 return MRI.getType(Reg) == LLT::pointer(3, 32) && MUI.isDivergentAtDef(Reg);
214 case DivP4:
215 return MRI.getType(Reg) == LLT::pointer(4, 64) && MUI.isDivergentAtDef(Reg);
216 case DivP5:
217 return MRI.getType(Reg) == LLT::pointer(5, 32) && MUI.isDivergentAtDef(Reg);
218 case DivPtr32:
219 return isAnyPtr(MRI.getType(Reg), 32) && MUI.isDivergentAtDef(Reg);
220 case DivPtr64:
221 return isAnyPtr(MRI.getType(Reg), 64) && MUI.isDivergentAtDef(Reg);
222 case DivPtr128:
223 return isAnyPtr(MRI.getType(Reg), 128) && MUI.isDivergentAtDef(Reg);
224 case DivV2S16:
225 return MRI.getType(Reg) == LLT::fixed_vector(2, 16) &&
227 case DivV2S32:
228 return MRI.getType(Reg) == LLT::fixed_vector(2, 32) &&
230 case DivV4S32:
231 return MRI.getType(Reg) == LLT::fixed_vector(4, 32) &&
233 case DivV2S64:
234 return MRI.getType(Reg) == LLT::fixed_vector(2, 64) &&
236 case DivV3S32:
237 return MRI.getType(Reg) == LLT::fixed_vector(3, 32) &&
239 case DivV4S16:
240 return MRI.getType(Reg) == LLT::fixed_vector(4, 16) &&
242 case DivV8S16:
243 return MRI.getType(Reg) == LLT::fixed_vector(8, 16) &&
245 case DivV8S32:
246 return MRI.getType(Reg) == LLT::fixed_vector(8, 32) &&
248 case DivV16S16:
249 return MRI.getType(Reg) == LLT::fixed_vector(16, 16) &&
251 case DivV16S32:
252 return MRI.getType(Reg) == LLT::fixed_vector(16, 32) &&
254 case DivV6S32:
255 return MRI.getType(Reg) == LLT::fixed_vector(6, 32) &&
257 case DivV32S16:
258 return MRI.getType(Reg) == LLT::fixed_vector(32, 16) &&
260 case DivV32S32:
261 return MRI.getType(Reg) == LLT::fixed_vector(32, 32) &&
263 case DivB32:
264 return MRI.getType(Reg).getSizeInBits() == 32 && MUI.isDivergentAtDef(Reg);
265 case DivB64:
266 return MRI.getType(Reg).getSizeInBits() == 64 && MUI.isDivergentAtDef(Reg);
267 case DivB96:
268 return MRI.getType(Reg).getSizeInBits() == 96 && MUI.isDivergentAtDef(Reg);
269 case DivB128:
270 return MRI.getType(Reg).getSizeInBits() == 128 && MUI.isDivergentAtDef(Reg);
271 case DivB160:
272 return MRI.getType(Reg).getSizeInBits() == 160 && MUI.isDivergentAtDef(Reg);
273 case DivB256:
274 return MRI.getType(Reg).getSizeInBits() == 256 && MUI.isDivergentAtDef(Reg);
275 case DivB512:
276 return MRI.getType(Reg).getSizeInBits() == 512 && MUI.isDivergentAtDef(Reg);
277 case DivBRC: {
278 if (MUI.isUniformAtDef(Reg))
279 return false;
280 // Check if there is VGPR register class of same size as the LLT.
281 const SIRegisterInfo *TRI =
282 static_cast<const SIRegisterInfo *>(MRI.getTargetRegisterInfo());
283 return TRI->getSGPRClassForBitWidth(MRI.getType(Reg).getSizeInBits());
284 }
285 case BRC: {
286 // Check if there is SGPR and VGPR register class of same size as the LLT.
287 const SIRegisterInfo *TRI =
288 static_cast<const SIRegisterInfo *>(MRI.getTargetRegisterInfo());
289 unsigned LLTSize = MRI.getType(Reg).getSizeInBits();
290 return LLTSize >= 32 && TRI->getSGPRClassForBitWidth(LLTSize) &&
291 TRI->getVGPRClassForBitWidth(LLTSize);
292 }
293 case _:
294 return true;
295 default:
296 llvm_unreachable("missing matchUniformityAndLLT");
297 }
298}
299
301 const MachineUniformityInfo &MUI,
302 const MachineRegisterInfo &MRI) const {
303 // Check LLT signature.
304 for (unsigned i = 0; i < OpUniformityAndTypes.size(); ++i) {
305 const MachineOperand &MO = MI.getOperand(i);
306 if (OpUniformityAndTypes[i] == _) {
307 assert((!MI.getOperand(i).isReg() ||
308 !MI.getOperand(i).getReg().isVirtual()) &&
309 "_ is for non-register and physical register operands only");
310 continue;
311 }
312
313 // Remaining IDs check registers.
314 if (!MO.isReg())
315 return false;
316
317 if (!matchUniformityAndLLT(MO.getReg(), OpUniformityAndTypes[i], MUI, MRI))
318 return false;
319 }
320
321 // More complex check.
322 if (TestFunc)
323 return TestFunc(MI);
324
325 return true;
326}
327
329
331 : FastTypes(FastTypes) {}
332
334 if (Ty == LLT::scalar(16))
335 return S16;
336 if (Ty == LLT::scalar(32))
337 return S32;
338 if (Ty == LLT::scalar(64))
339 return S64;
340 if (Ty == LLT::fixed_vector(2, 16))
341 return V2S16;
342 if (Ty == LLT::fixed_vector(2, 32))
343 return V2S32;
344 if (Ty == LLT::fixed_vector(3, 32))
345 return V3S32;
346 if (Ty == LLT::fixed_vector(4, 32))
347 return V4S32;
348 return _;
349}
350
352 if (Ty == LLT::scalar(32) || Ty == LLT::fixed_vector(2, 16) ||
353 isAnyPtr(Ty, 32))
354 return B32;
355 if (Ty == LLT::scalar(64) || Ty == LLT::fixed_vector(2, 32) ||
356 Ty == LLT::fixed_vector(4, 16) || isAnyPtr(Ty, 64))
357 return B64;
358 if (Ty == LLT::fixed_vector(3, 32))
359 return B96;
360 if (Ty == LLT::fixed_vector(4, 32) || Ty == LLT::fixed_vector(2, 64) ||
361 Ty == LLT::fixed_vector(8, 16) || isAnyPtr(Ty, 128))
362 return B128;
363 return _;
364}
365
366const RegBankLLTMapping *
368 const MachineRegisterInfo &MRI,
369 const MachineUniformityInfo &MUI) const {
370 // Search in "Fast Rules".
371 // Note: if fast rules are enabled, RegBankLLTMapping must be added in each
372 // slot that could "match fast Predicate". If not, InvalidMapping is
373 // returned which results in failure, does not search "Slow Rules".
374 if (FastTypes != NoFastRules) {
375 Register Reg = MI.getOperand(0).getReg();
376 int Slot;
377 if (FastTypes == StandardB)
378 Slot = getFastPredicateSlot(LLTToBId(MRI.getType(Reg)));
379 else
380 Slot = getFastPredicateSlot(LLTToId(MRI.getType(Reg)));
381
382 if (Slot != -1)
383 return MUI.isUniformAtDef(Reg) ? &Uni[Slot] : &Div[Slot];
384 }
385
386 // Slow search for more complex rules.
387 for (const RegBankLegalizeRule &Rule : Rules) {
388 if (Rule.Predicate.match(MI, MUI, MRI))
389 return &Rule.OperandMapping;
390 }
391
392 return nullptr;
393}
394
396 Rules.push_back(Rule);
397}
398
400 RegBankLLTMapping RuleApplyIDs) {
401 int Slot = getFastPredicateSlot(Ty);
402 assert(Slot != -1 && "Ty unsupported in this FastRulesTypes");
403 Div[Slot] = std::move(RuleApplyIDs);
404}
405
407 RegBankLLTMapping RuleApplyIDs) {
408 int Slot = getFastPredicateSlot(Ty);
409 assert(Slot != -1 && "Ty unsupported in this FastRulesTypes");
410 Uni[Slot] = std::move(RuleApplyIDs);
411}
412
413int SetOfRulesForOpcode::getFastPredicateSlot(
415 switch (FastTypes) {
416 case Standard: {
417 switch (Ty) {
418 case S32:
419 return 0;
420 case S16:
421 return 1;
422 case S64:
423 return 2;
424 case V2S16:
425 return 3;
426 default:
427 return -1;
428 }
429 }
430 case StandardB: {
431 switch (Ty) {
432 case B32:
433 return 0;
434 case B64:
435 return 1;
436 case B96:
437 return 2;
438 case B128:
439 return 3;
440 default:
441 return -1;
442 }
443 }
444 case Vector: {
445 switch (Ty) {
446 case S32:
447 return 0;
448 case V2S32:
449 return 1;
450 case V3S32:
451 return 2;
452 case V4S32:
453 return 3;
454 default:
455 return -1;
456 }
457 }
458 default:
459 return -1;
460 }
461}
462
463RegBankLegalizeRules::RuleSetInitializer
464RegBankLegalizeRules::addRulesForGOpcs(std::initializer_list<unsigned> OpcList,
465 FastRulesTypes FastTypes) {
466 return RuleSetInitializer(OpcList, GRulesAlias, GRules, FastTypes);
467}
468
469RegBankLegalizeRules::RuleSetInitializer
470RegBankLegalizeRules::addRulesForIOpcs(std::initializer_list<unsigned> OpcList,
471 FastRulesTypes FastTypes) {
472 return RuleSetInitializer(OpcList, IRulesAlias, IRules, FastTypes);
473}
474
477 unsigned Opc = MI.getOpcode();
478 if (Opc == AMDGPU::G_INTRINSIC || Opc == AMDGPU::G_INTRINSIC_CONVERGENT ||
479 Opc == AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS ||
480 Opc == AMDGPU::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS) {
481 unsigned IntrID = cast<GIntrinsic>(MI).getIntrinsicID();
482 auto IRAIt = IRulesAlias.find(IntrID);
483 if (IRAIt == IRulesAlias.end())
484 return nullptr;
485 return &IRules.at(IRAIt->second);
486 }
487
488 auto GRAIt = GRulesAlias.find(Opc);
489 if (GRAIt == GRulesAlias.end())
490 return nullptr;
491 return &GRules.at(GRAIt->second);
492}
493
494// Syntactic sugar wrapper for predicate lambda that enables '&&', '||' and '!'.
495class Predicate {
496private:
497 struct Elt {
498 // Save formula composed of Pred, '&&', '||' and '!' as a jump table.
499 // Sink ! to Pred. For example !((A && !B) || C) -> (!A || B) && !C
500 // Sequences of && and || will be represented by jumps, for example:
501 // (A && B && ... X) or (A && B && ... X) || Y
502 // A == true jump to B
503 // A == false jump to end or Y, result is A(false) or Y
504 // (A || B || ... X) or (A || B || ... X) && Y
505 // A == true jump to end or Y, result is A(true) or Y
506 // A == false jump to B
507 // Notice that when negating expression, we simply flip Neg on each Pred
508 // and swap TJumpOffset and FJumpOffset (&& becomes ||, || becomes &&).
509 std::function<bool(const MachineInstr &)> Pred;
510 bool Neg; // Neg of Pred is calculated before jump
511 unsigned TJumpOffset;
512 unsigned FJumpOffset;
513 };
514
515 SmallVector<Elt, 8> Expression;
516
517 Predicate(SmallVectorImpl<Elt> &&Expr) { Expression.swap(Expr); };
518
519public:
520 Predicate(std::function<bool(const MachineInstr &)> Pred) {
521 Expression.push_back({Pred, false, 1, 1});
522 };
523
524 bool operator()(const MachineInstr &MI) const {
525 unsigned Idx = 0;
526 unsigned ResultIdx = Expression.size();
527 bool Result;
528 do {
529 Result = Expression[Idx].Pred(MI);
530 Result = Expression[Idx].Neg ? !Result : Result;
531 if (Result) {
532 Idx += Expression[Idx].TJumpOffset;
533 } else {
534 Idx += Expression[Idx].FJumpOffset;
535 }
536 } while ((Idx != ResultIdx));
537
538 return Result;
539 };
540
541 Predicate operator!() const {
542 SmallVector<Elt, 8> NegExpression;
543 for (const Elt &ExprElt : Expression) {
544 NegExpression.push_back({ExprElt.Pred, !ExprElt.Neg, ExprElt.FJumpOffset,
545 ExprElt.TJumpOffset});
546 }
547 return Predicate(std::move(NegExpression));
548 };
549
550 Predicate operator&&(const Predicate &RHS) const {
551 SmallVector<Elt, 8> AndExpression = Expression;
552
553 unsigned RHSSize = RHS.Expression.size();
554 unsigned ResultIdx = Expression.size();
555 for (unsigned i = 0; i < ResultIdx; ++i) {
556 // LHS results in false, whole expression results in false.
557 if (i + AndExpression[i].FJumpOffset == ResultIdx)
558 AndExpression[i].FJumpOffset += RHSSize;
559 }
560
561 AndExpression.append(RHS.Expression);
562
563 return Predicate(std::move(AndExpression));
564 }
565
566 Predicate operator||(const Predicate &RHS) const {
567 SmallVector<Elt, 8> OrExpression = Expression;
568
569 unsigned RHSSize = RHS.Expression.size();
570 unsigned ResultIdx = Expression.size();
571 for (unsigned i = 0; i < ResultIdx; ++i) {
572 // LHS results in true, whole expression results in true.
573 if (i + OrExpression[i].TJumpOffset == ResultIdx)
574 OrExpression[i].TJumpOffset += RHSSize;
575 }
576
577 OrExpression.append(RHS.Expression);
578
579 return Predicate(std::move(OrExpression));
580 }
581};
582
583// Initialize rules
586 : ST(&_ST), MRI(&_MRI) {
587
588 addRulesForGOpcs({G_ADD, G_SUB}, Standard)
589 .Uni(S16, {{Sgpr32Trunc}, {Sgpr32AExt, Sgpr32AExt}})
590 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
591 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}})
592 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
594 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
595 .Uni(S64, {{Sgpr64}, {Sgpr64, Sgpr64}})
596 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}})
599
600 addRulesForGOpcs({G_UADDO, G_USUBO}, Standard)
601 .Uni(S32, {{Sgpr32, Sgpr32Trunc}, {Sgpr32, Sgpr32}})
602 .Div(S32, {{Vgpr32, Vcc}, {Vgpr32, Vgpr32}});
603
604 addRulesForGOpcs({G_UADDE, G_USUBE, G_SADDE, G_SSUBE}, Standard)
606 .Div(S32, {{Vgpr32, Vcc}, {Vgpr32, Vgpr32, Vcc}});
607
608 addRulesForGOpcs({G_UADDSAT, G_SADDSAT, G_USUBSAT, G_SSUBSAT}, Standard)
609 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}})
610 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
611 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}})
612 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
614 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}});
615
616 bool HasVecMulU64 = ST->hasVMulU64Inst();
617 addRulesForGOpcs({G_MUL}, Standard)
618 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
619 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}})
620 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
621 .Uni(S64, {{SgprB64}, {SgprB64, SgprB64}})
623 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
624 .Uni(S16, {{Sgpr32Trunc}, {Sgpr32AExt, Sgpr32AExt}})
625 .Div(S64, {{VgprB64}, {VgprB64, VgprB64}}, HasVecMulU64)
626 .Div(S64, {{VgprB64}, {VgprB64, VgprB64}, SplitTo32Mul}, !HasVecMulU64);
627
628 bool hasMulHi = ST->hasScalarMulHiInsts();
629 addRulesForGOpcs({G_UMULH, G_SMULH}, Standard)
630 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
631 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasMulHi)
632 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasMulHi);
633
634 addRulesForGOpcs({G_AMDGPU_MAD_U64_U32}, Standard)
635 .Div(S64, {{Vgpr64, Vcc}, {Vgpr32, Vgpr32, Vgpr64}})
637
638 bool HasScalarSMulU64 = ST->hasScalarSMulU64();
639 addRulesForGOpcs({G_AMDGPU_S_MUL_U64_U32, G_AMDGPU_S_MUL_I64_I32}, Standard)
640 .Uni(S64, {{Sgpr64}, {Sgpr64, Sgpr64}, UniMul64}, HasScalarSMulU64)
641 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}, DivSMulToMAD});
642
643 addRulesForGOpcs({G_XOR, G_OR, G_AND}, StandardB)
645 .Any({{DivS1}, {{Vcc}, {Vcc, Vcc}}})
646 .Any({{UniS16}, {{Sgpr16}, {Sgpr16, Sgpr16}}})
647 .Any({{DivS16}, {{Vgpr16}, {Vgpr16, Vgpr16}}})
648 .Uni(B32, {{SgprB32}, {SgprB32, SgprB32}})
649 .Div(B32, {{VgprB32}, {VgprB32, VgprB32}})
650 .Uni(B64, {{SgprB64}, {SgprB64, SgprB64}})
651 .Div(B64, {{VgprB64}, {VgprB64, VgprB64}, SplitTo32});
652
653 addRulesForGOpcs({G_SHL}, Standard)
654 .Uni(S16, {{Sgpr32Trunc}, {Sgpr32AExt, Sgpr32ZExt}})
655 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
657 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
658 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}})
659 .Uni(S64, {{Sgpr64}, {Sgpr64, Sgpr32}})
660 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
661 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr32}});
662
663 addRulesForGOpcs({G_LSHR}, Standard)
664 .Uni(S16, {{Sgpr32Trunc}, {Sgpr32ZExt, Sgpr32ZExt}})
665 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
667 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
668 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}})
669 .Uni(S64, {{Sgpr64}, {Sgpr64, Sgpr32}})
670 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
671 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr32}});
672
673 addRulesForGOpcs({G_ASHR}, Standard)
674 .Uni(S16, {{Sgpr32Trunc}, {Sgpr32SExt, Sgpr32ZExt}})
675 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
677 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
678 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}})
679 .Uni(S64, {{Sgpr64}, {Sgpr64, Sgpr32}})
680 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
681 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr32}});
682
683 addRulesForGOpcs({G_FSHR}, Standard)
684 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32, Vgpr32}})
685 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}});
686
687 addRulesForGOpcs({G_BSWAP}, Standard)
688 .Uni(S16, {{UniInVgprS16}, {Vgpr16}})
689 .Div(S16, {{Vgpr16}, {Vgpr16}})
690 .Uni(S32, {{UniInVgprS32}, {Vgpr32}})
691 .Div(S32, {{Vgpr32}, {Vgpr32}})
692 .Uni(V2S16, {{UniInVgprV2S16}, {VgprV2S16}})
693 .Div(V2S16, {{VgprV2S16}, {VgprV2S16}});
694
695 addRulesForGOpcs({G_AMDGPU_CVT_F32_UBYTE0, G_AMDGPU_CVT_F32_UBYTE1,
696 G_AMDGPU_CVT_F32_UBYTE2, G_AMDGPU_CVT_F32_UBYTE3,
697 G_AMDGPU_RCP_IFLAG},
698 Standard)
699 .Uni(S32, {{UniInVgprS32}, {Vgpr32}})
700 .Div(S32, {{Vgpr32}, {Vgpr32}});
701
702 addRulesForGOpcs({G_FRAME_INDEX}).Any({{UniP5, _}, {{SgprP5}, {None}}});
703
704 addRulesForGOpcs({G_UBFX, G_SBFX}, Standard)
705 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32, Sgpr32}, S_BFE})
706 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}})
707 .Uni(S64, {{Sgpr64}, {Sgpr64, Sgpr32, Sgpr32}, S_BFE})
708 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr32, Vgpr32}, V_BFE});
709
710 addRulesForGOpcs({G_SMIN, G_SMAX}, Standard)
711 .Uni(S16, {{Sgpr32Trunc}, {Sgpr32SExt, Sgpr32SExt}})
712 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
713 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}})
714 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
716 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
717 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64}})
718 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}});
719
720 addRulesForGOpcs({G_UMIN, G_UMAX}, Standard)
721 .Uni(S16, {{Sgpr32Trunc}, {Sgpr32ZExt, Sgpr32ZExt}})
722 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
723 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}})
724 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
726 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
727 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64}})
728 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}});
729
730 addRulesForGOpcs({G_IMPLICIT_DEF})
731 .Any({{UniS1}, {{Sgpr32Trunc}, {}}})
732 .Any({{UniS16}, {{Sgpr16}, {}}})
733 .Any({{UniBRC}, {{SgprBRC}, {}}});
734
735 addRulesForGOpcs({G_CONSTANT}, Standard)
736 .Any({{UniS1, _}, {{Sgpr32Trunc}, {}, UniCstExt}})
737 .Uni(S16, {{Sgpr16}, {}})
738 .Uni(S32, {{Sgpr32}, {}})
739 .Uni(S64, {{Sgpr64}, {}})
740 .Any({{UniPtr32, _}, {{SgprPtr32}, {}}})
741 .Any({{UniPtr64, _}, {{SgprPtr64}, {}}});
742
743 addRulesForGOpcs({G_FCONSTANT}, Standard)
744 .Uni(S16, {{Sgpr16}, {}})
745 .Uni(S32, {{Sgpr32}, {}})
746 .Uni(S64, {{Sgpr64}, {}});
747
748 addRulesForGOpcs({G_FREEZE})
749 .Any({{UniS1}, {{Sgpr32Trunc}, {Sgpr32AExt}}})
750 .Any({{DivS1}, {{Vcc}, {Vcc}}})
751 .Any({{UniS16}, {{Sgpr16}, {Sgpr16}}})
752 .Any({{UniBRC}, {{SgprBRC}, {SgprBRC}}})
753 .Any({{DivBRC}, {{VgprBRC}, {VgprBRC}}});
754
755 addRulesForGOpcs({G_BITCAST})
756 .Any({{UniS16}, {{Sgpr16}, {Sgpr16}}})
757 .Any({{DivS16}, {{Vgpr16}, {Vgpr16}}})
758 .Any({{UniBRC}, {{SgprBRC}, {SgprBRC}}})
759 .Any({{DivBRC}, {{VgprBRC}, {VgprBRC}}});
760
761 addRulesForGOpcs({G_UNMERGE_VALUES})
762 .Any({{UniS16}, {{}, {}, UnmergeToShiftTrunc}})
763 .Any({{UniBRC}, {{}, {}, VerifyAllSgpr}})
764 .Any({{DivBRC}, {{}, {}, ApplyAllVgpr}});
765
766 addRulesForGOpcs({G_BUILD_VECTOR, G_MERGE_VALUES})
767 .Any({{UniBRC, S16}, {{}, {}, VerifyAllSgpr}})
768 .Any({{UniBRC, BRC}, {{}, {}, VerifyAllSgpr}})
769 .Any({{DivBRC, S16}, {{}, {}, ApplyAllVgpr}})
770 .Any({{DivBRC, BRC}, {{}, {}, ApplyAllVgpr}});
771
772 addRulesForGOpcs({G_CONCAT_VECTORS})
773 .Any({{UniBRC, BRC}, {{}, {}, VerifyAllSgpr}})
774 .Any({{DivBRC, BRC}, {{}, {}, ApplyAllVgpr}});
775
776 addRulesForGOpcs({G_PHI})
777 .Any({{UniS1}, {{}, {}, AextToS32InIncomingBlockGPHI}})
778 .Any({{UniS16}, {{}, {}, VerifyAllSgprGPHI}})
779 .Any({{UniBRC}, {{}, {}, VerifyAllSgprGPHI}})
780 .Any({{DivBRC}, {{}, {}, VerifyAllSgprOrVgprGPHI}});
781
782 addRulesForGOpcs({G_EXTRACT_VECTOR_ELT})
783 .Any({{UniB32, UniBRC, UniS32}, {{SgprB32}, {SgprBRC, Sgpr32}}})
784 .Any({{DivB32, DivBRC, UniS32}, {{VgprB32}, {VgprBRC, Sgpr32}}})
785 .Any({{DivB32, BRC, DivS32},
787 .Any({{UniB64, UniBRC, UniS32}, {{SgprB64}, {SgprBRC, Sgpr32}}})
788 .Any({{DivB64, DivBRC, UniS32},
790 .Any({{DivB64, BRC, DivS32},
792
793 addRulesForGOpcs({G_INSERT_VECTOR_ELT})
795 {{SgprBRC}, {SgprBRC, SgprB32, Sgpr32}}})
796 .Any(
797 {{DivBRC, BRC, B32, UniS32}, {{VgprBRC}, {VgprBRC, VgprB32, Sgpr32}}})
798 .Any({{DivBRC, BRC, B32, DivS32},
802 .Any({{DivBRC, BRC, B64, UniS32},
804 .Any({{DivBRC, BRC, B64, DivS32},
806
807 // INTERSECT_RAY {Div}, {{VgprDst...}, {VgprSrc, ..., Sgpr_WF_RsrcIdx}}
808 // INTERSECT_RAY {Uni}, {{UniInVgprDst...}, {VgprSrc, ..., Sgpr_WF_RsrcIdx}}
809 addRulesForGOpcs({G_AMDGPU_BVH_INTERSECT_RAY, G_AMDGPU_BVH_DUAL_INTERSECT_RAY,
810 G_AMDGPU_BVH8_INTERSECT_RAY})
811 .Any({{}, {{}, {}, ApplyBVH_INTERSECT_RAY}});
812
813 // LOAD {Div}, {{VgprDst...}, {VgprSrc, ..., Sgpr_WF_RsrcIdx}}
814 // LOAD {Uni}, {{UniInVgprDst...}, {VgprSrc, ..., Sgpr_WF_RsrcIdx}}
815 // LOAD_NORET {}, {{}, {Imm, VgprSrc, ..., Sgpr_WF_RsrcIdx}}
816 // STORE {}, {{}, {VgprSrc, ..., Sgpr_WF_RsrcIdx}}
817 addRulesForGOpcs({G_AMDGPU_INTRIN_IMAGE_LOAD, G_AMDGPU_INTRIN_IMAGE_LOAD_D16,
818 G_AMDGPU_INTRIN_IMAGE_LOAD_NORET,
819 G_AMDGPU_INTRIN_IMAGE_STORE,
820 G_AMDGPU_INTRIN_IMAGE_STORE_D16})
821 .Any({{}, {{}, {}, ApplyINTRIN_IMAGE}});
822
823 Predicate isSignedICmp([](const MachineInstr &MI) -> bool {
824 auto Pred =
825 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
826 return CmpInst::isSigned(Pred);
827 });
828
829 Predicate isEqualityICmp([](const MachineInstr &MI) -> bool {
830 auto Pred =
831 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
832 return ICmpInst::isEquality(Pred);
833 });
834
835 bool HasScalarCompareEq64 = ST->hasScalarCompareEq64();
836 // clang-format off
837 addRulesForGOpcs({G_ICMP})
838 .Any({{{UniS1, _, S16}, isEqualityICmp}, {{Sgpr32Trunc}, {None, Sgpr32ZExt, Sgpr32ZExt}}})
839 .Any({{{UniS1, _, S16}, !isEqualityICmp && isSignedICmp}, {{Sgpr32Trunc}, {None, Sgpr32SExt, Sgpr32SExt}}})
840 .Any({{{UniS1, _, S16}, !isEqualityICmp && !isSignedICmp}, {{Sgpr32Trunc}, {None, Sgpr32ZExt, Sgpr32ZExt}}})
841 .Any({{{DivS1, _, S16}}, {{Vcc}, {None, Vgpr16, Vgpr16}}})
842 .Any({{{UniS1, _, S32}}, {{Sgpr32Trunc}, {None, Sgpr32, Sgpr32}}})
843 .Any({{{DivS1, _, S32}}, {{Vcc}, {None, Vgpr32, Vgpr32}}})
844 .Any({{{UniS1, _, S64}, isEqualityICmp}, {{Sgpr32Trunc}, {None, Sgpr64, Sgpr64}}}, HasScalarCompareEq64)
845 .Any({{{UniS1, _, S64}, isEqualityICmp}, {{UniInVcc}, {None, Vgpr64, Vgpr64}}}, !HasScalarCompareEq64)
846 .Any({{{UniS1, _, S64}, !isEqualityICmp}, {{UniInVcc}, {None, Vgpr64, Vgpr64}}})
847 .Any({{{DivS1, _, S64}}, {{Vcc}, {None, Vgpr64, Vgpr64}}})
848 .Any({{{UniS1, _, Ptr32}}, {{Sgpr32Trunc}, {None, SgprPtr32, SgprPtr32}}})
849 .Any({{{DivS1, _, Ptr32}}, {{Vcc}, {None, VgprPtr32, VgprPtr32}}})
850 .Any({{{UniS1, _, Ptr64}, isEqualityICmp}, {{Sgpr32Trunc}, {None, SgprPtr64, SgprPtr64}}}, HasScalarCompareEq64)
851 .Any({{{UniS1, _, Ptr64}, isEqualityICmp}, {{UniInVcc}, {None, VgprPtr64, VgprPtr64}}}, !HasScalarCompareEq64)
852 .Any({{{UniS1, _, Ptr64}, !isEqualityICmp}, {{UniInVcc}, {None, VgprPtr64, VgprPtr64}}})
853 .Any({{{DivS1, _, Ptr64}}, {{Vcc}, {None, VgprPtr64, VgprPtr64}}});
854 // clang-format on
855
856 addRulesForGOpcs({G_BRCOND})
857 .Any({{UniS1}, {{}, {Sgpr32AExtBoolInReg}}})
858 .Any({{DivS1}, {{}, {Vcc}}});
859
860 addRulesForGOpcs({G_BR}).Any({{_}, {{}, {None}}});
861
862 addRulesForGOpcs({G_SELECT}, StandardB)
863 .Any({{DivS16}, {{Vgpr16}, {Vcc, Vgpr16, Vgpr16}}})
865 .Div(B32, {{VgprB32}, {Vcc, VgprB32, VgprB32}})
869
870 addRulesForGOpcs({G_ANYEXT})
871 .Any({{UniS16, S1}, {{None}, {None}}}) // should be combined away
872 .Any({{UniS32, S1}, {{None}, {None}}}) // should be combined away
873 .Any({{UniS64, S1}, {{None}, {None}}}) // should be combined away
874 .Any({{DivS16, S1}, {{Vgpr16}, {Vcc}, VccExtToSel}})
875 .Any({{DivS32, S1}, {{Vgpr32}, {Vcc}, VccExtToSel}})
876 .Any({{DivS64, S1}, {{Vgpr64}, {Vcc}, VccExtToSel}})
877 .Any({{UniS64, S32}, {{Sgpr64}, {Sgpr32}, Ext32To64}})
878 .Any({{DivS64, S32}, {{Vgpr64}, {Vgpr32}, Ext32To64}})
879 .Any({{UniS64, S16}, {{Sgpr64}, {Sgpr32AExt}, Ext32To64}})
880 .Any({{DivS64, S16}, {{Vgpr64}, {Vgpr32AExt}, Ext32To64}})
881 .Any({{UniS32, S16}, {{Sgpr32}, {Sgpr16}}})
882 .Any({{DivS32, S16}, {{Vgpr32}, {Vgpr16}}});
883
884 bool Has16bitCmp = ST->has16BitInsts();
885
886 // In global-isel G_TRUNC in-reg is treated as no-op, inst selected into COPY.
887 // It is up to user to deal with truncated bits.
888 // S1, S16, S32 and S64 results are handled with specific rules. Remaining
889 // (result, source) pairs with valid register classes are covered by the
890 // generic UniBRC/DivBRC wildcard rules.
891 addRulesForGOpcs({G_TRUNC})
892 .Any({{UniS1, UniS16}, {{None}, {None}}}) // should be combined away
893 .Any({{UniS1, UniS32}, {{None}, {None}}}) // should be combined away
894 .Any({{UniS1, UniS64}, {{None}, {None}}}) // should be combined away
895 .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}})
896 .Any({{UniBRC, UniBRC}, {{SgprBRC}, {SgprBRC}}})
897 .Any({{DivBRC, DivBRC}, {{VgprBRC}, {VgprBRC}}})
898 .Any({{UniV2S16, V2S32}, {{SgprV2S16}, {SgprV2S32}}})
899 .Any({{DivV2S16, V2S32}, {{VgprV2S16}, {VgprV2S32}}})
900 // This is non-trivial. VgprToVccCopy is done using compare instruction.
901 .Any({{DivS1, DivS16}, {{Vcc}, {Vgpr16}, VgprToVccCopy}}, Has16bitCmp)
903 !Has16bitCmp)
904 .Any({{DivS1, DivS32}, {{Vcc}, {Vgpr32}, VgprToVccCopy}})
905 .Any({{DivS1, DivS64}, {{Vcc}, {Vgpr64}, VgprToVccCopy}});
906
907 addRulesForGOpcs({G_ZEXT})
911 .Any({{DivS16, S1}, {{Vgpr16}, {Vcc}, VccExtToSel}})
912 .Any({{DivS32, S1}, {{Vgpr32}, {Vcc}, VccExtToSel}})
913 .Any({{DivS64, S1}, {{Vgpr64}, {Vcc}, VccExtToSel}})
914 .Any({{UniS64, S32}, {{Sgpr64}, {Sgpr32}, Ext32To64}})
915 .Any({{DivS64, S32}, {{Vgpr64}, {Vgpr32}, Ext32To64}})
916 // not extending S16 to S32 is questionable.
917 .Any({{UniS64, S16}, {{Sgpr64}, {Sgpr32ZExt}, Ext32To64}})
918 .Any({{DivS64, S16}, {{Vgpr64}, {Vgpr32ZExt}, Ext32To64}})
919 .Any({{UniS32, S16}, {{Sgpr32}, {Sgpr16}}})
920 .Any({{DivS32, S16}, {{Vgpr32}, {Vgpr16}}});
921
922 addRulesForGOpcs({G_SEXT})
926 .Any({{DivS16, S1}, {{Vgpr16}, {Vcc}, VccExtToSel}})
927 .Any({{DivS32, S1}, {{Vgpr32}, {Vcc}, VccExtToSel}})
928 .Any({{DivS64, S1}, {{Vgpr64}, {Vcc}, VccExtToSel}})
929 .Any({{UniS64, S32}, {{Sgpr64}, {Sgpr32}, Ext32To64}})
930 .Any({{DivS64, S32}, {{Vgpr64}, {Vgpr32}, Ext32To64}})
931 // not extending S16 to S32 is questionable.
932 .Any({{UniS64, S16}, {{Sgpr64}, {Sgpr32SExt}, Ext32To64}})
933 .Any({{DivS64, S16}, {{Vgpr64}, {Vgpr32SExt}, Ext32To64}})
934 .Any({{UniS32, S16}, {{Sgpr32}, {Sgpr16}}})
935 .Any({{DivS32, S16}, {{Vgpr32}, {Vgpr16}}});
936
937 addRulesForGOpcs({G_SEXT_INREG})
938 .Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}})
939 .Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
940 .Any({{UniS64, S64}, {{Sgpr64}, {Sgpr64}}})
942
943 addRulesForGOpcs({G_ASSERT_ZEXT, G_ASSERT_SEXT}, Standard)
944 .Uni(S32, {{Sgpr32}, {Sgpr32, Imm}})
945 .Div(S32, {{Vgpr32}, {Vgpr32, Imm}})
946 .Uni(S64, {{Sgpr64}, {Sgpr64, Imm}})
947 .Div(S64, {{Vgpr64}, {Vgpr64, Imm}});
948
949 addRulesForGOpcs({G_ASSERT_ALIGN}, Standard)
950 .Uni(S32, {{Sgpr32}, {Sgpr32}})
951 .Div(S32, {{Vgpr32}, {Vgpr32}})
952 .Uni(S64, {{Sgpr64}, {Sgpr64}})
953 .Div(S64, {{Vgpr64}, {Vgpr64}})
954 .Any({{UniPtr32}, {{SgprPtr32}, {SgprPtr32}}})
955 .Any({{DivPtr32}, {{VgprPtr32}, {VgprPtr32}}})
956 .Any({{UniPtr64}, {{SgprPtr64}, {SgprPtr64}}})
957 .Any({{DivPtr64}, {{VgprPtr64}, {VgprPtr64}}});
958
959 // Atomic read-modify-write operations: result and value are always VGPR,
960 // pointer varies by address space.
961 addRulesForGOpcs({G_ATOMICRMW_ADD, G_ATOMICRMW_SUB, G_ATOMICRMW_XCHG,
962 G_ATOMICRMW_AND, G_ATOMICRMW_OR, G_ATOMICRMW_XOR,
963 G_ATOMICRMW_MIN, G_ATOMICRMW_MAX, G_ATOMICRMW_UMIN,
964 G_ATOMICRMW_UMAX, G_ATOMICRMW_UINC_WRAP,
965 G_ATOMICRMW_UDEC_WRAP, G_ATOMICRMW_FMIN, G_ATOMICRMW_FMAX})
966 .Any({{DivS32, P0, S32}, {{Vgpr32}, {VgprP0, Vgpr32}}})
967 .Any({{DivS64, P0, S64}, {{Vgpr64}, {VgprP0, Vgpr64}}})
968 .Any({{DivS32, P1, S32}, {{Vgpr32}, {VgprP1, Vgpr32}}})
969 .Any({{DivS64, P1, S64}, {{Vgpr64}, {VgprP1, Vgpr64}}})
970 .Any({{DivS32, P3, S32}, {{Vgpr32}, {VgprP3, Vgpr32}}})
971 .Any({{DivS64, P3, S64}, {{Vgpr64}, {VgprP3, Vgpr64}}});
972
973 addRulesForGOpcs({G_ATOMICRMW_USUB_SAT, G_ATOMICRMW_USUB_COND})
974 .Any({{DivS32, P0}, {{Vgpr32}, {VgprP0, Vgpr32}}})
975 .Any({{DivS32, P1}, {{Vgpr32}, {VgprP1, Vgpr32}}})
976 .Any({{DivS32, P3}, {{Vgpr32}, {VgprP3, Vgpr32}}});
977
978 bool HasAtomicFlatPkAdd16Insts = ST->hasAtomicFlatPkAdd16Insts();
979 bool HasAtomicBufferGlobalPkAddF16Insts =
980 ST->hasAtomicBufferGlobalPkAddF16NoRtnInsts() ||
981 ST->hasAtomicBufferGlobalPkAddF16Insts();
982 bool HasAtomicDsPkAdd16Insts = ST->hasAtomicDsPkAdd16Insts();
983 addRulesForGOpcs({G_ATOMICRMW_FADD})
984 .Any({{DivS32, P0, S32}, {{Vgpr32}, {VgprP0, Vgpr32}}})
985 .Any({{DivS64, P0, S64}, {{Vgpr64}, {VgprP0, Vgpr64}}})
986 .Any({{DivS32, P1, S32}, {{Vgpr32}, {VgprP1, Vgpr32}}})
987 .Any({{DivS64, P1, S64}, {{Vgpr64}, {VgprP1, Vgpr64}}})
988 .Any({{DivS32, P3, S32}, {{Vgpr32}, {VgprP3, Vgpr32}}})
989 .Any({{DivS64, P3, S64}, {{Vgpr64}, {VgprP3, Vgpr64}}})
990 .Any({{DivV2S16, P0, V2S16}, {{VgprV2S16}, {VgprP0, VgprV2S16}}},
991 HasAtomicFlatPkAdd16Insts)
992 .Any({{DivV2S16, P1, V2S16}, {{VgprV2S16}, {VgprP1, VgprV2S16}}},
993 HasAtomicBufferGlobalPkAddF16Insts)
994 .Any({{DivV2S16, P3, V2S16}, {{VgprV2S16}, {VgprP3, VgprV2S16}}},
995 HasAtomicDsPkAdd16Insts);
996
997 addRulesForGOpcs({G_ATOMIC_CMPXCHG})
998 .Any({{DivS32, P2}, {{Vgpr32}, {VgprP2, Vgpr32, Vgpr32}}})
999 .Any({{DivS64, P2}, {{Vgpr64}, {VgprP2, Vgpr64, Vgpr64}}})
1000 .Any({{DivS32, P3}, {{Vgpr32}, {VgprP3, Vgpr32, Vgpr32}}})
1001 .Any({{DivS64, P3}, {{Vgpr64}, {VgprP3, Vgpr64, Vgpr64}}});
1002
1003 addRulesForGOpcs({G_AMDGPU_ATOMIC_CMPXCHG})
1004 .Any({{DivS32, P0}, {{Vgpr32}, {VgprP0, VgprV2S32}}})
1005 .Any({{DivS32, P1}, {{Vgpr32}, {VgprP1, VgprV2S32}}})
1006 .Any({{DivS64, P0}, {{Vgpr64}, {VgprP0, VgprV2S64}}})
1007 .Any({{DivS64, P1}, {{Vgpr64}, {VgprP1, VgprV2S64}}});
1008
1009 addRulesForGOpcs({G_AMDGPU_BUFFER_ATOMIC_CMPSWAP}, Standard)
1010 .Div(S32, {{Vgpr32},
1012 .Div(S64, {{Vgpr64},
1014
1015 addRulesForGOpcs({G_AMDGPU_BUFFER_ATOMIC_ADD, G_AMDGPU_BUFFER_ATOMIC_AND,
1016 G_AMDGPU_BUFFER_ATOMIC_DEC, G_AMDGPU_BUFFER_ATOMIC_FMAX,
1017 G_AMDGPU_BUFFER_ATOMIC_FMIN, G_AMDGPU_BUFFER_ATOMIC_INC,
1018 G_AMDGPU_BUFFER_ATOMIC_OR, G_AMDGPU_BUFFER_ATOMIC_SMAX,
1019 G_AMDGPU_BUFFER_ATOMIC_SMIN, G_AMDGPU_BUFFER_ATOMIC_SUB,
1020 G_AMDGPU_BUFFER_ATOMIC_SWAP, G_AMDGPU_BUFFER_ATOMIC_UMAX,
1021 G_AMDGPU_BUFFER_ATOMIC_UMIN, G_AMDGPU_BUFFER_ATOMIC_XOR},
1022 Standard)
1025
1026 bool hasSMRDx3 = ST->hasScalarDwordx3Loads();
1027 bool hasSMRDSmall = ST->hasScalarSubwordLoads();
1028 bool usesTrue16 = ST->useRealTrue16Insts();
1029
1030 Predicate isAlign16([](const MachineInstr &MI) -> bool {
1031 return (*MI.memoperands_begin())->getAlign() >= Align(16);
1032 });
1033
1034 Predicate isAlign4([](const MachineInstr &MI) -> bool {
1035 return (*MI.memoperands_begin())->getAlign() >= Align(4);
1036 });
1037
1038 Predicate isAtomicMMO([](const MachineInstr &MI) -> bool {
1039 return (*MI.memoperands_begin())->isAtomic();
1040 });
1041
1042 Predicate isUniMMO([](const MachineInstr &MI) -> bool {
1043 return AMDGPU::isUniformMMO(*MI.memoperands_begin());
1044 });
1045
1046 Predicate isConst([](const MachineInstr &MI) -> bool {
1047 // Address space in MMO be different then address space on pointer.
1048 const MachineMemOperand *MMO = *MI.memoperands_begin();
1049 const unsigned AS = MMO->getAddrSpace();
1050 return AS == AMDGPUAS::CONSTANT_ADDRESS ||
1052 });
1053
1054 Predicate isVolatileMMO([](const MachineInstr &MI) -> bool {
1055 return (*MI.memoperands_begin())->isVolatile();
1056 });
1057
1058 Predicate isInvMMO([](const MachineInstr &MI) -> bool {
1059 return (*MI.memoperands_begin())->isInvariant();
1060 });
1061
1062 Predicate isNoClobberMMO([](const MachineInstr &MI) -> bool {
1063 return (*MI.memoperands_begin())->getFlags() & MONoClobber;
1064 });
1065
1066 Predicate isNaturalAligned([](const MachineInstr &MI) -> bool {
1067 const MachineMemOperand *MMO = *MI.memoperands_begin();
1068 return MMO->getAlign() >= Align(MMO->getSize().getValue());
1069 });
1070
1071 Predicate is8Or16BitMMO([](const MachineInstr &MI) -> bool {
1072 const MachineMemOperand *MMO = *MI.memoperands_begin();
1073 const unsigned MemSize = 8 * MMO->getSize().getValue();
1074 return MemSize == 16 || MemSize == 8;
1075 });
1076
1077 Predicate is32BitMMO([](const MachineInstr &MI) -> bool {
1078 const MachineMemOperand *MMO = *MI.memoperands_begin();
1079 return 8 * MMO->getSize().getValue() == 32;
1080 });
1081
1082 auto isUL = !isAtomicMMO && isUniMMO && (isConst || !isVolatileMMO) &&
1083 (isConst || isInvMMO || isNoClobberMMO);
1084
1085 // clang-format off
1086 // TODO: S32Dst, 16-bit any-extending load should not appear on True16 targets
1087 addRulesForGOpcs({G_LOAD})
1088 // flat, addrspace(0), never uniform - flat_load
1089 .Any({{DivS16, P0}, {{Vgpr16}, {VgprP0}}}, usesTrue16)
1090 .Any({{DivB32, P0}, {{VgprB32}, {VgprP0}}}) // 32-bit load, 8-bit and 16-bit any-extending load
1091 .Any({{DivB64, P0}, {{VgprB64}, {VgprP0}}})
1092 .Any({{DivB96, P0}, {{VgprB96}, {VgprP0}}})
1093 .Any({{DivB128, P0}, {{VgprB128}, {VgprP0}}})
1094
1095 // global, addrspace(1)
1096 // divergent - global_load
1097 .Any({{DivS16, P1}, {{Vgpr16}, {VgprP1}}}, usesTrue16)
1098 .Any({{DivB32, P1}, {{VgprB32}, {VgprP1}}}) //32-bit load, 8-bit and 16-bit any-extending load
1099 .Any({{DivB64, P1}, {{VgprB64}, {VgprP1}}})
1100 .Any({{DivB96, P1}, {{VgprB96}, {VgprP1}}})
1101 .Any({{DivB128, P1}, {{VgprB128}, {VgprP1}}})
1102 .Any({{DivB256, P1}, {{VgprB256}, {VgprP1}, SplitLoad}})
1103 .Any({{DivB512, P1}, {{VgprB512}, {VgprP1}, SplitLoad}})
1104
1105 // uniform - s_load
1106 .Any({{{UniS16, P1}, isNaturalAligned && isUL}, {{Sgpr32Trunc}, {SgprP1}}}, usesTrue16 && hasSMRDSmall) // s16 load
1107 .Any({{{UniS16, P1}, isAlign4 && isUL}, {{Sgpr32Trunc}, {SgprP1}, WidenMMOToS32}}, usesTrue16 && !hasSMRDSmall) // s16 load to 32-bit load
1108 .Any({{{UniB32, P1}, isNaturalAligned && isUL}, {{SgprB32}, {SgprP1}}}, hasSMRDSmall) //32-bit load, 8-bit and 16-bit any-extending load
1109 // TODO: SplitLoad when !isNaturalAligned && isUL and target hasSMRDSmall
1110 .Any({{{UniB32, P1}, is8Or16BitMMO && isAlign4 && isUL}, {{SgprB32}, {SgprP1}, WidenMMOToS32}}, !hasSMRDSmall) //8-bit and 16-bit any-extending load to 32-bit load
1111 .Any({{{UniB32, P1}, is32BitMMO && isAlign4 && isUL}, {{SgprB32}, {SgprP1}}}) //32-bit load
1112 .Any({{{UniB64, P1}, isAlign4 && isUL}, {{SgprB64}, {SgprP1}}})
1113 .Any({{{UniB96, P1}, isAlign16 && isUL}, {{SgprB96}, {SgprP1}, WidenLoad}}, !hasSMRDx3)
1114 .Any({{{UniB96, P1}, isAlign4 && !isAlign16 && isUL}, {{SgprB96}, {SgprP1}, SplitLoad}}, !hasSMRDx3)
1115 .Any({{{UniB96, P1}, isAlign4 && isUL}, {{SgprB96}, {SgprP1}}}, hasSMRDx3)
1116 .Any({{{UniB128, P1}, isAlign4 && isUL}, {{SgprB128}, {SgprP1}}})
1117 .Any({{{UniB256, P1}, isAlign4 && isUL}, {{SgprB256}, {SgprP1}}})
1118 .Any({{{UniB512, P1}, isAlign4 && isUL}, {{SgprB512}, {SgprP1}}})
1119
1120 // Uniform via global or buffer load, for example volatile or non-aligned
1121 // uniform load. Not using standard {{UniInVgprTy}, {VgprP1}} since it is
1122 // selected as global_load, use SgprP1 for pointer instead to match
1123 // patterns without flat-for-global, default for GFX7 and older.
1124 // -> +flat-for-global + {{UniInVgprTy}, {SgprP1}} - global_load
1125 // -> -flat-for-global + {{UniInVgprTy}, {SgprP1}} - buffer_load
1126 .Any({{{UniS16, P1}, !isNaturalAligned || !isUL}, {{UniInVgprS16}, {SgprP1}}}, usesTrue16 && hasSMRDSmall) // s16 load
1127 .Any({{{UniS16, P1}, !isAlign4 || !isUL}, {{UniInVgprS16}, {SgprP1}}}, usesTrue16 && !hasSMRDSmall) // s16 load
1128 .Any({{{UniB32, P1}, !isNaturalAligned || !isUL}, {{UniInVgprB32}, {SgprP1}}}, hasSMRDSmall) //32-bit load, 8-bit and 16-bit any-extending load
1129 .Any({{{UniB32, P1}, !isAlign4 || !isUL}, {{UniInVgprB32}, {SgprP1}}}, !hasSMRDSmall) //32-bit load, 8-bit and 16-bit any-extending load
1130 .Any({{{UniB64, P1}, !isAlign4 || !isUL}, {{UniInVgprB64}, {SgprP1}}})
1131 .Any({{{UniB96, P1}, !isAlign4 || !isUL}, {{UniInVgprB96}, {SgprP1}}})
1132 .Any({{{UniB128, P1}, !isAlign4 || !isUL}, {{UniInVgprB128}, {SgprP1}}})
1133 .Any({{{UniB256, P1}, !isAlign4 || !isUL}, {{UniInVgprB256}, {SgprP1}, SplitLoad}})
1134 .Any({{{UniB512, P1}, !isAlign4 || !isUL}, {{UniInVgprB512}, {SgprP1}, SplitLoad}})
1135
1136 // local, addrspace(3) - ds_load
1137 .Any({{DivS16, P3}, {{Vgpr16}, {VgprP3}}}, usesTrue16)
1138 .Any({{DivB32, P3}, {{VgprB32}, {VgprP3}}}) // 32-bit load, 8-bit and 16-bit any-extending load
1139 .Any({{DivB64, P3}, {{VgprB64}, {VgprP3}}})
1140 .Any({{DivB96, P3}, {{VgprB96}, {VgprP3}}})
1141 .Any({{DivB128, P3}, {{VgprB128}, {VgprP3}}})
1142
1143 .Any({{UniS16, P3}, {{UniInVgprS16}, {SgprP3}}}, usesTrue16) // 16-bit load
1144 .Any({{UniB32, P3}, {{UniInVgprB32}, {VgprP3}}}) // 32-bit load, 8-bit and 16-bit any-extending load
1145 .Any({{UniB64, P3}, {{UniInVgprB64}, {VgprP3}}})
1146 .Any({{UniB96, P3}, {{UniInVgprB96}, {VgprP3}}})
1147 .Any({{UniB128, P3}, {{UniInVgprB128}, {VgprP3}}})
1148
1149 // constant, addrspace(4)
1150 // divergent - global_load
1151 .Any({{DivS16, P4}, {{Vgpr16}, {VgprP4}}}, usesTrue16)
1152 .Any({{DivB32, P4}, {{VgprB32}, {VgprP4}}}) //32-bit load, 8-bit and 16-bit any-extending load
1153 .Any({{DivB64, P4}, {{VgprB64}, {VgprP4}}})
1154 .Any({{DivB96, P4}, {{VgprB96}, {VgprP4}}})
1155 .Any({{DivB128, P4}, {{VgprB128}, {VgprP4}}})
1156 .Any({{DivB256, P4}, {{VgprB256}, {VgprP4}, SplitLoad}})
1157 .Any({{DivB512, P4}, {{VgprB512}, {VgprP4}, SplitLoad}})
1158
1159 // uniform - s_load
1160 .Any({{{UniS16, P4}, isNaturalAligned && isUL}, {{Sgpr32Trunc}, {SgprP4}}}, usesTrue16 && hasSMRDSmall) // s16 load
1161 .Any({{{UniS16, P4}, isAlign4 && isUL}, {{Sgpr32Trunc}, {SgprP4}, WidenMMOToS32}}, usesTrue16 && !hasSMRDSmall) // s16 load to 32-bit load
1162 .Any({{{UniB32, P4}, isNaturalAligned && isUL}, {{SgprB32}, {SgprP4}}}, hasSMRDSmall) //32-bit load, 8-bit and 16-bit any-extending load
1163 .Any({{{UniB32, P4}, is8Or16BitMMO && isAlign4 && isUL}, {{SgprB32}, {SgprP4}, WidenMMOToS32}}, !hasSMRDSmall) //8-bit and 16-bit any-extending load to 32-bit load
1164 .Any({{{UniB32, P4}, is32BitMMO && isAlign4 && isUL}, {{SgprB32}, {SgprP4}}}) //32-bit load
1165 .Any({{{UniB64, P4}, isAlign4 && isUL}, {{SgprB64}, {SgprP4}}})
1166 .Any({{{UniB96, P4}, isAlign16 && isUL}, {{SgprB96}, {SgprP4}, WidenLoad}}, !hasSMRDx3)
1167 .Any({{{UniB96, P4}, isAlign4 && !isAlign16 && isUL}, {{SgprB96}, {SgprP4}, SplitLoad}}, !hasSMRDx3)
1168 .Any({{{UniB96, P4}, isAlign4 && isUL}, {{SgprB96}, {SgprP4}}}, hasSMRDx3)
1169 .Any({{{UniB128, P4}, isAlign4 && isUL}, {{SgprB128}, {SgprP4}}})
1170 .Any({{{UniB256, P4}, isAlign4 && isUL}, {{SgprB256}, {SgprP4}}})
1171 .Any({{{UniB512, P4}, isAlign4 && isUL}, {{SgprB512}, {SgprP4}}})
1172
1173 // uniform in vgpr - global_load or buffer_load
1174 .Any({{{UniS16, P4}, !isNaturalAligned || !isUL}, {{UniInVgprS16}, {SgprP4}}}, usesTrue16 && hasSMRDSmall) // s16 load
1175 .Any({{{UniS16, P4}, !isAlign4 || !isUL}, {{UniInVgprS16}, {SgprP4}}}, usesTrue16 && !hasSMRDSmall) // s16 load
1176 .Any({{{UniB32, P4}, !isNaturalAligned || !isUL}, {{UniInVgprB32}, {SgprP4}}}, hasSMRDSmall) //32-bit load, 8-bit and 16-bit any-extending load
1177 .Any({{{UniB32, P4}, !isAlign4 || !isUL}, {{UniInVgprB32}, {SgprP4}}}, !hasSMRDSmall) //32-bit load, 8-bit and 16-bit any-extending load
1178 .Any({{{UniB64, P4}, !isAlign4 || !isUL}, {{UniInVgprB64}, {SgprP4}}})
1179 .Any({{{UniB96, P4}, !isAlign4 || !isUL}, {{UniInVgprB96}, {SgprP4}}})
1180 .Any({{{UniB128, P4}, !isAlign4 || !isUL}, {{UniInVgprB128}, {SgprP4}}})
1181 .Any({{{UniB256, P4}, !isAlign4 || !isUL}, {{UniInVgprB256}, {SgprP4}, SplitLoad}})
1182 .Any({{{UniB512, P4}, !isAlign4 || !isUL}, {{UniInVgprB512}, {SgprP4}, SplitLoad}})
1183
1184 // private, addrspace(5), never uniform - scratch_load
1185 .Any({{DivS16, P5}, {{Vgpr16}, {VgprP5}}}, usesTrue16)
1186 .Any({{DivB32, P5}, {{VgprB32}, {VgprP5}}}) // 32-bit load, 8-bit and 16-bit any-extending load
1187 .Any({{DivB64, P5}, {{VgprB64}, {VgprP5}}})
1188 .Any({{DivB96, P5}, {{VgprB96}, {VgprP5}}})
1189 .Any({{DivB128, P5}, {{VgprB128}, {VgprP5}}})
1190
1191 .Any({{DivS32, Ptr128}, {{Vgpr32}, {VgprPtr128}}});
1192
1193
1194 addRulesForGOpcs({G_ZEXTLOAD, G_SEXTLOAD}) // i8 and i16 zeroextending loads
1195 .Any({{DivS32, P0}, {{Vgpr32}, {VgprP0}}})
1196 .Any({{DivS16, P0}, {{Vgpr16}, {VgprP0}}}, usesTrue16)
1197
1198 .Any({{DivS32, P1}, {{Vgpr32}, {VgprP1}}})
1199 .Any({{DivS16, P1}, {{Vgpr16}, {VgprP1}}}, usesTrue16)
1200 .Any({{{UniS32, P1}, isAlign4 && isUL}, {{Sgpr32}, {SgprP1}, WidenMMOToS32}}, !hasSMRDSmall)
1201 .Any({{{UniS32, P1}, isNaturalAligned && isUL}, {{Sgpr32}, {SgprP1}}}, hasSMRDSmall)
1202 .Any({{{UniS32, P1}, !isAlign4 || !isUL}, {{UniInVgprS32}, {SgprP1}}}, !hasSMRDSmall)
1203 .Any({{{UniS32, P1}, !isNaturalAligned || !isUL}, {{UniInVgprS32}, {SgprP1}}}, hasSMRDSmall)
1204
1205 .Any({{DivS32, P3}, {{Vgpr32}, {VgprP3}}})
1206 .Any({{DivS16, P3}, {{Vgpr16}, {VgprP3}}}, usesTrue16)
1207 .Any({{UniS32, P3}, {{UniInVgprS32}, {VgprP3}}})
1208
1209 .Any({{DivS32, P4}, {{Vgpr32}, {VgprP4}}})
1210 .Any({{DivS16, P4}, {{Vgpr16}, {VgprP4}}}, usesTrue16)
1211 .Any({{{UniS32, P4}, isAlign4 && isUL}, {{Sgpr32}, {SgprP4}, WidenMMOToS32}}, !hasSMRDSmall)
1212 .Any({{{UniS32, P4}, isNaturalAligned && isUL}, {{Sgpr32}, {SgprP4}}}, hasSMRDSmall)
1213 .Any({{{UniS32, P4}, !isAlign4 || !isUL}, {{UniInVgprS32}, {SgprP4}}}, !hasSMRDSmall)
1214 .Any({{{UniS32, P4}, !isNaturalAligned || !isUL}, {{UniInVgprS32}, {SgprP4}}}, hasSMRDSmall)
1215
1216 .Any({{DivS32, P5}, {{Vgpr32}, {VgprP5}}})
1217 .Any({{DivS16, P5}, {{Vgpr16}, {VgprP5}}}, usesTrue16);
1218
1219 addRulesForGOpcs({G_STORE})
1220 // addrspace(0)
1221 .Any({{S16, P0}, {{}, {Vgpr16, VgprP0}}}, usesTrue16) // 16-bit store
1222 .Any({{B32, P0}, {{}, {VgprB32, VgprP0}}}) // 32-bit store, 8-bit and 16-bit truncating store
1223 .Any({{B64, P0}, {{}, {VgprB64, VgprP0}}})
1224 .Any({{B96, P0}, {{}, {VgprB96, VgprP0}}})
1225 .Any({{B128, P0}, {{}, {VgprB128, VgprP0}}})
1226
1227 // addrspace(1), there are no stores to addrspace(4)
1228 // For targets:
1229 // - with "+flat-for-global" - global_store
1230 // - without(-flat-for-global) - buffer_store addr64
1231 .Any({{S16, DivP1}, {{}, {Vgpr16, VgprP1}}}, usesTrue16) // 16-bit store
1232 .Any({{B32, DivP1}, {{}, {VgprB32, VgprP1}}}) // 32-bit store, 8-bit and 16-bit truncating store
1233 .Any({{B64, DivP1}, {{}, {VgprB64, VgprP1}}})
1234 .Any({{B96, DivP1}, {{}, {VgprB96, VgprP1}}})
1235 .Any({{B128, DivP1}, {{}, {VgprB128, VgprP1}}})
1236
1237 // For UniP1, use sgpr ptr to match flat-for-global patterns. Targets:
1238 // - with "+flat-for-global" - global_store for both sgpr and vgpr ptr
1239 // - without(-flat-for-global) - need sgpr ptr to select buffer_store
1240 .Any({{S16, UniP1}, {{}, {Vgpr16, SgprP1}}}, usesTrue16) // 16-bit store
1241 .Any({{B32, UniP1}, {{}, {VgprB32, SgprP1}}}) // 32-bit store, 8-bit and 16-bit truncating store
1242 .Any({{B64, UniP1}, {{}, {VgprB64, SgprP1}}})
1243 .Any({{B96, UniP1}, {{}, {VgprB96, SgprP1}}})
1244 .Any({{B128, UniP1}, {{}, {VgprB128, SgprP1}}})
1245
1246 // addrspace(3) and addrspace(5)
1247 .Any({{S16, Ptr32}, {{}, {Vgpr16, VgprPtr32}}}, usesTrue16) // 16-bit store
1248 .Any({{B32, Ptr32}, {{}, {VgprB32, VgprPtr32}}}) // 32-bit store, 8-bit and 16-bit truncating store
1249 .Any({{B64, Ptr32}, {{}, {VgprB64, VgprPtr32}}})
1250 .Any({{B96, Ptr32}, {{}, {VgprB96, VgprPtr32}}})
1251 .Any({{B128, Ptr32}, {{}, {VgprB128, VgprPtr32}}});
1252
1253 // clang-format on
1254
1255 addRulesForGOpcs({G_AMDGPU_BUFFER_LOAD, G_AMDGPU_BUFFER_LOAD_FORMAT,
1256 G_AMDGPU_TBUFFER_LOAD_FORMAT},
1257 StandardB)
1266
1267 addRulesForGOpcs({G_AMDGPU_BUFFER_LOAD_USHORT, G_AMDGPU_BUFFER_LOAD_UBYTE,
1268 G_AMDGPU_BUFFER_LOAD_SSHORT, G_AMDGPU_BUFFER_LOAD_SBYTE},
1269 StandardB)
1272
1273 addRulesForGOpcs(
1274 {G_AMDGPU_BUFFER_LOAD_UBYTE_TFE, G_AMDGPU_BUFFER_LOAD_USHORT_TFE},
1275 StandardB)
1278
1279 addRulesForGOpcs({G_AMDGPU_BUFFER_LOAD_TFE, G_AMDGPU_BUFFER_LOAD_FORMAT_TFE},
1280 StandardB)
1288 .Any({{UniB160},
1290
1291 addRulesForGOpcs(
1292 {G_AMDGPU_BUFFER_LOAD_FORMAT_D16, G_AMDGPU_TBUFFER_LOAD_FORMAT_D16},
1293 StandardB)
1300
1301 addRulesForGOpcs({G_AMDGPU_S_BUFFER_LOAD})
1302 // waterfall expansion is part of S_BUF_to_BUF
1303 .Any({{UniB32}, {{SgprB32}, {SgprV4S32, Sgpr32}}})
1304 .Any({{DivB32, UniV4S32, DivB32},
1306 .Any({{DivB32, DivV4S32, UniB32},
1308 .Any({{DivB32, DivV4S32, DivB32},
1310
1311 .Any({{UniB64}, {{SgprB64}, {SgprV4S32, Sgpr32}}})
1312 .Any({{DivB64, UniV4S32, DivB32},
1314 .Any({{DivB64, DivV4S32, UniB32},
1316 .Any({{DivB64, DivV4S32, DivB32},
1318
1319 .Any({{UniB96}, {{SgprB96}, {SgprV4S32, Sgpr32}}})
1320 .Any({{DivB96, UniV4S32, DivB32},
1322 .Any({{DivB96, DivV4S32, UniB32},
1324 .Any({{DivB96, DivV4S32, DivB32},
1326
1327 .Any({{UniB128}, {{SgprB128}, {SgprV4S32, Sgpr32}}})
1328 .Any({{DivB128, UniV4S32, DivB32},
1330 .Any({{DivB128, DivV4S32, UniB32},
1332 .Any({{DivB128, DivV4S32, DivB32},
1334
1335 .Any({{UniB256}, {{SgprB256}, {SgprV4S32, Sgpr32}}})
1336 .Any({{DivB256, UniV4S32, DivB32},
1338 .Any({{DivB256, DivV4S32, UniB32},
1340 .Any({{DivB256, DivV4S32, DivB32},
1342
1343 .Any({{UniB512}, {{SgprB512}, {SgprV4S32, Sgpr32}}})
1344 .Any({{DivB512, UniV4S32, DivB32},
1346 .Any({{DivB512, DivV4S32, UniB32},
1348 .Any({{DivB512, DivV4S32, DivB32},
1350
1351 addRulesForGOpcs({G_AMDGPU_S_BUFFER_LOAD_SBYTE, G_AMDGPU_S_BUFFER_LOAD_UBYTE,
1352 G_AMDGPU_S_BUFFER_LOAD_SSHORT,
1353 G_AMDGPU_S_BUFFER_LOAD_USHORT})
1355 .Any({{DivS32, UniV4S32, DivS32},
1357 .Any({{DivS32, DivV4S32, UniS32},
1359 .Any({{DivS32, DivV4S32, DivS32},
1361
1362 addRulesForGOpcs({G_AMDGPU_BUFFER_STORE, G_AMDGPU_BUFFER_STORE_BYTE,
1363 G_AMDGPU_BUFFER_STORE_SHORT, G_AMDGPU_BUFFER_STORE_FORMAT,
1364 G_AMDGPU_BUFFER_STORE_FORMAT_D16,
1365 G_AMDGPU_TBUFFER_STORE_FORMAT,
1366 G_AMDGPU_TBUFFER_STORE_FORMAT_D16})
1367 .Any({{B32}, {{}, {VgprB32, SgprV4S32_WF, Vgpr32, Vgpr32, Sgpr32_WF}}})
1368 .Any({{B64}, {{}, {VgprB64, SgprV4S32_WF, Vgpr32, Vgpr32, Sgpr32_WF}}})
1369 .Any({{B96}, {{}, {VgprB96, SgprV4S32_WF, Vgpr32, Vgpr32, Sgpr32_WF}}})
1370 .Any({{B128}, {{}, {VgprB128, SgprV4S32_WF, Vgpr32, Vgpr32, Sgpr32_WF}}});
1371
1372 // Buffer atomics: resource descriptor + scalar offset are SGPR, data and
1373 // address components are VGPR.
1374 //
1375 // Operand order (SIInstructions.td BufferAtomicGenericInstruction):
1376 // dst = op vdata, rsrc, vindex, voffset, soffset, offset_imm, cachepolicy,
1377 // idxen_imm
1378 addRulesForGOpcs({G_AMDGPU_BUFFER_ATOMIC_FADD})
1379 .Any({{S32, S32, V4S32, S32, S32, S32},
1381 .Any({{S64, S64, V4S32, S32, S32, S32},
1383 .Any({{V2S16, V2S16, V4S32, S32, S32, S32},
1384 {{VgprV2S16},
1386
1387 addRulesForGOpcs({G_PTR_ADD})
1388 .Any({{UniPtr32}, {{SgprPtr32}, {SgprPtr32, Sgpr32}}})
1389 .Any({{DivPtr32}, {{VgprPtr32}, {VgprPtr32, Vgpr32}}})
1390 .Any({{UniPtr64}, {{SgprPtr64}, {SgprPtr64, Sgpr64}}})
1391 .Any({{DivPtr64}, {{VgprPtr64}, {VgprPtr64, Vgpr64}}});
1392
1393 addRulesForGOpcs({G_INTTOPTR})
1394 .Any({{UniPtr32}, {{SgprPtr32}, {Sgpr32}}})
1395 .Any({{DivPtr32}, {{VgprPtr32}, {Vgpr32}}})
1396 .Any({{UniPtr64}, {{SgprPtr64}, {Sgpr64}}})
1397 .Any({{DivPtr64}, {{VgprPtr64}, {Vgpr64}}})
1398 .Any({{UniPtr128}, {{SgprPtr128}, {Sgpr128}}})
1399 .Any({{DivPtr128}, {{VgprPtr128}, {Vgpr128}}});
1400
1401 addRulesForGOpcs({G_PTRTOINT})
1402 .Any({{UniS32}, {{Sgpr32}, {SgprPtr32}}})
1403 .Any({{DivS32}, {{Vgpr32}, {VgprPtr32}}})
1404 .Any({{UniS64}, {{Sgpr64}, {SgprPtr64}}})
1405 .Any({{DivS64}, {{Vgpr64}, {VgprPtr64}}})
1406 .Any({{UniS128}, {{Sgpr128}, {SgprPtr128}}})
1407 .Any({{DivS128}, {{Vgpr128}, {VgprPtr128}}});
1408
1409 // FIXME: Update llvm/test/CodeGen/AMDGPU/ptrmask.ll to use GlobalISel.
1410 // Currently crashes on P8 (buffer resource) tests due to legalizer issue.
1411 addRulesForGOpcs({G_PTRMASK})
1412 .Any({{UniP1}, {{SgprP1}, {SgprP1, Sgpr64}}})
1413 .Any({{DivP1}, {{VgprP1}, {VgprP1, Vgpr64}}})
1414 .Any({{UniP3}, {{SgprP3}, {SgprP3, Sgpr32}}})
1415 .Any({{DivP3}, {{VgprP3}, {VgprP3, Vgpr32}}});
1416
1417 addRulesForGOpcs({G_DYN_STACKALLOC})
1418 .Any({{UniP5, UniS32}, {{SgprP5}, {Sgpr32}, DynStackAlloc}})
1419 .Any({{UniP5, DivS32}, {{SgprP5}, {Vgpr32}, DynStackAlloc}});
1420
1421 addRulesForGOpcs({G_ABS}, Standard)
1422 .Uni(S16, {{Sgpr32Trunc}, {Sgpr32SExt}})
1423 .Div(S16, {{Vgpr16}, {Vgpr16}, AbsToNegMax})
1424 .Uni(S32, {{Sgpr32}, {Sgpr32}})
1425 .Div(S32, {{Vgpr32}, {Vgpr32}, AbsToNegMax})
1426 .Uni(V2S16, {{SgprV2S16}, {SgprV2S16}, AbsToS32})
1427 .Div(V2S16, {{VgprV2S16}, {VgprV2S16}, AbsToNegMax});
1428
1429 addRulesForGOpcs({G_BITREVERSE}, Standard)
1430 .Uni(S32, {{Sgpr32}, {Sgpr32}})
1431 .Div(S32, {{Vgpr32}, {Vgpr32}})
1432 .Uni(S64, {{Sgpr64}, {Sgpr64}})
1433 .Div(S64, {{Vgpr64}, {Vgpr64}});
1434
1435 addRulesForGOpcs({G_AMDGPU_FFBH_U32, G_AMDGPU_FFBL_B32, G_CTLZ_ZERO_POISON,
1436 G_CTTZ_ZERO_POISON})
1437 .Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}})
1438 .Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
1439 .Any({{UniS32, S64}, {{Sgpr32}, {Sgpr64}}})
1441
1442 addRulesForGOpcs({G_CTPOP})
1443 .Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}})
1444 .Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
1445 .Any({{UniS32, S64}, {{Sgpr32}, {Sgpr64}}})
1446 .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}, CtPop64To32}});
1447
1448 addRulesForGOpcs({G_FENCE}).Any({{{}}, {{}, {}}});
1449
1450 addRulesForGOpcs({G_READSTEADYCOUNTER, G_READCYCLECOUNTER}, Standard)
1451 .Uni(S64, {{Sgpr64}, {}});
1452
1453 addRulesForGOpcs({G_GET_ROUNDING}, Standard)
1454 .Uni(S32, {{Sgpr32}, {}, LowerGetRounding});
1455
1456 addRulesForGOpcs({G_SET_ROUNDING}, Standard)
1459
1460 addRulesForGOpcs({G_BLOCK_ADDR}).Any({{UniP0}, {{SgprP0}, {}}});
1461
1462 addRulesForGOpcs({G_GLOBAL_VALUE})
1463 .Any({{UniP0}, {{SgprP0}, {}}})
1464 .Any({{UniP1}, {{SgprP1}, {}}})
1465 .Any({{UniP3}, {{SgprP3}, {}}})
1466 .Any({{UniP4}, {{SgprP4}, {}}})
1467 .Any({{UniP8}, {{SgprP8}, {}}});
1468
1469 addRulesForGOpcs({G_AMDGPU_WAVE_ADDRESS}).Any({{UniP5}, {{SgprP5}, {}}});
1470
1471 addRulesForGOpcs({G_AMDGPU_SPONENTRY}, Standard).Uni(S32, {{Sgpr32}, {}});
1472
1473 addRulesForGOpcs({G_SI_CALL})
1474 .Any({{_, UniP0}, {{None}, {SgprP0}}})
1475 .Any({{_, DivP0}, {{None}, {SgprP0Call_WF}}})
1476 .Any({{_, UniP4}, {{None}, {SgprP4}}})
1477 .Any({{_, DivP4}, {{None}, {SgprP4Call_WF}}});
1478
1479 bool hasSALUFloat = ST->hasSALUFloatInsts();
1480
1481 addRulesForGOpcs({G_FADD, G_FMUL, G_STRICT_FADD, G_STRICT_FMUL}, Standard)
1482 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}}, !hasSALUFloat)
1483 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16}}, hasSALUFloat)
1484 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1485 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasSALUFloat)
1486 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasSALUFloat)
1487 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1488 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64}})
1489 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}})
1490 .Uni(V2S16, {{UniInVgprV2S16}, {VgprV2S16, VgprV2S16}}, !hasSALUFloat)
1492 hasSALUFloat)
1493 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
1497 .Any({{DivV2S64}, {{VgprV2S64}, {VgprV2S64, VgprV2S64}}});
1498
1499 addRulesForGOpcs({G_FSUB, G_STRICT_FSUB}, Standard)
1500 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1501 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1502 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16}}, hasSALUFloat)
1503 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}}, !hasSALUFloat)
1504 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasSALUFloat)
1505 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasSALUFloat);
1506
1507 addRulesForGOpcs({G_FMAD}, Standard)
1508 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16, Vgpr16}})
1509 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16, Vgpr16}})
1510 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32, Vgpr32}})
1511 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}});
1512
1513 addRulesForGOpcs({G_FLDEXP, G_STRICT_FLDEXP}, Standard)
1514 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}})
1515 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1516 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}})
1517 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1518 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr32}})
1519 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr32}});
1520
1521 addRulesForGOpcs({G_FMA, G_STRICT_FMA}, Standard)
1522 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16, Vgpr16}})
1523 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}})
1524 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64, Vgpr64}})
1525 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64, Vgpr64}})
1529 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16, Sgpr16}}, hasSALUFloat)
1530 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16, Vgpr16}}, !hasSALUFloat)
1531 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32, Sgpr32}}, hasSALUFloat)
1532 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32, Vgpr32}}, !hasSALUFloat)
1533 .Uni(V2S16,
1535 hasSALUFloat)
1537 !hasSALUFloat)
1540
1541 addRulesForGOpcs({G_AMDGPU_FMED3}, Standard)
1542 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16, Vgpr16}})
1543 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16, Vgpr16}})
1544 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32, Vgpr32}})
1545 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}});
1546
1547 // TODO: This opcode is generated from the i64->i16 signed clamped pattern in
1548 // the PreLegalizerCombiner. Move the combine to RegBankCombiner to keep more
1549 // instructions on SALU.
1550 addRulesForGOpcs({G_AMDGPU_SMED3}, Standard)
1551 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32, Vgpr32}})
1552 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}});
1553
1554 // FNEG and FABS are either folded as source modifiers or can be selected as
1555 // bitwise XOR and AND with Mask. XOR and AND are available on SALU but for
1556 // targets without SALU float we still select them as VGPR since there would
1557 // be no real sgpr use.
1558 addRulesForGOpcs({G_FNEG, G_FABS}, Standard)
1559 .Uni(S16, {{UniInVgprS16}, {Vgpr16}}, !hasSALUFloat)
1560 .Uni(S16, {{Sgpr16}, {Sgpr16}}, hasSALUFloat)
1561 .Div(S16, {{Vgpr16}, {Vgpr16}})
1562 .Uni(S32, {{UniInVgprS32}, {Vgpr32}}, !hasSALUFloat)
1563 .Uni(S32, {{Sgpr32}, {Sgpr32}}, hasSALUFloat)
1564 .Div(S32, {{Vgpr32}, {Vgpr32}})
1565 .Uni(S64, {{UniInVgprS64}, {Vgpr64}})
1566 .Div(S64, {{Vgpr64}, {Vgpr64}})
1567 .Uni(V2S16, {{UniInVgprV2S16}, {VgprV2S16}}, !hasSALUFloat)
1568 .Uni(V2S16, {{SgprV2S16}, {SgprV2S16}, ScalarizeToS16}, hasSALUFloat)
1569 .Div(V2S16, {{VgprV2S16}, {VgprV2S16}})
1570 .Any({{UniV2S32}, {{UniInVgprV2S32}, {VgprV2S32}}})
1571 .Any({{DivV2S32}, {{VgprV2S32}, {VgprV2S32}}});
1572
1573 addRulesForGOpcs({G_FCANONICALIZE}, Standard)
1574 .Uni(S32, {{UniInVgprS32}, {Vgpr32}})
1575 .Div(S32, {{Vgpr32}, {Vgpr32}})
1576 .Uni(S16, {{UniInVgprS16}, {Vgpr16}})
1577 .Div(S16, {{Vgpr16}, {Vgpr16}})
1578 .Uni(S64, {{UniInVgprS64}, {Vgpr64}})
1579 .Div(S64, {{Vgpr64}, {Vgpr64}})
1580 .Uni(V2S16, {{UniInVgprV2S16}, {VgprV2S16}})
1581 .Div(V2S16, {{VgprV2S16}, {VgprV2S16}})
1582 .Any({{UniV2S32}, {{UniInVgprV2S32}, {VgprV2S32}}})
1583 .Any({{DivV2S32}, {{VgprV2S32}, {VgprV2S32}}})
1584 .Any({{UniV2S64}, {{UniInVgprV2S64}, {VgprV2S64}}})
1585 .Any({{DivV2S64}, {{VgprV2S64}, {VgprV2S64}}});
1586
1587 bool hasPST = ST->hasPseudoScalarTrans();
1588 addRulesForGOpcs({G_FSQRT}, Standard)
1589 .Div(S16, {{Vgpr16}, {Vgpr16}})
1590 .Uni(S16, {{Sgpr16}, {Sgpr16}}, hasPST)
1591 .Uni(S16, {{UniInVgprS16}, {Vgpr16}}, !hasPST);
1592
1593 addRulesForGOpcs({G_FPTOUI, G_FPTOSI, G_FPTOUI_SAT, G_FPTOSI_SAT})
1594 .Any({{UniS16, S16}, {{UniInVgprS16}, {Vgpr16}}})
1595 .Any({{DivS16, S16}, {{Vgpr16}, {Vgpr16}}})
1596 .Any({{UniS32, S16}, {{Sgpr32}, {Sgpr16}}}, hasSALUFloat)
1597 .Any({{UniS32, S16}, {{UniInVgprS32}, {Vgpr16}}}, !hasSALUFloat)
1598 .Any({{DivS32, S16}, {{Vgpr32}, {Vgpr16}}})
1599 .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}}, hasSALUFloat)
1600 .Any({{UniS16, S32}, {{UniInVgprS16}, {Vgpr32}}}, !hasSALUFloat)
1601 .Any({{DivS16, S32}, {{Vgpr16}, {Vgpr32}}})
1602 .Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}}, hasSALUFloat)
1603 .Any({{UniS32, S32}, {{UniInVgprS32}, {Vgpr32}}}, !hasSALUFloat)
1604 .Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
1605 .Any({{UniS32, S64}, {{UniInVgprS32}, {Vgpr64}}})
1606 .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}}})
1608 .Any({{DivV2S16, V2S32}, {{VgprV2S16}, {VgprV2S32}}});
1609
1610 addRulesForGOpcs({G_UITOFP, G_SITOFP})
1611 .Any({{UniS16, S16}, {{UniInVgprS16}, {Vgpr16}}})
1612 .Any({{DivS16, S16}, {{Vgpr16}, {Vgpr16}}})
1613 .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}}, hasSALUFloat)
1614 .Any({{UniS16, S32}, {{UniInVgprS16}, {Vgpr32}}}, !hasSALUFloat)
1615 .Any({{DivS16, S32}, {{Vgpr16}, {Vgpr32}}})
1616 .Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}}, hasSALUFloat)
1617 .Any({{UniS32, S32}, {{UniInVgprS32}, {Vgpr32}}}, !hasSALUFloat)
1618 .Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
1619 .Any({{UniS64, S32}, {{UniInVgprS64}, {Vgpr32}}})
1620 .Any({{DivS64, S32}, {{Vgpr64}, {Vgpr32}}});
1621
1622 addRulesForGOpcs({G_AMDGPU_S_BUFFER_PREFETCH})
1624
1625 Predicate IsDataPF([](const MachineInstr &MI) -> bool {
1626 // prefetch cache type: 0 == instruction (I$) prefetch, 1 == data prefetch.
1627 return MI.getOperand(3).getImm() != 0;
1628 });
1629
1630 bool HasSMemPF = ST->hasSafeSmemPrefetch();
1631 bool HasVMemPF = ST->hasVmemPrefInsts();
1632 addRulesForGOpcs({G_PREFETCH})
1633 // Safe smem prefetch keeps both data and instruction prefetch.
1634 .Any({{UniPtr64}, {{}, {SgprPtr64}}}, HasSMemPF)
1635 // Vmem prefetch keeps data prefetch only.
1636 .Any({{{UniPtr64}, IsDataPF}, {{}, {SgprPtr64}}}, !HasSMemPF && HasVMemPF)
1637 .Any({{{UniPtr64}, IsDataPF}, {{}, {}, DeletePrefetch}},
1638 !HasSMemPF && !HasVMemPF)
1639 .Any({{{UniPtr64}, !IsDataPF}, {{}, {}, DeletePrefetch}}, !HasSMemPF)
1640
1641 .Any({{{DivPtr64}, IsDataPF}, {{}, {VgprPtr64}}}, HasVMemPF)
1642 .Any({{{DivPtr64}, IsDataPF}, {{}, {}, DeletePrefetch}}, !HasVMemPF)
1643 .Any({{{DivPtr64}, !IsDataPF}, {{}, {}, DeletePrefetch}})
1644
1645 .Any({{P3}, {{}, {}, DeletePrefetch}})
1646 .Any({{P5}, {{}, {}, DeletePrefetch}})
1647 .Any({{UniP6}, {{}, {SgprP6}}}, HasSMemPF)
1648 .Any({{UniP6}, {{}, {}, DeletePrefetch}}, !HasSMemPF);
1649
1650 addRulesForGOpcs({G_FPEXT})
1651 .Any({{DivS32, S16}, {{Vgpr32}, {Vgpr16}}})
1652 .Any({{UniS64, S32}, {{UniInVgprS64}, {Vgpr32}}})
1653 .Any({{DivS64, S32}, {{Vgpr64}, {Vgpr32}}})
1654 .Any({{UniS32, S16}, {{Sgpr32}, {Sgpr16}}}, hasSALUFloat)
1655 .Any({{UniS32, S16}, {{UniInVgprS32}, {Vgpr16}}}, !hasSALUFloat);
1656
1657 addRulesForGOpcs({G_AMDGPU_CVT_PK_I16_I32}, Standard)
1658 .Uni(V2S16, {{UniInVgprV2S16}, {Vgpr32, Vgpr32}})
1659 .Div(V2S16, {{VgprV2S16}, {Vgpr32, Vgpr32}});
1660
1661 addRulesForGOpcs({G_AMDGPU_FMIN_LEGACY, G_AMDGPU_FMAX_LEGACY}, Standard)
1662 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}})
1663 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}});
1664
1665 bool hasSALUMinimumMaximumInsts = ST->hasSALUMinimumMaximumInsts();
1666
1667 addRulesForGOpcs({G_FMINIMUM, G_FMAXIMUM}, Standard)
1668 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16}}, hasSALUMinimumMaximumInsts)
1669 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}}, !hasSALUMinimumMaximumInsts)
1670 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1671 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasSALUMinimumMaximumInsts)
1672 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasSALUMinimumMaximumInsts)
1673 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1674 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64}})
1675 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}})
1677 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}});
1678
1679 addRulesForGOpcs({G_FMINNUM_IEEE, G_FMAXNUM_IEEE, G_FMINNUM, G_FMAXNUM,
1680 G_FMINIMUMNUM, G_FMAXIMUMNUM},
1681 Standard)
1682 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1683 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1684 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64}})
1685 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}})
1687 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
1688 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16}}, hasSALUFloat)
1689 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}}, !hasSALUFloat)
1690 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasSALUFloat)
1691 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasSALUFloat);
1692
1693 addRulesForGOpcs({G_FPTRUNC})
1694 .Any({{DivS16, S32}, {{Vgpr16}, {Vgpr32}}})
1695 .Any({{UniS32, S64}, {{UniInVgprS32}, {Vgpr64}}})
1696 .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}}})
1698 .Any({{DivV2S16, V2S32}, {{VgprV2S16}, {VgprV2S32}}})
1699 .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}}, hasSALUFloat)
1700 .Any({{UniS16, S32}, {{UniInVgprS16}, {Vgpr32}}}, !hasSALUFloat);
1701
1702 addRulesForGOpcs({G_INTRINSIC_FPTRUNC_ROUND})
1703 .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}}, hasSALUFloat)
1704 .Any({{UniS16, S32}, {{UniInVgprS16}, {Vgpr32}}}, !hasSALUFloat)
1705 .Any({{DivS16, S32}, {{Vgpr16}, {Vgpr32}}})
1706 .Any({{UniS16, S64}, {{UniInVgprS16}, {Vgpr64}}})
1707 .Any({{DivS16, S64}, {{Vgpr16}, {Vgpr64}}})
1708 .Any({{UniS32, S64}, {{UniInVgprS32}, {Vgpr64}}})
1709 .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}}});
1710
1711 addRulesForGOpcs({G_IS_FPCLASS})
1712 .Any({{DivS1, S16}, {{Vcc}, {Vgpr16}}})
1713 .Any({{UniS1, S16}, {{UniInVcc}, {Vgpr16}}})
1714 .Any({{DivS1, S32}, {{Vcc}, {Vgpr32}}})
1715 .Any({{UniS1, S32}, {{UniInVcc}, {Vgpr32}}})
1716 .Any({{DivS1, S64}, {{Vcc}, {Vgpr64}}})
1717 .Any({{UniS1, S64}, {{UniInVcc}, {Vgpr64}}});
1718
1719 addRulesForGOpcs({G_FCMP}, Standard)
1720 .Any({{UniS1, _, S16}, {{Sgpr32Trunc}, {None, Sgpr16, Sgpr16}}},
1721 hasSALUFloat)
1722 .Any({{UniS1, _, S16}, {{UniInVcc}, {None, Vgpr16, Vgpr16}}},
1723 !hasSALUFloat)
1724 .Any({{DivS1, _, S16}, {{Vcc}, {None, Vgpr16, Vgpr16}}})
1725 .Any({{UniS1, _, S32}, {{Sgpr32Trunc}, {None, Sgpr32, Sgpr32}}},
1726 hasSALUFloat)
1727 .Any({{UniS1, _, S32}, {{UniInVcc}, {None, Vgpr32, Vgpr32}}},
1728 !hasSALUFloat)
1729 .Any({{DivS1, _, S32}, {{Vcc}, {None, Vgpr32, Vgpr32}}})
1730 .Any({{UniS1, _, S64}, {{UniInVcc}, {None, Vgpr64, Vgpr64}}})
1731 .Any({{DivS1, _, S64}, {{Vcc}, {None, Vgpr64, Vgpr64}}});
1732
1733 addRulesForGOpcs({G_INTRINSIC_ROUNDEVEN, G_FEXP2, G_FLOG2}, Standard)
1734 .Uni(S16, {{UniInVgprS16}, {Vgpr16}})
1735 .Div(S16, {{Vgpr16}, {Vgpr16}})
1736 .Uni(S32, {{UniInVgprS32}, {Vgpr32}})
1737 .Div(S32, {{Vgpr32}, {Vgpr32}})
1738 .Uni(S64, {{UniInVgprS64}, {Vgpr64}})
1739 .Div(S64, {{Vgpr64}, {Vgpr64}});
1740
1741 addRulesForGOpcs({G_INTRINSIC_TRUNC, G_FFLOOR, G_FCEIL}, Standard)
1742 .Uni(S16, {{UniInVgprS16}, {Vgpr16}})
1743 .Uni(S16, {{Sgpr16}, {Sgpr16}}, hasSALUFloat)
1744 .Div(S16, {{Vgpr16}, {Vgpr16}})
1745 .Uni(S32, {{UniInVgprS32}, {Vgpr32}})
1746 .Uni(S32, {{Sgpr32}, {Sgpr32}}, hasSALUFloat)
1747 .Div(S32, {{Vgpr32}, {Vgpr32}})
1748 .Uni(S64, {{UniInVgprS64}, {Vgpr64}})
1749 .Div(S64, {{Vgpr64}, {Vgpr64}});
1750
1751 addRulesForGOpcs({G_AMDGPU_GLOBAL_LOAD_MONITOR, G_AMDGPU_FLAT_LOAD_MONITOR},
1752 StandardB)
1753 .Uni(B32, {{UniInVgprB32}, {SgprPtr64}})
1754 .Div(B32, {{VgprB32}, {VgprPtr64}})
1755 .Uni(B64, {{UniInVgprB64}, {SgprPtr64}})
1756 .Div(B64, {{VgprB64}, {VgprPtr64}})
1757 .Uni(B128, {{UniInVgprB128}, {SgprPtr64}})
1758 .Div(B128, {{VgprB128}, {VgprPtr64}});
1759
1760 addRulesForGOpcs({G_AMDGPU_WHOLE_WAVE_FUNC_SETUP})
1761 .Any({{DivS1}, {{Vcc}, {}}});
1762
1763 addRulesForGOpcs({G_AMDGPU_WHOLE_WAVE_FUNC_RETURN}).Any({{}, {{}, {Vcc}}});
1764
1765 using namespace Intrinsic;
1766
1767 addRulesForIOpcs({returnaddress}).Any({{UniP0}, {{SgprP0}, {}}});
1768
1769 // Note: amdgcn.icmp with i1 inputs is legalized to ballot in the legalizer,
1770 // so no S1 rules are needed here.
1771 addRulesForIOpcs({amdgcn_icmp})
1772 .Any({{UniS64, _, S16}, {{Sgpr64}, {IntrId, Vgpr16, Vgpr16}}})
1773 .Any({{UniS64, _, S32}, {{Sgpr64}, {IntrId, Vgpr32, Vgpr32}}})
1774 .Any({{UniS64, _, S64}, {{Sgpr64}, {IntrId, Vgpr64, Vgpr64}}})
1775
1776 .Any({{UniS32, _, S16}, {{Sgpr32}, {IntrId, Vgpr16, Vgpr16}}})
1777 .Any({{UniS32, _, S32}, {{Sgpr32}, {IntrId, Vgpr32, Vgpr32}}})
1778 .Any({{UniS32, _, S64}, {{Sgpr32}, {IntrId, Vgpr64, Vgpr64}}});
1779
1780 addRulesForIOpcs({amdgcn_fcmp})
1781 .Any({{UniS64, _, S16}, {{Sgpr64}, {IntrId, Vgpr16, Vgpr16}}})
1782 .Any({{UniS64, _, S32}, {{Sgpr64}, {IntrId, Vgpr32, Vgpr32}}})
1783 .Any({{UniS64, _, S64}, {{Sgpr64}, {IntrId, Vgpr64, Vgpr64}}})
1784
1785 .Any({{UniS32, _, S16}, {{Sgpr32}, {IntrId, Vgpr16, Vgpr16}}})
1786 .Any({{UniS32, _, S32}, {{Sgpr32}, {IntrId, Vgpr32, Vgpr32}}})
1787 .Any({{UniS32, _, S64}, {{Sgpr32}, {IntrId, Vgpr64, Vgpr64}}});
1788
1789 addRulesForIOpcs({amdgcn_s_getpc}).Any({{UniS64, _}, {{Sgpr64}, {}}});
1790
1791 addRulesForIOpcs({amdgcn_s_getreg}).Any({{}, {{Sgpr32}, {IntrId}}});
1792
1793 addRulesForIOpcs({amdgcn_s_setreg})
1794 .Any({{_, _, S32}, {{}, {IntrId, Imm, SgprB32_ReadFirstLane}}});
1795
1796 addRulesForIOpcs({amdgcn_s_sendmsg, amdgcn_s_sendmsghalt})
1797 .Any({{}, {{}, {IntrId, Imm, SgprB32_M0}}});
1798
1799 addRulesForIOpcs({amdgcn_s_sendmsg_rtn})
1800 .Any({{S32}, {{Sgpr32}, {}}})
1801 .Any({{S64}, {{Sgpr64}, {}}});
1802
1803 addRulesForIOpcs({amdgcn_s_memrealtime, amdgcn_s_memtime}, Standard)
1804 .Uni(S64, {{Sgpr64}, {IntrId}});
1805
1806 addRulesForIOpcs({amdgcn_groupstaticsize, amdgcn_pops_exiting_wave_id,
1807 amdgcn_reloc_constant, amdgcn_s_get_waveid_in_workgroup},
1808 Standard)
1809 .Uni(S32, {{Sgpr32}, {IntrId}});
1810
1811 // Intrinsics with no register operands.
1812 addRulesForIOpcs({amdgcn_asyncmark,
1813 amdgcn_endpgm,
1814 amdgcn_iglp_opt,
1815 amdgcn_init_exec,
1816 amdgcn_s_barrier,
1817 amdgcn_s_barrier_leave,
1818 amdgcn_s_barrier_signal,
1819 amdgcn_s_barrier_wait,
1820 amdgcn_s_monitor_sleep,
1821 amdgcn_s_nop,
1822 amdgcn_s_sethalt,
1823 amdgcn_s_setprio,
1824 amdgcn_s_setprio_inc_wg,
1825 amdgcn_s_sleep,
1826 amdgcn_s_ttracedata_imm,
1827 amdgcn_s_wait_asynccnt,
1828 amdgcn_s_wait_bvhcnt,
1829 amdgcn_s_wait_dscnt,
1830 amdgcn_s_wait_event,
1831 amdgcn_s_wait_event_export_ready,
1832 amdgcn_s_wait_expcnt,
1833 amdgcn_s_wait_kmcnt,
1834 amdgcn_s_wait_loadcnt,
1835 amdgcn_s_wait_samplecnt,
1836 amdgcn_s_wait_storecnt,
1837 amdgcn_s_wait_tensorcnt,
1838 amdgcn_s_waitcnt,
1839 amdgcn_sched_barrier,
1840 amdgcn_sched_group_barrier,
1841 amdgcn_unreachable,
1842 amdgcn_wait_asyncmark,
1843 amdgcn_wave_barrier})
1844 .Any({{}, {{}, {}}});
1845
1846 addRulesForIOpcs({amdgcn_init_exec_from_input})
1847 .Any({{}, {{}, {IntrId, Sgpr32}}});
1848
1849 addRulesForIOpcs({amdgcn_s_ttracedata}).Any({{}, {{}, {IntrId, SgprB32_M0}}});
1850
1851 addRulesForIOpcs({amdgcn_s_sleep_var})
1852 .Any({{}, {{}, {IntrId, SgprB32_ReadFirstLane}}});
1853
1854 addRulesForIOpcs({amdgcn_s_barrier_join, amdgcn_s_wakeup_barrier})
1855 .Any({{}, {{}, {IntrId, SgprB32_M0}}});
1856
1857 addRulesForIOpcs({amdgcn_s_barrier_signal_var, amdgcn_s_barrier_init})
1858 .Any({{}, {{}, {IntrId, SgprB32_M0, SgprB32_M0}}});
1859
1860 addRulesForIOpcs({amdgcn_s_barrier_signal_isfirst})
1861 .Any({{UniS1}, {{Sgpr32Trunc}, {}}});
1862
1863 addRulesForIOpcs(
1864 {amdgcn_s_get_named_barrier_state, amdgcn_s_get_barrier_state}, Standard)
1865 .Uni(S32, {{Sgpr32}, {IntrId, SgprB32_M0}});
1866
1867 addRulesForIOpcs({amdgcn_flat_prefetch}).Any({{}, {{}, {IntrId, VgprP0}}});
1868
1869 addRulesForIOpcs({amdgcn_global_prefetch}).Any({{}, {{}, {IntrId, VgprP1}}});
1870
1871 addRulesForIOpcs({amdgcn_s_prefetch_data, amdgcn_s_prefetch_inst})
1873
1874 addRulesForIOpcs({amdgcn_class})
1875 .Any({{UniS1, _, S16}, {{UniInVcc}, {IntrId, Vgpr16, Vgpr32}}})
1876 .Any({{DivS1, _, S16}, {{Vcc}, {IntrId, Vgpr16, Vgpr32}}})
1877 .Any({{UniS1, _, S32}, {{UniInVcc}, {IntrId, Vgpr32, Vgpr32}}})
1878 .Any({{DivS1, _, S32}, {{Vcc}, {IntrId, Vgpr32, Vgpr32}}})
1879 .Any({{UniS1, _, S64}, {{UniInVcc}, {IntrId, Vgpr64, Vgpr32}}})
1880 .Any({{DivS1, _, S64}, {{Vcc}, {IntrId, Vgpr64, Vgpr32}}});
1881
1882 // This is "intrinsic lane mask" it was set to i32/i64 in llvm-ir.
1883 addRulesForIOpcs({amdgcn_end_cf})
1884 .Any({{_, UniS32}, {{}, {IntrId, Sgpr32}}})
1885 .Any({{_, UniS64}, {{}, {IntrId, Sgpr64}}});
1886
1887 addRulesForIOpcs({amdgcn_if_break}, Standard)
1888 .Uni(S64, {{Sgpr64}, {IntrId, Vcc, Sgpr64}})
1889 .Uni(S32, {{Sgpr32}, {IntrId, Vcc, Sgpr32}});
1890
1891 addRulesForIOpcs({amdgcn_exp})
1892 .Any({{_, _, _, S32, S32, S32, S32},
1893 {{}, {IntrId, Imm, Imm, Vgpr32, Vgpr32, Vgpr32, Vgpr32}}});
1894
1895 addRulesForIOpcs({amdgcn_exp_compr})
1896 .Any({{_, _, _, V2S16}, {{}, {IntrId, Imm, Imm, VgprV2S16, VgprV2S16}}});
1897
1898 addRulesForIOpcs({amdgcn_exp_row})
1899 .Any({{_, _, _, S32, S32, S32, S32, _, S32},
1900 {{},
1902 SgprB32_M0}}});
1903
1904 addRulesForIOpcs({amdgcn_lds_direct_load}, StandardB)
1905 .Div(B32, {{VgprB32}, {IntrId, SgprB32_M0}});
1906
1907 addRulesForIOpcs({amdgcn_lds_param_load}, Standard)
1908 .Div(S32, {{Vgpr32}, {IntrId, Imm, Imm, SgprB32_M0}});
1909
1910 addRulesForIOpcs({amdgcn_mbcnt_lo, amdgcn_mbcnt_hi}, Standard)
1911 .Div(S32, {{}, {Vgpr32, None, Vgpr32, Vgpr32}});
1912
1913 addRulesForIOpcs({amdgcn_readfirstlane})
1914 .Any({{UniB32, _, DivB32}, {{}, {SgprB32, None, VgprB32}}})
1915 // this should not exist in the first place, it is from call lowering
1916 // readfirstlaning just in case register is not in sgpr.
1917 .Any({{UniS32, _, UniS32}, {{}, {Sgpr32, None, Vgpr32}}});
1918
1919 addRulesForIOpcs({amdgcn_readlane}, StandardB)
1921
1922 addRulesForIOpcs({amdgcn_s_quadmask, amdgcn_s_wqm}, StandardB)
1924 .Uni(B64, {{SgprB64}, {IntrId, SgprB64_ReadFirstLane}});
1925
1926 addRulesForIOpcs({amdgcn_writelane}, StandardB)
1927 .Div(B32,
1928 {{VgprB32},
1930
1931 addRulesForIOpcs({amdgcn_add_max_i32, amdgcn_add_max_u32, amdgcn_add_min_i32,
1932 amdgcn_add_min_u32},
1933 Standard)
1934 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
1935 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
1936
1937 addRulesForIOpcs({amdgcn_pk_add_max_i16, amdgcn_pk_add_max_u16,
1938 amdgcn_pk_add_min_i16, amdgcn_pk_add_min_u16},
1939 Standard)
1942
1943 addRulesForIOpcs({amdgcn_permlane16, amdgcn_permlanex16}, Standard)
1944 .Div(S32, {{Vgpr32},
1947
1948 addRulesForIOpcs({amdgcn_permlane_bcast, amdgcn_permlane_up,
1949 amdgcn_permlane_down, amdgcn_permlane_xor},
1950 StandardB)
1951 .Div(B32,
1952 {{VgprB32},
1954
1955 addRulesForIOpcs({amdgcn_permlane_idx_gen}, Standard)
1957
1958 addRulesForIOpcs({amdgcn_perm}, Standard)
1959 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
1960 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
1961
1962 addRulesForIOpcs(
1963 {amdgcn_wave_reduce_add, amdgcn_wave_reduce_and, amdgcn_wave_reduce_fadd,
1964 amdgcn_wave_reduce_fmax, amdgcn_wave_reduce_fmin,
1965 amdgcn_wave_reduce_fsub, amdgcn_wave_reduce_max, amdgcn_wave_reduce_min,
1966 amdgcn_wave_reduce_or, amdgcn_wave_reduce_sub, amdgcn_wave_reduce_umax,
1967 amdgcn_wave_reduce_umin, amdgcn_wave_reduce_xor},
1968 Standard)
1969 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}})
1970 .Div(S32, {{Sgpr32ToVgprDst}, {IntrId, VgprB32}})
1971 .Uni(S64, {{Sgpr64}, {IntrId, Sgpr64}})
1972 .Div(S64, {{Sgpr64ToVgprDst}, {IntrId, VgprB64}});
1973
1974 addRulesForIOpcs({amdgcn_wave_shuffle}, Standard)
1975 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}})
1976 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}});
1977
1978 addRulesForIOpcs({amdgcn_bitop3, amdgcn_fmad_ftz}, Standard)
1979 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16, Vgpr16, Vgpr16}})
1980 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16, Vgpr16, Vgpr16}})
1981 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
1982 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
1983
1984 addRulesForIOpcs({amdgcn_udot4, amdgcn_sdot4, amdgcn_udot8, amdgcn_sdot8,
1985 amdgcn_dot4_f32_bf8_bf8, amdgcn_dot4_f32_bf8_fp8,
1986 amdgcn_dot4_f32_fp8_fp8, amdgcn_dot4_f32_fp8_bf8},
1987 Standard)
1988 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
1989 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
1990
1991 addRulesForIOpcs({amdgcn_rsq, amdgcn_rsq_clamp}, Standard)
1992 .Uni(S16, {{Sgpr16}, {IntrId, Sgpr16}}, hasPST)
1993 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}}, !hasPST)
1994 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
1995 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
1996 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST)
1997 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
1998 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64}})
1999 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64}});
2000
2001 addRulesForIOpcs({amdgcn_mul_u24, amdgcn_mul_i24}, Standard)
2002 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}})
2003 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}})
2004 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr32, Vgpr32}})
2005 .Div(S64, {{Vgpr64}, {IntrId, Vgpr32, Vgpr32}});
2006
2007 addRulesForIOpcs({amdgcn_ds_bpermute, amdgcn_ds_bpermute_fi_b32,
2008 amdgcn_ds_permute, amdgcn_fmul_legacy, amdgcn_mulhi_i24,
2009 amdgcn_mulhi_u24},
2010 Standard)
2011 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}})
2012 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}});
2013
2014 addRulesForIOpcs({amdgcn_cvt_sr_bf8_f32, amdgcn_cvt_sr_fp8_f32,
2015 amdgcn_cvt_sr_fp8_f32_e5m3, amdgcn_cvt_pk_bf8_f32,
2016 amdgcn_cvt_pk_fp8_f32, amdgcn_cvt_pk_fp8_f32_e5m3},
2017 Standard)
2018 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2019 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2020
2021 addRulesForIOpcs({amdgcn_cvt_off_f32_i4, amdgcn_cvt_f32_bf8,
2022 amdgcn_cvt_f32_fp8, amdgcn_cvt_f32_fp8_e5m3},
2023 Standard)
2024 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}})
2025 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}});
2026
2027 addRulesForIOpcs({amdgcn_cvt_pk_f32_bf8, amdgcn_cvt_pk_f32_fp8})
2028 .Any({{UniV2S32}, {{UniInVgprV2S32}, {IntrId, Vgpr32}}})
2029 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, Vgpr32}}});
2030
2031 addRulesForIOpcs({amdgcn_cvt_f16_bf8, amdgcn_cvt_f16_fp8}, Standard)
2032 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr32}})
2033 .Div(S16, {{Vgpr16}, {IntrId, Vgpr32}});
2034
2035 addRulesForIOpcs({amdgcn_cvt_pk_f16_bf8, amdgcn_cvt_pk_f16_fp8}, Standard)
2036 .Uni(V2S16, {{UniInVgprV2S16}, {IntrId, Vgpr16}})
2037 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr16}});
2038
2039 addRulesForIOpcs({amdgcn_cvt_pk_bf8_f16, amdgcn_cvt_pk_fp8_f16}, Standard)
2040 .Uni(S16, {{UniInVgprS16}, {IntrId, VgprV2S16}})
2041 .Div(S16, {{Vgpr16}, {IntrId, VgprV2S16}});
2042
2043 addRulesForIOpcs({amdgcn_cvt_sr_bf8_f16, amdgcn_cvt_sr_fp8_f16}, Standard)
2044 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr16, Vgpr32, Vgpr32}})
2045 .Div(S32, {{Vgpr32}, {IntrId, Vgpr16, Vgpr32, Vgpr32}});
2046
2047 addRulesForIOpcs({amdgcn_cvt_sr_pk_f16_f32}, Standard)
2049 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2050
2051 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_fp8_f16})
2052 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32, Vgpr16, Vgpr32, Vgpr32}}});
2053
2054 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_fp8_f32})
2055 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32, Vgpr32}}});
2056
2057 addRulesForIOpcs({amdgcn_cubesc, amdgcn_cubetc, amdgcn_cubema, amdgcn_cubeid,
2058 amdgcn_fma_legacy},
2059 Standard)
2060 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2061 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2062
2063 addRulesForIOpcs({amdgcn_frexp_mant, amdgcn_fract}, Standard)
2064 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
2065 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
2066 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}})
2067 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
2068 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64}})
2069 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64}});
2070
2071 addRulesForIOpcs({amdgcn_prng_b32})
2072 .Any({{UniS32}, {{UniInVgprS32}, {IntrId, Vgpr32}}})
2073 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32}}});
2074
2075 addRulesForIOpcs({amdgcn_sffbh}, Standard)
2076 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}})
2077 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}});
2078
2079 addRulesForIOpcs({amdgcn_ubfe, amdgcn_sbfe}, Standard)
2080 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2081 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32, Sgpr32, Sgpr32}, S_BFE})
2082 .Uni(S64, {{Sgpr64}, {IntrId, Sgpr64, Sgpr32, Sgpr32}, S_BFE})
2083 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64, Vgpr32, Vgpr32}, V_BFE});
2084
2085 addRulesForIOpcs({amdgcn_cvt_pk_i16, amdgcn_cvt_pk_u16, amdgcn_cvt_pknorm_i16,
2086 amdgcn_cvt_pknorm_u16},
2087 Standard)
2088 .Uni(V2S16, {{UniInVgprV2S16}, {IntrId, Vgpr32, Vgpr32}})
2089 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr32, Vgpr32}});
2090
2091 addRulesForIOpcs({amdgcn_cvt_pkrtz}, Standard)
2092 .Uni(V2S16, {{SgprV2S16}, {IntrId, Sgpr32, Sgpr32}}, hasSALUFloat)
2093 .Uni(V2S16, {{UniInVgprV2S16}, {IntrId, Vgpr32, Vgpr32}}, !hasSALUFloat)
2094 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr32, Vgpr32}});
2095
2096 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk32_bf6_f16,
2097 amdgcn_cvt_scalef32_sr_pk32_fp6_f16,
2098 amdgcn_cvt_scalef32_sr_pk32_bf6_bf16,
2099 amdgcn_cvt_scalef32_sr_pk32_fp6_bf16},
2100 Standard)
2102
2103 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk32_bf6_f32,
2104 amdgcn_cvt_scalef32_sr_pk32_fp6_f32},
2105 Standard)
2107
2108 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk_fp4_f16}, Standard)
2110 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, VgprV2S16, Vgpr32, Vgpr32}});
2111
2112 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk_fp4_f32}, Standard)
2114 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, VgprV2S32, Vgpr32, Vgpr32}});
2115
2116 addRulesForIOpcs(
2117 {amdgcn_cvt_scalef32_2xpk16_fp6_f32, amdgcn_cvt_scalef32_2xpk16_bf6_f32})
2118 .Any(
2120 .Any({{UniV6S32},
2122
2123 addRulesForIOpcs({amdgcn_cvt_scalef32_f16_fp8, amdgcn_cvt_scalef32_f16_bf8},
2124 Standard)
2125 .Div(V2S16, {{VgprV2S16}, {IntrId, VgprV2S16, Vgpr32, Vgpr32}})
2127
2128 addRulesForIOpcs({amdgcn_cvt_scalef32_f32_fp8, amdgcn_cvt_scalef32_f32_bf8},
2129 Standard)
2130 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}})
2131 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}});
2132
2133 addRulesForIOpcs(
2134 {amdgcn_cvt_scalef32_pk16_bf6_f16, amdgcn_cvt_scalef32_pk16_fp6_f16},
2135 Standard)
2138
2139 addRulesForIOpcs(
2140 {amdgcn_cvt_scalef32_pk16_bf6_f32, amdgcn_cvt_scalef32_pk16_fp6_f32},
2141 Standard)
2144
2145 addRulesForIOpcs(
2146 {amdgcn_cvt_scalef32_pk8_bf8_f16, amdgcn_cvt_scalef32_pk8_fp8_f16},
2147 Standard)
2150
2151 addRulesForIOpcs(
2152 {amdgcn_cvt_scalef32_pk8_bf8_f32, amdgcn_cvt_scalef32_pk8_fp8_f32},
2153 Standard)
2156
2157 addRulesForIOpcs({amdgcn_cvt_scalef32_pk8_fp4_f16}, Standard)
2158 .Div(S32, {{Vgpr32}, {IntrId, VgprV8S16, Vgpr32}})
2159 .Uni(S32, {{UniInVgprS32}, {IntrId, VgprV8S16, Vgpr32}});
2160
2161 addRulesForIOpcs({amdgcn_cvt_scalef32_pk8_fp4_f32}, Standard)
2162 .Div(S32, {{Vgpr32}, {IntrId, VgprV8S32, Vgpr32}})
2163 .Uni(S32, {{UniInVgprS32}, {IntrId, VgprV8S32, Vgpr32}});
2164
2165 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk16_bf6_f16,
2166 amdgcn_cvt_scalef32_sr_pk16_fp6_f16},
2167 Standard)
2169 .Any({{UniV3S32},
2171
2172 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk16_bf6_f32,
2173 amdgcn_cvt_scalef32_sr_pk16_fp6_f32},
2174 Standard)
2176 .Any({{UniV3S32},
2178
2179 addRulesForIOpcs(
2180 {amdgcn_cvt_scalef32_sr_pk8_bf8_f16, amdgcn_cvt_scalef32_sr_pk8_fp8_f16},
2181 Standard)
2183 .Any({{UniV2S32},
2185
2186 addRulesForIOpcs(
2187 {amdgcn_cvt_scalef32_sr_pk8_bf8_f32, amdgcn_cvt_scalef32_sr_pk8_fp8_f32},
2188 Standard)
2190 .Any({{UniV2S32},
2192
2193 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk8_fp4_f16}, Standard)
2194 .Div(S32, {{Vgpr32}, {IntrId, VgprV8S16, Vgpr32, Vgpr32}})
2195 .Uni(S32, {{UniInVgprS32}, {IntrId, VgprV8S16, Vgpr32, Vgpr32}});
2196
2197 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk8_fp4_f32}, Standard)
2198 .Div(S32, {{Vgpr32}, {IntrId, VgprV8S32, Vgpr32, Vgpr32}})
2199 .Uni(S32, {{UniInVgprS32}, {IntrId, VgprV8S32, Vgpr32, Vgpr32}});
2200
2201 addRulesForIOpcs(
2202 {amdgcn_cvt_scale_pk16_f16_bf6, amdgcn_cvt_scale_pk16_f16_fp6}, Standard)
2205
2206 addRulesForIOpcs(
2207 {amdgcn_cvt_scale_pk16_f32_bf6, amdgcn_cvt_scale_pk16_f32_fp6}, Standard)
2210
2211 addRulesForIOpcs({amdgcn_cvt_scale_pk8_f16_bf8, amdgcn_cvt_scale_pk8_f16_fp8},
2212 Standard)
2215
2216 addRulesForIOpcs({amdgcn_cvt_scale_pk8_f16_fp4}, Standard)
2217 .Any({{DivV8S16}, {{VgprV8S16}, {IntrId, Vgpr32, Vgpr32}}})
2219
2220 addRulesForIOpcs({amdgcn_cvt_scale_pk8_f32_bf8, amdgcn_cvt_scale_pk8_f32_fp8},
2221 Standard)
2224
2225 addRulesForIOpcs({amdgcn_cvt_scale_pk8_f32_fp4}, Standard)
2226 .Any({{DivV8S32}, {{VgprV8S32}, {IntrId, Vgpr32, Vgpr32}}})
2228
2229 addRulesForIOpcs(
2230 {amdgcn_cvt_scalef32_pk32_bf6_f16, amdgcn_cvt_scalef32_pk32_fp6_f16},
2231 Standard)
2234
2235 addRulesForIOpcs(
2236 {amdgcn_cvt_scalef32_pk32_bf6_f32, amdgcn_cvt_scalef32_pk32_fp6_f32},
2237 Standard)
2240
2241 addRulesForIOpcs(
2242 {amdgcn_cvt_scalef32_pk_fp8_f32, amdgcn_cvt_scalef32_pk_bf8_f32},
2243 Standard)
2245 .Uni(V2S16,
2247
2248 addRulesForIOpcs(
2249 {amdgcn_cvt_scalef32_pk_f32_fp8, amdgcn_cvt_scalef32_pk_f32_bf8},
2250 Standard)
2251 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, Vgpr32, Vgpr32}}})
2253
2254 addRulesForIOpcs(
2255 {amdgcn_cvt_scalef32_pk_fp8_f16, amdgcn_cvt_scalef32_pk_bf8_f16},
2256 Standard)
2259
2260 addRulesForIOpcs({amdgcn_cvt_scalef32_pk_f32_fp4}, Standard)
2261 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, Vgpr32, Vgpr32}}})
2263
2264 addRulesForIOpcs({amdgcn_cvt_scalef32_pk_fp4_f32}, Standard)
2265 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32, Vgpr32}})
2266 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32, Vgpr32}});
2267
2268 addRulesForIOpcs({amdgcn_cvt_scalef32_pk_f16_fp4,
2269 amdgcn_cvt_scalef32_pk_f16_fp8,
2270 amdgcn_cvt_scalef32_pk_f16_bf8},
2271 Standard)
2272 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr32, Vgpr32}})
2273 .Uni(V2S16, {{UniInVgprV2S16}, {IntrId, Vgpr32, Vgpr32}});
2274
2275 addRulesForIOpcs(
2276 {amdgcn_cvt_scalef32_pk32_f32_fp6, amdgcn_cvt_scalef32_pk32_f32_bf6},
2277 Standard)
2280
2281 addRulesForIOpcs(
2282 {amdgcn_cvt_scalef32_pk32_f16_fp6, amdgcn_cvt_scalef32_pk32_f16_bf6},
2283 Standard)
2286
2287 addRulesForIOpcs({amdgcn_cvt_scalef32_pk_fp4_f16}, Standard)
2288 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, VgprV2S16, Vgpr32}})
2289 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, VgprV2S16, Vgpr32}});
2290
2291 addRulesForIOpcs({amdgcn_global_load_tr_b64})
2292 .Any({{DivB64, _, UniP1}, {{VgprB64}, {IntrId, SgprP1}}})
2293 .Any({{DivB64, _, DivP1}, {{VgprB64}, {IntrId, VgprP1}}})
2294 .Any({{DivB32, _, UniP1}, {{VgprB32}, {IntrId, SgprP1}}})
2295 .Any({{DivB32, _, DivP1}, {{VgprB32}, {IntrId, VgprP1}}});
2296
2297 addRulesForIOpcs({amdgcn_global_load_tr_b128})
2298 .Any({{DivB64, _, UniP1}, {{VgprB64}, {IntrId, SgprP1}}})
2299 .Any({{DivB64, _, DivP1}, {{VgprB64}, {IntrId, VgprP1}}})
2300 .Any({{DivB128, _, UniP1}, {{VgprB128}, {IntrId, SgprP1}}})
2301 .Any({{DivB128, _, DivP1}, {{VgprB128}, {IntrId, VgprP1}}});
2302
2303 addRulesForIOpcs({amdgcn_global_load_tr4_b64})
2304 .Any({{DivV2S32, _, UniP1}, {{VgprV2S32}, {IntrId, SgprP1}}})
2305 .Any({{DivV2S32, _, DivP1}, {{VgprV2S32}, {IntrId, VgprP1}}});
2306
2307 addRulesForIOpcs({amdgcn_global_load_tr6_b96})
2308 .Any({{DivV3S32, _, UniP1}, {{VgprV3S32}, {IntrId, SgprP1}}})
2309 .Any({{DivV3S32, _, DivP1}, {{VgprV3S32}, {IntrId, VgprP1}}});
2310
2311 addRulesForIOpcs({amdgcn_ds_load_tr4_b64, amdgcn_ds_load_tr8_b64})
2312 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, VgprP3}}});
2313
2314 addRulesForIOpcs({amdgcn_ds_load_tr6_b96})
2315 .Any({{DivV3S32}, {{VgprV3S32}, {IntrId, VgprP3}}});
2316
2317 addRulesForIOpcs({amdgcn_ds_load_tr16_b128})
2318 .Any({{DivB128}, {{VgprB128}, {IntrId, VgprP3}}});
2319
2320 addRulesForIOpcs({amdgcn_global_atomic_ordered_add_b64})
2321 .Any({{DivS64}, {{Vgpr64}, {IntrId, VgprP1, Vgpr64}}});
2322
2323 addRulesForIOpcs(
2324 {amdgcn_global_atomic_fmin_num, amdgcn_global_atomic_fmax_num}, Standard)
2325 .Div(S32, {{Vgpr32}, {IntrId, VgprP1, Vgpr32}});
2326
2327 addRulesForIOpcs({amdgcn_flat_atomic_fmin_num, amdgcn_flat_atomic_fmax_num},
2328 Standard)
2329 .Div(S32, {{Vgpr32}, {IntrId, VgprP0, Vgpr32}});
2330
2331 addRulesForIOpcs({amdgcn_raw_buffer_load_lds})
2332 .Any({{_}, {{}, {IntrId, SgprV4S32, SgprP3, Imm, Vgpr32, Sgpr32}}});
2333
2334 addRulesForIOpcs({amdgcn_raw_buffer_load_async_lds})
2335 .Any({{_}, {{}, {IntrId, SgprV4S32, SgprB32_M0, Imm, Vgpr32, Sgpr32}}});
2336
2337 addRulesForIOpcs({amdgcn_struct_buffer_load_async_lds})
2338 .Any(
2339 {{_},
2341
2342 addRulesForIOpcs({amdgcn_struct_buffer_load_lds})
2343 .Any({{_},
2344 {{}, {IntrId, SgprV4S32, SgprP3, Imm, Vgpr32, Vgpr32, Sgpr32}}});
2345
2346 addRulesForIOpcs({amdgcn_raw_ptr_buffer_load_lds})
2347 .Any({{_}, {{}, {IntrId, SgprP8, SgprP3, Imm, Vgpr32, Sgpr32}}});
2348
2349 addRulesForIOpcs({amdgcn_raw_ptr_buffer_load_async_lds})
2350 .Any({{}, {{}, {IntrId, SgprP8, SgprB32_M0, Imm, VgprB32, SgprB32}}});
2351
2352 addRulesForIOpcs({amdgcn_struct_ptr_buffer_load_async_lds})
2353 .Any({{_},
2354 {{}, {IntrId, SgprP8, SgprB32_M0, Imm, Vgpr32, Vgpr32, Sgpr32}}});
2355
2356 addRulesForIOpcs({amdgcn_struct_ptr_buffer_load_lds})
2357 .Any({{_}, {{}, {IntrId, SgprP8, SgprP3, Imm, Vgpr32, Vgpr32, Sgpr32}}});
2358
2359 addRulesForIOpcs(
2360 {amdgcn_global_load_lds, amdgcn_load_to_lds, amdgcn_load_async_to_lds})
2361 .Any({{}, {{}, {IntrId, VgprP1, SgprB32_M0}}});
2362
2363 addRulesForIOpcs({amdgcn_global_load_async_to_lds_b8,
2364 amdgcn_global_load_async_to_lds_b32,
2365 amdgcn_global_load_async_to_lds_b64,
2366 amdgcn_global_load_async_to_lds_b128,
2367 amdgcn_global_store_async_from_lds_b8,
2368 amdgcn_global_store_async_from_lds_b32,
2369 amdgcn_global_store_async_from_lds_b64,
2370 amdgcn_global_store_async_from_lds_b128})
2371 .Any({{}, {{}, {IntrId, VgprP1, VgprP3}}});
2372
2373 addRulesForIOpcs({amdgcn_global_load_async_lds})
2374 .Any({{}, {{}, {IntrId, VgprP1, SgprB32_M0}}});
2375
2376 addRulesForIOpcs({amdgcn_tensor_load_to_lds, amdgcn_tensor_store_from_lds})
2377 .Any({{},
2378 {{},
2382
2383 addRulesForIOpcs({amdgcn_cluster_load_b32})
2385 .Any({{DivB32, _, UniP1}, {{VgprB32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
2386 .Any(
2387 {{DivB32, _, DivP1}, {{VgprB32}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
2388
2389 addRulesForIOpcs({amdgcn_cluster_load_b64})
2391 .Any({{DivB64, _, UniP1}, {{VgprB64}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
2392 .Any(
2393 {{DivB64, _, DivP1}, {{VgprB64}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
2394
2395 addRulesForIOpcs({amdgcn_cluster_load_b128})
2397 .Any({{DivB128, _, UniP1},
2398 {{VgprB128}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
2399 .Any({{DivB128, _, DivP1},
2400 {{VgprB128}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
2401
2402 addRulesForIOpcs({amdgcn_cluster_load_async_to_lds_b8,
2403 amdgcn_cluster_load_async_to_lds_b32,
2404 amdgcn_cluster_load_async_to_lds_b64,
2405 amdgcn_cluster_load_async_to_lds_b128})
2406 .Any({{}, {{}, {IntrId, VgprP1, VgprP3, Imm, Imm, SgprB32_M0}}});
2407
2408 addRulesForIOpcs({amdgcn_perm_pk16_b4_u4}, StandardB)
2409 .Uni(B64, {{UniInVgprB64}, {IntrId, Vgpr32, Vgpr32, VgprV2S32}})
2410 .Div(B64, {{VgprB64}, {IntrId, Vgpr32, Vgpr32, VgprV2S32}});
2411
2412 addRulesForIOpcs({amdgcn_perm_pk16_b6_u4}, StandardB)
2414 .Div(B96, {{VgprB96}, {IntrId, Vgpr32, VgprB64, VgprV2S32}});
2415
2416 addRulesForIOpcs({amdgcn_perm_pk16_b8_u4}, StandardB)
2418 .Div(B128, {{VgprB128}, {IntrId, VgprB64, VgprB64, VgprV2S32}});
2419
2420 addRulesForIOpcs({amdgcn_wwm, amdgcn_strict_wwm, amdgcn_wqm, amdgcn_softwqm,
2421 amdgcn_strict_wqm},
2422 StandardB)
2423 .Div(B32, {{VgprB32}, {IntrId, VgprB32}})
2424 .Uni(B32, {{SgprB32}, {IntrId, SgprB32}})
2425 .Div(B64, {{VgprB64}, {IntrId, VgprB64}})
2426 .Uni(B64, {{SgprB64}, {IntrId, SgprB64}})
2427 .Div(B96, {{VgprB96}, {IntrId, VgprB96}})
2428 .Uni(B96, {{SgprB96}, {IntrId, SgprB96}})
2429 .Div(B128, {{VgprB128}, {IntrId, VgprB128}})
2430 .Uni(B128, {{SgprB128}, {IntrId, SgprB128}})
2431 .Any({{UniB256}, {{SgprB256}, {IntrId, SgprB256}}})
2432 .Any({{DivB256}, {{VgprB256}, {IntrId, VgprB256}}})
2433 .Any({{UniB512}, {{SgprB512}, {IntrId, SgprB512}}})
2434 .Any({{DivB512}, {{VgprB512}, {IntrId, VgprB512}}});
2435
2436 addRulesForIOpcs({amdgcn_init_whole_wave}).Any({{DivS1}, {{Vcc}, {IntrId}}});
2437
2438 addRulesForIOpcs({amdgcn_kill, amdgcn_wqm_demote})
2439 .Any({{}, {{}, {IntrId, Vcc}}});
2440
2441 addRulesForIOpcs({amdgcn_set_inactive}, StandardB)
2442 .Div(B32, {{VgprB32}, {IntrId, VgprB32, VgprB32}});
2443
2444 addRulesForIOpcs({amdgcn_set_inactive_chain_arg}, Standard)
2445 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}});
2446
2447 addRulesForIOpcs({amdgcn_cvt_sr_bf16_f32, amdgcn_cvt_sr_f16_f32}, Standard)
2448 .Div(V2S16, {{VgprV2S16}, {IntrId, VgprV2S16, Vgpr32, Vgpr32}});
2449
2450 addRulesForIOpcs({amdgcn_ballot}, Standard)
2451 .Uni(S64, {{Sgpr64}, {IntrId, Vcc}})
2452 .Uni(S32, {{Sgpr32}, {IntrId, Vcc}});
2453
2454 addRulesForIOpcs({amdgcn_inverse_ballot})
2455 .Any({{DivS1, _, S32}, {{Vcc}, {IntrId, SgprB32_ReadFirstLane}}})
2456 .Any({{DivS1, _, S64}, {{Vcc}, {IntrId, SgprB64_ReadFirstLane}}});
2457
2458 addRulesForIOpcs({amdgcn_live_mask, amdgcn_ps_live})
2459 .Any({{DivS1}, {{Vcc}, {}}});
2460
2461 addRulesForIOpcs({amdgcn_mov_dpp, amdgcn_mov_dpp8}, StandardB)
2462 .Div(B32, {{VgprB32}, {IntrId, VgprB32}})
2463 .Div(B64, {{VgprB64}, {IntrId, VgprB64}});
2464
2465 addRulesForIOpcs({amdgcn_update_dpp}, StandardB)
2466 .Div(B32, {{VgprB32}, {IntrId, VgprB32, VgprB32}})
2467 .Div(B64, {{VgprB64}, {IntrId, VgprB64, VgprB64}});
2468
2469 addRulesForIOpcs({amdgcn_sin, amdgcn_cos}, Standard)
2470 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
2471 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
2472 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
2473 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}});
2474
2475 addRulesForIOpcs({amdgcn_trig_preop}, Standard)
2476 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64, Vgpr32}})
2477 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64, Vgpr32}});
2478
2479 addRulesForIOpcs({amdgcn_exp2}, Standard)
2480 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
2481 .Uni(S16, {{Sgpr16}, {IntrId, Sgpr16}}, hasPST)
2482 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}}, !hasPST)
2483 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
2484 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
2485 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST);
2486
2487 addRulesForIOpcs({amdgcn_rcp, amdgcn_sqrt}, Standard)
2488 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
2489 .Uni(S16, {{Sgpr16}, {IntrId, Sgpr16}}, hasPST)
2490 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}}, !hasPST)
2491 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
2492 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
2493 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST)
2494 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64}})
2495 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64}});
2496
2497 addRulesForIOpcs({amdgcn_log}, Standard)
2498 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
2499 .Uni(S16, {{Sgpr16}, {IntrId, Sgpr16}}, hasPST)
2500 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}}, !hasPST)
2501 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
2502 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}}, hasPST)
2503 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}}, !hasPST);
2504
2505 addRulesForIOpcs({amdgcn_ds_atomic_async_barrier_arrive_b64})
2506 .Any({{}, {{}, {IntrId, VgprP3}}});
2507
2508 addRulesForIOpcs({amdgcn_ds_atomic_barrier_arrive_rtn_b64}, Standard)
2509 .Div(S64, {{Vgpr64}, {IntrId, VgprP3, Vgpr64}});
2510
2511 addRulesForIOpcs({amdgcn_ds_add_gs_reg_rtn, amdgcn_ds_sub_gs_reg_rtn},
2512 Standard)
2513 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
2514 .Div(S64, {{Vgpr64}, {IntrId, Vgpr32}});
2515
2516 addRulesForIOpcs({amdgcn_ds_append, amdgcn_ds_consume}, Standard)
2517 .Uni(S32, {{UniInVgprS32}, {IntrId, SgprB32_M0}})
2518 .Div(S32, {{Vgpr32}, {IntrId, SgprB32_M0}});
2519
2520 addRulesForIOpcs(
2521 {amdgcn_ds_bvh_stack_rtn, amdgcn_ds_bvh_stack_push4_pop1_rtn}, Standard)
2522 .Div(S32, {{Vgpr32, Vgpr32}, {IntrId, Vgpr32, Vgpr32, VgprV4S32}});
2523
2524 addRulesForIOpcs({amdgcn_ds_bvh_stack_push8_pop1_rtn}, Standard)
2525 .Div(S32, {{Vgpr32, Vgpr32}, {IntrId, Vgpr32, Vgpr32, VgprV8S32}});
2526
2527 addRulesForIOpcs({amdgcn_ds_bvh_stack_push8_pop2_rtn}, Standard)
2528 .Div(S64, {{Vgpr64, Vgpr32}, {IntrId, Vgpr32, Vgpr32, VgprV8S32}});
2529
2530 addRulesForIOpcs({amdgcn_ds_gws_sema_p, amdgcn_ds_gws_sema_v,
2531 amdgcn_ds_gws_sema_release_all})
2532 .Any({{}, {{}, {IntrId, SgprB32_M0}}});
2533
2534 addRulesForIOpcs(
2535 {amdgcn_ds_gws_barrier, amdgcn_ds_gws_init, amdgcn_ds_gws_sema_br})
2536 .Any({{}, {{}, {IntrId, Vgpr32, SgprB32_M0}}});
2537
2538 addRulesForIOpcs({amdgcn_ds_ordered_add, amdgcn_ds_ordered_swap}, Standard)
2539 .Div(S32, {{Vgpr32}, {IntrId, SgprB32_M0, Vgpr32}});
2540
2541 addRulesForIOpcs({amdgcn_ds_swizzle}, Standard)
2542 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}})
2543 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}});
2544
2545 addRulesForIOpcs({amdgcn_permlane16_var, amdgcn_permlanex16_var}, Standard)
2546 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2547
2548 addRulesForIOpcs({amdgcn_permlane16_swap, amdgcn_permlane32_swap}, Standard)
2549 .Div(S32, {{Vgpr32, Vgpr32}, {IntrId, Vgpr32, Vgpr32}});
2550
2551 addRulesForIOpcs({amdgcn_permlane64}, StandardB)
2552 .Div(B32, {{VgprB32}, {IntrId, VgprB32}});
2553
2554 addRulesForIOpcs({amdgcn_ds_read_tr4_b64, amdgcn_ds_read_tr8_b64})
2555 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, VgprP3}}});
2556
2557 addRulesForIOpcs({amdgcn_ds_read_tr6_b96})
2558 .Any({{DivV3S32}, {{VgprV3S32}, {IntrId, VgprP3}}});
2559
2560 addRulesForIOpcs({amdgcn_ds_read_tr16_b64})
2561 .Any({{DivV4S16}, {{VgprV4S16}, {IntrId, VgprP3}}});
2562
2563 addRulesForIOpcs({amdgcn_interp_p1}, Standard)
2564 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Imm, Imm, SgprB32_M0}});
2565
2566 addRulesForIOpcs({amdgcn_interp_p1_f16}, Standard)
2567 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Imm, Imm, Imm, SgprB32_M0}});
2568
2569 addRulesForIOpcs({amdgcn_interp_p2}, Standard)
2570 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Imm, Imm, SgprB32_M0}});
2571
2572 addRulesForIOpcs({amdgcn_interp_p2_f16}, Standard)
2573 .Div(S16,
2575
2576 addRulesForIOpcs({amdgcn_interp_mov}, Standard)
2577 .Div(S32, {{Vgpr32}, {IntrId, Imm, Imm, Imm, SgprB32_M0}});
2578
2579 addRulesForIOpcs({amdgcn_interp_inreg_p10, amdgcn_interp_inreg_p2,
2580 amdgcn_interp_inreg_p10_f16, amdgcn_interp_p10_rtz_f16},
2581 Standard)
2582 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2583 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2584
2585 addRulesForIOpcs({amdgcn_interp_inreg_p2_f16, amdgcn_interp_p2_rtz_f16},
2586 Standard)
2587 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2588 .Div(S16, {{Vgpr16}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2589
2590 addRulesForIOpcs({amdgcn_frexp_exp})
2591 .Any({{UniS16}, {{UniInVgprS16}, {IntrId, Vgpr16}}})
2592 .Any({{DivS16}, {{Vgpr16}, {IntrId, Vgpr16}}})
2593 .Any({{UniS32, _, S32}, {{UniInVgprS32}, {IntrId, Vgpr32}}})
2594 .Any({{DivS32, _, S32}, {{Vgpr32}, {IntrId, Vgpr32}}})
2595 .Any({{UniS32, _, S64}, {{UniInVgprS32}, {IntrId, Vgpr64}}})
2596 .Any({{DivS32, _, S64}, {{Vgpr32}, {IntrId, Vgpr64}}});
2597
2598 addRulesForIOpcs({amdgcn_div_fmas}, Standard)
2599 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32, Vcc}})
2600 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32, Vcc}})
2601 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64, Vgpr64, Vgpr64, Vcc}})
2602 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64, Vgpr64, Vgpr64, Vcc}});
2603
2604 addRulesForIOpcs({amdgcn_div_fixup}, Standard)
2605 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16, Vgpr16, Vgpr16}})
2606 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16, Vgpr16, Vgpr16}})
2607 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2608 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2609 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64, Vgpr64, Vgpr64}})
2610 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64, Vgpr64, Vgpr64}});
2611
2612 addRulesForIOpcs({amdgcn_div_scale}, Standard)
2613 .Div(S32, {{Vgpr32, Vcc}, {IntrId, Vgpr32, Vgpr32}})
2614 .Uni(S32, {{UniInVgprS32, UniInVcc}, {IntrId, Vgpr32, Vgpr32}})
2615 .Div(S64, {{Vgpr64, Vcc}, {IntrId, Vgpr64, Vgpr64}})
2616 .Uni(S64, {{UniInVgprS64, UniInVcc}, {IntrId, Vgpr64, Vgpr64}});
2617
2618 addRulesForIOpcs({amdgcn_fdot2, amdgcn_sdot2, amdgcn_udot2}, Standard)
2620 .Div(S32, {{Vgpr32}, {IntrId, VgprV2S16, VgprV2S16, Vgpr32}});
2621
2622 addRulesForIOpcs({amdgcn_fdot2_f16_f16}, Standard)
2624 .Div(S16, {{Vgpr16}, {IntrId, VgprV2S16, VgprV2S16, Vgpr16}});
2625
2626 addRulesForIOpcs({amdgcn_sudot4, amdgcn_sudot8}, Standard)
2627 .Uni(S32, {{UniInVgprS32}, {IntrId, Imm, Vgpr32, Imm, Vgpr32, Vgpr32}})
2628 .Div(S32, {{Vgpr32}, {IntrId, Imm, Vgpr32, Imm, Vgpr32, Vgpr32}});
2629
2630 addRulesForIOpcs({amdgcn_s_alloc_vgpr})
2632
2633 addRulesForIOpcs({amdgcn_sat_pk4_i4_i8, amdgcn_sat_pk4_u4_u8}, Standard)
2634 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr32}})
2635 .Div(S16, {{Vgpr16}, {IntrId, Vgpr32}});
2636
2637 bool HasGFX90AInsts = ST->hasGFX90AInsts();
2638
2639 // On gfx90a+ both AGPR-form and VGPR-form exists
2640 addRulesForIOpcs({amdgcn_mfma_f32_32x32x1f32, amdgcn_mfma_f32_16x16x1f32,
2641 amdgcn_mfma_f32_4x4x1f32, amdgcn_mfma_f32_32x32x2f32,
2642 amdgcn_mfma_f32_16x16x4f32, amdgcn_mfma_f32_32x32x4f16,
2643 amdgcn_mfma_f32_16x16x4f16, amdgcn_mfma_f32_4x4x4f16,
2644 amdgcn_mfma_f32_32x32x8f16, amdgcn_mfma_f32_16x16x16f16,
2645 amdgcn_mfma_i32_32x32x4i8, amdgcn_mfma_i32_16x16x4i8,
2646 amdgcn_mfma_i32_4x4x4i8, amdgcn_mfma_i32_32x32x8i8,
2647 amdgcn_mfma_i32_16x16x16i8, amdgcn_mfma_f32_32x32x2bf16,
2648 amdgcn_mfma_f32_16x16x2bf16, amdgcn_mfma_f32_4x4x2bf16,
2649 amdgcn_mfma_f32_32x32x4bf16, amdgcn_mfma_f32_16x16x8bf16})
2650 .Any({{DivAnyTy},
2652 !HasGFX90AInsts)
2653 .Any({{DivAnyTy},
2654 {{VgprOrAgprAnyTy},
2656 HasGFX90AInsts);
2657
2658 // gfx90a+ only MFMAs
2659 addRulesForIOpcs(
2660 {
2661 amdgcn_mfma_f32_32x32x4bf16_1k,
2662 amdgcn_mfma_f32_16x16x4bf16_1k,
2663 amdgcn_mfma_f32_4x4x4bf16_1k,
2664 amdgcn_mfma_f32_32x32x8bf16_1k,
2665 amdgcn_mfma_f32_16x16x16bf16_1k,
2666 amdgcn_mfma_f64_16x16x4f64,
2667 amdgcn_mfma_f64_4x4x4f64,
2668 amdgcn_mfma_i32_16x16x32_i8,
2669 amdgcn_mfma_i32_32x32x16_i8,
2670 amdgcn_mfma_f32_16x16x8_xf32,
2671 amdgcn_mfma_f32_32x32x4_xf32,
2672 amdgcn_mfma_f32_16x16x32_bf8_bf8,
2673 amdgcn_mfma_f32_16x16x32_bf8_fp8,
2674 amdgcn_mfma_f32_16x16x32_fp8_bf8,
2675 amdgcn_mfma_f32_16x16x32_fp8_fp8,
2676 amdgcn_mfma_f32_32x32x16_bf8_bf8,
2677 amdgcn_mfma_f32_32x32x16_bf8_fp8,
2678 amdgcn_mfma_f32_32x32x16_fp8_bf8,
2679 amdgcn_mfma_f32_32x32x16_fp8_fp8,
2680 // gfx950
2681 amdgcn_mfma_f32_16x16x32_f16,
2682 amdgcn_mfma_f32_32x32x16_f16,
2683 amdgcn_mfma_i32_16x16x64_i8,
2684 amdgcn_mfma_i32_32x32x32_i8,
2685 // TODO: bf16 variants fail in IRTranslator.
2686 // amdgcn_mfma_f32_16x16x32_bf16, amdgcn_mfma_f32_32x32x16_bf16,
2687 })
2688 .Any({{DivAnyTy},
2689 {{VgprOrAgprAnyTy},
2691
2692 addRulesForIOpcs(
2693 {// gfx942+
2694 amdgcn_smfmac_f32_16x16x32_f16, amdgcn_smfmac_f32_32x32x16_f16,
2695 amdgcn_smfmac_f32_16x16x32_bf16, amdgcn_smfmac_f32_32x32x16_bf16,
2696 amdgcn_smfmac_i32_16x16x64_i8, amdgcn_smfmac_i32_32x32x32_i8,
2697 amdgcn_smfmac_f32_16x16x64_bf8_bf8, amdgcn_smfmac_f32_16x16x64_bf8_fp8,
2698 amdgcn_smfmac_f32_16x16x64_fp8_bf8, amdgcn_smfmac_f32_16x16x64_fp8_fp8,
2699 amdgcn_smfmac_f32_32x32x32_bf8_bf8, amdgcn_smfmac_f32_32x32x32_bf8_fp8,
2700 amdgcn_smfmac_f32_32x32x32_fp8_bf8, amdgcn_smfmac_f32_32x32x32_fp8_fp8,
2701 // gfx950+
2702 amdgcn_smfmac_f32_16x16x64_f16, amdgcn_smfmac_f32_32x32x32_f16,
2703 amdgcn_smfmac_i32_16x16x128_i8, amdgcn_smfmac_i32_32x32x64_i8,
2704 amdgcn_smfmac_f32_16x16x128_bf8_bf8, amdgcn_smfmac_f32_16x16x128_bf8_fp8,
2705 amdgcn_smfmac_f32_16x16x128_fp8_bf8, amdgcn_smfmac_f32_16x16x128_fp8_fp8,
2706 amdgcn_smfmac_f32_32x32x64_bf8_bf8, amdgcn_smfmac_f32_32x32x64_bf8_fp8,
2707 amdgcn_smfmac_f32_32x32x64_fp8_bf8, amdgcn_smfmac_f32_32x32x64_fp8_fp8})
2708 .Any({{DivAnyTy},
2709 {{VgprOrAgprAnyTy},
2711
2712 addRulesForIOpcs({amdgcn_mfma_scale_f32_32x32x64_f8f6f4,
2713 amdgcn_mfma_scale_f32_16x16x128_f8f6f4})
2714 .Any({{DivAnyTy},
2715 {{VgprOrAgprAnyTy},
2717 Vgpr32, Imm, Vgpr32}}});
2718
2719 // WMMA/SWMMAC intrinsics: all register operands map to VGPR.
2720 addRulesForIOpcs(
2721 {// WMMA GFX11+
2722 amdgcn_wmma_f32_16x16x16_f16, amdgcn_wmma_f32_16x16x16_bf16,
2723 amdgcn_wmma_f16_16x16x16_f16, amdgcn_wmma_bf16_16x16x16_bf16,
2724 amdgcn_wmma_f16_16x16x16_f16_tied, amdgcn_wmma_bf16_16x16x16_bf16_tied,
2725 amdgcn_wmma_i32_16x16x16_iu8, amdgcn_wmma_i32_16x16x16_iu4,
2726 // WMMA GFX12
2727 amdgcn_wmma_f32_16x16x16_fp8_fp8, amdgcn_wmma_f32_16x16x16_fp8_bf8,
2728 amdgcn_wmma_f32_16x16x16_bf8_fp8, amdgcn_wmma_f32_16x16x16_bf8_bf8,
2729 amdgcn_wmma_i32_16x16x32_iu4,
2730 // WMMA GFX1250
2731 amdgcn_wmma_f32_16x16x4_f32, amdgcn_wmma_f32_16x16x32_bf16,
2732 amdgcn_wmma_f32_16x16x32_f16, amdgcn_wmma_f16_16x16x32_f16,
2733 amdgcn_wmma_bf16_16x16x32_bf16, amdgcn_wmma_bf16f32_16x16x32_bf16,
2734 amdgcn_wmma_f32_16x16x64_fp8_fp8, amdgcn_wmma_f32_16x16x64_fp8_bf8,
2735 amdgcn_wmma_f32_16x16x64_bf8_fp8, amdgcn_wmma_f32_16x16x64_bf8_bf8,
2736 amdgcn_wmma_f16_16x16x64_fp8_fp8, amdgcn_wmma_f16_16x16x64_fp8_bf8,
2737 amdgcn_wmma_f16_16x16x64_bf8_fp8, amdgcn_wmma_f16_16x16x64_bf8_bf8,
2738 amdgcn_wmma_f16_16x16x128_fp8_fp8, amdgcn_wmma_f16_16x16x128_fp8_bf8,
2739 amdgcn_wmma_f16_16x16x128_bf8_fp8, amdgcn_wmma_f16_16x16x128_bf8_bf8,
2740 amdgcn_wmma_f32_16x16x128_fp8_fp8, amdgcn_wmma_f32_16x16x128_fp8_bf8,
2741 amdgcn_wmma_f32_16x16x128_bf8_fp8, amdgcn_wmma_f32_16x16x128_bf8_bf8,
2742 amdgcn_wmma_i32_16x16x64_iu8, amdgcn_wmma_f32_16x16x128_f8f6f4,
2743 amdgcn_wmma_scale_f32_16x16x128_f8f6f4,
2744 amdgcn_wmma_scale16_f32_16x16x128_f8f6f4, amdgcn_wmma_f32_32x16x128_f4,
2745 amdgcn_wmma_scale_f32_32x16x128_f4, amdgcn_wmma_scale16_f32_32x16x128_f4,
2746 // WMMA GFX1251
2747 amdgcn_wmma_f64_16x16x4_f64,
2748 // SWMMAC GFX12
2749 amdgcn_swmmac_f32_16x16x32_f16, amdgcn_swmmac_f32_16x16x32_bf16,
2750 amdgcn_swmmac_f16_16x16x32_f16, amdgcn_swmmac_bf16_16x16x32_bf16,
2751 amdgcn_swmmac_i32_16x16x32_iu8, amdgcn_swmmac_i32_16x16x32_iu4,
2752 amdgcn_swmmac_i32_16x16x64_iu4, amdgcn_swmmac_f32_16x16x32_fp8_fp8,
2753 amdgcn_swmmac_f32_16x16x32_fp8_bf8, amdgcn_swmmac_f32_16x16x32_bf8_fp8,
2754 amdgcn_swmmac_f32_16x16x32_bf8_bf8,
2755 // SWMMAC GFX1250
2756 amdgcn_swmmac_f32_16x16x64_f16, amdgcn_swmmac_f32_16x16x64_bf16,
2757 amdgcn_swmmac_f16_16x16x64_f16, amdgcn_swmmac_bf16_16x16x64_bf16,
2758 amdgcn_swmmac_bf16f32_16x16x64_bf16, amdgcn_swmmac_f32_16x16x128_fp8_fp8,
2759 amdgcn_swmmac_f32_16x16x128_fp8_bf8, amdgcn_swmmac_f32_16x16x128_bf8_fp8,
2760 amdgcn_swmmac_f32_16x16x128_bf8_bf8, amdgcn_swmmac_f16_16x16x128_fp8_fp8,
2761 amdgcn_swmmac_f16_16x16x128_fp8_bf8, amdgcn_swmmac_f16_16x16x128_bf8_fp8,
2762 amdgcn_swmmac_f16_16x16x128_bf8_bf8, amdgcn_swmmac_i32_16x16x128_iu8})
2763 .Any({{}, {{}, {}, ApplyAllVgpr}});
2764
2765} // end initialize rules
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU address space definition.
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
constexpr LLT S16
constexpr LLT S1
constexpr LLT V2S16
constexpr LLT S32
constexpr LLT V4S32
constexpr LLT V3S32
constexpr LLT S64
constexpr LLT V2S32
constexpr LLT S128
UniformityLLTOpPredicateID LLTToBId(LLT Ty)
bool matchUniformityAndLLT(Register Reg, UniformityLLTOpPredicateID UniID, const MachineUniformityInfo &MUI, const MachineRegisterInfo &MRI)
UniformityLLTOpPredicateID LLTToId(LLT Ty)
AMD GCN specific subclass of TargetSubtarget.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
#define _
IRTranslator LLVM IR MI
Register Reg
Register const TargetRegisterInfo * TRI
Machine IR instance of the generic uniformity analysis.
bool operator()(const MachineInstr &MI) const
Predicate operator||(const Predicate &RHS) const
Predicate operator&&(const Predicate &RHS) const
Predicate(std::function< bool(const MachineInstr &)> Pred)
Predicate operator!() const
RegBankLegalizeRules(const GCNSubtarget &ST, MachineRegisterInfo &MRI)
const SetOfRulesForOpcode * getRulesForOpc(MachineInstr &MI) const
const RegBankLLTMapping * findMappingForMI(const MachineInstr &MI, const MachineRegisterInfo &MRI, const MachineUniformityInfo &MUI) const
void addFastRuleDivergent(UniformityLLTOpPredicateID Ty, RegBankLLTMapping RuleApplyIDs)
void addFastRuleUniform(UniformityLLTOpPredicateID Ty, RegBankLLTMapping RuleApplyIDs)
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
bool isSigned() const
Definition InstrTypes.h:993
bool isDivergentAtDef(ConstValueRefT V) const
Whether V is divergent at its definition.
bool isUniformAtDef(ConstValueRefT V) const
Whether V is uniform/non-divergent at its definition.
bool isEquality() const
Return true if this predicate is either EQ or NE.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
TypeSize getValue() const
Representation of each machine instruction.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
unsigned getAddrSpace() const
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
const TargetRegisterInfo * getTargetRegisterInfo() const
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void swap(SmallVectorImpl &RHS)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
bool isAnyPtr(LLT Ty, unsigned Width)
bool isUniformMMO(const MachineMemOperand *MMO)
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
This is an optimization pass for GlobalISel generic memory operations.
GenericUniformityInfo< MachineSSAContext > MachineUniformityInfo
static const MachineMemOperand::Flags MONoClobber
Mark the MMO of a uniform load if there are no potentially clobbering stores on any path from the sta...
Definition SIInstrInfo.h:46
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
SmallVector< UniformityLLTOpPredicateID, 4 > OpUniformityAndTypes
PredicateMapping(std::initializer_list< UniformityLLTOpPredicateID > OpList, std::function< bool(const MachineInstr &)> TestFunc=nullptr)
bool match(const MachineInstr &MI, const MachineUniformityInfo &MUI, const MachineRegisterInfo &MRI) const
std::function< bool(const MachineInstr &)> TestFunc
RegBankLLTMapping(std::initializer_list< RegBankLLTMappingApplyID > DstOpMappingList, std::initializer_list< RegBankLLTMappingApplyID > SrcOpMappingList, LoweringMethodID LoweringMethod=DoNotLower)
SmallVector< RegBankLLTMappingApplyID, 2 > DstOpMapping
SmallVector< RegBankLLTMappingApplyID, 4 > SrcOpMapping
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39