1 //===-- llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h -----*- 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 // This file contains some helper functions which try to cleanup artifacts 9 // such as G_TRUNCs/G_[ZSA]EXTENDS that were created during legalization to make 10 // the types match. This file also contains some combines of merges that happens 11 // at the end of the legalization. 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZATIONARTIFACTCOMBINER_H 15 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZATIONARTIFACTCOMBINER_H 16 17 #include "llvm/ADT/SmallBitVector.h" 18 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 19 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" 20 #include "llvm/CodeGen/GlobalISel/Legalizer.h" 21 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 22 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 23 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 24 #include "llvm/CodeGen/GlobalISel/Utils.h" 25 #include "llvm/CodeGen/MachineRegisterInfo.h" 26 #include "llvm/CodeGen/Register.h" 27 #include "llvm/CodeGen/TargetOpcodes.h" 28 #include "llvm/IR/Constants.h" 29 #include "llvm/IR/DebugInfoMetadata.h" 30 #include "llvm/Support/Debug.h" 31 32 #define DEBUG_TYPE "legalizer" 33 34 namespace llvm { 35 class LegalizationArtifactCombiner { 36 MachineIRBuilder &Builder; 37 MachineRegisterInfo &MRI; 38 const LegalizerInfo &LI; 39 GISelKnownBits *KB; 40 41 static bool isArtifactCast(unsigned Opc) { 42 switch (Opc) { 43 case TargetOpcode::G_TRUNC: 44 case TargetOpcode::G_SEXT: 45 case TargetOpcode::G_ZEXT: 46 case TargetOpcode::G_ANYEXT: 47 return true; 48 default: 49 return false; 50 } 51 } 52 53 public: 54 LegalizationArtifactCombiner(MachineIRBuilder &B, MachineRegisterInfo &MRI, 55 const LegalizerInfo &LI, 56 GISelKnownBits *KB = nullptr) 57 : Builder(B), MRI(MRI), LI(LI), KB(KB) {} 58 59 bool tryCombineAnyExt(MachineInstr &MI, 60 SmallVectorImpl<MachineInstr *> &DeadInsts, 61 SmallVectorImpl<Register> &UpdatedDefs, 62 GISelObserverWrapper &Observer) { 63 using namespace llvm::MIPatternMatch; 64 assert(MI.getOpcode() == TargetOpcode::G_ANYEXT); 65 66 Builder.setInstrAndDebugLoc(MI); 67 Register DstReg = MI.getOperand(0).getReg(); 68 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 69 70 // aext(trunc x) - > aext/copy/trunc x 71 Register TruncSrc; 72 if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) { 73 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI); 74 if (MRI.getType(DstReg) == MRI.getType(TruncSrc)) 75 replaceRegOrBuildCopy(DstReg, TruncSrc, MRI, Builder, UpdatedDefs, 76 Observer); 77 else 78 Builder.buildAnyExtOrTrunc(DstReg, TruncSrc); 79 UpdatedDefs.push_back(DstReg); 80 markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 81 return true; 82 } 83 84 // aext([asz]ext x) -> [asz]ext x 85 Register ExtSrc; 86 MachineInstr *ExtMI; 87 if (mi_match(SrcReg, MRI, 88 m_all_of(m_MInstr(ExtMI), m_any_of(m_GAnyExt(m_Reg(ExtSrc)), 89 m_GSExt(m_Reg(ExtSrc)), 90 m_GZExt(m_Reg(ExtSrc)))))) { 91 Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc}); 92 UpdatedDefs.push_back(DstReg); 93 markInstAndDefDead(MI, *ExtMI, DeadInsts); 94 return true; 95 } 96 97 // Try to fold aext(g_constant) when the larger constant type is legal. 98 auto *SrcMI = MRI.getVRegDef(SrcReg); 99 if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) { 100 const LLT DstTy = MRI.getType(DstReg); 101 if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) { 102 auto &CstVal = SrcMI->getOperand(1); 103 auto *MergedLocation = DILocation::getMergedLocation( 104 MI.getDebugLoc().get(), SrcMI->getDebugLoc().get()); 105 // Set the debug location to the merged location of the SrcMI and the MI 106 // if the aext fold is successful. 107 Builder.setDebugLoc(MergedLocation); 108 Builder.buildConstant( 109 DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits())); 110 UpdatedDefs.push_back(DstReg); 111 markInstAndDefDead(MI, *SrcMI, DeadInsts); 112 return true; 113 } 114 } 115 return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs, Observer); 116 } 117 118 bool tryCombineZExt(MachineInstr &MI, 119 SmallVectorImpl<MachineInstr *> &DeadInsts, 120 SmallVectorImpl<Register> &UpdatedDefs, 121 GISelObserverWrapper &Observer) { 122 using namespace llvm::MIPatternMatch; 123 assert(MI.getOpcode() == TargetOpcode::G_ZEXT); 124 125 Builder.setInstrAndDebugLoc(MI); 126 Register DstReg = MI.getOperand(0).getReg(); 127 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 128 129 // zext(trunc x) - > and (aext/copy/trunc x), mask 130 // zext(sext x) -> and (sext x), mask 131 Register TruncSrc; 132 Register SextSrc; 133 if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc))) || 134 mi_match(SrcReg, MRI, m_GSExt(m_Reg(SextSrc)))) { 135 LLT DstTy = MRI.getType(DstReg); 136 if (isInstUnsupported({TargetOpcode::G_AND, {DstTy}}) || 137 isConstantUnsupported(DstTy)) 138 return false; 139 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI); 140 LLT SrcTy = MRI.getType(SrcReg); 141 APInt MaskVal = APInt::getAllOnes(SrcTy.getScalarSizeInBits()); 142 if (SextSrc && (DstTy != MRI.getType(SextSrc))) 143 SextSrc = Builder.buildSExtOrTrunc(DstTy, SextSrc).getReg(0); 144 if (TruncSrc && (DstTy != MRI.getType(TruncSrc))) 145 TruncSrc = Builder.buildAnyExtOrTrunc(DstTy, TruncSrc).getReg(0); 146 APInt ExtMaskVal = MaskVal.zext(DstTy.getScalarSizeInBits()); 147 Register AndSrc = SextSrc ? SextSrc : TruncSrc; 148 // Elide G_AND and mask constant if possible. 149 // The G_AND would also be removed by the post-legalize redundant_and 150 // combine, but in this very common case, eliding early and regardless of 151 // OptLevel results in significant compile-time and O0 code-size 152 // improvements. Inserting unnecessary instructions between boolean defs 153 // and uses hinders a lot of folding during ISel. 154 if (KB && (KB->getKnownZeroes(AndSrc) | ExtMaskVal).isAllOnes()) { 155 replaceRegOrBuildCopy(DstReg, AndSrc, MRI, Builder, UpdatedDefs, 156 Observer); 157 } else { 158 auto Mask = Builder.buildConstant(DstTy, ExtMaskVal); 159 Builder.buildAnd(DstReg, AndSrc, Mask); 160 } 161 markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 162 return true; 163 } 164 165 // zext(zext x) -> (zext x) 166 Register ZextSrc; 167 if (mi_match(SrcReg, MRI, m_GZExt(m_Reg(ZextSrc)))) { 168 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI); 169 Observer.changingInstr(MI); 170 MI.getOperand(1).setReg(ZextSrc); 171 Observer.changedInstr(MI); 172 UpdatedDefs.push_back(DstReg); 173 markDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 174 return true; 175 } 176 177 // Try to fold zext(g_constant) when the larger constant type is legal. 178 auto *SrcMI = MRI.getVRegDef(SrcReg); 179 if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) { 180 const LLT DstTy = MRI.getType(DstReg); 181 if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) { 182 auto &CstVal = SrcMI->getOperand(1); 183 Builder.buildConstant( 184 DstReg, CstVal.getCImm()->getValue().zext(DstTy.getSizeInBits())); 185 UpdatedDefs.push_back(DstReg); 186 markInstAndDefDead(MI, *SrcMI, DeadInsts); 187 return true; 188 } 189 } 190 return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs, Observer); 191 } 192 193 bool tryCombineSExt(MachineInstr &MI, 194 SmallVectorImpl<MachineInstr *> &DeadInsts, 195 SmallVectorImpl<Register> &UpdatedDefs, 196 GISelObserverWrapper &Observer) { 197 using namespace llvm::MIPatternMatch; 198 assert(MI.getOpcode() == TargetOpcode::G_SEXT); 199 200 Builder.setInstrAndDebugLoc(MI); 201 Register DstReg = MI.getOperand(0).getReg(); 202 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 203 204 // sext(trunc x) - > (sext_inreg (aext/copy/trunc x), c) 205 Register TruncSrc; 206 if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) { 207 LLT DstTy = MRI.getType(DstReg); 208 if (isInstUnsupported({TargetOpcode::G_SEXT_INREG, {DstTy}})) 209 return false; 210 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI); 211 LLT SrcTy = MRI.getType(SrcReg); 212 uint64_t SizeInBits = SrcTy.getScalarSizeInBits(); 213 if (DstTy != MRI.getType(TruncSrc)) 214 TruncSrc = Builder.buildAnyExtOrTrunc(DstTy, TruncSrc).getReg(0); 215 // Elide G_SEXT_INREG if possible. This is similar to eliding G_AND in 216 // tryCombineZExt. Refer to the comment in tryCombineZExt for rationale. 217 if (KB && KB->computeNumSignBits(TruncSrc) > 218 DstTy.getScalarSizeInBits() - SizeInBits) 219 replaceRegOrBuildCopy(DstReg, TruncSrc, MRI, Builder, UpdatedDefs, 220 Observer); 221 else 222 Builder.buildSExtInReg(DstReg, TruncSrc, SizeInBits); 223 markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 224 return true; 225 } 226 227 // sext(zext x) -> (zext x) 228 // sext(sext x) -> (sext x) 229 Register ExtSrc; 230 MachineInstr *ExtMI; 231 if (mi_match(SrcReg, MRI, 232 m_all_of(m_MInstr(ExtMI), m_any_of(m_GZExt(m_Reg(ExtSrc)), 233 m_GSExt(m_Reg(ExtSrc)))))) { 234 LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI); 235 Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc}); 236 UpdatedDefs.push_back(DstReg); 237 markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 238 return true; 239 } 240 241 // Try to fold sext(g_constant) when the larger constant type is legal. 242 auto *SrcMI = MRI.getVRegDef(SrcReg); 243 if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) { 244 const LLT DstTy = MRI.getType(DstReg); 245 if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) { 246 auto &CstVal = SrcMI->getOperand(1); 247 Builder.buildConstant( 248 DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits())); 249 UpdatedDefs.push_back(DstReg); 250 markInstAndDefDead(MI, *SrcMI, DeadInsts); 251 return true; 252 } 253 } 254 255 return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs, Observer); 256 } 257 258 bool tryCombineTrunc(MachineInstr &MI, 259 SmallVectorImpl<MachineInstr *> &DeadInsts, 260 SmallVectorImpl<Register> &UpdatedDefs, 261 GISelObserverWrapper &Observer) { 262 using namespace llvm::MIPatternMatch; 263 assert(MI.getOpcode() == TargetOpcode::G_TRUNC); 264 265 Builder.setInstr(MI); 266 Register DstReg = MI.getOperand(0).getReg(); 267 const LLT DstTy = MRI.getType(DstReg); 268 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 269 270 // Try to fold trunc(g_constant) when the smaller constant type is legal. 271 auto *SrcMI = MRI.getVRegDef(SrcReg); 272 if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) { 273 if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) { 274 auto &CstVal = SrcMI->getOperand(1); 275 Builder.buildConstant( 276 DstReg, CstVal.getCImm()->getValue().trunc(DstTy.getSizeInBits())); 277 UpdatedDefs.push_back(DstReg); 278 markInstAndDefDead(MI, *SrcMI, DeadInsts); 279 return true; 280 } 281 } 282 283 // Try to fold trunc(merge) to directly use the source of the merge. 284 // This gets rid of large, difficult to legalize, merges 285 if (auto *SrcMerge = dyn_cast<GMerge>(SrcMI)) { 286 const Register MergeSrcReg = SrcMerge->getSourceReg(0); 287 const LLT MergeSrcTy = MRI.getType(MergeSrcReg); 288 289 // We can only fold if the types are scalar 290 const unsigned DstSize = DstTy.getSizeInBits(); 291 const unsigned MergeSrcSize = MergeSrcTy.getSizeInBits(); 292 if (!DstTy.isScalar() || !MergeSrcTy.isScalar()) 293 return false; 294 295 if (DstSize < MergeSrcSize) { 296 // When the merge source is larger than the destination, we can just 297 // truncate the merge source directly 298 if (isInstUnsupported({TargetOpcode::G_TRUNC, {DstTy, MergeSrcTy}})) 299 return false; 300 301 LLVM_DEBUG(dbgs() << "Combining G_TRUNC(G_MERGE_VALUES) to G_TRUNC: " 302 << MI); 303 304 Builder.buildTrunc(DstReg, MergeSrcReg); 305 UpdatedDefs.push_back(DstReg); 306 } else if (DstSize == MergeSrcSize) { 307 // If the sizes match we can simply try to replace the register 308 LLVM_DEBUG( 309 dbgs() << "Replacing G_TRUNC(G_MERGE_VALUES) with merge input: " 310 << MI); 311 replaceRegOrBuildCopy(DstReg, MergeSrcReg, MRI, Builder, UpdatedDefs, 312 Observer); 313 } else if (DstSize % MergeSrcSize == 0) { 314 // If the trunc size is a multiple of the merge source size we can use 315 // a smaller merge instead 316 if (isInstUnsupported( 317 {TargetOpcode::G_MERGE_VALUES, {DstTy, MergeSrcTy}})) 318 return false; 319 320 LLVM_DEBUG( 321 dbgs() << "Combining G_TRUNC(G_MERGE_VALUES) to G_MERGE_VALUES: " 322 << MI); 323 324 const unsigned NumSrcs = DstSize / MergeSrcSize; 325 assert(NumSrcs < SrcMI->getNumOperands() - 1 && 326 "trunc(merge) should require less inputs than merge"); 327 SmallVector<Register, 8> SrcRegs(NumSrcs); 328 for (unsigned i = 0; i < NumSrcs; ++i) 329 SrcRegs[i] = SrcMerge->getSourceReg(i); 330 331 Builder.buildMergeValues(DstReg, SrcRegs); 332 UpdatedDefs.push_back(DstReg); 333 } else { 334 // Unable to combine 335 return false; 336 } 337 338 markInstAndDefDead(MI, *SrcMerge, DeadInsts); 339 return true; 340 } 341 342 // trunc(trunc) -> trunc 343 Register TruncSrc; 344 if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) { 345 // Always combine trunc(trunc) since the eventual resulting trunc must be 346 // legal anyway as it must be legal for all outputs of the consumer type 347 // set. 348 LLVM_DEBUG(dbgs() << ".. Combine G_TRUNC(G_TRUNC): " << MI); 349 350 Builder.buildTrunc(DstReg, TruncSrc); 351 UpdatedDefs.push_back(DstReg); 352 markInstAndDefDead(MI, *MRI.getVRegDef(TruncSrc), DeadInsts); 353 return true; 354 } 355 356 // trunc(ext x) -> x 357 ArtifactValueFinder Finder(MRI, Builder, LI); 358 if (Register FoundReg = 359 Finder.findValueFromDef(DstReg, 0, DstTy.getSizeInBits())) { 360 LLT FoundRegTy = MRI.getType(FoundReg); 361 if (DstTy == FoundRegTy) { 362 LLVM_DEBUG(dbgs() << ".. Combine G_TRUNC(G_[S,Z,ANY]EXT/G_TRUNC...): " 363 << MI); 364 365 replaceRegOrBuildCopy(DstReg, FoundReg, MRI, Builder, UpdatedDefs, 366 Observer); 367 UpdatedDefs.push_back(DstReg); 368 markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); 369 return true; 370 } 371 } 372 373 return false; 374 } 375 376 /// Try to fold G_[ASZ]EXT (G_IMPLICIT_DEF). 377 bool tryFoldImplicitDef(MachineInstr &MI, 378 SmallVectorImpl<MachineInstr *> &DeadInsts, 379 SmallVectorImpl<Register> &UpdatedDefs, 380 GISelObserverWrapper &Observer) { 381 unsigned Opcode = MI.getOpcode(); 382 assert(Opcode == TargetOpcode::G_ANYEXT || Opcode == TargetOpcode::G_ZEXT || 383 Opcode == TargetOpcode::G_SEXT); 384 385 if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, 386 MI.getOperand(1).getReg(), MRI)) { 387 Builder.setInstr(MI); 388 Register DstReg = MI.getOperand(0).getReg(); 389 LLT DstTy = MRI.getType(DstReg); 390 391 if (Opcode == TargetOpcode::G_ANYEXT) { 392 // G_ANYEXT (G_IMPLICIT_DEF) -> G_IMPLICIT_DEF 393 if (!isInstLegal({TargetOpcode::G_IMPLICIT_DEF, {DstTy}})) 394 return false; 395 LLVM_DEBUG(dbgs() << ".. Combine G_ANYEXT(G_IMPLICIT_DEF): " << MI); 396 auto Impl = Builder.buildUndef(DstTy); 397 replaceRegOrBuildCopy(DstReg, Impl.getReg(0), MRI, Builder, UpdatedDefs, 398 Observer); 399 UpdatedDefs.push_back(DstReg); 400 } else { 401 // G_[SZ]EXT (G_IMPLICIT_DEF) -> G_CONSTANT 0 because the top 402 // bits will be 0 for G_ZEXT and 0/1 for the G_SEXT. 403 if (isConstantUnsupported(DstTy)) 404 return false; 405 LLVM_DEBUG(dbgs() << ".. Combine G_[SZ]EXT(G_IMPLICIT_DEF): " << MI); 406 auto Cnst = Builder.buildConstant(DstTy, 0); 407 replaceRegOrBuildCopy(DstReg, Cnst.getReg(0), MRI, Builder, UpdatedDefs, 408 Observer); 409 UpdatedDefs.push_back(DstReg); 410 } 411 412 markInstAndDefDead(MI, *DefMI, DeadInsts); 413 return true; 414 } 415 return false; 416 } 417 418 bool tryFoldUnmergeCast(MachineInstr &MI, MachineInstr &CastMI, 419 SmallVectorImpl<MachineInstr *> &DeadInsts, 420 SmallVectorImpl<Register> &UpdatedDefs) { 421 422 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES); 423 424 const unsigned CastOpc = CastMI.getOpcode(); 425 426 if (!isArtifactCast(CastOpc)) 427 return false; 428 429 const unsigned NumDefs = MI.getNumOperands() - 1; 430 431 const Register CastSrcReg = CastMI.getOperand(1).getReg(); 432 const LLT CastSrcTy = MRI.getType(CastSrcReg); 433 const LLT DestTy = MRI.getType(MI.getOperand(0).getReg()); 434 const LLT SrcTy = MRI.getType(MI.getOperand(NumDefs).getReg()); 435 436 const unsigned CastSrcSize = CastSrcTy.getSizeInBits(); 437 const unsigned DestSize = DestTy.getSizeInBits(); 438 439 if (CastOpc == TargetOpcode::G_TRUNC) { 440 if (SrcTy.isVector() && SrcTy.getScalarType() == DestTy.getScalarType()) { 441 // %1:_(<4 x s8>) = G_TRUNC %0(<4 x s32>) 442 // %2:_(s8), %3:_(s8), %4:_(s8), %5:_(s8) = G_UNMERGE_VALUES %1 443 // => 444 // %6:_(s32), %7:_(s32), %8:_(s32), %9:_(s32) = G_UNMERGE_VALUES %0 445 // %2:_(s8) = G_TRUNC %6 446 // %3:_(s8) = G_TRUNC %7 447 // %4:_(s8) = G_TRUNC %8 448 // %5:_(s8) = G_TRUNC %9 449 450 unsigned UnmergeNumElts = 451 DestTy.isVector() ? CastSrcTy.getNumElements() / NumDefs : 1; 452 LLT UnmergeTy = CastSrcTy.changeElementCount( 453 ElementCount::getFixed(UnmergeNumElts)); 454 LLT SrcWideTy = 455 SrcTy.changeElementCount(ElementCount::getFixed(UnmergeNumElts)); 456 457 if (isInstUnsupported( 458 {TargetOpcode::G_UNMERGE_VALUES, {UnmergeTy, CastSrcTy}}) || 459 LI.getAction({TargetOpcode::G_TRUNC, {SrcWideTy, UnmergeTy}}) 460 .Action == LegalizeActions::MoreElements) 461 return false; 462 463 Builder.setInstr(MI); 464 auto NewUnmerge = Builder.buildUnmerge(UnmergeTy, CastSrcReg); 465 466 for (unsigned I = 0; I != NumDefs; ++I) { 467 Register DefReg = MI.getOperand(I).getReg(); 468 UpdatedDefs.push_back(DefReg); 469 Builder.buildTrunc(DefReg, NewUnmerge.getReg(I)); 470 } 471 472 markInstAndDefDead(MI, CastMI, DeadInsts); 473 return true; 474 } 475 476 if (CastSrcTy.isScalar() && SrcTy.isScalar() && !DestTy.isVector()) { 477 // %1:_(s16) = G_TRUNC %0(s32) 478 // %2:_(s8), %3:_(s8) = G_UNMERGE_VALUES %1 479 // => 480 // %2:_(s8), %3:_(s8), %4:_(s8), %5:_(s8) = G_UNMERGE_VALUES %0 481 482 // Unmerge(trunc) can be combined if the trunc source size is a multiple 483 // of the unmerge destination size 484 if (CastSrcSize % DestSize != 0) 485 return false; 486 487 // Check if the new unmerge is supported 488 if (isInstUnsupported( 489 {TargetOpcode::G_UNMERGE_VALUES, {DestTy, CastSrcTy}})) 490 return false; 491 492 // Gather the original destination registers and create new ones for the 493 // unused bits 494 const unsigned NewNumDefs = CastSrcSize / DestSize; 495 SmallVector<Register, 8> DstRegs(NewNumDefs); 496 for (unsigned Idx = 0; Idx < NewNumDefs; ++Idx) { 497 if (Idx < NumDefs) 498 DstRegs[Idx] = MI.getOperand(Idx).getReg(); 499 else 500 DstRegs[Idx] = MRI.createGenericVirtualRegister(DestTy); 501 } 502 503 // Build new unmerge 504 Builder.setInstr(MI); 505 Builder.buildUnmerge(DstRegs, CastSrcReg); 506 UpdatedDefs.append(DstRegs.begin(), DstRegs.begin() + NewNumDefs); 507 markInstAndDefDead(MI, CastMI, DeadInsts); 508 return true; 509 } 510 } 511 512 // TODO: support combines with other casts as well 513 return false; 514 } 515 516 static bool canFoldMergeOpcode(unsigned MergeOp, unsigned ConvertOp, 517 LLT OpTy, LLT DestTy) { 518 // Check if we found a definition that is like G_MERGE_VALUES. 519 switch (MergeOp) { 520 default: 521 return false; 522 case TargetOpcode::G_BUILD_VECTOR: 523 case TargetOpcode::G_MERGE_VALUES: 524 // The convert operation that we will need to insert is 525 // going to convert the input of that type of instruction (scalar) 526 // to the destination type (DestTy). 527 // The conversion needs to stay in the same domain (scalar to scalar 528 // and vector to vector), so if we were to allow to fold the merge 529 // we would need to insert some bitcasts. 530 // E.g., 531 // <2 x s16> = build_vector s16, s16 532 // <2 x s32> = zext <2 x s16> 533 // <2 x s16>, <2 x s16> = unmerge <2 x s32> 534 // 535 // As is the folding would produce: 536 // <2 x s16> = zext s16 <-- scalar to vector 537 // <2 x s16> = zext s16 <-- scalar to vector 538 // Which is invalid. 539 // Instead we would want to generate: 540 // s32 = zext s16 541 // <2 x s16> = bitcast s32 542 // s32 = zext s16 543 // <2 x s16> = bitcast s32 544 // 545 // That is not done yet. 546 if (ConvertOp == 0) 547 return true; 548 return !DestTy.isVector() && OpTy.isVector() && 549 DestTy == OpTy.getElementType(); 550 case TargetOpcode::G_CONCAT_VECTORS: { 551 if (ConvertOp == 0) 552 return true; 553 if (!DestTy.isVector()) 554 return false; 555 556 const unsigned OpEltSize = OpTy.getElementType().getSizeInBits(); 557 558 // Don't handle scalarization with a cast that isn't in the same 559 // direction as the vector cast. This could be handled, but it would 560 // require more intermediate unmerges. 561 if (ConvertOp == TargetOpcode::G_TRUNC) 562 return DestTy.getSizeInBits() <= OpEltSize; 563 return DestTy.getSizeInBits() >= OpEltSize; 564 } 565 } 566 } 567 568 /// Try to replace DstReg with SrcReg or build a COPY instruction 569 /// depending on the register constraints. 570 static void replaceRegOrBuildCopy(Register DstReg, Register SrcReg, 571 MachineRegisterInfo &MRI, 572 MachineIRBuilder &Builder, 573 SmallVectorImpl<Register> &UpdatedDefs, 574 GISelChangeObserver &Observer) { 575 if (!llvm::canReplaceReg(DstReg, SrcReg, MRI)) { 576 Builder.buildCopy(DstReg, SrcReg); 577 UpdatedDefs.push_back(DstReg); 578 return; 579 } 580 SmallVector<MachineInstr *, 4> UseMIs; 581 // Get the users and notify the observer before replacing. 582 for (auto &UseMI : MRI.use_instructions(DstReg)) { 583 UseMIs.push_back(&UseMI); 584 Observer.changingInstr(UseMI); 585 } 586 // Replace the registers. 587 MRI.replaceRegWith(DstReg, SrcReg); 588 UpdatedDefs.push_back(SrcReg); 589 // Notify the observer that we changed the instructions. 590 for (auto *UseMI : UseMIs) 591 Observer.changedInstr(*UseMI); 592 } 593 594 /// Return the operand index in \p MI that defines \p Def 595 static unsigned getDefIndex(const MachineInstr &MI, Register SearchDef) { 596 unsigned DefIdx = 0; 597 for (const MachineOperand &Def : MI.defs()) { 598 if (Def.getReg() == SearchDef) 599 break; 600 ++DefIdx; 601 } 602 603 return DefIdx; 604 } 605 606 /// This class provides utilities for finding source registers of specific 607 /// bit ranges in an artifact. The routines can look through the source 608 /// registers if they're other artifacts to try to find a non-artifact source 609 /// of a value. 610 class ArtifactValueFinder { 611 MachineRegisterInfo &MRI; 612 MachineIRBuilder &MIB; 613 const LegalizerInfo &LI; 614 615 // Stores the best register found in the current query so far. 616 Register CurrentBest = Register(); 617 618 /// Given an concat_vector op \p Concat and a start bit and size, try to 619 /// find the origin of the value defined by that start position and size. 620 /// 621 /// \returns a register with the requested size, or the current best 622 /// register found during the current query. 623 Register findValueFromConcat(GConcatVectors &Concat, unsigned StartBit, 624 unsigned Size) { 625 assert(Size > 0); 626 627 // Find the source operand that provides the bits requested. 628 Register Src1Reg = Concat.getSourceReg(0); 629 unsigned SrcSize = MRI.getType(Src1Reg).getSizeInBits(); 630 631 // Operand index of the source that provides the start of the bit range. 632 unsigned StartSrcIdx = (StartBit / SrcSize) + 1; 633 // Offset into the source at which the bit range starts. 634 unsigned InRegOffset = StartBit % SrcSize; 635 // Check that the bits don't span multiple sources. 636 // FIXME: we might be able return multiple sources? Or create an 637 // appropriate concat to make it fit. 638 if (InRegOffset + Size > SrcSize) 639 return CurrentBest; 640 641 Register SrcReg = Concat.getReg(StartSrcIdx); 642 if (InRegOffset == 0 && Size == SrcSize) { 643 CurrentBest = SrcReg; 644 return findValueFromDefImpl(SrcReg, 0, Size); 645 } 646 647 return findValueFromDefImpl(SrcReg, InRegOffset, Size); 648 } 649 650 /// Given an build_vector op \p BV and a start bit and size, try to find 651 /// the origin of the value defined by that start position and size. 652 /// 653 /// \returns a register with the requested size, or the current best 654 /// register found during the current query. 655 Register findValueFromBuildVector(GBuildVector &BV, unsigned StartBit, 656 unsigned Size) { 657 assert(Size > 0); 658 659 // Find the source operand that provides the bits requested. 660 Register Src1Reg = BV.getSourceReg(0); 661 unsigned SrcSize = MRI.getType(Src1Reg).getSizeInBits(); 662 663 // Operand index of the source that provides the start of the bit range. 664 unsigned StartSrcIdx = (StartBit / SrcSize) + 1; 665 // Offset into the source at which the bit range starts. 666 unsigned InRegOffset = StartBit % SrcSize; 667 668 if (InRegOffset != 0) 669 return CurrentBest; // Give up, bits don't start at a scalar source. 670 if (Size < SrcSize) 671 return CurrentBest; // Scalar source is too large for requested bits. 672 673 // If the bits cover multiple sources evenly, then create a new 674 // build_vector to synthesize the required size, if that's been requested. 675 if (Size > SrcSize) { 676 if (Size % SrcSize > 0) 677 return CurrentBest; // Isn't covered exactly by sources. 678 679 unsigned NumSrcsUsed = Size / SrcSize; 680 // If we're requesting all of the sources, just return this def. 681 if (NumSrcsUsed == BV.getNumSources()) 682 return BV.getReg(0); 683 684 LLT SrcTy = MRI.getType(Src1Reg); 685 LLT NewBVTy = LLT::fixed_vector(NumSrcsUsed, SrcTy); 686 687 // Check if the resulting build vector would be legal. 688 LegalizeActionStep ActionStep = 689 LI.getAction({TargetOpcode::G_BUILD_VECTOR, {NewBVTy, SrcTy}}); 690 if (ActionStep.Action != LegalizeActions::Legal) 691 return CurrentBest; 692 693 SmallVector<Register> NewSrcs; 694 for (unsigned SrcIdx = StartSrcIdx; SrcIdx < StartSrcIdx + NumSrcsUsed; 695 ++SrcIdx) 696 NewSrcs.push_back(BV.getReg(SrcIdx)); 697 MIB.setInstrAndDebugLoc(BV); 698 return MIB.buildBuildVector(NewBVTy, NewSrcs).getReg(0); 699 } 700 // A single source is requested, just return it. 701 return BV.getReg(StartSrcIdx); 702 } 703 704 /// Given an G_INSERT op \p MI and a start bit and size, try to find 705 /// the origin of the value defined by that start position and size. 706 /// 707 /// \returns a register with the requested size, or the current best 708 /// register found during the current query. 709 Register findValueFromInsert(MachineInstr &MI, unsigned StartBit, 710 unsigned Size) { 711 assert(MI.getOpcode() == TargetOpcode::G_INSERT); 712 assert(Size > 0); 713 714 Register ContainerSrcReg = MI.getOperand(1).getReg(); 715 Register InsertedReg = MI.getOperand(2).getReg(); 716 LLT InsertedRegTy = MRI.getType(InsertedReg); 717 unsigned InsertOffset = MI.getOperand(3).getImm(); 718 719 // There are 4 possible container/insertreg + requested bit-range layouts 720 // that the instruction and query could be representing. 721 // For: %_ = G_INSERT %CONTAINER, %INS, InsOff (abbrev. to 'IO') 722 // and a start bit 'SB', with size S, giving an end bit 'EB', we could 723 // have... 724 // Scenario A: 725 // -------------------------- 726 // | INS | CONTAINER | 727 // -------------------------- 728 // | | 729 // SB EB 730 // 731 // Scenario B: 732 // -------------------------- 733 // | INS | CONTAINER | 734 // -------------------------- 735 // | | 736 // SB EB 737 // 738 // Scenario C: 739 // -------------------------- 740 // | CONTAINER | INS | 741 // -------------------------- 742 // | | 743 // SB EB 744 // 745 // Scenario D: 746 // -------------------------- 747 // | CONTAINER | INS | 748 // -------------------------- 749 // | | 750 // SB EB 751 // 752 // So therefore, A and D are requesting data from the INS operand, while 753 // B and C are requesting from the container operand. 754 755 unsigned InsertedEndBit = InsertOffset + InsertedRegTy.getSizeInBits(); 756 unsigned EndBit = StartBit + Size; 757 unsigned NewStartBit; 758 Register SrcRegToUse; 759 if (EndBit <= InsertOffset || InsertedEndBit <= StartBit) { 760 SrcRegToUse = ContainerSrcReg; 761 NewStartBit = StartBit; 762 return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size); 763 } 764 if (InsertOffset <= StartBit && EndBit <= InsertedEndBit) { 765 SrcRegToUse = InsertedReg; 766 NewStartBit = StartBit - InsertOffset; 767 if (NewStartBit == 0 && 768 Size == MRI.getType(SrcRegToUse).getSizeInBits()) 769 CurrentBest = SrcRegToUse; 770 return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size); 771 } 772 // The bit range spans both the inserted and container regions. 773 return Register(); 774 } 775 776 /// Given an G_SEXT, G_ZEXT, G_ANYEXT op \p MI and a start bit and 777 /// size, try to find the origin of the value defined by that start 778 /// position and size. 779 /// 780 /// \returns a register with the requested size, or the current best 781 /// register found during the current query. 782 Register findValueFromExt(MachineInstr &MI, unsigned StartBit, 783 unsigned Size) { 784 assert(MI.getOpcode() == TargetOpcode::G_SEXT || 785 MI.getOpcode() == TargetOpcode::G_ZEXT || 786 MI.getOpcode() == TargetOpcode::G_ANYEXT); 787 assert(Size > 0); 788 789 Register SrcReg = MI.getOperand(1).getReg(); 790 LLT SrcType = MRI.getType(SrcReg); 791 unsigned SrcSize = SrcType.getSizeInBits(); 792 793 // Currently we don't go into vectors. 794 if (!SrcType.isScalar()) 795 return CurrentBest; 796 797 if (StartBit + Size > SrcSize) 798 return CurrentBest; 799 800 if (StartBit == 0 && SrcType.getSizeInBits() == Size) 801 CurrentBest = SrcReg; 802 return findValueFromDefImpl(SrcReg, StartBit, Size); 803 } 804 805 /// Given an G_TRUNC op \p MI and a start bit and size, try to find 806 /// the origin of the value defined by that start position and size. 807 /// 808 /// \returns a register with the requested size, or the current best 809 /// register found during the current query. 810 Register findValueFromTrunc(MachineInstr &MI, unsigned StartBit, 811 unsigned Size) { 812 assert(MI.getOpcode() == TargetOpcode::G_TRUNC); 813 assert(Size > 0); 814 815 Register SrcReg = MI.getOperand(1).getReg(); 816 LLT SrcType = MRI.getType(SrcReg); 817 818 // Currently we don't go into vectors. 819 if (!SrcType.isScalar()) 820 return CurrentBest; 821 822 return findValueFromDefImpl(SrcReg, StartBit, Size); 823 } 824 825 /// Internal implementation for findValueFromDef(). findValueFromDef() 826 /// initializes some data like the CurrentBest register, which this method 827 /// and its callees rely upon. 828 Register findValueFromDefImpl(Register DefReg, unsigned StartBit, 829 unsigned Size) { 830 std::optional<DefinitionAndSourceRegister> DefSrcReg = 831 getDefSrcRegIgnoringCopies(DefReg, MRI); 832 MachineInstr *Def = DefSrcReg->MI; 833 DefReg = DefSrcReg->Reg; 834 // If the instruction has a single def, then simply delegate the search. 835 // For unmerge however with multiple defs, we need to compute the offset 836 // into the source of the unmerge. 837 switch (Def->getOpcode()) { 838 case TargetOpcode::G_CONCAT_VECTORS: 839 return findValueFromConcat(cast<GConcatVectors>(*Def), StartBit, Size); 840 case TargetOpcode::G_UNMERGE_VALUES: { 841 unsigned DefStartBit = 0; 842 unsigned DefSize = MRI.getType(DefReg).getSizeInBits(); 843 for (const auto &MO : Def->defs()) { 844 if (MO.getReg() == DefReg) 845 break; 846 DefStartBit += DefSize; 847 } 848 Register SrcReg = Def->getOperand(Def->getNumOperands() - 1).getReg(); 849 Register SrcOriginReg = 850 findValueFromDefImpl(SrcReg, StartBit + DefStartBit, Size); 851 if (SrcOriginReg) 852 return SrcOriginReg; 853 // Failed to find a further value. If the StartBit and Size perfectly 854 // covered the requested DefReg, return that since it's better than 855 // nothing. 856 if (StartBit == 0 && Size == DefSize) 857 return DefReg; 858 return CurrentBest; 859 } 860 case TargetOpcode::G_BUILD_VECTOR: 861 return findValueFromBuildVector(cast<GBuildVector>(*Def), StartBit, 862 Size); 863 case TargetOpcode::G_INSERT: 864 return findValueFromInsert(*Def, StartBit, Size); 865 case TargetOpcode::G_TRUNC: 866 return findValueFromTrunc(*Def, StartBit, Size); 867 case TargetOpcode::G_SEXT: 868 case TargetOpcode::G_ZEXT: 869 case TargetOpcode::G_ANYEXT: 870 return findValueFromExt(*Def, StartBit, Size); 871 default: 872 return CurrentBest; 873 } 874 } 875 876 public: 877 ArtifactValueFinder(MachineRegisterInfo &Mri, MachineIRBuilder &Builder, 878 const LegalizerInfo &Info) 879 : MRI(Mri), MIB(Builder), LI(Info) {} 880 881 /// Try to find a source of the value defined in the def \p DefReg, starting 882 /// at position \p StartBit with size \p Size. 883 /// \returns a register with the requested size, or an empty Register if no 884 /// better value could be found. 885 Register findValueFromDef(Register DefReg, unsigned StartBit, 886 unsigned Size) { 887 CurrentBest = Register(); 888 Register FoundReg = findValueFromDefImpl(DefReg, StartBit, Size); 889 return FoundReg != DefReg ? FoundReg : Register(); 890 } 891 892 /// Try to combine the defs of an unmerge \p MI by attempting to find 893 /// values that provides the bits for each def reg. 894 /// \returns true if all the defs of the unmerge have been made dead. 895 bool tryCombineUnmergeDefs(GUnmerge &MI, GISelChangeObserver &Observer, 896 SmallVectorImpl<Register> &UpdatedDefs) { 897 unsigned NumDefs = MI.getNumDefs(); 898 LLT DestTy = MRI.getType(MI.getReg(0)); 899 900 SmallBitVector DeadDefs(NumDefs); 901 for (unsigned DefIdx = 0; DefIdx < NumDefs; ++DefIdx) { 902 Register DefReg = MI.getReg(DefIdx); 903 if (MRI.use_nodbg_empty(DefReg)) { 904 DeadDefs[DefIdx] = true; 905 continue; 906 } 907 Register FoundVal = findValueFromDef(DefReg, 0, DestTy.getSizeInBits()); 908 if (!FoundVal) 909 continue; 910 if (MRI.getType(FoundVal) != DestTy) 911 continue; 912 913 replaceRegOrBuildCopy(DefReg, FoundVal, MRI, MIB, UpdatedDefs, 914 Observer); 915 // We only want to replace the uses, not the def of the old reg. 916 Observer.changingInstr(MI); 917 MI.getOperand(DefIdx).setReg(DefReg); 918 Observer.changedInstr(MI); 919 DeadDefs[DefIdx] = true; 920 } 921 return DeadDefs.all(); 922 } 923 924 GUnmerge *findUnmergeThatDefinesReg(Register Reg, unsigned Size, 925 unsigned &DefOperandIdx) { 926 if (Register Def = findValueFromDefImpl(Reg, 0, Size)) { 927 if (auto *Unmerge = dyn_cast<GUnmerge>(MRI.getVRegDef(Def))) { 928 DefOperandIdx = 929 Unmerge->findRegisterDefOperandIdx(Def, /*TRI=*/nullptr); 930 return Unmerge; 931 } 932 } 933 return nullptr; 934 } 935 936 // Check if sequence of elements from merge-like instruction is defined by 937 // another sequence of elements defined by unmerge. Most often this is the 938 // same sequence. Search for elements using findValueFromDefImpl. 939 bool isSequenceFromUnmerge(GMergeLikeInstr &MI, unsigned MergeStartIdx, 940 GUnmerge *Unmerge, unsigned UnmergeIdxStart, 941 unsigned NumElts, unsigned EltSize, 942 bool AllowUndef) { 943 assert(MergeStartIdx + NumElts <= MI.getNumSources()); 944 for (unsigned i = MergeStartIdx; i < MergeStartIdx + NumElts; ++i) { 945 unsigned EltUnmergeIdx; 946 GUnmerge *EltUnmerge = findUnmergeThatDefinesReg( 947 MI.getSourceReg(i), EltSize, EltUnmergeIdx); 948 // Check if source i comes from the same Unmerge. 949 if (EltUnmerge == Unmerge) { 950 // Check that source i's def has same index in sequence in Unmerge. 951 if (i - MergeStartIdx != EltUnmergeIdx - UnmergeIdxStart) 952 return false; 953 } else if (!AllowUndef || 954 MRI.getVRegDef(MI.getSourceReg(i))->getOpcode() != 955 TargetOpcode::G_IMPLICIT_DEF) 956 return false; 957 } 958 return true; 959 } 960 961 bool tryCombineMergeLike(GMergeLikeInstr &MI, 962 SmallVectorImpl<MachineInstr *> &DeadInsts, 963 SmallVectorImpl<Register> &UpdatedDefs, 964 GISelChangeObserver &Observer) { 965 Register Elt0 = MI.getSourceReg(0); 966 LLT EltTy = MRI.getType(Elt0); 967 unsigned EltSize = EltTy.getSizeInBits(); 968 969 unsigned Elt0UnmergeIdx; 970 // Search for unmerge that will be candidate for combine. 971 auto *Unmerge = findUnmergeThatDefinesReg(Elt0, EltSize, Elt0UnmergeIdx); 972 if (!Unmerge) 973 return false; 974 975 unsigned NumMIElts = MI.getNumSources(); 976 Register Dst = MI.getReg(0); 977 LLT DstTy = MRI.getType(Dst); 978 Register UnmergeSrc = Unmerge->getSourceReg(); 979 LLT UnmergeSrcTy = MRI.getType(UnmergeSrc); 980 981 // Recognize copy of UnmergeSrc to Dst. 982 // Unmerge UnmergeSrc and reassemble it using merge-like opcode into Dst. 983 // 984 // %0:_(EltTy), %1, ... = G_UNMERGE_VALUES %UnmergeSrc:_(Ty) 985 // %Dst:_(Ty) = G_merge_like_opcode %0:_(EltTy), %1, ... 986 // 987 // %Dst:_(Ty) = COPY %UnmergeSrc:_(Ty) 988 if ((DstTy == UnmergeSrcTy) && (Elt0UnmergeIdx == 0)) { 989 if (!isSequenceFromUnmerge(MI, 0, Unmerge, 0, NumMIElts, EltSize, 990 /*AllowUndef=*/DstTy.isVector())) 991 return false; 992 993 replaceRegOrBuildCopy(Dst, UnmergeSrc, MRI, MIB, UpdatedDefs, Observer); 994 DeadInsts.push_back(&MI); 995 return true; 996 } 997 998 // Recognize UnmergeSrc that can be unmerged to DstTy directly. 999 // Types have to be either both vector or both non-vector types. 1000 // Merge-like opcodes are combined one at the time. First one creates new 1001 // unmerge, following should use the same unmerge (builder performs CSE). 1002 // 1003 // %0:_(EltTy), %1, %2, %3 = G_UNMERGE_VALUES %UnmergeSrc:_(UnmergeSrcTy) 1004 // %Dst:_(DstTy) = G_merge_like_opcode %0:_(EltTy), %1 1005 // %AnotherDst:_(DstTy) = G_merge_like_opcode %2:_(EltTy), %3 1006 // 1007 // %Dst:_(DstTy), %AnotherDst = G_UNMERGE_VALUES %UnmergeSrc 1008 if ((DstTy.isVector() == UnmergeSrcTy.isVector()) && 1009 (Elt0UnmergeIdx % NumMIElts == 0) && 1010 getCoverTy(UnmergeSrcTy, DstTy) == UnmergeSrcTy) { 1011 if (!isSequenceFromUnmerge(MI, 0, Unmerge, Elt0UnmergeIdx, NumMIElts, 1012 EltSize, false)) 1013 return false; 1014 MIB.setInstrAndDebugLoc(MI); 1015 auto NewUnmerge = MIB.buildUnmerge(DstTy, Unmerge->getSourceReg()); 1016 unsigned DstIdx = (Elt0UnmergeIdx * EltSize) / DstTy.getSizeInBits(); 1017 replaceRegOrBuildCopy(Dst, NewUnmerge.getReg(DstIdx), MRI, MIB, 1018 UpdatedDefs, Observer); 1019 DeadInsts.push_back(&MI); 1020 return true; 1021 } 1022 1023 // Recognize when multiple unmerged sources with UnmergeSrcTy type 1024 // can be merged into Dst with DstTy type directly. 1025 // Types have to be either both vector or both non-vector types. 1026 1027 // %0:_(EltTy), %1 = G_UNMERGE_VALUES %UnmergeSrc:_(UnmergeSrcTy) 1028 // %2:_(EltTy), %3 = G_UNMERGE_VALUES %AnotherUnmergeSrc:_(UnmergeSrcTy) 1029 // %Dst:_(DstTy) = G_merge_like_opcode %0:_(EltTy), %1, %2, %3 1030 // 1031 // %Dst:_(DstTy) = G_merge_like_opcode %UnmergeSrc, %AnotherUnmergeSrc 1032 1033 if ((DstTy.isVector() == UnmergeSrcTy.isVector()) && 1034 getCoverTy(DstTy, UnmergeSrcTy) == DstTy) { 1035 SmallVector<Register, 4> ConcatSources; 1036 unsigned NumElts = Unmerge->getNumDefs(); 1037 for (unsigned i = 0; i < MI.getNumSources(); i += NumElts) { 1038 unsigned EltUnmergeIdx; 1039 auto *UnmergeI = findUnmergeThatDefinesReg(MI.getSourceReg(i), 1040 EltSize, EltUnmergeIdx); 1041 // All unmerges have to be the same size. 1042 if ((!UnmergeI) || (UnmergeI->getNumDefs() != NumElts) || 1043 (EltUnmergeIdx != 0)) 1044 return false; 1045 if (!isSequenceFromUnmerge(MI, i, UnmergeI, 0, NumElts, EltSize, 1046 false)) 1047 return false; 1048 ConcatSources.push_back(UnmergeI->getSourceReg()); 1049 } 1050 1051 MIB.setInstrAndDebugLoc(MI); 1052 MIB.buildMergeLikeInstr(Dst, ConcatSources); 1053 DeadInsts.push_back(&MI); 1054 return true; 1055 } 1056 1057 return false; 1058 } 1059 }; 1060 1061 bool tryCombineUnmergeValues(GUnmerge &MI, 1062 SmallVectorImpl<MachineInstr *> &DeadInsts, 1063 SmallVectorImpl<Register> &UpdatedDefs, 1064 GISelChangeObserver &Observer) { 1065 unsigned NumDefs = MI.getNumDefs(); 1066 Register SrcReg = MI.getSourceReg(); 1067 MachineInstr *SrcDef = getDefIgnoringCopies(SrcReg, MRI); 1068 if (!SrcDef) 1069 return false; 1070 1071 LLT OpTy = MRI.getType(SrcReg); 1072 LLT DestTy = MRI.getType(MI.getReg(0)); 1073 unsigned SrcDefIdx = getDefIndex(*SrcDef, SrcReg); 1074 1075 Builder.setInstrAndDebugLoc(MI); 1076 1077 ArtifactValueFinder Finder(MRI, Builder, LI); 1078 if (Finder.tryCombineUnmergeDefs(MI, Observer, UpdatedDefs)) { 1079 markInstAndDefDead(MI, *SrcDef, DeadInsts, SrcDefIdx); 1080 return true; 1081 } 1082 1083 if (auto *SrcUnmerge = dyn_cast<GUnmerge>(SrcDef)) { 1084 // %0:_(<4 x s16>) = G_FOO 1085 // %1:_(<2 x s16>), %2:_(<2 x s16>) = G_UNMERGE_VALUES %0 1086 // %3:_(s16), %4:_(s16) = G_UNMERGE_VALUES %1 1087 // 1088 // %3:_(s16), %4:_(s16), %5:_(s16), %6:_(s16) = G_UNMERGE_VALUES %0 1089 Register SrcUnmergeSrc = SrcUnmerge->getSourceReg(); 1090 LLT SrcUnmergeSrcTy = MRI.getType(SrcUnmergeSrc); 1091 1092 // If we need to decrease the number of vector elements in the result type 1093 // of an unmerge, this would involve the creation of an equivalent unmerge 1094 // to copy back to the original result registers. 1095 LegalizeActionStep ActionStep = LI.getAction( 1096 {TargetOpcode::G_UNMERGE_VALUES, {OpTy, SrcUnmergeSrcTy}}); 1097 switch (ActionStep.Action) { 1098 case LegalizeActions::Legal: 1099 if (!OpTy.isVector() || !LI.isLegal({TargetOpcode::G_UNMERGE_VALUES, 1100 {DestTy, SrcUnmergeSrcTy}})) 1101 return false; 1102 break; 1103 case LegalizeActions::Lower: 1104 case LegalizeActions::Unsupported: 1105 break; 1106 case LegalizeActions::FewerElements: 1107 case LegalizeActions::NarrowScalar: 1108 if (ActionStep.TypeIdx == 1) 1109 return false; 1110 break; 1111 default: 1112 return false; 1113 } 1114 1115 auto NewUnmerge = Builder.buildUnmerge(DestTy, SrcUnmergeSrc); 1116 1117 // TODO: Should we try to process out the other defs now? If the other 1118 // defs of the source unmerge are also unmerged, we end up with a separate 1119 // unmerge for each one. 1120 for (unsigned I = 0; I != NumDefs; ++I) { 1121 Register Def = MI.getReg(I); 1122 replaceRegOrBuildCopy(Def, NewUnmerge.getReg(SrcDefIdx * NumDefs + I), 1123 MRI, Builder, UpdatedDefs, Observer); 1124 } 1125 1126 markInstAndDefDead(MI, *SrcUnmerge, DeadInsts, SrcDefIdx); 1127 return true; 1128 } 1129 1130 MachineInstr *MergeI = SrcDef; 1131 unsigned ConvertOp = 0; 1132 1133 // Handle intermediate conversions 1134 unsigned SrcOp = SrcDef->getOpcode(); 1135 if (isArtifactCast(SrcOp)) { 1136 ConvertOp = SrcOp; 1137 MergeI = getDefIgnoringCopies(SrcDef->getOperand(1).getReg(), MRI); 1138 } 1139 1140 if (!MergeI || !canFoldMergeOpcode(MergeI->getOpcode(), 1141 ConvertOp, OpTy, DestTy)) { 1142 // We might have a chance to combine later by trying to combine 1143 // unmerge(cast) first 1144 return tryFoldUnmergeCast(MI, *SrcDef, DeadInsts, UpdatedDefs); 1145 } 1146 1147 const unsigned NumMergeRegs = MergeI->getNumOperands() - 1; 1148 1149 if (NumMergeRegs < NumDefs) { 1150 if (NumDefs % NumMergeRegs != 0) 1151 return false; 1152 1153 Builder.setInstr(MI); 1154 // Transform to UNMERGEs, for example 1155 // %1 = G_MERGE_VALUES %4, %5 1156 // %9, %10, %11, %12 = G_UNMERGE_VALUES %1 1157 // to 1158 // %9, %10 = G_UNMERGE_VALUES %4 1159 // %11, %12 = G_UNMERGE_VALUES %5 1160 1161 const unsigned NewNumDefs = NumDefs / NumMergeRegs; 1162 for (unsigned Idx = 0; Idx < NumMergeRegs; ++Idx) { 1163 SmallVector<Register, 8> DstRegs; 1164 for (unsigned j = 0, DefIdx = Idx * NewNumDefs; j < NewNumDefs; 1165 ++j, ++DefIdx) 1166 DstRegs.push_back(MI.getReg(DefIdx)); 1167 1168 if (ConvertOp) { 1169 LLT MergeDstTy = MRI.getType(SrcDef->getOperand(0).getReg()); 1170 1171 // This is a vector that is being split and casted. Extract to the 1172 // element type, and do the conversion on the scalars (or smaller 1173 // vectors). 1174 LLT MergeEltTy = MergeDstTy.divide(NumMergeRegs); 1175 1176 // Handle split to smaller vectors, with conversions. 1177 // %2(<8 x s8>) = G_CONCAT_VECTORS %0(<4 x s8>), %1(<4 x s8>) 1178 // %3(<8 x s16>) = G_SEXT %2 1179 // %4(<2 x s16>), %5(<2 x s16>), %6(<2 x s16>), %7(<2 x s16>) = 1180 // G_UNMERGE_VALUES %3 1181 // 1182 // => 1183 // 1184 // %8(<4 x s16>) = G_SEXT %0 1185 // %9(<4 x s16>) = G_SEXT %1 1186 // %4(<2 x s16>), %5(<2 x s16>) = G_UNMERGE_VALUES %8 1187 // %7(<2 x s16>), %7(<2 x s16>) = G_UNMERGE_VALUES %9 1188 1189 Register TmpReg = MRI.createGenericVirtualRegister(MergeEltTy); 1190 Builder.buildInstr(ConvertOp, {TmpReg}, 1191 {MergeI->getOperand(Idx + 1).getReg()}); 1192 Builder.buildUnmerge(DstRegs, TmpReg); 1193 } else { 1194 Builder.buildUnmerge(DstRegs, MergeI->getOperand(Idx + 1).getReg()); 1195 } 1196 UpdatedDefs.append(DstRegs.begin(), DstRegs.end()); 1197 } 1198 1199 } else if (NumMergeRegs > NumDefs) { 1200 if (ConvertOp != 0 || NumMergeRegs % NumDefs != 0) 1201 return false; 1202 1203 Builder.setInstr(MI); 1204 // Transform to MERGEs 1205 // %6 = G_MERGE_VALUES %17, %18, %19, %20 1206 // %7, %8 = G_UNMERGE_VALUES %6 1207 // to 1208 // %7 = G_MERGE_VALUES %17, %18 1209 // %8 = G_MERGE_VALUES %19, %20 1210 1211 const unsigned NumRegs = NumMergeRegs / NumDefs; 1212 for (unsigned DefIdx = 0; DefIdx < NumDefs; ++DefIdx) { 1213 SmallVector<Register, 8> Regs; 1214 for (unsigned j = 0, Idx = NumRegs * DefIdx + 1; j < NumRegs; 1215 ++j, ++Idx) 1216 Regs.push_back(MergeI->getOperand(Idx).getReg()); 1217 1218 Register DefReg = MI.getReg(DefIdx); 1219 Builder.buildMergeLikeInstr(DefReg, Regs); 1220 UpdatedDefs.push_back(DefReg); 1221 } 1222 1223 } else { 1224 LLT MergeSrcTy = MRI.getType(MergeI->getOperand(1).getReg()); 1225 1226 if (!ConvertOp && DestTy != MergeSrcTy) { 1227 if (DestTy.isPointer()) 1228 ConvertOp = TargetOpcode::G_INTTOPTR; 1229 else if (MergeSrcTy.isPointer()) 1230 ConvertOp = TargetOpcode::G_PTRTOINT; 1231 else 1232 ConvertOp = TargetOpcode::G_BITCAST; 1233 } 1234 1235 if (ConvertOp) { 1236 Builder.setInstr(MI); 1237 1238 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) { 1239 Register DefReg = MI.getOperand(Idx).getReg(); 1240 Register MergeSrc = MergeI->getOperand(Idx + 1).getReg(); 1241 1242 if (!MRI.use_empty(DefReg)) { 1243 Builder.buildInstr(ConvertOp, {DefReg}, {MergeSrc}); 1244 UpdatedDefs.push_back(DefReg); 1245 } 1246 } 1247 1248 markInstAndDefDead(MI, *MergeI, DeadInsts); 1249 return true; 1250 } 1251 1252 assert(DestTy == MergeSrcTy && 1253 "Bitcast and the other kinds of conversions should " 1254 "have happened earlier"); 1255 1256 Builder.setInstr(MI); 1257 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) { 1258 Register DstReg = MI.getOperand(Idx).getReg(); 1259 Register SrcReg = MergeI->getOperand(Idx + 1).getReg(); 1260 replaceRegOrBuildCopy(DstReg, SrcReg, MRI, Builder, UpdatedDefs, 1261 Observer); 1262 } 1263 } 1264 1265 markInstAndDefDead(MI, *MergeI, DeadInsts); 1266 return true; 1267 } 1268 1269 bool tryCombineExtract(MachineInstr &MI, 1270 SmallVectorImpl<MachineInstr *> &DeadInsts, 1271 SmallVectorImpl<Register> &UpdatedDefs) { 1272 assert(MI.getOpcode() == TargetOpcode::G_EXTRACT); 1273 1274 // Try to use the source registers from a G_MERGE_VALUES 1275 // 1276 // %2 = G_MERGE_VALUES %0, %1 1277 // %3 = G_EXTRACT %2, N 1278 // => 1279 // 1280 // for N < %2.getSizeInBits() / 2 1281 // %3 = G_EXTRACT %0, N 1282 // 1283 // for N >= %2.getSizeInBits() / 2 1284 // %3 = G_EXTRACT %1, (N - %0.getSizeInBits() 1285 1286 Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); 1287 MachineInstr *MergeI = MRI.getVRegDef(SrcReg); 1288 if (!MergeI || !isa<GMergeLikeInstr>(MergeI)) 1289 return false; 1290 1291 Register DstReg = MI.getOperand(0).getReg(); 1292 LLT DstTy = MRI.getType(DstReg); 1293 LLT SrcTy = MRI.getType(SrcReg); 1294 1295 // TODO: Do we need to check if the resulting extract is supported? 1296 unsigned ExtractDstSize = DstTy.getSizeInBits(); 1297 unsigned Offset = MI.getOperand(2).getImm(); 1298 unsigned NumMergeSrcs = MergeI->getNumOperands() - 1; 1299 unsigned MergeSrcSize = SrcTy.getSizeInBits() / NumMergeSrcs; 1300 unsigned MergeSrcIdx = Offset / MergeSrcSize; 1301 1302 // Compute the offset of the last bit the extract needs. 1303 unsigned EndMergeSrcIdx = (Offset + ExtractDstSize - 1) / MergeSrcSize; 1304 1305 // Can't handle the case where the extract spans multiple inputs. 1306 if (MergeSrcIdx != EndMergeSrcIdx) 1307 return false; 1308 1309 // TODO: We could modify MI in place in most cases. 1310 Builder.setInstr(MI); 1311 Builder.buildExtract(DstReg, MergeI->getOperand(MergeSrcIdx + 1).getReg(), 1312 Offset - MergeSrcIdx * MergeSrcSize); 1313 UpdatedDefs.push_back(DstReg); 1314 markInstAndDefDead(MI, *MergeI, DeadInsts); 1315 return true; 1316 } 1317 1318 /// Try to combine away MI. 1319 /// Returns true if it combined away the MI. 1320 /// Adds instructions that are dead as a result of the combine 1321 /// into DeadInsts, which can include MI. 1322 bool tryCombineInstruction(MachineInstr &MI, 1323 SmallVectorImpl<MachineInstr *> &DeadInsts, 1324 GISelObserverWrapper &WrapperObserver) { 1325 ArtifactValueFinder Finder(MRI, Builder, LI); 1326 1327 // This might be a recursive call, and we might have DeadInsts already 1328 // populated. To avoid bad things happening later with multiple vreg defs 1329 // etc, process the dead instructions now if any. 1330 if (!DeadInsts.empty()) 1331 deleteMarkedDeadInsts(DeadInsts, WrapperObserver); 1332 1333 // Put here every vreg that was redefined in such a way that it's at least 1334 // possible that one (or more) of its users (immediate or COPY-separated) 1335 // could become artifact combinable with the new definition (or the 1336 // instruction reachable from it through a chain of copies if any). 1337 SmallVector<Register, 4> UpdatedDefs; 1338 bool Changed = false; 1339 switch (MI.getOpcode()) { 1340 default: 1341 return false; 1342 case TargetOpcode::G_ANYEXT: 1343 Changed = tryCombineAnyExt(MI, DeadInsts, UpdatedDefs, WrapperObserver); 1344 break; 1345 case TargetOpcode::G_ZEXT: 1346 Changed = tryCombineZExt(MI, DeadInsts, UpdatedDefs, WrapperObserver); 1347 break; 1348 case TargetOpcode::G_SEXT: 1349 Changed = tryCombineSExt(MI, DeadInsts, UpdatedDefs, WrapperObserver); 1350 break; 1351 case TargetOpcode::G_UNMERGE_VALUES: 1352 Changed = tryCombineUnmergeValues(cast<GUnmerge>(MI), DeadInsts, 1353 UpdatedDefs, WrapperObserver); 1354 break; 1355 case TargetOpcode::G_MERGE_VALUES: 1356 case TargetOpcode::G_BUILD_VECTOR: 1357 case TargetOpcode::G_CONCAT_VECTORS: 1358 // If any of the users of this merge are an unmerge, then add them to the 1359 // artifact worklist in case there's folding that can be done looking up. 1360 for (MachineInstr &U : MRI.use_instructions(MI.getOperand(0).getReg())) { 1361 if (U.getOpcode() == TargetOpcode::G_UNMERGE_VALUES || 1362 U.getOpcode() == TargetOpcode::G_TRUNC) { 1363 UpdatedDefs.push_back(MI.getOperand(0).getReg()); 1364 break; 1365 } 1366 } 1367 Changed = Finder.tryCombineMergeLike(cast<GMergeLikeInstr>(MI), DeadInsts, 1368 UpdatedDefs, WrapperObserver); 1369 break; 1370 case TargetOpcode::G_EXTRACT: 1371 Changed = tryCombineExtract(MI, DeadInsts, UpdatedDefs); 1372 break; 1373 case TargetOpcode::G_TRUNC: 1374 Changed = tryCombineTrunc(MI, DeadInsts, UpdatedDefs, WrapperObserver); 1375 if (!Changed) { 1376 // Try to combine truncates away even if they are legal. As all artifact 1377 // combines at the moment look only "up" the def-use chains, we achieve 1378 // that by throwing truncates' users (with look through copies) into the 1379 // ArtifactList again. 1380 UpdatedDefs.push_back(MI.getOperand(0).getReg()); 1381 } 1382 break; 1383 } 1384 // If the main loop through the ArtifactList found at least one combinable 1385 // pair of artifacts, not only combine it away (as done above), but also 1386 // follow the def-use chain from there to combine everything that can be 1387 // combined within this def-use chain of artifacts. 1388 while (!UpdatedDefs.empty()) { 1389 Register NewDef = UpdatedDefs.pop_back_val(); 1390 assert(NewDef.isVirtual() && "Unexpected redefinition of a physreg"); 1391 for (MachineInstr &Use : MRI.use_instructions(NewDef)) { 1392 switch (Use.getOpcode()) { 1393 // Keep this list in sync with the list of all artifact combines. 1394 case TargetOpcode::G_ANYEXT: 1395 case TargetOpcode::G_ZEXT: 1396 case TargetOpcode::G_SEXT: 1397 case TargetOpcode::G_UNMERGE_VALUES: 1398 case TargetOpcode::G_EXTRACT: 1399 case TargetOpcode::G_TRUNC: 1400 case TargetOpcode::G_BUILD_VECTOR: 1401 // Adding Use to ArtifactList. 1402 WrapperObserver.changedInstr(Use); 1403 break; 1404 case TargetOpcode::G_ASSERT_SEXT: 1405 case TargetOpcode::G_ASSERT_ZEXT: 1406 case TargetOpcode::G_ASSERT_ALIGN: 1407 case TargetOpcode::COPY: { 1408 Register Copy = Use.getOperand(0).getReg(); 1409 if (Copy.isVirtual()) 1410 UpdatedDefs.push_back(Copy); 1411 break; 1412 } 1413 default: 1414 // If we do not have an artifact combine for the opcode, there is no 1415 // point in adding it to the ArtifactList as nothing interesting will 1416 // be done to it anyway. 1417 break; 1418 } 1419 } 1420 } 1421 return Changed; 1422 } 1423 1424 private: 1425 static Register getArtifactSrcReg(const MachineInstr &MI) { 1426 switch (MI.getOpcode()) { 1427 case TargetOpcode::COPY: 1428 case TargetOpcode::G_TRUNC: 1429 case TargetOpcode::G_ZEXT: 1430 case TargetOpcode::G_ANYEXT: 1431 case TargetOpcode::G_SEXT: 1432 case TargetOpcode::G_EXTRACT: 1433 case TargetOpcode::G_ASSERT_SEXT: 1434 case TargetOpcode::G_ASSERT_ZEXT: 1435 case TargetOpcode::G_ASSERT_ALIGN: 1436 return MI.getOperand(1).getReg(); 1437 case TargetOpcode::G_UNMERGE_VALUES: 1438 return MI.getOperand(MI.getNumOperands() - 1).getReg(); 1439 default: 1440 llvm_unreachable("Not a legalization artifact happen"); 1441 } 1442 } 1443 1444 /// Mark a def of one of MI's original operands, DefMI, as dead if changing MI 1445 /// (either by killing it or changing operands) results in DefMI being dead 1446 /// too. In-between COPYs or artifact-casts are also collected if they are 1447 /// dead. 1448 /// MI is not marked dead. 1449 void markDefDead(MachineInstr &MI, MachineInstr &DefMI, 1450 SmallVectorImpl<MachineInstr *> &DeadInsts, 1451 unsigned DefIdx = 0) { 1452 // Collect all the copy instructions that are made dead, due to deleting 1453 // this instruction. Collect all of them until the Trunc(DefMI). 1454 // Eg, 1455 // %1(s1) = G_TRUNC %0(s32) 1456 // %2(s1) = COPY %1(s1) 1457 // %3(s1) = COPY %2(s1) 1458 // %4(s32) = G_ANYEXT %3(s1) 1459 // In this case, we would have replaced %4 with a copy of %0, 1460 // and as a result, %3, %2, %1 are dead. 1461 MachineInstr *PrevMI = &MI; 1462 while (PrevMI != &DefMI) { 1463 Register PrevRegSrc = getArtifactSrcReg(*PrevMI); 1464 1465 MachineInstr *TmpDef = MRI.getVRegDef(PrevRegSrc); 1466 if (MRI.hasOneUse(PrevRegSrc)) { 1467 if (TmpDef != &DefMI) { 1468 assert((TmpDef->getOpcode() == TargetOpcode::COPY || 1469 isArtifactCast(TmpDef->getOpcode()) || 1470 isPreISelGenericOptimizationHint(TmpDef->getOpcode())) && 1471 "Expecting copy or artifact cast here"); 1472 1473 DeadInsts.push_back(TmpDef); 1474 } 1475 } else 1476 break; 1477 PrevMI = TmpDef; 1478 } 1479 1480 if (PrevMI == &DefMI) { 1481 unsigned I = 0; 1482 bool IsDead = true; 1483 for (MachineOperand &Def : DefMI.defs()) { 1484 if (I != DefIdx) { 1485 if (!MRI.use_empty(Def.getReg())) { 1486 IsDead = false; 1487 break; 1488 } 1489 } else { 1490 if (!MRI.hasOneUse(DefMI.getOperand(DefIdx).getReg())) 1491 break; 1492 } 1493 1494 ++I; 1495 } 1496 1497 if (IsDead) 1498 DeadInsts.push_back(&DefMI); 1499 } 1500 } 1501 1502 /// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be 1503 /// dead due to MI being killed, then mark DefMI as dead too. 1504 /// Some of the combines (extends(trunc)), try to walk through redundant 1505 /// copies in between the extends and the truncs, and this attempts to collect 1506 /// the in between copies if they're dead. 1507 void markInstAndDefDead(MachineInstr &MI, MachineInstr &DefMI, 1508 SmallVectorImpl<MachineInstr *> &DeadInsts, 1509 unsigned DefIdx = 0) { 1510 DeadInsts.push_back(&MI); 1511 markDefDead(MI, DefMI, DeadInsts, DefIdx); 1512 } 1513 1514 /// Erase the dead instructions in the list and call the observer hooks. 1515 /// Normally the Legalizer will deal with erasing instructions that have been 1516 /// marked dead. However, for the trunc(ext(x)) cases we can end up trying to 1517 /// process instructions which have been marked dead, but otherwise break the 1518 /// MIR by introducing multiple vreg defs. For those cases, allow the combines 1519 /// to explicitly delete the instructions before we run into trouble. 1520 void deleteMarkedDeadInsts(SmallVectorImpl<MachineInstr *> &DeadInsts, 1521 GISelObserverWrapper &WrapperObserver) { 1522 for (auto *DeadMI : DeadInsts) { 1523 LLVM_DEBUG(dbgs() << *DeadMI << "Is dead, eagerly deleting\n"); 1524 WrapperObserver.erasingInstr(*DeadMI); 1525 DeadMI->eraseFromParent(); 1526 } 1527 DeadInsts.clear(); 1528 } 1529 1530 /// Checks if the target legalizer info has specified anything about the 1531 /// instruction, or if unsupported. 1532 bool isInstUnsupported(const LegalityQuery &Query) const { 1533 using namespace LegalizeActions; 1534 auto Step = LI.getAction(Query); 1535 return Step.Action == Unsupported || Step.Action == NotFound; 1536 } 1537 1538 bool isInstLegal(const LegalityQuery &Query) const { 1539 return LI.getAction(Query).Action == LegalizeActions::Legal; 1540 } 1541 1542 bool isConstantUnsupported(LLT Ty) const { 1543 if (!Ty.isVector()) 1544 return isInstUnsupported({TargetOpcode::G_CONSTANT, {Ty}}); 1545 1546 LLT EltTy = Ty.getElementType(); 1547 return isInstUnsupported({TargetOpcode::G_CONSTANT, {EltTy}}) || 1548 isInstUnsupported({TargetOpcode::G_BUILD_VECTOR, {Ty, EltTy}}); 1549 } 1550 1551 /// Looks through copy instructions and returns the actual 1552 /// source register. 1553 Register lookThroughCopyInstrs(Register Reg) { 1554 Register TmpReg = getSrcRegIgnoringCopies(Reg, MRI); 1555 return TmpReg.isValid() ? TmpReg : Reg; 1556 } 1557 }; 1558 1559 } // namespace llvm 1560 1561 #endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZATIONARTIFACTCOMBINER_H 1562