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