1 //===- AMDGPUInstructionSelector.cpp ----------------------------*- C++ -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// This file implements the targeting of the InstructionSelector class for 11 /// AMDGPU. 12 /// \todo This should be generated by TableGen. 13 //===----------------------------------------------------------------------===// 14 15 #include "AMDGPUInstructionSelector.h" 16 #include "AMDGPUInstrInfo.h" 17 #include "AMDGPURegisterBankInfo.h" 18 #include "AMDGPURegisterInfo.h" 19 #include "AMDGPUSubtarget.h" 20 #include "AMDGPUTargetMachine.h" 21 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 22 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 23 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" 24 #include "llvm/CodeGen/GlobalISel/Utils.h" 25 #include "llvm/CodeGen/MachineBasicBlock.h" 26 #include "llvm/CodeGen/MachineFunction.h" 27 #include "llvm/CodeGen/MachineInstr.h" 28 #include "llvm/CodeGen/MachineInstrBuilder.h" 29 #include "llvm/CodeGen/MachineRegisterInfo.h" 30 #include "llvm/IR/Type.h" 31 #include "llvm/Support/Debug.h" 32 #include "llvm/Support/raw_ostream.h" 33 34 #define DEBUG_TYPE "amdgpu-isel" 35 36 using namespace llvm; 37 38 #define GET_GLOBALISEL_IMPL 39 #include "AMDGPUGenGlobalISel.inc" 40 #undef GET_GLOBALISEL_IMPL 41 42 AMDGPUInstructionSelector::AMDGPUInstructionSelector( 43 const SISubtarget &STI, const AMDGPURegisterBankInfo &RBI, 44 const AMDGPUTargetMachine &TM) 45 : InstructionSelector(), TII(*STI.getInstrInfo()), 46 TRI(*STI.getRegisterInfo()), RBI(RBI), TM(TM), 47 STI(STI), 48 EnableLateStructurizeCFG(AMDGPUTargetMachine::EnableLateStructurizeCFG), 49 #define GET_GLOBALISEL_PREDICATES_INIT 50 #include "AMDGPUGenGlobalISel.inc" 51 #undef GET_GLOBALISEL_PREDICATES_INIT 52 #define GET_GLOBALISEL_TEMPORARIES_INIT 53 #include "AMDGPUGenGlobalISel.inc" 54 #undef GET_GLOBALISEL_TEMPORARIES_INIT 55 ,AMDGPUASI(STI.getAMDGPUAS()) 56 { 57 } 58 59 const char *AMDGPUInstructionSelector::getName() { return DEBUG_TYPE; } 60 61 bool AMDGPUInstructionSelector::selectCOPY(MachineInstr &I) const { 62 MachineBasicBlock *BB = I.getParent(); 63 MachineFunction *MF = BB->getParent(); 64 MachineRegisterInfo &MRI = MF->getRegInfo(); 65 I.setDesc(TII.get(TargetOpcode::COPY)); 66 for (const MachineOperand &MO : I.operands()) { 67 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) 68 continue; 69 70 const TargetRegisterClass *RC = 71 TRI.getConstrainedRegClassForOperand(MO, MRI); 72 if (!RC) 73 continue; 74 RBI.constrainGenericRegister(MO.getReg(), *RC, MRI); 75 } 76 return true; 77 } 78 79 MachineOperand 80 AMDGPUInstructionSelector::getSubOperand64(MachineOperand &MO, 81 unsigned SubIdx) const { 82 83 MachineInstr *MI = MO.getParent(); 84 MachineBasicBlock *BB = MO.getParent()->getParent(); 85 MachineFunction *MF = BB->getParent(); 86 MachineRegisterInfo &MRI = MF->getRegInfo(); 87 unsigned DstReg = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass); 88 89 if (MO.isReg()) { 90 unsigned ComposedSubIdx = TRI.composeSubRegIndices(MO.getSubReg(), SubIdx); 91 unsigned Reg = MO.getReg(); 92 BuildMI(*BB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), DstReg) 93 .addReg(Reg, 0, ComposedSubIdx); 94 95 return MachineOperand::CreateReg(DstReg, MO.isDef(), MO.isImplicit(), 96 MO.isKill(), MO.isDead(), MO.isUndef(), 97 MO.isEarlyClobber(), 0, MO.isDebug(), 98 MO.isInternalRead()); 99 } 100 101 assert(MO.isImm()); 102 103 APInt Imm(64, MO.getImm()); 104 105 switch (SubIdx) { 106 default: 107 llvm_unreachable("do not know to split immediate with this sub index."); 108 case AMDGPU::sub0: 109 return MachineOperand::CreateImm(Imm.getLoBits(32).getSExtValue()); 110 case AMDGPU::sub1: 111 return MachineOperand::CreateImm(Imm.getHiBits(32).getSExtValue()); 112 } 113 } 114 115 bool AMDGPUInstructionSelector::selectG_ADD(MachineInstr &I) const { 116 MachineBasicBlock *BB = I.getParent(); 117 MachineFunction *MF = BB->getParent(); 118 MachineRegisterInfo &MRI = MF->getRegInfo(); 119 unsigned Size = RBI.getSizeInBits(I.getOperand(0).getReg(), MRI, TRI); 120 unsigned DstLo = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); 121 unsigned DstHi = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); 122 123 if (Size != 64) 124 return false; 125 126 DebugLoc DL = I.getDebugLoc(); 127 128 MachineOperand Lo1(getSubOperand64(I.getOperand(1), AMDGPU::sub0)); 129 MachineOperand Lo2(getSubOperand64(I.getOperand(2), AMDGPU::sub0)); 130 131 BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADD_U32), DstLo) 132 .add(Lo1) 133 .add(Lo2); 134 135 MachineOperand Hi1(getSubOperand64(I.getOperand(1), AMDGPU::sub1)); 136 MachineOperand Hi2(getSubOperand64(I.getOperand(2), AMDGPU::sub1)); 137 138 BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADDC_U32), DstHi) 139 .add(Hi1) 140 .add(Hi2); 141 142 BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), I.getOperand(0).getReg()) 143 .addReg(DstLo) 144 .addImm(AMDGPU::sub0) 145 .addReg(DstHi) 146 .addImm(AMDGPU::sub1); 147 148 for (MachineOperand &MO : I.explicit_operands()) { 149 if (!MO.isReg() || TargetRegisterInfo::isPhysicalRegister(MO.getReg())) 150 continue; 151 RBI.constrainGenericRegister(MO.getReg(), AMDGPU::SReg_64RegClass, MRI); 152 } 153 154 I.eraseFromParent(); 155 return true; 156 } 157 158 bool AMDGPUInstructionSelector::selectG_GEP(MachineInstr &I) const { 159 return selectG_ADD(I); 160 } 161 162 bool AMDGPUInstructionSelector::selectG_INTRINSIC(MachineInstr &I, 163 CodeGenCoverage &CoverageInfo) const { 164 unsigned IntrinsicID = I.getOperand(1).getIntrinsicID(); 165 166 switch (IntrinsicID) { 167 default: 168 break; 169 case Intrinsic::amdgcn_cvt_pkrtz: 170 return selectImpl(I, CoverageInfo); 171 } 172 return false; 173 } 174 175 bool AMDGPUInstructionSelector::selectG_STORE(MachineInstr &I) const { 176 MachineBasicBlock *BB = I.getParent(); 177 MachineFunction *MF = BB->getParent(); 178 MachineRegisterInfo &MRI = MF->getRegInfo(); 179 DebugLoc DL = I.getDebugLoc(); 180 unsigned StoreSize = RBI.getSizeInBits(I.getOperand(0).getReg(), MRI, TRI); 181 unsigned Opcode; 182 183 // FIXME: Select store instruction based on address space 184 switch (StoreSize) { 185 default: 186 return false; 187 case 32: 188 Opcode = AMDGPU::FLAT_STORE_DWORD; 189 break; 190 case 64: 191 Opcode = AMDGPU::FLAT_STORE_DWORDX2; 192 break; 193 case 96: 194 Opcode = AMDGPU::FLAT_STORE_DWORDX3; 195 break; 196 case 128: 197 Opcode = AMDGPU::FLAT_STORE_DWORDX4; 198 break; 199 } 200 201 MachineInstr *Flat = BuildMI(*BB, &I, DL, TII.get(Opcode)) 202 .add(I.getOperand(1)) 203 .add(I.getOperand(0)) 204 .addImm(0) // offset 205 .addImm(0) // glc 206 .addImm(0); // slc 207 208 209 // Now that we selected an opcode, we need to constrain the register 210 // operands to use appropriate classes. 211 bool Ret = constrainSelectedInstRegOperands(*Flat, TII, TRI, RBI); 212 213 I.eraseFromParent(); 214 return Ret; 215 } 216 217 bool AMDGPUInstructionSelector::selectG_CONSTANT(MachineInstr &I) const { 218 MachineBasicBlock *BB = I.getParent(); 219 MachineFunction *MF = BB->getParent(); 220 MachineRegisterInfo &MRI = MF->getRegInfo(); 221 MachineOperand &ImmOp = I.getOperand(1); 222 223 // The AMDGPU backend only supports Imm operands and not CImm or FPImm. 224 if (ImmOp.isFPImm()) { 225 const APInt &Imm = ImmOp.getFPImm()->getValueAPF().bitcastToAPInt(); 226 ImmOp.ChangeToImmediate(Imm.getZExtValue()); 227 } else if (ImmOp.isCImm()) { 228 ImmOp.ChangeToImmediate(ImmOp.getCImm()->getZExtValue()); 229 } 230 231 unsigned DstReg = I.getOperand(0).getReg(); 232 unsigned Size; 233 bool IsSgpr; 234 const RegisterBank *RB = MRI.getRegBankOrNull(I.getOperand(0).getReg()); 235 if (RB) { 236 IsSgpr = RB->getID() == AMDGPU::SGPRRegBankID; 237 Size = MRI.getType(DstReg).getSizeInBits(); 238 } else { 239 const TargetRegisterClass *RC = TRI.getRegClassForReg(MRI, DstReg); 240 IsSgpr = TRI.isSGPRClass(RC); 241 Size = TRI.getRegSizeInBits(*RC); 242 } 243 244 if (Size != 32 && Size != 64) 245 return false; 246 247 unsigned Opcode = IsSgpr ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32; 248 if (Size == 32) { 249 I.setDesc(TII.get(Opcode)); 250 I.addImplicitDefUseOperands(*MF); 251 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 252 } 253 254 DebugLoc DL = I.getDebugLoc(); 255 const TargetRegisterClass *RC = IsSgpr ? &AMDGPU::SReg_32_XM0RegClass : 256 &AMDGPU::VGPR_32RegClass; 257 unsigned LoReg = MRI.createVirtualRegister(RC); 258 unsigned HiReg = MRI.createVirtualRegister(RC); 259 const APInt &Imm = APInt(Size, I.getOperand(1).getImm()); 260 261 BuildMI(*BB, &I, DL, TII.get(Opcode), LoReg) 262 .addImm(Imm.trunc(32).getZExtValue()); 263 264 BuildMI(*BB, &I, DL, TII.get(Opcode), HiReg) 265 .addImm(Imm.ashr(32).getZExtValue()); 266 267 const MachineInstr *RS = 268 BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg) 269 .addReg(LoReg) 270 .addImm(AMDGPU::sub0) 271 .addReg(HiReg) 272 .addImm(AMDGPU::sub1); 273 274 // We can't call constrainSelectedInstRegOperands here, because it doesn't 275 // work for target independent opcodes 276 I.eraseFromParent(); 277 const TargetRegisterClass *DstRC = 278 TRI.getConstrainedRegClassForOperand(RS->getOperand(0), MRI); 279 if (!DstRC) 280 return true; 281 return RBI.constrainGenericRegister(DstReg, *DstRC, MRI); 282 } 283 284 static bool isConstant(const MachineInstr &MI) { 285 return MI.getOpcode() == TargetOpcode::G_CONSTANT; 286 } 287 288 void AMDGPUInstructionSelector::getAddrModeInfo(const MachineInstr &Load, 289 const MachineRegisterInfo &MRI, SmallVectorImpl<GEPInfo> &AddrInfo) const { 290 291 const MachineInstr *PtrMI = MRI.getUniqueVRegDef(Load.getOperand(1).getReg()); 292 293 assert(PtrMI); 294 295 if (PtrMI->getOpcode() != TargetOpcode::G_GEP) 296 return; 297 298 GEPInfo GEPInfo(*PtrMI); 299 300 for (unsigned i = 1, e = 3; i < e; ++i) { 301 const MachineOperand &GEPOp = PtrMI->getOperand(i); 302 const MachineInstr *OpDef = MRI.getUniqueVRegDef(GEPOp.getReg()); 303 assert(OpDef); 304 if (isConstant(*OpDef)) { 305 // FIXME: Is it possible to have multiple Imm parts? Maybe if we 306 // are lacking other optimizations. 307 assert(GEPInfo.Imm == 0); 308 GEPInfo.Imm = OpDef->getOperand(1).getCImm()->getSExtValue(); 309 continue; 310 } 311 const RegisterBank *OpBank = RBI.getRegBank(GEPOp.getReg(), MRI, TRI); 312 if (OpBank->getID() == AMDGPU::SGPRRegBankID) 313 GEPInfo.SgprParts.push_back(GEPOp.getReg()); 314 else 315 GEPInfo.VgprParts.push_back(GEPOp.getReg()); 316 } 317 318 AddrInfo.push_back(GEPInfo); 319 getAddrModeInfo(*PtrMI, MRI, AddrInfo); 320 } 321 322 static bool isInstrUniform(const MachineInstr &MI) { 323 if (!MI.hasOneMemOperand()) 324 return false; 325 326 const MachineMemOperand *MMO = *MI.memoperands_begin(); 327 const Value *Ptr = MMO->getValue(); 328 329 // UndefValue means this is a load of a kernel input. These are uniform. 330 // Sometimes LDS instructions have constant pointers. 331 // If Ptr is null, then that means this mem operand contains a 332 // PseudoSourceValue like GOT. 333 if (!Ptr || isa<UndefValue>(Ptr) || isa<Argument>(Ptr) || 334 isa<Constant>(Ptr) || isa<GlobalValue>(Ptr)) 335 return true; 336 337 if (MMO->getAddrSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT) 338 return true; 339 340 const Instruction *I = dyn_cast<Instruction>(Ptr); 341 return I && I->getMetadata("amdgpu.uniform"); 342 } 343 344 static unsigned getSmrdOpcode(unsigned BaseOpcode, unsigned LoadSize) { 345 346 if (LoadSize == 32) 347 return BaseOpcode; 348 349 switch (BaseOpcode) { 350 case AMDGPU::S_LOAD_DWORD_IMM: 351 switch (LoadSize) { 352 case 64: 353 return AMDGPU::S_LOAD_DWORDX2_IMM; 354 case 128: 355 return AMDGPU::S_LOAD_DWORDX4_IMM; 356 case 256: 357 return AMDGPU::S_LOAD_DWORDX8_IMM; 358 case 512: 359 return AMDGPU::S_LOAD_DWORDX16_IMM; 360 } 361 break; 362 case AMDGPU::S_LOAD_DWORD_IMM_ci: 363 switch (LoadSize) { 364 case 64: 365 return AMDGPU::S_LOAD_DWORDX2_IMM_ci; 366 case 128: 367 return AMDGPU::S_LOAD_DWORDX4_IMM_ci; 368 case 256: 369 return AMDGPU::S_LOAD_DWORDX8_IMM_ci; 370 case 512: 371 return AMDGPU::S_LOAD_DWORDX16_IMM_ci; 372 } 373 break; 374 case AMDGPU::S_LOAD_DWORD_SGPR: 375 switch (LoadSize) { 376 case 64: 377 return AMDGPU::S_LOAD_DWORDX2_SGPR; 378 case 128: 379 return AMDGPU::S_LOAD_DWORDX4_SGPR; 380 case 256: 381 return AMDGPU::S_LOAD_DWORDX8_SGPR; 382 case 512: 383 return AMDGPU::S_LOAD_DWORDX16_SGPR; 384 } 385 break; 386 } 387 llvm_unreachable("Invalid base smrd opcode or size"); 388 } 389 390 bool AMDGPUInstructionSelector::hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const { 391 for (const GEPInfo &GEPInfo : AddrInfo) { 392 if (!GEPInfo.VgprParts.empty()) 393 return true; 394 } 395 return false; 396 } 397 398 bool AMDGPUInstructionSelector::selectSMRD(MachineInstr &I, 399 ArrayRef<GEPInfo> AddrInfo) const { 400 401 if (!I.hasOneMemOperand()) 402 return false; 403 404 if ((*I.memoperands_begin())->getAddrSpace() != AMDGPUASI.CONSTANT_ADDRESS && 405 (*I.memoperands_begin())->getAddrSpace() != AMDGPUASI.CONSTANT_ADDRESS_32BIT) 406 return false; 407 408 if (!isInstrUniform(I)) 409 return false; 410 411 if (hasVgprParts(AddrInfo)) 412 return false; 413 414 MachineBasicBlock *BB = I.getParent(); 415 MachineFunction *MF = BB->getParent(); 416 const SISubtarget &Subtarget = MF->getSubtarget<SISubtarget>(); 417 MachineRegisterInfo &MRI = MF->getRegInfo(); 418 unsigned DstReg = I.getOperand(0).getReg(); 419 const DebugLoc &DL = I.getDebugLoc(); 420 unsigned Opcode; 421 unsigned LoadSize = RBI.getSizeInBits(DstReg, MRI, TRI); 422 423 if (!AddrInfo.empty() && AddrInfo[0].SgprParts.size() == 1) { 424 425 const GEPInfo &GEPInfo = AddrInfo[0]; 426 427 unsigned PtrReg = GEPInfo.SgprParts[0]; 428 int64_t EncodedImm = AMDGPU::getSMRDEncodedOffset(Subtarget, GEPInfo.Imm); 429 if (AMDGPU::isLegalSMRDImmOffset(Subtarget, GEPInfo.Imm)) { 430 Opcode = getSmrdOpcode(AMDGPU::S_LOAD_DWORD_IMM, LoadSize); 431 432 MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg) 433 .addReg(PtrReg) 434 .addImm(EncodedImm) 435 .addImm(0); // glc 436 return constrainSelectedInstRegOperands(*SMRD, TII, TRI, RBI); 437 } 438 439 if (Subtarget.getGeneration() == AMDGPUSubtarget::SEA_ISLANDS && 440 isUInt<32>(EncodedImm)) { 441 Opcode = getSmrdOpcode(AMDGPU::S_LOAD_DWORD_IMM_ci, LoadSize); 442 MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg) 443 .addReg(PtrReg) 444 .addImm(EncodedImm) 445 .addImm(0); // glc 446 return constrainSelectedInstRegOperands(*SMRD, TII, TRI, RBI); 447 } 448 449 if (isUInt<32>(GEPInfo.Imm)) { 450 Opcode = getSmrdOpcode(AMDGPU::S_LOAD_DWORD_SGPR, LoadSize); 451 unsigned OffsetReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); 452 BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_MOV_B32), OffsetReg) 453 .addImm(GEPInfo.Imm); 454 455 MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg) 456 .addReg(PtrReg) 457 .addReg(OffsetReg) 458 .addImm(0); // glc 459 return constrainSelectedInstRegOperands(*SMRD, TII, TRI, RBI); 460 } 461 } 462 463 unsigned PtrReg = I.getOperand(1).getReg(); 464 Opcode = getSmrdOpcode(AMDGPU::S_LOAD_DWORD_IMM, LoadSize); 465 MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg) 466 .addReg(PtrReg) 467 .addImm(0) 468 .addImm(0); // glc 469 return constrainSelectedInstRegOperands(*SMRD, TII, TRI, RBI); 470 } 471 472 473 bool AMDGPUInstructionSelector::selectG_LOAD(MachineInstr &I) const { 474 MachineBasicBlock *BB = I.getParent(); 475 MachineFunction *MF = BB->getParent(); 476 MachineRegisterInfo &MRI = MF->getRegInfo(); 477 DebugLoc DL = I.getDebugLoc(); 478 unsigned DstReg = I.getOperand(0).getReg(); 479 unsigned PtrReg = I.getOperand(1).getReg(); 480 unsigned LoadSize = RBI.getSizeInBits(DstReg, MRI, TRI); 481 unsigned Opcode; 482 483 SmallVector<GEPInfo, 4> AddrInfo; 484 485 getAddrModeInfo(I, MRI, AddrInfo); 486 487 if (selectSMRD(I, AddrInfo)) { 488 I.eraseFromParent(); 489 return true; 490 } 491 492 switch (LoadSize) { 493 default: 494 llvm_unreachable("Load size not supported\n"); 495 case 32: 496 Opcode = AMDGPU::FLAT_LOAD_DWORD; 497 break; 498 case 64: 499 Opcode = AMDGPU::FLAT_LOAD_DWORDX2; 500 break; 501 } 502 503 MachineInstr *Flat = BuildMI(*BB, &I, DL, TII.get(Opcode)) 504 .add(I.getOperand(0)) 505 .addReg(PtrReg) 506 .addImm(0) // offset 507 .addImm(0) // glc 508 .addImm(0); // slc 509 510 bool Ret = constrainSelectedInstRegOperands(*Flat, TII, TRI, RBI); 511 I.eraseFromParent(); 512 return Ret; 513 } 514 515 bool AMDGPUInstructionSelector::select(MachineInstr &I, 516 CodeGenCoverage &CoverageInfo) const { 517 518 if (!isPreISelGenericOpcode(I.getOpcode())) 519 return true; 520 521 switch (I.getOpcode()) { 522 default: 523 break; 524 case TargetOpcode::G_FMUL: 525 case TargetOpcode::G_FADD: 526 case TargetOpcode::G_FPTOUI: 527 case TargetOpcode::G_OR: 528 return selectImpl(I, CoverageInfo); 529 case TargetOpcode::G_ADD: 530 return selectG_ADD(I); 531 case TargetOpcode::G_BITCAST: 532 return selectCOPY(I); 533 case TargetOpcode::G_CONSTANT: 534 case TargetOpcode::G_FCONSTANT: 535 return selectG_CONSTANT(I); 536 case TargetOpcode::G_GEP: 537 return selectG_GEP(I); 538 case TargetOpcode::G_INTRINSIC: 539 return selectG_INTRINSIC(I, CoverageInfo); 540 case TargetOpcode::G_LOAD: 541 return selectG_LOAD(I); 542 case TargetOpcode::G_STORE: 543 return selectG_STORE(I); 544 } 545 return false; 546 } 547 548 /// 549 /// This will select either an SGPR or VGPR operand and will save us from 550 /// having to write an extra tablegen pattern. 551 InstructionSelector::ComplexRendererFns 552 AMDGPUInstructionSelector::selectVSRC0(MachineOperand &Root) const { 553 return {{ 554 [=](MachineInstrBuilder &MIB) { MIB.add(Root); } 555 }}; 556 } 557 558 InstructionSelector::ComplexRendererFns 559 AMDGPUInstructionSelector::selectVOP3Mods0(MachineOperand &Root) const { 560 return {{ 561 [=](MachineInstrBuilder &MIB) { MIB.add(Root); }, 562 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, // src0_mods 563 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, // clamp 564 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); } // omod 565 }}; 566 } 567 568 InstructionSelector::ComplexRendererFns 569 AMDGPUInstructionSelector::selectVOP3Mods(MachineOperand &Root) const { 570 return {{ 571 [=](MachineInstrBuilder &MIB) { MIB.add(Root); }, 572 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); } // src_mods 573 }}; 574 } 575