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_ABS}, Standard)
1432 .Uni(S16, {{Sgpr32Trunc}, {Sgpr32SExt}})
1433 .Div(S16, {{Vgpr16}, {Vgpr16}, AbsToNegMax})
1434 .Uni(S32, {{Sgpr32}, {Sgpr32}})
1435 .Div(S32, {{Vgpr32}, {Vgpr32}, AbsToNegMax})
1436 .Uni(V2S16, {{SgprV2S16}, {SgprV2S16}, AbsToS32})
1437 .Div(V2S16, {{VgprV2S16}, {VgprV2S16}, AbsToNegMax});
1438
1439 addRulesForGOpcs({G_BITREVERSE}, Standard)
1440 .Uni(S32, {{Sgpr32}, {Sgpr32}})
1441 .Div(S32, {{Vgpr32}, {Vgpr32}})
1442 .Uni(S64, {{Sgpr64}, {Sgpr64}})
1443 .Div(S64, {{Vgpr64}, {Vgpr64}});
1444
1445 addRulesForGOpcs({G_AMDGPU_FFBH_U32, G_AMDGPU_FFBL_B32, G_CTLZ_ZERO_POISON,
1446 G_CTTZ_ZERO_POISON})
1447 .Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}})
1448 .Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
1449 .Any({{UniS32, S64}, {{Sgpr32}, {Sgpr64}}})
1451
1452 addRulesForGOpcs({G_CTPOP})
1453 .Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}})
1454 .Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
1455 .Any({{UniS32, S64}, {{Sgpr32}, {Sgpr64}}})
1456 .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}, CtPop64To32}});
1457
1458 addRulesForGOpcs({G_FENCE}).Any({{{}}, {{}, {}}});
1459
1460 addRulesForGOpcs({G_READSTEADYCOUNTER, G_READCYCLECOUNTER}, Standard)
1461 .Uni(S64, {{Sgpr64}, {}});
1462
1463 addRulesForGOpcs({G_GET_ROUNDING}, Standard)
1464 .Uni(S32, {{Sgpr32}, {}, LowerGetRounding});
1465
1466 addRulesForGOpcs({G_SET_ROUNDING}, Standard)
1469
1470 addRulesForGOpcs({G_WRITE_REGISTER})
1471 .Any({{_, B32}, {{}, {None, SgprB32_ReadFirstLane}}})
1472 .Any({{_, B64}, {{}, {None, SgprB64_ReadFirstLane}}});
1473
1474 addRulesForGOpcs({G_BLOCK_ADDR}).Any({{UniP0}, {{SgprP0}, {}}});
1475
1476 addRulesForGOpcs({G_GLOBAL_VALUE})
1477 .Any({{UniP0}, {{SgprP0}, {}}})
1478 .Any({{UniP1}, {{SgprP1}, {}}})
1479 .Any({{UniP3}, {{SgprP3}, {}}})
1480 .Any({{UniP4}, {{SgprP4}, {}}})
1481 .Any({{UniP8}, {{SgprP8}, {}}});
1482
1483 addRulesForGOpcs({G_AMDGPU_WAVE_ADDRESS}).Any({{UniP5}, {{SgprP5}, {}}});
1484
1485 addRulesForGOpcs({G_AMDGPU_SPONENTRY}, Standard).Uni(S32, {{Sgpr32}, {}});
1486
1487 addRulesForGOpcs({G_SI_CALL})
1488 .Any({{_, UniP0}, {{None}, {SgprP0}}})
1489 .Any({{_, DivP0}, {{None}, {SgprP0Call_WF}}})
1490 .Any({{_, UniP4}, {{None}, {SgprP4}}})
1491 .Any({{_, DivP4}, {{None}, {SgprP4Call_WF}}});
1492
1493 bool hasSALUFloat = ST->hasSALUFloatInsts();
1494
1495 addRulesForGOpcs({G_FADD, G_FMUL, G_STRICT_FADD, G_STRICT_FMUL}, Standard)
1496 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}}, !hasSALUFloat)
1497 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16}}, hasSALUFloat)
1498 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1499 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasSALUFloat)
1500 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasSALUFloat)
1501 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1502 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64}})
1503 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}})
1505 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
1509 .Any({{DivV2S64}, {{VgprV2S64}, {VgprV2S64, VgprV2S64}}});
1510
1511 addRulesForGOpcs({G_FSUB, G_STRICT_FSUB}, Standard)
1512 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1513 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1514 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16}}, hasSALUFloat)
1515 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}}, !hasSALUFloat)
1516 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasSALUFloat)
1517 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasSALUFloat)
1519 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}});
1520
1521 addRulesForGOpcs({G_FMAD}, Standard)
1522 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16, Vgpr16}})
1523 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16, Vgpr16}})
1524 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32, Vgpr32}})
1525 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}});
1526
1527 addRulesForGOpcs({G_FLDEXP, G_STRICT_FLDEXP}, Standard)
1528 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}})
1529 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1530 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}})
1531 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1532 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr32}})
1533 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr32}});
1534
1535 addRulesForGOpcs({G_FMA, G_STRICT_FMA}, Standard)
1536 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16, Sgpr16}}, hasSALUFloat)
1537 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16, Vgpr16}}, !hasSALUFloat)
1538 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16, Vgpr16}})
1539 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32, Sgpr32}}, hasSALUFloat)
1540 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32, Vgpr32}}, !hasSALUFloat)
1541 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}})
1542 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64, Vgpr64}})
1543 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64, Vgpr64}})
1550
1551 addRulesForGOpcs({G_AMDGPU_FMED3}, Standard)
1552 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16, Vgpr16}})
1553 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16, Vgpr16}})
1554 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32, Vgpr32}})
1555 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}});
1556
1557 // TODO: This opcode is generated from the i64->i16 signed clamped pattern in
1558 // the PreLegalizerCombiner. Move the combine to RegBankCombiner to keep more
1559 // instructions on SALU.
1560 addRulesForGOpcs({G_AMDGPU_SMED3}, Standard)
1561 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32, Vgpr32}})
1562 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32, Vgpr32}});
1563
1564 // FNEG and FABS are either folded as source modifiers or can be selected as
1565 // bitwise XOR and AND with Mask. XOR and AND are available on SALU but for
1566 // targets without SALU float we still select them as VGPR since there would
1567 // be no real sgpr use.
1568 addRulesForGOpcs({G_FNEG, G_FABS}, Standard)
1569 .Uni(S16, {{UniInVgprS16}, {Vgpr16}}, !hasSALUFloat)
1570 .Uni(S16, {{Sgpr16}, {Sgpr16}}, hasSALUFloat)
1571 .Div(S16, {{Vgpr16}, {Vgpr16}})
1572 .Uni(S32, {{UniInVgprS32}, {Vgpr32}}, !hasSALUFloat)
1573 .Uni(S32, {{Sgpr32}, {Sgpr32}}, hasSALUFloat)
1574 .Div(S32, {{Vgpr32}, {Vgpr32}})
1575 .Uni(S64, {{UniInVgprS64}, {Vgpr64}})
1576 .Div(S64, {{Vgpr64}, {Vgpr64}})
1577 .Uni(V2S16, {{SgprV2S16}, {SgprV2S16}})
1578 .Div(V2S16, {{VgprV2S16}, {VgprV2S16}})
1579 .Any({{UniV2S32}, {{UniInVgprV2S32}, {VgprV2S32}}})
1580 .Any({{DivV2S32}, {{VgprV2S32}, {VgprV2S32}}});
1581
1582 addRulesForGOpcs({G_FCANONICALIZE}, Standard)
1583 .Uni(S32, {{UniInVgprS32}, {Vgpr32}})
1584 .Div(S32, {{Vgpr32}, {Vgpr32}})
1585 .Uni(S16, {{UniInVgprS16}, {Vgpr16}})
1586 .Div(S16, {{Vgpr16}, {Vgpr16}})
1587 .Uni(S64, {{UniInVgprS64}, {Vgpr64}})
1588 .Div(S64, {{Vgpr64}, {Vgpr64}})
1589 .Uni(V2S16, {{UniInVgprV2S16}, {VgprV2S16}})
1590 .Div(V2S16, {{VgprV2S16}, {VgprV2S16}})
1591 .Any({{UniV2S32}, {{UniInVgprV2S32}, {VgprV2S32}}})
1592 .Any({{DivV2S32}, {{VgprV2S32}, {VgprV2S32}}})
1593 .Any({{UniV2S64}, {{UniInVgprV2S64}, {VgprV2S64}}})
1594 .Any({{DivV2S64}, {{VgprV2S64}, {VgprV2S64}}});
1595
1596 bool hasPST = ST->hasPseudoScalarTrans();
1597 // Only 16-bit G_FSQRT operations are legal. F32/F64 is handled with a custom
1598 // legalization in the legalizer.
1599 addRulesForGOpcs({G_FSQRT})
1600 .Any({{DivS16}, {{Vgpr16}, {Vgpr16}}})
1601 .Any({{UniBF16}, {{UniInVgprS16}, {Vgpr16}}})
1602 .Any({{UniS16}, {{Sgpr16}, {Sgpr16}}}, hasPST)
1603 .Any({{UniS16}, {{UniInVgprS16}, {Vgpr16}}}, !hasPST);
1604
1605 addRulesForGOpcs({G_FPTOUI, G_FPTOSI, G_FPTOUI_SAT, G_FPTOSI_SAT})
1606 .Any({{UniS16, S16}, {{UniInVgprS16}, {Vgpr16}}})
1607 .Any({{DivS16, S16}, {{Vgpr16}, {Vgpr16}}})
1608 .Any({{UniS32, S16}, {{Sgpr32}, {Sgpr16}}}, hasSALUFloat)
1609 .Any({{UniS32, S16}, {{UniInVgprS32}, {Vgpr16}}}, !hasSALUFloat)
1610 .Any({{DivS32, S16}, {{Vgpr32}, {Vgpr16}}})
1611 .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}}, hasSALUFloat)
1612 .Any({{UniS16, S32}, {{UniInVgprS16}, {Vgpr32}}}, !hasSALUFloat)
1613 .Any({{DivS16, S32}, {{Vgpr16}, {Vgpr32}}})
1614 .Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}}, hasSALUFloat)
1615 .Any({{UniS32, S32}, {{UniInVgprS32}, {Vgpr32}}}, !hasSALUFloat)
1616 .Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
1617 .Any({{UniS32, S64}, {{UniInVgprS32}, {Vgpr64}}})
1618 .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}}})
1620 .Any({{DivV2S16, V2S32}, {{VgprV2S16}, {VgprV2S32}}});
1621
1622 addRulesForGOpcs({G_UITOFP, G_SITOFP})
1623 .Any({{UniS16, S16}, {{UniInVgprS16}, {Vgpr16}}})
1624 .Any({{DivS16, S16}, {{Vgpr16}, {Vgpr16}}})
1625 .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}}, hasSALUFloat)
1626 .Any({{UniS16, S32}, {{UniInVgprS16}, {Vgpr32}}}, !hasSALUFloat)
1627 .Any({{DivS16, S32}, {{Vgpr16}, {Vgpr32}}})
1628 .Any({{UniS32, S32}, {{Sgpr32}, {Sgpr32}}}, hasSALUFloat)
1629 .Any({{UniS32, S32}, {{UniInVgprS32}, {Vgpr32}}}, !hasSALUFloat)
1630 .Any({{DivS32, S32}, {{Vgpr32}, {Vgpr32}}})
1631 .Any({{UniS64, S32}, {{UniInVgprS64}, {Vgpr32}}})
1632 .Any({{DivS64, S32}, {{Vgpr64}, {Vgpr32}}});
1633
1634 addRulesForGOpcs({G_AMDGPU_S_BUFFER_PREFETCH})
1636
1637 Predicate IsDataPF([](const MachineInstr &MI) -> bool {
1638 // prefetch cache type: 0 == instruction (I$) prefetch, 1 == data prefetch.
1639 return MI.getOperand(3).getImm() != 0;
1640 });
1641
1642 bool HasSMemPF = ST->hasSafeSmemPrefetch();
1643 bool HasVMemPF = ST->hasVmemPrefInsts();
1644 addRulesForGOpcs({G_PREFETCH})
1645 // Safe smem prefetch keeps both data and instruction prefetch.
1646 .Any({{UniPtr64}, {{}, {SgprPtr64}}}, HasSMemPF)
1647 // Vmem prefetch keeps data prefetch only.
1648 .Any({{{UniPtr64}, IsDataPF}, {{}, {SgprPtr64}}}, !HasSMemPF && HasVMemPF)
1649 .Any({{{UniPtr64}, IsDataPF}, {{}, {}, DeletePrefetch}},
1650 !HasSMemPF && !HasVMemPF)
1651 .Any({{{UniPtr64}, !IsDataPF}, {{}, {}, DeletePrefetch}}, !HasSMemPF)
1652
1653 .Any({{{DivPtr64}, IsDataPF}, {{}, {VgprPtr64}}}, HasVMemPF)
1654 // Otherwise prefetch the first active lane's address.
1655 .Any({{DivPtr64}, {{}, {SgprB64_ReadFirstLane}}}, HasSMemPF)
1656 .Any({{DivPtr64}, {{}, {}, DeletePrefetch}})
1657
1658 .Any({{Ptr32}, {{}, {}, DeletePrefetch}})
1659 .Any({{P8}, {{}, {}, DeletePrefetch}});
1660
1661 addRulesForGOpcs({G_FPEXT})
1662 .Any({{DivS32, S16}, {{Vgpr32}, {Vgpr16}}})
1663 .Any({{UniS64, S32}, {{UniInVgprS64}, {Vgpr32}}})
1664 .Any({{DivS64, S32}, {{Vgpr64}, {Vgpr32}}})
1665 .Any({{UniS32, S16}, {{Sgpr32}, {Sgpr16}}}, hasSALUFloat)
1666 .Any({{UniS32, S16}, {{UniInVgprS32}, {Vgpr16}}}, !hasSALUFloat);
1667
1668 addRulesForGOpcs({G_AMDGPU_CVT_PK_I16_I32}, Standard)
1669 .Uni(V2S16, {{UniInVgprV2S16}, {Vgpr32, Vgpr32}})
1670 .Div(V2S16, {{VgprV2S16}, {Vgpr32, Vgpr32}});
1671
1672 addRulesForGOpcs({G_AMDGPU_FMIN_LEGACY, G_AMDGPU_FMAX_LEGACY}, Standard)
1673 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}})
1674 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}});
1675
1676 bool hasSALUMinimumMaximumInsts = ST->hasSALUMinimumMaximumInsts();
1677
1678 addRulesForGOpcs({G_FMINIMUM, G_FMAXIMUM}, Standard)
1679 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16}}, hasSALUMinimumMaximumInsts)
1680 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}}, !hasSALUMinimumMaximumInsts)
1681 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1682 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasSALUMinimumMaximumInsts)
1683 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasSALUMinimumMaximumInsts)
1684 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1685 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64}})
1686 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}})
1688 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}});
1689
1690 addRulesForGOpcs({G_FMINNUM_IEEE, G_FMAXNUM_IEEE}, Standard)
1691 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1692 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1693 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64}})
1694 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}})
1696 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
1697 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16}}, hasSALUFloat)
1698 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}}, !hasSALUFloat)
1699 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasSALUFloat)
1700 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasSALUFloat);
1701
1702 addRulesForGOpcs({G_FMINNUM, G_FMAXNUM, G_FMINIMUMNUM, G_FMAXIMUMNUM},
1703 Standard)
1704 .Div(S16, {{Vgpr16}, {Vgpr16, Vgpr16}})
1705 .Div(S32, {{Vgpr32}, {Vgpr32, Vgpr32}})
1706 .Uni(S64, {{UniInVgprS64}, {Vgpr64, Vgpr64}})
1707 .Div(S64, {{Vgpr64}, {Vgpr64, Vgpr64}})
1709 .Div(V2S16, {{VgprV2S16}, {VgprV2S16, VgprV2S16}})
1710 .Uni(S16, {{Sgpr16}, {Sgpr16, Sgpr16}}, hasSALUFloat)
1711 .Uni(S16, {{UniInVgprS16}, {Vgpr16, Vgpr16}}, !hasSALUFloat)
1712 .Uni(S32, {{Sgpr32}, {Sgpr32, Sgpr32}}, hasSALUFloat)
1713 .Uni(S32, {{UniInVgprS32}, {Vgpr32, Vgpr32}}, !hasSALUFloat)
1715 .Any({{DivV2S64}, {{VgprV2S64}, {VgprV2S64, VgprV2S64}}});
1716
1717 addRulesForGOpcs({G_FPTRUNC})
1718 .Any({{DivS16, S32}, {{Vgpr16}, {Vgpr32}}})
1719 .Any({{UniS32, S64}, {{UniInVgprS32}, {Vgpr64}}})
1720 .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}}})
1722 .Any({{DivV2S16, V2S32}, {{VgprV2S16}, {VgprV2S32}}})
1723 .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}}, hasSALUFloat)
1724 .Any({{UniS16, S32}, {{UniInVgprS16}, {Vgpr32}}}, !hasSALUFloat);
1725
1726 addRulesForGOpcs({G_INTRINSIC_FPTRUNC_ROUND})
1727 .Any({{UniS16, S32}, {{Sgpr16}, {Sgpr32}}}, hasSALUFloat)
1728 .Any({{UniS16, S32}, {{UniInVgprS16}, {Vgpr32}}}, !hasSALUFloat)
1729 .Any({{DivS16, S32}, {{Vgpr16}, {Vgpr32}}})
1730 .Any({{UniS16, S64}, {{UniInVgprS16}, {Vgpr64}}})
1731 .Any({{DivS16, S64}, {{Vgpr16}, {Vgpr64}}})
1732 .Any({{UniS32, S64}, {{UniInVgprS32}, {Vgpr64}}})
1733 .Any({{DivS32, S64}, {{Vgpr32}, {Vgpr64}}});
1734
1735 addRulesForGOpcs({G_IS_FPCLASS})
1736 .Any({{DivS1, S16}, {{Vcc}, {Vgpr16}}})
1737 .Any({{UniS1, S16}, {{UniInVcc}, {Vgpr16}}})
1738 .Any({{DivS1, S32}, {{Vcc}, {Vgpr32}}})
1739 .Any({{UniS1, S32}, {{UniInVcc}, {Vgpr32}}})
1740 .Any({{DivS1, S64}, {{Vcc}, {Vgpr64}}})
1741 .Any({{UniS1, S64}, {{UniInVcc}, {Vgpr64}}});
1742
1743 addRulesForGOpcs({G_FCMP}, Standard)
1744 .Any({{UniS1, _, S16}, {{Sgpr32Trunc}, {None, Sgpr16, Sgpr16}}},
1745 hasSALUFloat)
1746 .Any({{UniS1, _, S16}, {{UniInVcc}, {None, Vgpr16, Vgpr16}}},
1747 !hasSALUFloat)
1748 .Any({{DivS1, _, S16}, {{Vcc}, {None, Vgpr16, Vgpr16}}})
1749 .Any({{UniS1, _, S32}, {{Sgpr32Trunc}, {None, Sgpr32, Sgpr32}}},
1750 hasSALUFloat)
1751 .Any({{UniS1, _, S32}, {{UniInVcc}, {None, Vgpr32, Vgpr32}}},
1752 !hasSALUFloat)
1753 .Any({{DivS1, _, S32}, {{Vcc}, {None, Vgpr32, Vgpr32}}})
1754 .Any({{UniS1, _, S64}, {{UniInVcc}, {None, Vgpr64, Vgpr64}}})
1755 .Any({{DivS1, _, S64}, {{Vcc}, {None, Vgpr64, Vgpr64}}});
1756
1757 addRulesForGOpcs({G_INTRINSIC_ROUNDEVEN, G_FEXP2, G_FLOG2}, Standard)
1758 .Uni(S16, {{UniInVgprS16}, {Vgpr16}})
1759 .Div(S16, {{Vgpr16}, {Vgpr16}})
1760 .Uni(S32, {{UniInVgprS32}, {Vgpr32}})
1761 .Div(S32, {{Vgpr32}, {Vgpr32}})
1762 .Uni(S64, {{UniInVgprS64}, {Vgpr64}})
1763 .Div(S64, {{Vgpr64}, {Vgpr64}});
1764
1765 addRulesForGOpcs({G_INTRINSIC_TRUNC, G_FFLOOR, G_FCEIL}, Standard)
1766 .Uni(S16, {{UniInVgprS16}, {Vgpr16}})
1767 .Uni(S16, {{Sgpr16}, {Sgpr16}}, hasSALUFloat)
1768 .Div(S16, {{Vgpr16}, {Vgpr16}})
1769 .Uni(S32, {{UniInVgprS32}, {Vgpr32}})
1770 .Uni(S32, {{Sgpr32}, {Sgpr32}}, hasSALUFloat)
1771 .Div(S32, {{Vgpr32}, {Vgpr32}})
1772 .Uni(S64, {{UniInVgprS64}, {Vgpr64}})
1773 .Div(S64, {{Vgpr64}, {Vgpr64}});
1774
1775 addRulesForGOpcs({G_AMDGPU_GLOBAL_LOAD_MONITOR, G_AMDGPU_FLAT_LOAD_MONITOR},
1776 StandardB)
1777 .Uni(B32, {{UniInVgprB32}, {SgprPtr64}})
1778 .Div(B32, {{VgprB32}, {VgprPtr64}})
1779 .Uni(B64, {{UniInVgprB64}, {SgprPtr64}})
1780 .Div(B64, {{VgprB64}, {VgprPtr64}})
1781 .Uni(B128, {{UniInVgprB128}, {SgprPtr64}})
1782 .Div(B128, {{VgprB128}, {VgprPtr64}});
1783
1784 addRulesForGOpcs({G_AMDGPU_WHOLE_WAVE_FUNC_SETUP})
1785 .Any({{DivS1}, {{Vcc}, {}}});
1786
1787 addRulesForGOpcs({G_AMDGPU_WHOLE_WAVE_FUNC_RETURN}).Any({{}, {{}, {Vcc}}});
1788
1789 using namespace Intrinsic;
1790
1791 addRulesForIOpcs({returnaddress}).Any({{UniP0}, {{SgprP0}, {}}});
1792
1793 addRulesForIOpcs({amdgcn_s_bitreplicate}, Standard)
1794 .Uni(S64, {{Sgpr64}, {IntrId, Sgpr32}})
1796
1797 addRulesForIOpcs({amdgcn_s_getpc}).Any({{UniS64, _}, {{Sgpr64}, {}}});
1798
1799 addRulesForIOpcs({amdgcn_s_getreg}).Any({{}, {{Sgpr32}, {IntrId}}});
1800
1801 addRulesForIOpcs({amdgcn_s_setreg})
1802 .Any({{_, _, S32}, {{}, {IntrId, Imm, SgprB32_ReadFirstLane}}});
1803
1804 addRulesForIOpcs({amdgcn_s_sendmsg, amdgcn_s_sendmsghalt})
1805 .Any({{}, {{}, {IntrId, Imm, SgprB32_M0}}});
1806
1807 addRulesForIOpcs({amdgcn_s_sendmsg_rtn})
1808 .Any({{S32}, {{Sgpr32}, {}}})
1809 .Any({{S64}, {{Sgpr64}, {}}});
1810
1811 addRulesForIOpcs({amdgcn_s_memrealtime, amdgcn_s_memtime}, Standard)
1812 .Uni(S64, {{Sgpr64}, {IntrId}});
1813
1814 addRulesForIOpcs({amdgcn_groupstaticsize, amdgcn_pops_exiting_wave_id,
1815 amdgcn_reloc_constant, amdgcn_s_get_waveid_in_workgroup},
1816 Standard)
1817 .Uni(S32, {{Sgpr32}, {IntrId}});
1818
1819 // Intrinsics with no register operands.
1820 addRulesForIOpcs({amdgcn_asyncmark,
1821 amdgcn_endpgm,
1822 amdgcn_iglp_opt,
1823 amdgcn_init_exec,
1824 amdgcn_s_barrier,
1825 amdgcn_s_barrier_leave,
1826 amdgcn_s_barrier_signal,
1827 amdgcn_s_barrier_wait,
1828 amdgcn_s_decperflevel,
1829 amdgcn_s_incperflevel,
1830 amdgcn_s_monitor_sleep,
1831 amdgcn_s_nop,
1832 amdgcn_s_sethalt,
1833 amdgcn_s_setprio,
1834 amdgcn_s_setprio_inc_wg,
1835 amdgcn_s_sleep,
1836 amdgcn_s_ttracedata_imm,
1837 amdgcn_s_wait_asynccnt,
1838 amdgcn_s_wait_bvhcnt,
1839 amdgcn_s_wait_dscnt,
1840 amdgcn_s_wait_event,
1841 amdgcn_s_wait_event_export_ready,
1842 amdgcn_s_wait_expcnt,
1843 amdgcn_s_wait_kmcnt,
1844 amdgcn_s_wait_loadcnt,
1845 amdgcn_s_wait_samplecnt,
1846 amdgcn_s_wait_storecnt,
1847 amdgcn_s_wait_tensorcnt,
1848 amdgcn_s_waitcnt,
1849 amdgcn_sched_barrier,
1850 amdgcn_sched_group_barrier,
1851 amdgcn_unreachable,
1852 amdgcn_wait_asyncmark,
1853 amdgcn_wave_barrier})
1854 .Any({{}, {{}, {}}});
1855
1856 addRulesForIOpcs({amdgcn_init_exec_from_input})
1857 .Any({{}, {{}, {IntrId, Sgpr32}}});
1858
1859 addRulesForIOpcs({amdgcn_s_ttracedata}).Any({{}, {{}, {IntrId, SgprB32_M0}}});
1860
1861 addRulesForIOpcs({amdgcn_s_sleep_var})
1862 .Any({{}, {{}, {IntrId, SgprB32_ReadFirstLane}}});
1863
1864 addRulesForIOpcs({amdgcn_s_barrier_join, amdgcn_s_wakeup_barrier})
1865 .Any({{}, {{}, {IntrId, SgprB32_M0}}});
1866
1867 addRulesForIOpcs({amdgcn_s_barrier_signal_var, amdgcn_s_barrier_init})
1868 .Any({{}, {{}, {IntrId, SgprB32_M0, SgprB32_M0}}});
1869
1870 addRulesForIOpcs({amdgcn_s_barrier_signal_isfirst})
1871 .Any({{UniS1}, {{Sgpr32Trunc}, {}}});
1872
1873 addRulesForIOpcs(
1874 {amdgcn_s_get_named_barrier_state, amdgcn_s_get_barrier_state}, Standard)
1875 .Uni(S32, {{Sgpr32}, {IntrId, SgprB32_M0}});
1876
1877 addRulesForIOpcs({amdgcn_flat_prefetch}).Any({{}, {{}, {IntrId, VgprP0}}});
1878
1879 addRulesForIOpcs({amdgcn_global_prefetch}).Any({{}, {{}, {IntrId, VgprP1}}});
1880
1881 addRulesForIOpcs({amdgcn_s_prefetch_data, amdgcn_s_prefetch_inst})
1882 .Any({{_, Ptr32}, {{}, {}, DeletePrefetch}})
1883 .Any({{_, P8}, {{}, {}, DeletePrefetch}})
1885
1886 addRulesForIOpcs({amdgcn_class})
1887 .Any({{UniS1, _, S16}, {{UniInVcc}, {IntrId, Vgpr16, Vgpr32}}})
1888 .Any({{DivS1, _, S16}, {{Vcc}, {IntrId, Vgpr16, Vgpr32}}})
1889 .Any({{UniS1, _, S32}, {{UniInVcc}, {IntrId, Vgpr32, Vgpr32}}})
1890 .Any({{DivS1, _, S32}, {{Vcc}, {IntrId, Vgpr32, Vgpr32}}})
1891 .Any({{UniS1, _, S64}, {{UniInVcc}, {IntrId, Vgpr64, Vgpr32}}})
1892 .Any({{DivS1, _, S64}, {{Vcc}, {IntrId, Vgpr64, Vgpr32}}});
1893
1894 // This is "intrinsic lane mask" it was set to i32/i64 in llvm-ir.
1895 addRulesForIOpcs({amdgcn_end_cf})
1896 .Any({{_, UniS32}, {{}, {IntrId, Sgpr32}}})
1897 .Any({{_, UniS64}, {{}, {IntrId, Sgpr64}}});
1898
1899 addRulesForIOpcs({amdgcn_if_break}, Standard)
1900 .Uni(S64, {{Sgpr64}, {IntrId, Vcc, Sgpr64}})
1901 .Uni(S32, {{Sgpr32}, {IntrId, Vcc, Sgpr32}});
1902
1903 addRulesForIOpcs({amdgcn_exp})
1904 .Any({{_, _, _, S32, S32, S32, S32},
1905 {{}, {IntrId, Imm, Imm, Vgpr32, Vgpr32, Vgpr32, Vgpr32}}});
1906
1907 addRulesForIOpcs({amdgcn_exp_compr})
1908 .Any({{_, _, _, V2S16}, {{}, {IntrId, Imm, Imm, VgprV2S16, VgprV2S16}}});
1909
1910 addRulesForIOpcs({amdgcn_exp_row})
1911 .Any({{_, _, _, S32, S32, S32, S32, _, S32},
1912 {{},
1914 SgprB32_M0}}});
1915
1916 addRulesForIOpcs({amdgcn_lds_direct_load}, StandardB)
1917 .Div(B32, {{VgprB32}, {IntrId, SgprB32_M0}});
1918
1919 addRulesForIOpcs({amdgcn_lds_param_load}, Standard)
1920 .Div(S32, {{Vgpr32}, {IntrId, Imm, Imm, SgprB32_M0}});
1921
1922 addRulesForIOpcs({amdgcn_mbcnt_lo, amdgcn_mbcnt_hi}, Standard)
1923 .Div(S32, {{}, {Vgpr32, None, Vgpr32, Vgpr32}});
1924
1925 addRulesForIOpcs({amdgcn_readfirstlane})
1926 .Any({{UniB32, _, DivB32}, {{}, {SgprB32, None, VgprB32}}})
1927 // this should not exist in the first place, it is from call lowering
1928 // readfirstlaning just in case register is not in sgpr.
1929 .Any({{UniS32, _, UniS32}, {{}, {Sgpr32, None, Vgpr32}}});
1930
1931 addRulesForIOpcs({amdgcn_readlane}, StandardB)
1933
1934 addRulesForIOpcs({amdgcn_s_quadmask, amdgcn_s_wqm}, StandardB)
1936 .Uni(B64, {{SgprB64}, {IntrId, SgprB64_ReadFirstLane}});
1937
1938 addRulesForIOpcs({amdgcn_writelane}, StandardB)
1939 .Div(B32,
1940 {{VgprB32},
1942
1943 addRulesForIOpcs({amdgcn_add_max_i32, amdgcn_add_max_u32, amdgcn_add_min_i32,
1944 amdgcn_add_min_u32},
1945 Standard)
1946 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
1947 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
1948
1949 addRulesForIOpcs({amdgcn_pk_add_max_i16, amdgcn_pk_add_max_u16,
1950 amdgcn_pk_add_min_i16, amdgcn_pk_add_min_u16},
1951 Standard)
1954
1955 addRulesForIOpcs({amdgcn_permlane16, amdgcn_permlanex16}, StandardB)
1956 .Div(B32, {{VgprB32},
1959
1960 addRulesForIOpcs({amdgcn_permlane_bcast, amdgcn_permlane_up,
1961 amdgcn_permlane_down, amdgcn_permlane_xor},
1962 StandardB)
1963 .Div(B32,
1964 {{VgprB32},
1966
1967 addRulesForIOpcs({amdgcn_permlane_idx_gen}, Standard)
1969
1970 addRulesForIOpcs({amdgcn_alignbyte, amdgcn_perm}, Standard)
1971 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
1972 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
1973
1974 addRulesForIOpcs({amdgcn_mqsad_pk_u16_u8, amdgcn_qsad_pk_u16_u8}, Standard)
1975 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64, Vgpr32, Vgpr64}})
1976 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64, Vgpr32, Vgpr64}});
1977
1978 addRulesForIOpcs({amdgcn_mqsad_u32_u8})
1979 .Any(
1982
1983 addRulesForIOpcs({amdgcn_lerp}, Standard)
1984 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
1985 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
1986
1987 addRulesForIOpcs(
1988 {amdgcn_msad_u8, amdgcn_sad_hi_u8, amdgcn_sad_u16, amdgcn_sad_u8},
1989 Standard)
1990 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
1991 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
1992
1993 addRulesForIOpcs(
1994 {amdgcn_wave_reduce_add, amdgcn_wave_reduce_and, amdgcn_wave_reduce_fadd,
1995 amdgcn_wave_reduce_fmax, amdgcn_wave_reduce_fmin,
1996 amdgcn_wave_reduce_fsub, amdgcn_wave_reduce_max, amdgcn_wave_reduce_min,
1997 amdgcn_wave_reduce_or, amdgcn_wave_reduce_sub, amdgcn_wave_reduce_umax,
1998 amdgcn_wave_reduce_umin, amdgcn_wave_reduce_xor},
1999 Standard)
2000 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}})
2001 .Div(S32, {{Sgpr32ToVgprDst}, {IntrId, VgprB32}})
2002 .Uni(S64, {{Sgpr64}, {IntrId, Sgpr64}})
2003 .Div(S64, {{Sgpr64ToVgprDst}, {IntrId, VgprB64}});
2004
2005 addRulesForIOpcs({amdgcn_wave_shuffle}, Standard)
2006 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}})
2007 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}});
2008
2009 addRulesForIOpcs({amdgcn_bitop3, amdgcn_fmad_ftz}, Standard)
2010 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16, Vgpr16, Vgpr16}})
2011 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16, Vgpr16, Vgpr16}})
2012 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2013 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2014
2015 addRulesForIOpcs({amdgcn_udot4, amdgcn_sdot4, amdgcn_udot8, amdgcn_sdot8,
2016 amdgcn_dot4_f32_bf8_bf8, amdgcn_dot4_f32_bf8_fp8,
2017 amdgcn_dot4_f32_fp8_fp8, amdgcn_dot4_f32_fp8_bf8},
2018 Standard)
2019 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2020 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2021
2022 addRulesForIOpcs({amdgcn_rsq, amdgcn_rsq_clamp})
2023 .Any({{UniBF16}, {{UniInVgprS16}, {IntrId, Vgpr16}}})
2024 .Any({{UniS16}, {{Sgpr16}, {IntrId, Sgpr16}}}, hasPST)
2025 .Any({{UniS16}, {{UniInVgprS16}, {IntrId, Vgpr16}}}, !hasPST)
2026 .Any({{DivS16}, {{Vgpr16}, {IntrId, Vgpr16}}})
2027 .Any({{UniS32}, {{Sgpr32}, {IntrId, Sgpr32}}}, hasPST)
2028 .Any({{UniS32}, {{UniInVgprS32}, {IntrId, Vgpr32}}}, !hasPST)
2029 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32}}})
2030 .Any({{UniS64}, {{UniInVgprS64}, {IntrId, Vgpr64}}})
2031 .Any({{DivS64}, {{Vgpr64}, {IntrId, Vgpr64}}});
2032
2033 addRulesForIOpcs({amdgcn_mul_u24, amdgcn_mul_i24}, Standard)
2034 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}})
2035 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}})
2036 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr32, Vgpr32}})
2037 .Div(S64, {{Vgpr64}, {IntrId, Vgpr32, Vgpr32}});
2038
2039 addRulesForIOpcs({amdgcn_ds_bpermute, amdgcn_ds_bpermute_fi_b32,
2040 amdgcn_ds_permute, amdgcn_fmul_legacy, amdgcn_mulhi_i24,
2041 amdgcn_mulhi_u24},
2042 Standard)
2043 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}})
2044 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}});
2045
2046 addRulesForIOpcs({amdgcn_cvt_sr_bf8_f32, amdgcn_cvt_sr_fp8_f32,
2047 amdgcn_cvt_sr_fp8_f32_e5m3, amdgcn_cvt_pk_bf8_f32,
2048 amdgcn_cvt_pk_fp8_f32, amdgcn_cvt_pk_fp8_f32_e5m3,
2049 amdgcn_cvt_pk_u8_f32},
2050 Standard)
2051 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2052 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2053
2054 addRulesForIOpcs({amdgcn_cvt_off_f32_i4, amdgcn_cvt_f32_bf8,
2055 amdgcn_cvt_f32_fp8, amdgcn_cvt_f32_fp8_e5m3},
2056 Standard)
2057 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}})
2058 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}});
2059
2060 addRulesForIOpcs({amdgcn_cvt_pk_f32_bf8, amdgcn_cvt_pk_f32_fp8})
2061 .Any({{UniV2S32}, {{UniInVgprV2S32}, {IntrId, Vgpr32}}})
2062 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, Vgpr32}}});
2063
2064 addRulesForIOpcs({amdgcn_cvt_f16_bf8, amdgcn_cvt_f16_fp8}, Standard)
2065 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr32}})
2066 .Div(S16, {{Vgpr16}, {IntrId, Vgpr32}});
2067
2068 addRulesForIOpcs({amdgcn_cvt_pk_f16_bf8, amdgcn_cvt_pk_f16_fp8}, Standard)
2069 .Uni(V2S16, {{UniInVgprV2S16}, {IntrId, Vgpr16}})
2070 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr16}});
2071
2072 addRulesForIOpcs({amdgcn_cvt_pk_bf8_f16, amdgcn_cvt_pk_fp8_f16}, Standard)
2073 .Uni(S16, {{UniInVgprS16}, {IntrId, VgprV2S16}})
2074 .Div(S16, {{Vgpr16}, {IntrId, VgprV2S16}});
2075
2076 addRulesForIOpcs({amdgcn_cvt_sr_bf8_f16, amdgcn_cvt_sr_fp8_f16}, Standard)
2077 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr16, Vgpr32, Vgpr32}})
2078 .Div(S32, {{Vgpr32}, {IntrId, Vgpr16, Vgpr32, Vgpr32}});
2079
2080 addRulesForIOpcs({amdgcn_cvt_sr_pk_f16_f32, amdgcn_cvt_sr_pk_bf16_f32},
2081 Standard)
2083 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2084
2085 addRulesForIOpcs(
2086 {amdgcn_cvt_scalef32_sr_fp8_f16, amdgcn_cvt_scalef32_sr_bf8_f16,
2087 amdgcn_cvt_scalef32_sr_fp8_bf16, amdgcn_cvt_scalef32_sr_bf8_bf16})
2088 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32, Vgpr16, Vgpr32, Vgpr32}}})
2089 .Any({{UniS32},
2091
2092 addRulesForIOpcs(
2093 {amdgcn_cvt_scalef32_sr_fp8_f32, amdgcn_cvt_scalef32_sr_bf8_f32})
2094 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32, Vgpr32}}})
2095 .Any({{UniS32},
2097
2098 addRulesForIOpcs({amdgcn_cubesc, amdgcn_cubetc, amdgcn_cubema, amdgcn_cubeid,
2099 amdgcn_fma_legacy},
2100 Standard)
2101 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2102 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2103
2104 addRulesForIOpcs({amdgcn_frexp_mant, amdgcn_fract}, Standard)
2105 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
2106 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
2107 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}})
2108 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
2109 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64}})
2110 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64}});
2111
2112 addRulesForIOpcs({amdgcn_prng_b32})
2113 .Any({{UniS32}, {{UniInVgprS32}, {IntrId, Vgpr32}}})
2114 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32}}});
2115
2116 addRulesForIOpcs(
2117 {amdgcn_exclusive_scan_sum_i32, amdgcn_exclusive_scan_sum_u32}, Standard)
2118 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Imm}})
2119 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Imm}});
2120
2121 addRulesForIOpcs(
2122 {amdgcn_exclusive_scan_xor_b32, amdgcn_exclusive_scan_or_b32,
2123 amdgcn_exclusive_scan_and_b32, amdgcn_exclusive_scan_min_i32,
2124 amdgcn_exclusive_scan_min_u32, amdgcn_exclusive_scan_max_i32,
2125 amdgcn_exclusive_scan_max_u32},
2126 Standard)
2127 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}})
2128 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}});
2129
2130 addRulesForIOpcs(
2131 {amdgcn_exclusive_scan_min_i16, amdgcn_exclusive_scan_min_u16,
2132 amdgcn_exclusive_scan_max_i16, amdgcn_exclusive_scan_max_u16},
2133 Standard)
2134 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16, Vgpr32}})
2135 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16, Vgpr32}});
2136
2137 addRulesForIOpcs({amdgcn_wave_match_b32})
2138 .Any({{UniS32}, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}}})
2139 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}}});
2140
2141 addRulesForIOpcs({amdgcn_sffbh}, Standard)
2142 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32}})
2143 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}});
2144
2145 addRulesForIOpcs({amdgcn_ubfe, amdgcn_sbfe}, Standard)
2146 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2147 .Uni(S32, {{Sgpr32}, {IntrId, Sgpr32, Sgpr32, Sgpr32}, S_BFE})
2148 .Uni(S64, {{Sgpr64}, {IntrId, Sgpr64, Sgpr32, Sgpr32}, S_BFE})
2149 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64, Vgpr32, Vgpr32}, V_BFE});
2150
2151 addRulesForIOpcs({amdgcn_cvt_pk_i16, amdgcn_cvt_pk_u16, amdgcn_cvt_pknorm_i16,
2152 amdgcn_cvt_pknorm_u16},
2153 Standard)
2154 .Uni(V2S16, {{UniInVgprV2S16}, {IntrId, Vgpr32, Vgpr32}})
2155 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr32, Vgpr32}});
2156
2157 addRulesForIOpcs({amdgcn_cvt_pkrtz}, Standard)
2158 .Uni(V2S16, {{SgprV2S16}, {IntrId, Sgpr32, Sgpr32}}, hasSALUFloat)
2159 .Uni(V2S16, {{UniInVgprV2S16}, {IntrId, Vgpr32, Vgpr32}}, !hasSALUFloat)
2160 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr32, Vgpr32}});
2161
2162 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk32_bf6_f16,
2163 amdgcn_cvt_scalef32_sr_pk32_fp6_f16,
2164 amdgcn_cvt_scalef32_sr_pk32_bf6_bf16,
2165 amdgcn_cvt_scalef32_sr_pk32_fp6_bf16},
2166 Standard)
2168 .Any({{UniV6S32},
2170
2171 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk32_bf6_f32,
2172 amdgcn_cvt_scalef32_sr_pk32_fp6_f32},
2173 Standard)
2175 .Any({{UniV6S32},
2177
2178 addRulesForIOpcs(
2179 {amdgcn_cvt_scalef32_sr_pk_fp4_f16, amdgcn_cvt_scalef32_sr_pk_fp4_bf16},
2180 Standard)
2182 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, VgprV2S16, Vgpr32, Vgpr32}});
2183
2184 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk_fp4_f32}, Standard)
2186 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, VgprV2S32, Vgpr32, Vgpr32}});
2187
2188 addRulesForIOpcs(
2189 {amdgcn_cvt_scalef32_2xpk16_fp6_f32, amdgcn_cvt_scalef32_2xpk16_bf6_f32})
2190 .Any(
2192 .Any({{UniV6S32},
2194
2195 addRulesForIOpcs({amdgcn_cvt_scalef32_f16_fp8, amdgcn_cvt_scalef32_f16_bf8},
2196 Standard)
2197 .Div(V2S16, {{VgprV2S16}, {IntrId, VgprV2S16, Vgpr32, Vgpr32}})
2199
2200 addRulesForIOpcs({amdgcn_cvt_scalef32_f32_fp8, amdgcn_cvt_scalef32_f32_bf8},
2201 Standard)
2202 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}})
2203 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32}});
2204
2205 addRulesForIOpcs(
2206 {amdgcn_cvt_scalef32_pk16_bf6_f16, amdgcn_cvt_scalef32_pk16_fp6_f16,
2207 amdgcn_cvt_scalef32_pk16_bf6_bf16, amdgcn_cvt_scalef32_pk16_fp6_bf16},
2208 Standard)
2211
2212 addRulesForIOpcs(
2213 {amdgcn_cvt_scalef32_pk16_bf6_f32, amdgcn_cvt_scalef32_pk16_fp6_f32},
2214 Standard)
2217
2218 addRulesForIOpcs(
2219 {amdgcn_cvt_scalef32_pk8_bf8_f16, amdgcn_cvt_scalef32_pk8_fp8_f16,
2220 amdgcn_cvt_scalef32_pk8_bf8_bf16, amdgcn_cvt_scalef32_pk8_fp8_bf16},
2221 Standard)
2224
2225 addRulesForIOpcs(
2226 {amdgcn_cvt_scalef32_pk8_bf8_f32, amdgcn_cvt_scalef32_pk8_fp8_f32},
2227 Standard)
2230
2231 addRulesForIOpcs(
2232 {amdgcn_cvt_scalef32_pk8_fp4_f16, amdgcn_cvt_scalef32_pk8_fp4_bf16},
2233 Standard)
2234 .Div(S32, {{Vgpr32}, {IntrId, VgprV8S16, Vgpr32}})
2235 .Uni(S32, {{UniInVgprS32}, {IntrId, VgprV8S16, Vgpr32}});
2236
2237 addRulesForIOpcs({amdgcn_cvt_scalef32_pk8_fp4_f32}, Standard)
2238 .Div(S32, {{Vgpr32}, {IntrId, VgprV8S32, Vgpr32}})
2239 .Uni(S32, {{UniInVgprS32}, {IntrId, VgprV8S32, Vgpr32}});
2240
2241 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk16_bf6_f16,
2242 amdgcn_cvt_scalef32_sr_pk16_fp6_f16,
2243 amdgcn_cvt_scalef32_sr_pk16_bf6_bf16,
2244 amdgcn_cvt_scalef32_sr_pk16_fp6_bf16},
2245 Standard)
2247 .Any({{UniV3S32},
2249
2250 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk16_bf6_f32,
2251 amdgcn_cvt_scalef32_sr_pk16_fp6_f32},
2252 Standard)
2254 .Any({{UniV3S32},
2256
2257 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk8_bf8_f16,
2258 amdgcn_cvt_scalef32_sr_pk8_fp8_f16,
2259 amdgcn_cvt_scalef32_sr_pk8_bf8_bf16,
2260 amdgcn_cvt_scalef32_sr_pk8_fp8_bf16},
2261 Standard)
2263 .Any({{UniV2S32},
2265
2266 addRulesForIOpcs(
2267 {amdgcn_cvt_scalef32_sr_pk8_bf8_f32, amdgcn_cvt_scalef32_sr_pk8_fp8_f32},
2268 Standard)
2270 .Any({{UniV2S32},
2272
2273 addRulesForIOpcs(
2274 {amdgcn_cvt_scalef32_sr_pk8_fp4_f16, amdgcn_cvt_scalef32_sr_pk8_fp4_bf16},
2275 Standard)
2276 .Div(S32, {{Vgpr32}, {IntrId, VgprV8S16, Vgpr32, Vgpr32}})
2277 .Uni(S32, {{UniInVgprS32}, {IntrId, VgprV8S16, Vgpr32, Vgpr32}});
2278
2279 addRulesForIOpcs({amdgcn_cvt_scalef32_sr_pk8_fp4_f32}, Standard)
2280 .Div(S32, {{Vgpr32}, {IntrId, VgprV8S32, Vgpr32, Vgpr32}})
2281 .Uni(S32, {{UniInVgprS32}, {IntrId, VgprV8S32, Vgpr32, Vgpr32}});
2282
2283 addRulesForIOpcs(
2284 {amdgcn_cvt_scale_pk16_f16_bf6, amdgcn_cvt_scale_pk16_f16_fp6,
2285 amdgcn_cvt_scale_pk16_bf16_bf6, amdgcn_cvt_scale_pk16_bf16_fp6},
2286 Standard)
2289
2290 addRulesForIOpcs(
2291 {amdgcn_cvt_scale_pk16_f32_bf6, amdgcn_cvt_scale_pk16_f32_fp6}, Standard)
2294
2295 addRulesForIOpcs(
2296 {amdgcn_cvt_scale_pk32_f16_bf6, amdgcn_cvt_scale_pk32_f16_fp6,
2297 amdgcn_cvt_scale_pk32_bf16_bf6, amdgcn_cvt_scale_pk32_bf16_fp6},
2298 Standard)
2301
2302 addRulesForIOpcs(
2303 {amdgcn_cvt_scale_pk32_f32_bf6, amdgcn_cvt_scale_pk32_f32_fp6}, Standard)
2306
2307 addRulesForIOpcs({amdgcn_cvt_scale_pk8_f16_bf8, amdgcn_cvt_scale_pk8_f16_fp8,
2308 amdgcn_cvt_scale_pk8_bf16_bf8,
2309 amdgcn_cvt_scale_pk8_bf16_fp8},
2310 Standard)
2313
2314 addRulesForIOpcs(
2315 {amdgcn_cvt_scale_pk8_f16_fp4, amdgcn_cvt_scale_pk8_bf16_fp4}, Standard)
2316 .Any({{DivV8S16}, {{VgprV8S16}, {IntrId, Vgpr32, Vgpr32}}})
2318
2319 addRulesForIOpcs({amdgcn_cvt_scale_pk8_f32_bf8, amdgcn_cvt_scale_pk8_f32_fp8},
2320 Standard)
2323
2324 addRulesForIOpcs({amdgcn_cvt_scale_pk8_f32_fp4}, Standard)
2325 .Any({{DivV8S32}, {{VgprV8S32}, {IntrId, Vgpr32, Vgpr32}}})
2327
2328 addRulesForIOpcs(
2329 {amdgcn_cvt_scalef32_pk32_bf6_f16, amdgcn_cvt_scalef32_pk32_fp6_f16,
2330 amdgcn_cvt_scalef32_pk32_bf6_bf16, amdgcn_cvt_scalef32_pk32_fp6_bf16},
2331 Standard)
2334
2335 addRulesForIOpcs(
2336 {amdgcn_cvt_scalef32_pk32_bf6_f32, amdgcn_cvt_scalef32_pk32_fp6_f32},
2337 Standard)
2340
2341 addRulesForIOpcs(
2342 {amdgcn_cvt_scalef32_pk_fp8_f32, amdgcn_cvt_scalef32_pk_bf8_f32},
2343 Standard)
2345 .Uni(V2S16,
2347
2348 addRulesForIOpcs(
2349 {amdgcn_cvt_scalef32_pk_f32_fp8, amdgcn_cvt_scalef32_pk_f32_bf8},
2350 Standard)
2351 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, Vgpr32, Vgpr32}}})
2353
2354 addRulesForIOpcs(
2355 {amdgcn_cvt_scalef32_pk_fp8_f16, amdgcn_cvt_scalef32_pk_bf8_f16,
2356 amdgcn_cvt_scalef32_pk_fp8_bf16, amdgcn_cvt_scalef32_pk_bf8_bf16},
2357 Standard)
2360
2361 addRulesForIOpcs({amdgcn_cvt_scalef32_pk_f32_fp4}, Standard)
2362 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, Vgpr32, Vgpr32}}})
2364
2365 addRulesForIOpcs({amdgcn_cvt_scalef32_pk_fp4_f32}, Standard)
2366 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32, Vgpr32}})
2367 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32, Vgpr32}});
2368
2369 addRulesForIOpcs(
2370 {amdgcn_cvt_scalef32_pk_f16_fp4, amdgcn_cvt_scalef32_pk_f16_fp8,
2371 amdgcn_cvt_scalef32_pk_f16_bf8, amdgcn_cvt_scalef32_pk_bf16_fp4,
2372 amdgcn_cvt_scalef32_pk_bf16_fp8, amdgcn_cvt_scalef32_pk_bf16_bf8},
2373 Standard)
2374 .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr32, Vgpr32}})
2375 .Uni(V2S16, {{UniInVgprV2S16}, {IntrId, Vgpr32, Vgpr32}});
2376
2377 addRulesForIOpcs(
2378 {amdgcn_cvt_scalef32_pk32_f32_fp6, amdgcn_cvt_scalef32_pk32_f32_bf6},
2379 Standard)
2382
2383 addRulesForIOpcs(
2384 {amdgcn_cvt_scalef32_pk32_f16_fp6, amdgcn_cvt_scalef32_pk32_f16_bf6,
2385 amdgcn_cvt_scalef32_pk32_bf16_fp6, amdgcn_cvt_scalef32_pk32_bf16_bf6},
2386 Standard)
2389
2390 addRulesForIOpcs(
2391 {amdgcn_cvt_scalef32_pk_fp4_f16, amdgcn_cvt_scalef32_pk_fp4_bf16},
2392 Standard)
2393 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, VgprV2S16, Vgpr32}})
2394 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, VgprV2S16, Vgpr32}});
2395
2396 addRulesForIOpcs({amdgcn_global_load_tr_b64})
2397 .Any({{DivB64, _, UniP1}, {{VgprB64}, {IntrId, SgprP1}}})
2398 .Any({{DivB64, _, DivP1}, {{VgprB64}, {IntrId, VgprP1}}})
2399 .Any({{DivB32, _, UniP1}, {{VgprB32}, {IntrId, SgprP1}}})
2400 .Any({{DivB32, _, DivP1}, {{VgprB32}, {IntrId, VgprP1}}});
2401
2402 addRulesForIOpcs({amdgcn_global_load_tr_b128})
2403 .Any({{DivB64, _, UniP1}, {{VgprB64}, {IntrId, SgprP1}}})
2404 .Any({{DivB64, _, DivP1}, {{VgprB64}, {IntrId, VgprP1}}})
2405 .Any({{DivB128, _, UniP1}, {{VgprB128}, {IntrId, SgprP1}}})
2406 .Any({{DivB128, _, DivP1}, {{VgprB128}, {IntrId, VgprP1}}});
2407
2408 addRulesForIOpcs({amdgcn_global_load_tr4_b64})
2409 .Any({{DivV2S32, _, UniP1}, {{VgprV2S32}, {IntrId, SgprP1}}})
2410 .Any({{DivV2S32, _, DivP1}, {{VgprV2S32}, {IntrId, VgprP1}}});
2411
2412 addRulesForIOpcs({amdgcn_global_load_tr6_b96})
2413 .Any({{DivV3S32, _, UniP1}, {{VgprV3S32}, {IntrId, SgprP1}}})
2414 .Any({{DivV3S32, _, DivP1}, {{VgprV3S32}, {IntrId, VgprP1}}});
2415
2416 addRulesForIOpcs({amdgcn_ds_load_tr4_b64, amdgcn_ds_load_tr8_b64})
2417 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, VgprP3}}});
2418
2419 addRulesForIOpcs({amdgcn_ds_load_tr6_b96})
2420 .Any({{DivV3S32}, {{VgprV3S32}, {IntrId, VgprP3}}});
2421
2422 addRulesForIOpcs({amdgcn_ds_load_tr16_b128})
2423 .Any({{DivB128}, {{VgprB128}, {IntrId, VgprP3}}});
2424
2425 addRulesForIOpcs({amdgcn_global_atomic_ordered_add_b64})
2426 .Any({{DivS64}, {{Vgpr64}, {IntrId, VgprP1, Vgpr64}}});
2427
2428 addRulesForIOpcs(
2429 {amdgcn_global_atomic_fmin_num, amdgcn_global_atomic_fmax_num}, Standard)
2430 .Div(S32, {{Vgpr32}, {IntrId, VgprP1, Vgpr32}});
2431
2432 addRulesForIOpcs({amdgcn_flat_atomic_fmin_num, amdgcn_flat_atomic_fmax_num},
2433 Standard)
2434 .Div(S32, {{Vgpr32}, {IntrId, VgprP0, Vgpr32}});
2435
2436 addRulesForIOpcs({amdgcn_raw_buffer_load_lds})
2437 .Any({{_}, {{}, {IntrId, SgprV4S32, SgprP3, Imm, Vgpr32, Sgpr32}}});
2438
2439 addRulesForIOpcs({amdgcn_raw_buffer_load_async_lds})
2440 .Any({{_}, {{}, {IntrId, SgprV4S32, SgprB32_M0, Imm, Vgpr32, Sgpr32}}});
2441
2442 addRulesForIOpcs({amdgcn_struct_buffer_load_async_lds})
2443 .Any(
2444 {{_},
2446
2447 addRulesForIOpcs({amdgcn_struct_buffer_load_lds})
2448 .Any({{_},
2449 {{}, {IntrId, SgprV4S32, SgprP3, Imm, Vgpr32, Vgpr32, Sgpr32}}});
2450
2451 addRulesForIOpcs({amdgcn_raw_ptr_buffer_load_lds})
2452 .Any({{_}, {{}, {IntrId, SgprP8, SgprP3, Imm, Vgpr32, Sgpr32}}});
2453
2454 addRulesForIOpcs({amdgcn_raw_ptr_buffer_load_async_lds})
2455 .Any({{}, {{}, {IntrId, SgprP8, SgprB32_M0, Imm, VgprB32, SgprB32}}});
2456
2457 addRulesForIOpcs({amdgcn_struct_ptr_buffer_load_async_lds})
2458 .Any({{_},
2459 {{}, {IntrId, SgprP8, SgprB32_M0, Imm, Vgpr32, Vgpr32, Sgpr32}}});
2460
2461 addRulesForIOpcs({amdgcn_struct_ptr_buffer_load_lds})
2462 .Any({{_}, {{}, {IntrId, SgprP8, SgprP3, Imm, Vgpr32, Vgpr32, Sgpr32}}});
2463
2464 addRulesForIOpcs(
2465 {amdgcn_global_load_lds, amdgcn_load_to_lds, amdgcn_load_async_to_lds})
2466 .Any({{}, {{}, {IntrId, VgprP1, SgprB32_M0}}});
2467
2468 addRulesForIOpcs({amdgcn_global_load_async_to_lds_b8,
2469 amdgcn_global_load_async_to_lds_b32,
2470 amdgcn_global_load_async_to_lds_b64,
2471 amdgcn_global_load_async_to_lds_b128,
2472 amdgcn_global_store_async_from_lds_b8,
2473 amdgcn_global_store_async_from_lds_b32,
2474 amdgcn_global_store_async_from_lds_b64,
2475 amdgcn_global_store_async_from_lds_b128})
2476 .Any({{}, {{}, {IntrId, VgprP1, VgprP3}}});
2477
2478 addRulesForIOpcs({amdgcn_global_load_async_lds})
2479 .Any({{}, {{}, {IntrId, VgprP1, SgprB32_M0}}});
2480
2481 addRulesForIOpcs({amdgcn_tensor_load_to_lds, amdgcn_tensor_store_from_lds})
2482 .Any({{},
2483 {{},
2487
2488 addRulesForIOpcs({amdgcn_cluster_load_b32})
2490 .Any({{DivB32, _, UniP1}, {{VgprB32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
2491 .Any(
2492 {{DivB32, _, DivP1}, {{VgprB32}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
2493
2494 addRulesForIOpcs({amdgcn_cluster_load_b64})
2496 .Any({{DivB64, _, UniP1}, {{VgprB64}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
2497 .Any(
2498 {{DivB64, _, DivP1}, {{VgprB64}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
2499
2500 addRulesForIOpcs({amdgcn_cluster_load_b128})
2502 .Any({{DivB128, _, UniP1},
2503 {{VgprB128}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
2504 .Any({{DivB128, _, DivP1},
2505 {{VgprB128}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
2506
2507 addRulesForIOpcs({amdgcn_cluster_load_async_to_lds_b8,
2508 amdgcn_cluster_load_async_to_lds_b32,
2509 amdgcn_cluster_load_async_to_lds_b64,
2510 amdgcn_cluster_load_async_to_lds_b128})
2511 .Any({{}, {{}, {IntrId, VgprP1, VgprP3, Imm, Imm, SgprB32_M0}}});
2512
2513 addRulesForIOpcs({amdgcn_perm_pk16_b4_u4}, StandardB)
2514 .Uni(B64, {{UniInVgprB64}, {IntrId, Vgpr32, Vgpr32, VgprV2S32}})
2515 .Div(B64, {{VgprB64}, {IntrId, Vgpr32, Vgpr32, VgprV2S32}});
2516
2517 addRulesForIOpcs({amdgcn_perm_pk16_b6_u4}, StandardB)
2519 .Div(B96, {{VgprB96}, {IntrId, Vgpr32, VgprB64, VgprV2S32}});
2520
2521 addRulesForIOpcs({amdgcn_perm_pk16_b8_u4}, StandardB)
2523 .Div(B128, {{VgprB128}, {IntrId, VgprB64, VgprB64, VgprV2S32}});
2524
2525 addRulesForIOpcs({amdgcn_wwm, amdgcn_strict_wwm, amdgcn_wqm, amdgcn_softwqm,
2526 amdgcn_strict_wqm},
2527 StandardB)
2528 .Div(B32, {{VgprB32}, {IntrId, VgprB32}})
2529 .Uni(B32, {{SgprB32}, {IntrId, SgprB32}})
2530 .Div(B64, {{VgprB64}, {IntrId, VgprB64}})
2531 .Uni(B64, {{SgprB64}, {IntrId, SgprB64}})
2532 .Div(B96, {{VgprB96}, {IntrId, VgprB96}})
2533 .Uni(B96, {{SgprB96}, {IntrId, SgprB96}})
2534 .Div(B128, {{VgprB128}, {IntrId, VgprB128}})
2535 .Uni(B128, {{SgprB128}, {IntrId, SgprB128}})
2536 .Any({{UniB256}, {{SgprB256}, {IntrId, SgprB256}}})
2537 .Any({{DivB256}, {{VgprB256}, {IntrId, VgprB256}}})
2538 .Any({{UniB512}, {{SgprB512}, {IntrId, SgprB512}}})
2539 .Any({{DivB512}, {{VgprB512}, {IntrId, VgprB512}}});
2540
2541 addRulesForIOpcs({amdgcn_init_whole_wave}).Any({{DivS1}, {{Vcc}, {IntrId}}});
2542
2543 addRulesForIOpcs({amdgcn_kill, amdgcn_wqm_demote})
2544 .Any({{}, {{}, {IntrId, Vcc}}});
2545
2546 addRulesForIOpcs({amdgcn_set_inactive}, StandardB)
2547 .Div(B32, {{VgprB32}, {IntrId, VgprB32, VgprB32}});
2548
2549 addRulesForIOpcs({amdgcn_set_inactive_chain_arg}, Standard)
2550 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32}});
2551
2552 addRulesForIOpcs({amdgcn_cvt_sr_bf16_f32, amdgcn_cvt_sr_f16_f32}, Standard)
2553 .Div(V2S16, {{VgprV2S16}, {IntrId, VgprV2S16, Vgpr32, Vgpr32}});
2554
2555 addRulesForIOpcs({amdgcn_ballot}, Standard)
2556 .Uni(S64, {{Sgpr64}, {IntrId, Vcc}})
2557 .Uni(S32, {{Sgpr32}, {IntrId, Vcc}});
2558
2559 addRulesForIOpcs({amdgcn_inverse_ballot})
2560 .Any({{DivS1, _, S32}, {{Vcc}, {IntrId, SgprB32_ReadFirstLane}}})
2561 .Any({{DivS1, _, S64}, {{Vcc}, {IntrId, SgprB64_ReadFirstLane}}});
2562
2563 addRulesForIOpcs({amdgcn_live_mask, amdgcn_ps_live})
2564 .Any({{DivS1}, {{Vcc}, {}}});
2565
2566 addRulesForIOpcs({amdgcn_mov_dpp, amdgcn_mov_dpp8}, StandardB)
2567 .Div(B32, {{VgprB32}, {IntrId, VgprB32}})
2568 .Div(B64, {{VgprB64}, {IntrId, VgprB64}});
2569
2570 addRulesForIOpcs({amdgcn_update_dpp}, StandardB)
2571 .Div(B32, {{VgprB32}, {IntrId, VgprB32, VgprB32}})
2572 .Div(B64, {{VgprB64}, {IntrId, VgprB64, VgprB64}});
2573
2574 addRulesForIOpcs({amdgcn_sin, amdgcn_cos, amdgcn_tanh}, Standard)
2575 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16}})
2576 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16}})
2577 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
2578 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}});
2579
2580 addRulesForIOpcs({amdgcn_trig_preop}, Standard)
2581 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64, Vgpr32}})
2582 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64, Vgpr32}});
2583
2584 addRulesForIOpcs({amdgcn_exp2})
2585 .Any({{DivS16}, {{Vgpr16}, {IntrId, Vgpr16}}})
2586 .Any({{UniBF16}, {{UniInVgprS16}, {IntrId, Vgpr16}}})
2587 .Any({{UniS16}, {{Sgpr16}, {IntrId, Sgpr16}}}, hasPST)
2588 .Any({{UniS16}, {{UniInVgprS16}, {IntrId, Vgpr16}}}, !hasPST)
2589 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32}}})
2590 .Any({{UniS32}, {{Sgpr32}, {IntrId, Sgpr32}}}, hasPST)
2591 .Any({{UniS32}, {{UniInVgprS32}, {IntrId, Vgpr32}}}, !hasPST);
2592
2593 addRulesForIOpcs({amdgcn_rcp, amdgcn_sqrt})
2594 .Any({{DivS16}, {{Vgpr16}, {IntrId, Vgpr16}}})
2595 .Any({{UniBF16}, {{UniInVgprS16}, {IntrId, Vgpr16}}})
2596 .Any({{UniS16}, {{Sgpr16}, {IntrId, Sgpr16}}}, hasPST)
2597 .Any({{UniS16}, {{UniInVgprS16}, {IntrId, Vgpr16}}}, !hasPST)
2598 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32}}})
2599 .Any({{UniS32}, {{Sgpr32}, {IntrId, Sgpr32}}}, hasPST)
2600 .Any({{UniS32}, {{UniInVgprS32}, {IntrId, Vgpr32}}}, !hasPST)
2601 .Any({{DivS64}, {{Vgpr64}, {IntrId, Vgpr64}}})
2602 .Any({{UniS64}, {{UniInVgprS64}, {IntrId, Vgpr64}}});
2603
2604 addRulesForIOpcs({amdgcn_log})
2605 .Any({{DivS16}, {{Vgpr16}, {IntrId, Vgpr16}}})
2606 .Any({{UniBF16}, {{UniInVgprS16}, {IntrId, Vgpr16}}})
2607 .Any({{UniS16}, {{Sgpr16}, {IntrId, Sgpr16}}}, hasPST)
2608 .Any({{UniS16}, {{UniInVgprS16}, {IntrId, Vgpr16}}}, !hasPST)
2609 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32}}})
2610 .Any({{UniS32}, {{Sgpr32}, {IntrId, Sgpr32}}}, hasPST)
2611 .Any({{UniS32}, {{UniInVgprS32}, {IntrId, Vgpr32}}}, !hasPST);
2612
2613 addRulesForIOpcs({amdgcn_ds_atomic_async_barrier_arrive_b64})
2614 .Any({{}, {{}, {IntrId, VgprP3}}});
2615
2616 addRulesForIOpcs({amdgcn_ds_atomic_barrier_arrive_rtn_b64}, Standard)
2617 .Div(S64, {{Vgpr64}, {IntrId, VgprP3, Vgpr64}});
2618
2619 addRulesForIOpcs({amdgcn_ds_add_gs_reg_rtn, amdgcn_ds_sub_gs_reg_rtn},
2620 Standard)
2621 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}})
2622 .Div(S64, {{Vgpr64}, {IntrId, Vgpr32}});
2623
2624 addRulesForIOpcs({amdgcn_ds_append, amdgcn_ds_consume}, Standard)
2625 .Uni(S32, {{UniInVgprS32}, {IntrId, SgprB32_M0}})
2626 .Div(S32, {{Vgpr32}, {IntrId, SgprB32_M0}});
2627
2628 addRulesForIOpcs(
2629 {amdgcn_ds_bvh_stack_rtn, amdgcn_ds_bvh_stack_push4_pop1_rtn}, Standard)
2630 .Div(S32, {{Vgpr32, Vgpr32}, {IntrId, Vgpr32, Vgpr32, VgprV4S32}});
2631
2632 addRulesForIOpcs({amdgcn_ds_bvh_stack_push8_pop1_rtn}, Standard)
2633 .Div(S32, {{Vgpr32, Vgpr32}, {IntrId, Vgpr32, Vgpr32, VgprV8S32}});
2634
2635 addRulesForIOpcs({amdgcn_ds_bvh_stack_push8_pop2_rtn}, Standard)
2636 .Div(S64, {{Vgpr64, Vgpr32}, {IntrId, Vgpr32, Vgpr32, VgprV8S32}});
2637
2638 addRulesForIOpcs({amdgcn_ds_gws_sema_p, amdgcn_ds_gws_sema_v,
2639 amdgcn_ds_gws_sema_release_all})
2640 .Any({{}, {{}, {IntrId, SgprB32_M0}}});
2641
2642 addRulesForIOpcs(
2643 {amdgcn_ds_gws_barrier, amdgcn_ds_gws_init, amdgcn_ds_gws_sema_br})
2644 .Any({{}, {{}, {IntrId, Vgpr32, SgprB32_M0}}});
2645
2646 addRulesForIOpcs({amdgcn_ds_ordered_add, amdgcn_ds_ordered_swap}, Standard)
2647 .Div(S32, {{Vgpr32}, {IntrId, SgprB32_M0, Vgpr32}});
2648
2649 addRulesForIOpcs({amdgcn_ds_swizzle}, Standard)
2650 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32}})
2651 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32}});
2652
2653 addRulesForIOpcs({amdgcn_permlane16_var, amdgcn_permlanex16_var}, Standard)
2654 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2655
2656 addRulesForIOpcs({amdgcn_permlane16_swap, amdgcn_permlane32_swap}, Standard)
2657 .Div(S32, {{Vgpr32, Vgpr32}, {IntrId, Vgpr32, Vgpr32}});
2658
2659 addRulesForIOpcs({amdgcn_permlane64}, StandardB)
2660 .Div(B32, {{VgprB32}, {IntrId, VgprB32}});
2661
2662 addRulesForIOpcs({amdgcn_ds_read_tr4_b64, amdgcn_ds_read_tr8_b64})
2663 .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, VgprP3}}});
2664
2665 addRulesForIOpcs({amdgcn_ds_read_tr6_b96})
2666 .Any({{DivV3S32}, {{VgprV3S32}, {IntrId, VgprP3}}});
2667
2668 addRulesForIOpcs({amdgcn_ds_read_tr16_b64})
2669 .Any({{DivV4S16}, {{VgprV4S16}, {IntrId, VgprP3}}});
2670
2671 addRulesForIOpcs({amdgcn_interp_p1}, Standard)
2672 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Imm, Imm, SgprB32_M0}});
2673
2674 addRulesForIOpcs({amdgcn_interp_p1_f16}, Standard)
2675 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Imm, Imm, Imm, SgprB32_M0}});
2676
2677 addRulesForIOpcs({amdgcn_interp_p2}, Standard)
2678 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Imm, Imm, SgprB32_M0}});
2679
2680 addRulesForIOpcs({amdgcn_interp_p2_f16}, Standard)
2681 .Div(S16,
2683
2684 addRulesForIOpcs({amdgcn_interp_mov}, Standard)
2685 .Div(S32, {{Vgpr32}, {IntrId, Imm, Imm, Imm, SgprB32_M0}});
2686
2687 addRulesForIOpcs({amdgcn_interp_inreg_p10, amdgcn_interp_inreg_p2,
2688 amdgcn_interp_inreg_p10_f16, amdgcn_interp_p10_rtz_f16},
2689 Standard)
2690 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2691 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2692
2693 addRulesForIOpcs({amdgcn_interp_inreg_p2_f16, amdgcn_interp_p2_rtz_f16},
2694 Standard)
2695 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2696 .Div(S16, {{Vgpr16}, {IntrId, Vgpr32, Vgpr32, Vgpr32}});
2697
2698 addRulesForIOpcs({amdgcn_frexp_exp})
2699 .Any({{UniS16}, {{UniInVgprS16}, {IntrId, Vgpr16}}})
2700 .Any({{DivS16}, {{Vgpr16}, {IntrId, Vgpr16}}})
2701 .Any({{UniS32, _, S32}, {{UniInVgprS32}, {IntrId, Vgpr32}}})
2702 .Any({{DivS32, _, S32}, {{Vgpr32}, {IntrId, Vgpr32}}})
2703 .Any({{UniS32, _, S64}, {{UniInVgprS32}, {IntrId, Vgpr64}}})
2704 .Any({{DivS32, _, S64}, {{Vgpr32}, {IntrId, Vgpr64}}});
2705
2706 Predicate isUnscaledDivFmas([](const MachineInstr &MI) -> bool {
2707 return AMDGPU::isUnscaledIEEEDivFmas(MI, MI.getMF()->getRegInfo());
2708 });
2709
2710 addRulesForIOpcs({amdgcn_div_fmas})
2711 .Any({{DivS32}, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32, Vcc}}})
2712 .Any({{{UniS32}, isUnscaledDivFmas},
2713 {{Sgpr32}, {IntrId, Sgpr32, Sgpr32, Sgpr32, Vcc}}},
2714 hasSALUFloat)
2716 .Any({{DivS64}, {{Vgpr64}, {IntrId, Vgpr64, Vgpr64, Vgpr64, Vcc}}})
2717 .Any({{UniS64}, {{UniInVgprS64}, {IntrId, Vgpr64, Vgpr64, Vgpr64, Vcc}}});
2718
2719 addRulesForIOpcs({amdgcn_div_fixup}, Standard)
2720 .Div(S16, {{Vgpr16}, {IntrId, Vgpr16, Vgpr16, Vgpr16}})
2721 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr16, Vgpr16, Vgpr16}})
2722 .Div(S32, {{Vgpr32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2723 .Uni(S32, {{UniInVgprS32}, {IntrId, Vgpr32, Vgpr32, Vgpr32}})
2724 .Div(S64, {{Vgpr64}, {IntrId, Vgpr64, Vgpr64, Vgpr64}})
2725 .Uni(S64, {{UniInVgprS64}, {IntrId, Vgpr64, Vgpr64, Vgpr64}});
2726
2727 addRulesForIOpcs({amdgcn_div_scale}, Standard)
2728 .Div(S32, {{Vgpr32, Vcc}, {IntrId, Vgpr32, Vgpr32}})
2729 .Uni(S32, {{UniInVgprS32, UniInVcc}, {IntrId, Vgpr32, Vgpr32}})
2730 .Div(S64, {{Vgpr64, Vcc}, {IntrId, Vgpr64, Vgpr64}})
2731 .Uni(S64, {{UniInVgprS64, UniInVcc}, {IntrId, Vgpr64, Vgpr64}});
2732
2733 addRulesForIOpcs(
2734 {amdgcn_fdot2, amdgcn_fdot2_f32_bf16, amdgcn_sdot2, amdgcn_udot2},
2735 Standard)
2737 .Div(S32, {{Vgpr32}, {IntrId, VgprV2S16, VgprV2S16, Vgpr32}});
2738
2739 addRulesForIOpcs({amdgcn_fdot2_f16_f16, amdgcn_fdot2_bf16_bf16}, Standard)
2741 .Div(S16, {{Vgpr16}, {IntrId, VgprV2S16, VgprV2S16, Vgpr16}});
2742
2743 addRulesForIOpcs({amdgcn_sudot4, amdgcn_sudot8}, Standard)
2744 .Uni(S32, {{UniInVgprS32}, {IntrId, Imm, Vgpr32, Imm, Vgpr32, Vgpr32}})
2745 .Div(S32, {{Vgpr32}, {IntrId, Imm, Vgpr32, Imm, Vgpr32, Vgpr32}});
2746
2747 addRulesForIOpcs({amdgcn_s_alloc_vgpr})
2749
2750 addRulesForIOpcs({amdgcn_sat_pk4_i4_i8, amdgcn_sat_pk4_u4_u8}, Standard)
2751 .Uni(S16, {{UniInVgprS16}, {IntrId, Vgpr32}})
2752 .Div(S16, {{Vgpr16}, {IntrId, Vgpr32}});
2753
2754 bool HasGFX90AInsts = ST->hasGFX90AInsts();
2755
2756 // On gfx90a+ both AGPR-form and VGPR-form exists
2757 addRulesForIOpcs({amdgcn_mfma_f32_32x32x1f32, amdgcn_mfma_f32_16x16x1f32,
2758 amdgcn_mfma_f32_4x4x1f32, amdgcn_mfma_f32_32x32x2f32,
2759 amdgcn_mfma_f32_16x16x4f32, amdgcn_mfma_f32_32x32x4f16,
2760 amdgcn_mfma_f32_16x16x4f16, amdgcn_mfma_f32_4x4x4f16,
2761 amdgcn_mfma_f32_32x32x8f16, amdgcn_mfma_f32_16x16x16f16,
2762 amdgcn_mfma_i32_32x32x4i8, amdgcn_mfma_i32_16x16x4i8,
2763 amdgcn_mfma_i32_4x4x4i8, amdgcn_mfma_i32_32x32x8i8,
2764 amdgcn_mfma_i32_16x16x16i8, amdgcn_mfma_f32_32x32x2bf16,
2765 amdgcn_mfma_f32_16x16x2bf16, amdgcn_mfma_f32_4x4x2bf16,
2766 amdgcn_mfma_f32_32x32x4bf16, amdgcn_mfma_f32_16x16x8bf16})
2767 .Any({{DivAnyTy},
2769 !HasGFX90AInsts)
2770 .Any({{DivAnyTy},
2771 {{VgprOrAgprAnyTy},
2773 HasGFX90AInsts);
2774
2775 // gfx90a+ only MFMAs
2776 addRulesForIOpcs({
2777 amdgcn_mfma_f32_32x32x4bf16_1k,
2778 amdgcn_mfma_f32_16x16x4bf16_1k,
2779 amdgcn_mfma_f32_4x4x4bf16_1k,
2780 amdgcn_mfma_f32_32x32x8bf16_1k,
2781 amdgcn_mfma_f32_16x16x16bf16_1k,
2782 amdgcn_mfma_f64_16x16x4f64,
2783 amdgcn_mfma_f64_4x4x4f64,
2784 amdgcn_mfma_i32_16x16x32_i8,
2785 amdgcn_mfma_i32_32x32x16_i8,
2786 amdgcn_mfma_f32_16x16x8_xf32,
2787 amdgcn_mfma_f32_32x32x4_xf32,
2788 amdgcn_mfma_f32_16x16x32_bf8_bf8,
2789 amdgcn_mfma_f32_16x16x32_bf8_fp8,
2790 amdgcn_mfma_f32_16x16x32_fp8_bf8,
2791 amdgcn_mfma_f32_16x16x32_fp8_fp8,
2792 amdgcn_mfma_f32_32x32x16_bf8_bf8,
2793 amdgcn_mfma_f32_32x32x16_bf8_fp8,
2794 amdgcn_mfma_f32_32x32x16_fp8_bf8,
2795 amdgcn_mfma_f32_32x32x16_fp8_fp8,
2796 // gfx950
2797 amdgcn_mfma_f32_16x16x32_f16,
2798 amdgcn_mfma_f32_32x32x16_f16,
2799 amdgcn_mfma_i32_16x16x64_i8,
2800 amdgcn_mfma_i32_32x32x32_i8,
2801 amdgcn_mfma_f32_16x16x32_bf16,
2802 amdgcn_mfma_f32_32x32x16_bf16,
2803 })
2804 .Any({{DivAnyTy},
2805 {{VgprOrAgprAnyTy},
2807
2808 addRulesForIOpcs(
2809 {// gfx942+
2810 amdgcn_smfmac_f32_16x16x32_f16, amdgcn_smfmac_f32_32x32x16_f16,
2811 amdgcn_smfmac_f32_16x16x32_bf16, amdgcn_smfmac_f32_32x32x16_bf16,
2812 amdgcn_smfmac_i32_16x16x64_i8, amdgcn_smfmac_i32_32x32x32_i8,
2813 amdgcn_smfmac_f32_16x16x64_bf8_bf8, amdgcn_smfmac_f32_16x16x64_bf8_fp8,
2814 amdgcn_smfmac_f32_16x16x64_fp8_bf8, amdgcn_smfmac_f32_16x16x64_fp8_fp8,
2815 amdgcn_smfmac_f32_32x32x32_bf8_bf8, amdgcn_smfmac_f32_32x32x32_bf8_fp8,
2816 amdgcn_smfmac_f32_32x32x32_fp8_bf8, amdgcn_smfmac_f32_32x32x32_fp8_fp8,
2817 // gfx950+
2818 amdgcn_smfmac_f32_16x16x64_f16, amdgcn_smfmac_f32_32x32x32_f16,
2819 amdgcn_smfmac_f32_16x16x64_bf16, amdgcn_smfmac_f32_32x32x32_bf16,
2820 amdgcn_smfmac_i32_16x16x128_i8, amdgcn_smfmac_i32_32x32x64_i8,
2821 amdgcn_smfmac_f32_16x16x128_bf8_bf8, amdgcn_smfmac_f32_16x16x128_bf8_fp8,
2822 amdgcn_smfmac_f32_16x16x128_fp8_bf8, amdgcn_smfmac_f32_16x16x128_fp8_fp8,
2823 amdgcn_smfmac_f32_32x32x64_bf8_bf8, amdgcn_smfmac_f32_32x32x64_bf8_fp8,
2824 amdgcn_smfmac_f32_32x32x64_fp8_bf8, amdgcn_smfmac_f32_32x32x64_fp8_fp8})
2825 .Any({{DivAnyTy},
2826 {{VgprOrAgprAnyTy},
2828
2829 addRulesForIOpcs({amdgcn_mfma_scale_f32_32x32x64_f8f6f4,
2830 amdgcn_mfma_scale_f32_16x16x128_f8f6f4})
2831 .Any({{DivAnyTy},
2832 {{VgprOrAgprAnyTy},
2834 Vgpr32, Imm, Vgpr32}}});
2835
2836 // WMMA/SWMMAC intrinsics: all register operands map to VGPR.
2837 addRulesForIOpcs(
2838 {// WMMA GFX11+
2839 amdgcn_wmma_f32_16x16x16_f16, amdgcn_wmma_f32_16x16x16_bf16,
2840 amdgcn_wmma_f16_16x16x16_f16, amdgcn_wmma_bf16_16x16x16_bf16,
2841 amdgcn_wmma_f16_16x16x16_f16_tied, amdgcn_wmma_bf16_16x16x16_bf16_tied,
2842 amdgcn_wmma_i32_16x16x16_iu8, amdgcn_wmma_i32_16x16x16_iu4,
2843 // WMMA GFX12
2844 amdgcn_wmma_f32_16x16x16_fp8_fp8, amdgcn_wmma_f32_16x16x16_fp8_bf8,
2845 amdgcn_wmma_f32_16x16x16_bf8_fp8, amdgcn_wmma_f32_16x16x16_bf8_bf8,
2846 amdgcn_wmma_i32_16x16x32_iu4,
2847 // WMMA GFX1250
2848 amdgcn_wmma_f32_16x16x4_f32, amdgcn_wmma_f32_16x16x32_bf16,
2849 amdgcn_wmma_f32_16x16x32_f16, amdgcn_wmma_f16_16x16x32_f16,
2850 amdgcn_wmma_bf16_16x16x32_bf16, amdgcn_wmma_bf16f32_16x16x32_bf16,
2851 amdgcn_wmma_f32_16x16x64_fp8_fp8, amdgcn_wmma_f32_16x16x64_fp8_bf8,
2852 amdgcn_wmma_f32_16x16x64_bf8_fp8, amdgcn_wmma_f32_16x16x64_bf8_bf8,
2853 amdgcn_wmma_f16_16x16x64_fp8_fp8, amdgcn_wmma_f16_16x16x64_fp8_bf8,
2854 amdgcn_wmma_f16_16x16x64_bf8_fp8, amdgcn_wmma_f16_16x16x64_bf8_bf8,
2855 amdgcn_wmma_f16_16x16x128_fp8_fp8, amdgcn_wmma_f16_16x16x128_fp8_bf8,
2856 amdgcn_wmma_f16_16x16x128_bf8_fp8, amdgcn_wmma_f16_16x16x128_bf8_bf8,
2857 amdgcn_wmma_f32_16x16x128_fp8_fp8, amdgcn_wmma_f32_16x16x128_fp8_bf8,
2858 amdgcn_wmma_f32_16x16x128_bf8_fp8, amdgcn_wmma_f32_16x16x128_bf8_bf8,
2859 amdgcn_wmma_i32_16x16x64_iu8, amdgcn_wmma_f32_16x16x128_f8f6f4,
2860 amdgcn_wmma_scale_f32_16x16x128_f8f6f4,
2861 amdgcn_wmma_scale16_f32_16x16x128_f8f6f4, amdgcn_wmma_f32_32x16x128_f4,
2862 amdgcn_wmma_scale_f32_32x16x128_f4, amdgcn_wmma_scale16_f32_32x16x128_f4,
2863 // WMMA GFX1251
2864 amdgcn_wmma_f64_16x16x4_f64,
2865 // SWMMAC GFX12
2866 amdgcn_swmmac_f32_16x16x32_f16, amdgcn_swmmac_f32_16x16x32_bf16,
2867 amdgcn_swmmac_f16_16x16x32_f16, amdgcn_swmmac_bf16_16x16x32_bf16,
2868 amdgcn_swmmac_i32_16x16x32_iu8, amdgcn_swmmac_i32_16x16x32_iu4,
2869 amdgcn_swmmac_i32_16x16x64_iu4, amdgcn_swmmac_f32_16x16x32_fp8_fp8,
2870 amdgcn_swmmac_f32_16x16x32_fp8_bf8, amdgcn_swmmac_f32_16x16x32_bf8_fp8,
2871 amdgcn_swmmac_f32_16x16x32_bf8_bf8,
2872 // SWMMAC GFX1250
2873 amdgcn_swmmac_f32_16x16x64_f16, amdgcn_swmmac_f32_16x16x64_bf16,
2874 amdgcn_swmmac_f16_16x16x64_f16, amdgcn_swmmac_bf16_16x16x64_bf16,
2875 amdgcn_swmmac_bf16f32_16x16x64_bf16, amdgcn_swmmac_f32_16x16x128_fp8_fp8,
2876 amdgcn_swmmac_f32_16x16x128_fp8_bf8, amdgcn_swmmac_f32_16x16x128_bf8_fp8,
2877 amdgcn_swmmac_f32_16x16x128_bf8_bf8, amdgcn_swmmac_f16_16x16x128_fp8_fp8,
2878 amdgcn_swmmac_f16_16x16x128_fp8_bf8, amdgcn_swmmac_f16_16x16x128_bf8_fp8,
2879 amdgcn_swmmac_f16_16x16x128_bf8_bf8, amdgcn_swmmac_i32_16x16x128_iu8})
2880 .Any({{}, {{}, {}, ApplyAllVgpr}});
2881
2882} // 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