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