1 //===- llvm/CodeGen/GlobalISel/Utils.cpp -------------------------*- C++ -*-==// 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 /// \file This file implements the utility functions used by the GlobalISel 9 /// pipeline. 10 //===----------------------------------------------------------------------===// 11 12 #include "llvm/CodeGen/GlobalISel/Utils.h" 13 #include "llvm/ADT/APFloat.h" 14 #include "llvm/ADT/APInt.h" 15 #include "llvm/ADT/Optional.h" 16 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 17 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 18 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 19 #include "llvm/CodeGen/MachineInstr.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 22 #include "llvm/CodeGen/MachineRegisterInfo.h" 23 #include "llvm/CodeGen/StackProtector.h" 24 #include "llvm/CodeGen/TargetInstrInfo.h" 25 #include "llvm/CodeGen/TargetLowering.h" 26 #include "llvm/CodeGen/TargetPassConfig.h" 27 #include "llvm/CodeGen/TargetRegisterInfo.h" 28 #include "llvm/IR/Constants.h" 29 30 #define DEBUG_TYPE "globalisel-utils" 31 32 using namespace llvm; 33 using namespace MIPatternMatch; 34 35 Register llvm::constrainRegToClass(MachineRegisterInfo &MRI, 36 const TargetInstrInfo &TII, 37 const RegisterBankInfo &RBI, Register Reg, 38 const TargetRegisterClass &RegClass) { 39 if (!RBI.constrainGenericRegister(Reg, RegClass, MRI)) 40 return MRI.createVirtualRegister(&RegClass); 41 42 return Reg; 43 } 44 45 Register llvm::constrainOperandRegClass( 46 const MachineFunction &MF, const TargetRegisterInfo &TRI, 47 MachineRegisterInfo &MRI, const TargetInstrInfo &TII, 48 const RegisterBankInfo &RBI, MachineInstr &InsertPt, 49 const TargetRegisterClass &RegClass, const MachineOperand &RegMO) { 50 Register Reg = RegMO.getReg(); 51 // Assume physical registers are properly constrained. 52 assert(Register::isVirtualRegister(Reg) && "PhysReg not implemented"); 53 54 Register ConstrainedReg = constrainRegToClass(MRI, TII, RBI, Reg, RegClass); 55 // If we created a new virtual register because the class is not compatible 56 // then create a copy between the new and the old register. 57 if (ConstrainedReg != Reg) { 58 MachineBasicBlock::iterator InsertIt(&InsertPt); 59 MachineBasicBlock &MBB = *InsertPt.getParent(); 60 if (RegMO.isUse()) { 61 BuildMI(MBB, InsertIt, InsertPt.getDebugLoc(), 62 TII.get(TargetOpcode::COPY), ConstrainedReg) 63 .addReg(Reg); 64 } else { 65 assert(RegMO.isDef() && "Must be a definition"); 66 BuildMI(MBB, std::next(InsertIt), InsertPt.getDebugLoc(), 67 TII.get(TargetOpcode::COPY), Reg) 68 .addReg(ConstrainedReg); 69 } 70 } else { 71 if (GISelChangeObserver *Observer = MF.getObserver()) { 72 if (!RegMO.isDef()) { 73 MachineInstr *RegDef = MRI.getVRegDef(Reg); 74 Observer->changedInstr(*RegDef); 75 } 76 Observer->changingAllUsesOfReg(MRI, Reg); 77 Observer->finishedChangingAllUsesOfReg(); 78 } 79 } 80 return ConstrainedReg; 81 } 82 83 Register llvm::constrainOperandRegClass( 84 const MachineFunction &MF, const TargetRegisterInfo &TRI, 85 MachineRegisterInfo &MRI, const TargetInstrInfo &TII, 86 const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II, 87 const MachineOperand &RegMO, unsigned OpIdx) { 88 Register Reg = RegMO.getReg(); 89 // Assume physical registers are properly constrained. 90 assert(Register::isVirtualRegister(Reg) && "PhysReg not implemented"); 91 92 const TargetRegisterClass *RegClass = TII.getRegClass(II, OpIdx, &TRI, MF); 93 // Some of the target independent instructions, like COPY, may not impose any 94 // register class constraints on some of their operands: If it's a use, we can 95 // skip constraining as the instruction defining the register would constrain 96 // it. 97 98 // We can't constrain unallocatable register classes, because we can't create 99 // virtual registers for these classes, so we need to let targets handled this 100 // case. 101 if (RegClass && !RegClass->isAllocatable()) 102 RegClass = TRI.getConstrainedRegClassForOperand(RegMO, MRI); 103 104 if (!RegClass) { 105 assert((!isTargetSpecificOpcode(II.getOpcode()) || RegMO.isUse()) && 106 "Register class constraint is required unless either the " 107 "instruction is target independent or the operand is a use"); 108 // FIXME: Just bailing out like this here could be not enough, unless we 109 // expect the users of this function to do the right thing for PHIs and 110 // COPY: 111 // v1 = COPY v0 112 // v2 = COPY v1 113 // v1 here may end up not being constrained at all. Please notice that to 114 // reproduce the issue we likely need a destination pattern of a selection 115 // rule producing such extra copies, not just an input GMIR with them as 116 // every existing target using selectImpl handles copies before calling it 117 // and they never reach this function. 118 return Reg; 119 } 120 return constrainOperandRegClass(MF, TRI, MRI, TII, RBI, InsertPt, *RegClass, 121 RegMO); 122 } 123 124 bool llvm::constrainSelectedInstRegOperands(MachineInstr &I, 125 const TargetInstrInfo &TII, 126 const TargetRegisterInfo &TRI, 127 const RegisterBankInfo &RBI) { 128 assert(!isPreISelGenericOpcode(I.getOpcode()) && 129 "A selected instruction is expected"); 130 MachineBasicBlock &MBB = *I.getParent(); 131 MachineFunction &MF = *MBB.getParent(); 132 MachineRegisterInfo &MRI = MF.getRegInfo(); 133 134 for (unsigned OpI = 0, OpE = I.getNumExplicitOperands(); OpI != OpE; ++OpI) { 135 MachineOperand &MO = I.getOperand(OpI); 136 137 // There's nothing to be done on non-register operands. 138 if (!MO.isReg()) 139 continue; 140 141 LLVM_DEBUG(dbgs() << "Converting operand: " << MO << '\n'); 142 assert(MO.isReg() && "Unsupported non-reg operand"); 143 144 Register Reg = MO.getReg(); 145 // Physical registers don't need to be constrained. 146 if (Register::isPhysicalRegister(Reg)) 147 continue; 148 149 // Register operands with a value of 0 (e.g. predicate operands) don't need 150 // to be constrained. 151 if (Reg == 0) 152 continue; 153 154 // If the operand is a vreg, we should constrain its regclass, and only 155 // insert COPYs if that's impossible. 156 // constrainOperandRegClass does that for us. 157 MO.setReg(constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(), 158 MO, OpI)); 159 160 // Tie uses to defs as indicated in MCInstrDesc if this hasn't already been 161 // done. 162 if (MO.isUse()) { 163 int DefIdx = I.getDesc().getOperandConstraint(OpI, MCOI::TIED_TO); 164 if (DefIdx != -1 && !I.isRegTiedToUseOperand(DefIdx)) 165 I.tieOperands(DefIdx, OpI); 166 } 167 } 168 return true; 169 } 170 171 bool llvm::canReplaceReg(Register DstReg, Register SrcReg, 172 MachineRegisterInfo &MRI) { 173 // Give up if either DstReg or SrcReg is a physical register. 174 if (DstReg.isPhysical() || SrcReg.isPhysical()) 175 return false; 176 // Give up if the types don't match. 177 if (MRI.getType(DstReg) != MRI.getType(SrcReg)) 178 return false; 179 // Replace if either DstReg has no constraints or the register 180 // constraints match. 181 return !MRI.getRegClassOrRegBank(DstReg) || 182 MRI.getRegClassOrRegBank(DstReg) == MRI.getRegClassOrRegBank(SrcReg); 183 } 184 185 bool llvm::isTriviallyDead(const MachineInstr &MI, 186 const MachineRegisterInfo &MRI) { 187 // FIXME: This logical is mostly duplicated with 188 // DeadMachineInstructionElim::isDead. Why is LOCAL_ESCAPE not considered in 189 // MachineInstr::isLabel? 190 191 // Don't delete frame allocation labels. 192 if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE) 193 return false; 194 195 // If we can move an instruction, we can remove it. Otherwise, it has 196 // a side-effect of some sort. 197 bool SawStore = false; 198 if (!MI.isSafeToMove(/*AA=*/nullptr, SawStore) && !MI.isPHI()) 199 return false; 200 201 // Instructions without side-effects are dead iff they only define dead vregs. 202 for (auto &MO : MI.operands()) { 203 if (!MO.isReg() || !MO.isDef()) 204 continue; 205 206 Register Reg = MO.getReg(); 207 if (Register::isPhysicalRegister(Reg) || !MRI.use_nodbg_empty(Reg)) 208 return false; 209 } 210 return true; 211 } 212 213 static void reportGISelDiagnostic(DiagnosticSeverity Severity, 214 MachineFunction &MF, 215 const TargetPassConfig &TPC, 216 MachineOptimizationRemarkEmitter &MORE, 217 MachineOptimizationRemarkMissed &R) { 218 bool IsFatal = Severity == DS_Error && 219 TPC.isGlobalISelAbortEnabled(); 220 // Print the function name explicitly if we don't have a debug location (which 221 // makes the diagnostic less useful) or if we're going to emit a raw error. 222 if (!R.getLocation().isValid() || IsFatal) 223 R << (" (in function: " + MF.getName() + ")").str(); 224 225 if (IsFatal) 226 report_fatal_error(R.getMsg()); 227 else 228 MORE.emit(R); 229 } 230 231 void llvm::reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC, 232 MachineOptimizationRemarkEmitter &MORE, 233 MachineOptimizationRemarkMissed &R) { 234 reportGISelDiagnostic(DS_Warning, MF, TPC, MORE, R); 235 } 236 237 void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, 238 MachineOptimizationRemarkEmitter &MORE, 239 MachineOptimizationRemarkMissed &R) { 240 MF.getProperties().set(MachineFunctionProperties::Property::FailedISel); 241 reportGISelDiagnostic(DS_Error, MF, TPC, MORE, R); 242 } 243 244 void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, 245 MachineOptimizationRemarkEmitter &MORE, 246 const char *PassName, StringRef Msg, 247 const MachineInstr &MI) { 248 MachineOptimizationRemarkMissed R(PassName, "GISelFailure: ", 249 MI.getDebugLoc(), MI.getParent()); 250 R << Msg; 251 // Printing MI is expensive; only do it if expensive remarks are enabled. 252 if (TPC.isGlobalISelAbortEnabled() || MORE.allowExtraAnalysis(PassName)) 253 R << ": " << ore::MNV("Inst", MI); 254 reportGISelFailure(MF, TPC, MORE, R); 255 } 256 257 Optional<int64_t> llvm::getConstantVRegVal(Register VReg, 258 const MachineRegisterInfo &MRI) { 259 Optional<ValueAndVReg> ValAndVReg = 260 getConstantVRegValWithLookThrough(VReg, MRI, /*LookThroughInstrs*/ false); 261 assert((!ValAndVReg || ValAndVReg->VReg == VReg) && 262 "Value found while looking through instrs"); 263 if (!ValAndVReg) 264 return None; 265 return ValAndVReg->Value; 266 } 267 268 Optional<ValueAndVReg> llvm::getConstantVRegValWithLookThrough( 269 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs, 270 bool HandleFConstant) { 271 SmallVector<std::pair<unsigned, unsigned>, 4> SeenOpcodes; 272 MachineInstr *MI; 273 auto IsConstantOpcode = [HandleFConstant](unsigned Opcode) { 274 return Opcode == TargetOpcode::G_CONSTANT || 275 (HandleFConstant && Opcode == TargetOpcode::G_FCONSTANT); 276 }; 277 auto GetImmediateValue = [HandleFConstant, 278 &MRI](const MachineInstr &MI) -> Optional<APInt> { 279 const MachineOperand &CstVal = MI.getOperand(1); 280 if (!CstVal.isImm() && !CstVal.isCImm() && 281 (!HandleFConstant || !CstVal.isFPImm())) 282 return None; 283 if (!CstVal.isFPImm()) { 284 unsigned BitWidth = 285 MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 286 APInt Val = CstVal.isImm() ? APInt(BitWidth, CstVal.getImm()) 287 : CstVal.getCImm()->getValue(); 288 assert(Val.getBitWidth() == BitWidth && 289 "Value bitwidth doesn't match definition type"); 290 return Val; 291 } 292 return CstVal.getFPImm()->getValueAPF().bitcastToAPInt(); 293 }; 294 while ((MI = MRI.getVRegDef(VReg)) && !IsConstantOpcode(MI->getOpcode()) && 295 LookThroughInstrs) { 296 switch (MI->getOpcode()) { 297 case TargetOpcode::G_TRUNC: 298 case TargetOpcode::G_SEXT: 299 case TargetOpcode::G_ZEXT: 300 SeenOpcodes.push_back(std::make_pair( 301 MI->getOpcode(), 302 MRI.getType(MI->getOperand(0).getReg()).getSizeInBits())); 303 VReg = MI->getOperand(1).getReg(); 304 break; 305 case TargetOpcode::COPY: 306 VReg = MI->getOperand(1).getReg(); 307 if (Register::isPhysicalRegister(VReg)) 308 return None; 309 break; 310 case TargetOpcode::G_INTTOPTR: 311 VReg = MI->getOperand(1).getReg(); 312 break; 313 default: 314 return None; 315 } 316 } 317 if (!MI || !IsConstantOpcode(MI->getOpcode())) 318 return None; 319 320 Optional<APInt> MaybeVal = GetImmediateValue(*MI); 321 if (!MaybeVal) 322 return None; 323 APInt &Val = *MaybeVal; 324 while (!SeenOpcodes.empty()) { 325 std::pair<unsigned, unsigned> OpcodeAndSize = SeenOpcodes.pop_back_val(); 326 switch (OpcodeAndSize.first) { 327 case TargetOpcode::G_TRUNC: 328 Val = Val.trunc(OpcodeAndSize.second); 329 break; 330 case TargetOpcode::G_SEXT: 331 Val = Val.sext(OpcodeAndSize.second); 332 break; 333 case TargetOpcode::G_ZEXT: 334 Val = Val.zext(OpcodeAndSize.second); 335 break; 336 } 337 } 338 339 if (Val.getBitWidth() > 64) 340 return None; 341 342 return ValueAndVReg{Val.getSExtValue(), VReg}; 343 } 344 345 const ConstantFP * 346 llvm::getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI) { 347 MachineInstr *MI = MRI.getVRegDef(VReg); 348 if (TargetOpcode::G_FCONSTANT != MI->getOpcode()) 349 return nullptr; 350 return MI->getOperand(1).getFPImm(); 351 } 352 353 namespace { 354 struct DefinitionAndSourceRegister { 355 MachineInstr *MI; 356 Register Reg; 357 }; 358 } // namespace 359 360 static Optional<DefinitionAndSourceRegister> 361 getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI) { 362 Register DefSrcReg = Reg; 363 auto *DefMI = MRI.getVRegDef(Reg); 364 auto DstTy = MRI.getType(DefMI->getOperand(0).getReg()); 365 if (!DstTy.isValid()) 366 return None; 367 while (DefMI->getOpcode() == TargetOpcode::COPY) { 368 Register SrcReg = DefMI->getOperand(1).getReg(); 369 auto SrcTy = MRI.getType(SrcReg); 370 if (!SrcTy.isValid()) 371 break; 372 DefMI = MRI.getVRegDef(SrcReg); 373 DefSrcReg = SrcReg; 374 } 375 return DefinitionAndSourceRegister{DefMI, DefSrcReg}; 376 } 377 378 MachineInstr *llvm::getDefIgnoringCopies(Register Reg, 379 const MachineRegisterInfo &MRI) { 380 Optional<DefinitionAndSourceRegister> DefSrcReg = 381 getDefSrcRegIgnoringCopies(Reg, MRI); 382 return DefSrcReg ? DefSrcReg->MI : nullptr; 383 } 384 385 Register llvm::getSrcRegIgnoringCopies(Register Reg, 386 const MachineRegisterInfo &MRI) { 387 Optional<DefinitionAndSourceRegister> DefSrcReg = 388 getDefSrcRegIgnoringCopies(Reg, MRI); 389 return DefSrcReg ? DefSrcReg->Reg : Register(); 390 } 391 392 MachineInstr *llvm::getOpcodeDef(unsigned Opcode, Register Reg, 393 const MachineRegisterInfo &MRI) { 394 MachineInstr *DefMI = getDefIgnoringCopies(Reg, MRI); 395 return DefMI && DefMI->getOpcode() == Opcode ? DefMI : nullptr; 396 } 397 398 APFloat llvm::getAPFloatFromSize(double Val, unsigned Size) { 399 if (Size == 32) 400 return APFloat(float(Val)); 401 if (Size == 64) 402 return APFloat(Val); 403 if (Size != 16) 404 llvm_unreachable("Unsupported FPConstant size"); 405 bool Ignored; 406 APFloat APF(Val); 407 APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored); 408 return APF; 409 } 410 411 Optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode, const Register Op1, 412 const Register Op2, 413 const MachineRegisterInfo &MRI) { 414 auto MaybeOp2Cst = getConstantVRegVal(Op2, MRI); 415 if (!MaybeOp2Cst) 416 return None; 417 418 auto MaybeOp1Cst = getConstantVRegVal(Op1, MRI); 419 if (!MaybeOp1Cst) 420 return None; 421 422 LLT Ty = MRI.getType(Op1); 423 APInt C1(Ty.getSizeInBits(), *MaybeOp1Cst, true); 424 APInt C2(Ty.getSizeInBits(), *MaybeOp2Cst, true); 425 switch (Opcode) { 426 default: 427 break; 428 case TargetOpcode::G_ADD: 429 return C1 + C2; 430 case TargetOpcode::G_AND: 431 return C1 & C2; 432 case TargetOpcode::G_ASHR: 433 return C1.ashr(C2); 434 case TargetOpcode::G_LSHR: 435 return C1.lshr(C2); 436 case TargetOpcode::G_MUL: 437 return C1 * C2; 438 case TargetOpcode::G_OR: 439 return C1 | C2; 440 case TargetOpcode::G_SHL: 441 return C1 << C2; 442 case TargetOpcode::G_SUB: 443 return C1 - C2; 444 case TargetOpcode::G_XOR: 445 return C1 ^ C2; 446 case TargetOpcode::G_UDIV: 447 if (!C2.getBoolValue()) 448 break; 449 return C1.udiv(C2); 450 case TargetOpcode::G_SDIV: 451 if (!C2.getBoolValue()) 452 break; 453 return C1.sdiv(C2); 454 case TargetOpcode::G_UREM: 455 if (!C2.getBoolValue()) 456 break; 457 return C1.urem(C2); 458 case TargetOpcode::G_SREM: 459 if (!C2.getBoolValue()) 460 break; 461 return C1.srem(C2); 462 } 463 464 return None; 465 } 466 467 bool llvm::isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI, 468 bool SNaN) { 469 const MachineInstr *DefMI = MRI.getVRegDef(Val); 470 if (!DefMI) 471 return false; 472 473 if (DefMI->getFlag(MachineInstr::FmNoNans)) 474 return true; 475 476 if (SNaN) { 477 // FP operations quiet. For now, just handle the ones inserted during 478 // legalization. 479 switch (DefMI->getOpcode()) { 480 case TargetOpcode::G_FPEXT: 481 case TargetOpcode::G_FPTRUNC: 482 case TargetOpcode::G_FCANONICALIZE: 483 return true; 484 default: 485 return false; 486 } 487 } 488 489 return false; 490 } 491 492 Align llvm::inferAlignFromPtrInfo(MachineFunction &MF, 493 const MachinePointerInfo &MPO) { 494 auto PSV = MPO.V.dyn_cast<const PseudoSourceValue *>(); 495 if (auto FSPV = dyn_cast_or_null<FixedStackPseudoSourceValue>(PSV)) { 496 MachineFrameInfo &MFI = MF.getFrameInfo(); 497 return commonAlignment(MFI.getObjectAlign(FSPV->getFrameIndex()), 498 MPO.Offset); 499 } 500 501 return Align(1); 502 } 503 504 Register llvm::getFunctionLiveInPhysReg(MachineFunction &MF, 505 const TargetInstrInfo &TII, 506 MCRegister PhysReg, 507 const TargetRegisterClass &RC, 508 LLT RegTy) { 509 DebugLoc DL; // FIXME: Is no location the right choice? 510 MachineBasicBlock &EntryMBB = MF.front(); 511 MachineRegisterInfo &MRI = MF.getRegInfo(); 512 Register LiveIn = MRI.getLiveInVirtReg(PhysReg); 513 if (LiveIn) { 514 MachineInstr *Def = MRI.getVRegDef(LiveIn); 515 if (Def) { 516 // FIXME: Should the verifier check this is in the entry block? 517 assert(Def->getParent() == &EntryMBB && "live-in copy not in entry block"); 518 return LiveIn; 519 } 520 521 // It's possible the incoming argument register and copy was added during 522 // lowering, but later deleted due to being/becoming dead. If this happens, 523 // re-insert the copy. 524 } else { 525 // The live in register was not present, so add it. 526 LiveIn = MF.addLiveIn(PhysReg, &RC); 527 if (RegTy.isValid()) 528 MRI.setType(LiveIn, RegTy); 529 } 530 531 BuildMI(EntryMBB, EntryMBB.begin(), DL, TII.get(TargetOpcode::COPY), LiveIn) 532 .addReg(PhysReg); 533 if (!EntryMBB.isLiveIn(PhysReg)) 534 EntryMBB.addLiveIn(PhysReg); 535 return LiveIn; 536 } 537 538 Optional<APInt> llvm::ConstantFoldExtOp(unsigned Opcode, const Register Op1, 539 uint64_t Imm, 540 const MachineRegisterInfo &MRI) { 541 auto MaybeOp1Cst = getConstantVRegVal(Op1, MRI); 542 if (MaybeOp1Cst) { 543 LLT Ty = MRI.getType(Op1); 544 APInt C1(Ty.getSizeInBits(), *MaybeOp1Cst, true); 545 switch (Opcode) { 546 default: 547 break; 548 case TargetOpcode::G_SEXT_INREG: 549 return C1.trunc(Imm).sext(C1.getBitWidth()); 550 } 551 } 552 return None; 553 } 554 555 void llvm::getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU) { 556 AU.addPreserved<StackProtector>(); 557 } 558 559 static unsigned getLCMSize(unsigned OrigSize, unsigned TargetSize) { 560 unsigned Mul = OrigSize * TargetSize; 561 unsigned GCDSize = greatestCommonDivisor(OrigSize, TargetSize); 562 return Mul / GCDSize; 563 } 564 565 LLT llvm::getLCMType(LLT OrigTy, LLT TargetTy) { 566 const unsigned OrigSize = OrigTy.getSizeInBits(); 567 const unsigned TargetSize = TargetTy.getSizeInBits(); 568 569 if (OrigSize == TargetSize) 570 return OrigTy; 571 572 if (OrigTy.isVector()) { 573 const LLT OrigElt = OrigTy.getElementType(); 574 575 if (TargetTy.isVector()) { 576 const LLT TargetElt = TargetTy.getElementType(); 577 578 if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) { 579 int GCDElts = greatestCommonDivisor(OrigTy.getNumElements(), 580 TargetTy.getNumElements()); 581 // Prefer the original element type. 582 int Mul = OrigTy.getNumElements() * TargetTy.getNumElements(); 583 return LLT::vector(Mul / GCDElts, OrigTy.getElementType()); 584 } 585 } else { 586 if (OrigElt.getSizeInBits() == TargetSize) 587 return OrigTy; 588 } 589 590 unsigned LCMSize = getLCMSize(OrigSize, TargetSize); 591 return LLT::vector(LCMSize / OrigElt.getSizeInBits(), OrigElt); 592 } 593 594 if (TargetTy.isVector()) { 595 unsigned LCMSize = getLCMSize(OrigSize, TargetSize); 596 return LLT::vector(LCMSize / OrigSize, OrigTy); 597 } 598 599 unsigned LCMSize = getLCMSize(OrigSize, TargetSize); 600 601 // Preserve pointer types. 602 if (LCMSize == OrigSize) 603 return OrigTy; 604 if (LCMSize == TargetSize) 605 return TargetTy; 606 607 return LLT::scalar(LCMSize); 608 } 609 610 LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) { 611 const unsigned OrigSize = OrigTy.getSizeInBits(); 612 const unsigned TargetSize = TargetTy.getSizeInBits(); 613 614 if (OrigSize == TargetSize) 615 return OrigTy; 616 617 if (OrigTy.isVector()) { 618 LLT OrigElt = OrigTy.getElementType(); 619 if (TargetTy.isVector()) { 620 LLT TargetElt = TargetTy.getElementType(); 621 if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) { 622 int GCD = greatestCommonDivisor(OrigTy.getNumElements(), 623 TargetTy.getNumElements()); 624 return LLT::scalarOrVector(GCD, OrigElt); 625 } 626 } else { 627 // If the source is a vector of pointers, return a pointer element. 628 if (OrigElt.getSizeInBits() == TargetSize) 629 return OrigElt; 630 } 631 632 unsigned GCD = greatestCommonDivisor(OrigSize, TargetSize); 633 if (GCD == OrigElt.getSizeInBits()) 634 return OrigElt; 635 636 // If we can't produce the original element type, we have to use a smaller 637 // scalar. 638 if (GCD < OrigElt.getSizeInBits()) 639 return LLT::scalar(GCD); 640 return LLT::vector(GCD / OrigElt.getSizeInBits(), OrigElt); 641 } 642 643 if (TargetTy.isVector()) { 644 // Try to preserve the original element type. 645 LLT TargetElt = TargetTy.getElementType(); 646 if (TargetElt.getSizeInBits() == OrigSize) 647 return OrigTy; 648 } 649 650 unsigned GCD = greatestCommonDivisor(OrigSize, TargetSize); 651 return LLT::scalar(GCD); 652 } 653 654 Optional<int> llvm::getSplatIndex(MachineInstr &MI) { 655 assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR && 656 "Only G_SHUFFLE_VECTOR can have a splat index!"); 657 ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask(); 658 auto FirstDefinedIdx = find_if(Mask, [](int Elt) { return Elt >= 0; }); 659 660 // If all elements are undefined, this shuffle can be considered a splat. 661 // Return 0 for better potential for callers to simplify. 662 if (FirstDefinedIdx == Mask.end()) 663 return 0; 664 665 // Make sure all remaining elements are either undef or the same 666 // as the first non-undef value. 667 int SplatValue = *FirstDefinedIdx; 668 if (any_of(make_range(std::next(FirstDefinedIdx), Mask.end()), 669 [&SplatValue](int Elt) { return Elt >= 0 && Elt != SplatValue; })) 670 return None; 671 672 return SplatValue; 673 } 674 675 static bool isBuildVectorOp(unsigned Opcode) { 676 return Opcode == TargetOpcode::G_BUILD_VECTOR || 677 Opcode == TargetOpcode::G_BUILD_VECTOR_TRUNC; 678 } 679 680 // TODO: Handle mixed undef elements. 681 static bool isBuildVectorConstantSplat(const MachineInstr &MI, 682 const MachineRegisterInfo &MRI, 683 int64_t SplatValue) { 684 if (!isBuildVectorOp(MI.getOpcode())) 685 return false; 686 687 const unsigned NumOps = MI.getNumOperands(); 688 for (unsigned I = 1; I != NumOps; ++I) { 689 Register Element = MI.getOperand(I).getReg(); 690 int64_t ElementValue; 691 if (!mi_match(Element, MRI, m_ICst(ElementValue)) || 692 ElementValue != SplatValue) 693 return false; 694 } 695 696 return true; 697 } 698 699 Optional<int64_t> 700 llvm::getBuildVectorConstantSplat(const MachineInstr &MI, 701 const MachineRegisterInfo &MRI) { 702 if (!isBuildVectorOp(MI.getOpcode())) 703 return None; 704 705 const unsigned NumOps = MI.getNumOperands(); 706 Optional<int64_t> Scalar; 707 for (unsigned I = 1; I != NumOps; ++I) { 708 Register Element = MI.getOperand(I).getReg(); 709 int64_t ElementValue; 710 if (!mi_match(Element, MRI, m_ICst(ElementValue))) 711 return None; 712 if (!Scalar) 713 Scalar = ElementValue; 714 else if (*Scalar != ElementValue) 715 return None; 716 } 717 718 return Scalar; 719 } 720 721 bool llvm::isBuildVectorAllZeros(const MachineInstr &MI, 722 const MachineRegisterInfo &MRI) { 723 return isBuildVectorConstantSplat(MI, MRI, 0); 724 } 725 726 bool llvm::isBuildVectorAllOnes(const MachineInstr &MI, 727 const MachineRegisterInfo &MRI) { 728 return isBuildVectorConstantSplat(MI, MRI, -1); 729 } 730 731 bool llvm::isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector, 732 bool IsFP) { 733 switch (TLI.getBooleanContents(IsVector, IsFP)) { 734 case TargetLowering::UndefinedBooleanContent: 735 return Val & 0x1; 736 case TargetLowering::ZeroOrOneBooleanContent: 737 return Val == 1; 738 case TargetLowering::ZeroOrNegativeOneBooleanContent: 739 return Val == -1; 740 } 741 llvm_unreachable("Invalid boolean contents"); 742 } 743 744 int64_t llvm::getICmpTrueVal(const TargetLowering &TLI, bool IsVector, 745 bool IsFP) { 746 switch (TLI.getBooleanContents(IsVector, IsFP)) { 747 case TargetLowering::UndefinedBooleanContent: 748 case TargetLowering::ZeroOrOneBooleanContent: 749 return 1; 750 case TargetLowering::ZeroOrNegativeOneBooleanContent: 751 return -1; 752 } 753 llvm_unreachable("Invalid boolean contents"); 754 } 755