1 //===- X86InstructionSelector.cpp -----------------------------------------===// 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 /// X86. 12 /// \todo This should be generated by TableGen. 13 //===----------------------------------------------------------------------===// 14 15 #include "MCTargetDesc/X86BaseInfo.h" 16 #include "X86InstrBuilder.h" 17 #include "X86InstrInfo.h" 18 #include "X86RegisterBankInfo.h" 19 #include "X86RegisterInfo.h" 20 #include "X86Subtarget.h" 21 #include "X86TargetMachine.h" 22 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 23 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" 24 #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 25 #include "llvm/CodeGen/GlobalISel/Utils.h" 26 #include "llvm/CodeGen/MachineBasicBlock.h" 27 #include "llvm/CodeGen/MachineConstantPool.h" 28 #include "llvm/CodeGen/MachineFunction.h" 29 #include "llvm/CodeGen/MachineInstr.h" 30 #include "llvm/CodeGen/MachineInstrBuilder.h" 31 #include "llvm/CodeGen/MachineMemOperand.h" 32 #include "llvm/CodeGen/MachineOperand.h" 33 #include "llvm/CodeGen/MachineRegisterInfo.h" 34 #include "llvm/CodeGen/TargetOpcodes.h" 35 #include "llvm/CodeGen/TargetRegisterInfo.h" 36 #include "llvm/IR/DataLayout.h" 37 #include "llvm/IR/InstrTypes.h" 38 #include "llvm/Support/AtomicOrdering.h" 39 #include "llvm/Support/CodeGen.h" 40 #include "llvm/Support/Debug.h" 41 #include "llvm/Support/ErrorHandling.h" 42 #include "llvm/Support/LowLevelTypeImpl.h" 43 #include "llvm/Support/MathExtras.h" 44 #include "llvm/Support/raw_ostream.h" 45 #include <cassert> 46 #include <cstdint> 47 #include <tuple> 48 49 #define DEBUG_TYPE "X86-isel" 50 51 using namespace llvm; 52 53 namespace { 54 55 #define GET_GLOBALISEL_PREDICATE_BITSET 56 #include "X86GenGlobalISel.inc" 57 #undef GET_GLOBALISEL_PREDICATE_BITSET 58 59 class X86InstructionSelector : public InstructionSelector { 60 public: 61 X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI, 62 const X86RegisterBankInfo &RBI); 63 64 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override; 65 static const char *getName() { return DEBUG_TYPE; } 66 67 private: 68 /// tblgen-erated 'select' implementation, used as the initial selector for 69 /// the patterns that don't require complex C++. 70 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; 71 72 // TODO: remove after supported by Tablegen-erated instruction selection. 73 unsigned getLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc, 74 uint64_t Alignment) const; 75 76 bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI, 77 MachineFunction &MF) const; 78 bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI, 79 MachineFunction &MF) const; 80 bool selectGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI, 81 MachineFunction &MF) const; 82 bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI, 83 MachineFunction &MF) const; 84 bool selectTruncOrPtrToInt(MachineInstr &I, MachineRegisterInfo &MRI, 85 MachineFunction &MF) const; 86 bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI, 87 MachineFunction &MF) const; 88 bool selectAnyext(MachineInstr &I, MachineRegisterInfo &MRI, 89 MachineFunction &MF) const; 90 bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI, 91 MachineFunction &MF) const; 92 bool selectUadde(MachineInstr &I, MachineRegisterInfo &MRI, 93 MachineFunction &MF) const; 94 bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const; 95 bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI, 96 MachineFunction &MF, 97 CodeGenCoverage &CoverageInfo) const; 98 bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI, 99 MachineFunction &MF, 100 CodeGenCoverage &CoverageInfo) const; 101 bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI, 102 MachineFunction &MF) const; 103 bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI, 104 MachineFunction &MF) const; 105 bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI, 106 MachineFunction &MF) const; 107 bool selectTurnIntoCOPY(MachineInstr &I, MachineRegisterInfo &MRI, 108 const unsigned DstReg, 109 const TargetRegisterClass *DstRC, 110 const unsigned SrcReg, 111 const TargetRegisterClass *SrcRC) const; 112 bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI, 113 MachineFunction &MF) const; 114 bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const; 115 bool selectShift(MachineInstr &I, MachineRegisterInfo &MRI, 116 MachineFunction &MF) const; 117 bool selectSDiv(MachineInstr &I, MachineRegisterInfo &MRI, 118 MachineFunction &MF) const; 119 120 // emit insert subreg instruction and insert it before MachineInstr &I 121 bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I, 122 MachineRegisterInfo &MRI, MachineFunction &MF) const; 123 // emit extract subreg instruction and insert it before MachineInstr &I 124 bool emitExtractSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I, 125 MachineRegisterInfo &MRI, MachineFunction &MF) const; 126 127 const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const; 128 const TargetRegisterClass *getRegClass(LLT Ty, unsigned Reg, 129 MachineRegisterInfo &MRI) const; 130 131 const X86TargetMachine &TM; 132 const X86Subtarget &STI; 133 const X86InstrInfo &TII; 134 const X86RegisterInfo &TRI; 135 const X86RegisterBankInfo &RBI; 136 137 #define GET_GLOBALISEL_PREDICATES_DECL 138 #include "X86GenGlobalISel.inc" 139 #undef GET_GLOBALISEL_PREDICATES_DECL 140 141 #define GET_GLOBALISEL_TEMPORARIES_DECL 142 #include "X86GenGlobalISel.inc" 143 #undef GET_GLOBALISEL_TEMPORARIES_DECL 144 }; 145 146 } // end anonymous namespace 147 148 #define GET_GLOBALISEL_IMPL 149 #include "X86GenGlobalISel.inc" 150 #undef GET_GLOBALISEL_IMPL 151 152 X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM, 153 const X86Subtarget &STI, 154 const X86RegisterBankInfo &RBI) 155 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), 156 TRI(*STI.getRegisterInfo()), RBI(RBI), 157 #define GET_GLOBALISEL_PREDICATES_INIT 158 #include "X86GenGlobalISel.inc" 159 #undef GET_GLOBALISEL_PREDICATES_INIT 160 #define GET_GLOBALISEL_TEMPORARIES_INIT 161 #include "X86GenGlobalISel.inc" 162 #undef GET_GLOBALISEL_TEMPORARIES_INIT 163 { 164 } 165 166 // FIXME: This should be target-independent, inferred from the types declared 167 // for each class in the bank. 168 const TargetRegisterClass * 169 X86InstructionSelector::getRegClass(LLT Ty, const RegisterBank &RB) const { 170 if (RB.getID() == X86::GPRRegBankID) { 171 if (Ty.getSizeInBits() <= 8) 172 return &X86::GR8RegClass; 173 if (Ty.getSizeInBits() == 16) 174 return &X86::GR16RegClass; 175 if (Ty.getSizeInBits() == 32) 176 return &X86::GR32RegClass; 177 if (Ty.getSizeInBits() == 64) 178 return &X86::GR64RegClass; 179 } 180 if (RB.getID() == X86::VECRRegBankID) { 181 if (Ty.getSizeInBits() == 32) 182 return STI.hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass; 183 if (Ty.getSizeInBits() == 64) 184 return STI.hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass; 185 if (Ty.getSizeInBits() == 128) 186 return STI.hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass; 187 if (Ty.getSizeInBits() == 256) 188 return STI.hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass; 189 if (Ty.getSizeInBits() == 512) 190 return &X86::VR512RegClass; 191 } 192 193 llvm_unreachable("Unknown RegBank!"); 194 } 195 196 const TargetRegisterClass * 197 X86InstructionSelector::getRegClass(LLT Ty, unsigned Reg, 198 MachineRegisterInfo &MRI) const { 199 const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI); 200 return getRegClass(Ty, RegBank); 201 } 202 203 static unsigned getSubRegIndex(const TargetRegisterClass *RC) { 204 unsigned SubIdx = X86::NoSubRegister; 205 if (RC == &X86::GR32RegClass) { 206 SubIdx = X86::sub_32bit; 207 } else if (RC == &X86::GR16RegClass) { 208 SubIdx = X86::sub_16bit; 209 } else if (RC == &X86::GR8RegClass) { 210 SubIdx = X86::sub_8bit; 211 } 212 213 return SubIdx; 214 } 215 216 static const TargetRegisterClass *getRegClassFromGRPhysReg(unsigned Reg) { 217 assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 218 if (X86::GR64RegClass.contains(Reg)) 219 return &X86::GR64RegClass; 220 if (X86::GR32RegClass.contains(Reg)) 221 return &X86::GR32RegClass; 222 if (X86::GR16RegClass.contains(Reg)) 223 return &X86::GR16RegClass; 224 if (X86::GR8RegClass.contains(Reg)) 225 return &X86::GR8RegClass; 226 227 llvm_unreachable("Unknown RegClass for PhysReg!"); 228 } 229 230 // Set X86 Opcode and constrain DestReg. 231 bool X86InstructionSelector::selectCopy(MachineInstr &I, 232 MachineRegisterInfo &MRI) const { 233 unsigned DstReg = I.getOperand(0).getReg(); 234 const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI); 235 const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI); 236 237 unsigned SrcReg = I.getOperand(1).getReg(); 238 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI); 239 const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI); 240 241 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) { 242 assert(I.isCopy() && "Generic operators do not allow physical registers"); 243 244 if (DstSize > SrcSize && SrcRegBank.getID() == X86::GPRRegBankID && 245 DstRegBank.getID() == X86::GPRRegBankID) { 246 247 const TargetRegisterClass *SrcRC = 248 getRegClass(MRI.getType(SrcReg), SrcRegBank); 249 const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg); 250 251 if (SrcRC != DstRC) { 252 // This case can be generated by ABI lowering, performe anyext 253 unsigned ExtSrc = MRI.createVirtualRegister(DstRC); 254 BuildMI(*I.getParent(), I, I.getDebugLoc(), 255 TII.get(TargetOpcode::SUBREG_TO_REG)) 256 .addDef(ExtSrc) 257 .addImm(0) 258 .addReg(SrcReg) 259 .addImm(getSubRegIndex(SrcRC)); 260 261 I.getOperand(1).setReg(ExtSrc); 262 } 263 } 264 265 return true; 266 } 267 268 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) && 269 "No phys reg on generic operators"); 270 assert((DstSize == SrcSize || 271 // Copies are a mean to setup initial types, the number of 272 // bits may not exactly match. 273 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && 274 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) && 275 "Copy with different width?!"); 276 277 const TargetRegisterClass *DstRC = 278 getRegClass(MRI.getType(DstReg), DstRegBank); 279 280 if (SrcRegBank.getID() == X86::GPRRegBankID && 281 DstRegBank.getID() == X86::GPRRegBankID && SrcSize > DstSize && 282 TargetRegisterInfo::isPhysicalRegister(SrcReg)) { 283 // Change the physical register to performe truncate. 284 285 const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg); 286 287 if (DstRC != SrcRC) { 288 I.getOperand(1).setSubReg(getSubRegIndex(DstRC)); 289 I.getOperand(1).substPhysReg(SrcReg, TRI); 290 } 291 } 292 293 // No need to constrain SrcReg. It will get constrained when 294 // we hit another of its use or its defs. 295 // Copies do not have constraints. 296 const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg); 297 if (!OldRC || !DstRC->hasSubClassEq(OldRC)) { 298 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { 299 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 300 << " operand\n"); 301 return false; 302 } 303 } 304 I.setDesc(TII.get(X86::COPY)); 305 return true; 306 } 307 308 bool X86InstructionSelector::select(MachineInstr &I, 309 CodeGenCoverage &CoverageInfo) const { 310 assert(I.getParent() && "Instruction should be in a basic block!"); 311 assert(I.getParent()->getParent() && "Instruction should be in a function!"); 312 313 MachineBasicBlock &MBB = *I.getParent(); 314 MachineFunction &MF = *MBB.getParent(); 315 MachineRegisterInfo &MRI = MF.getRegInfo(); 316 317 unsigned Opcode = I.getOpcode(); 318 if (!isPreISelGenericOpcode(Opcode)) { 319 // Certain non-generic instructions also need some special handling. 320 321 if (Opcode == TargetOpcode::LOAD_STACK_GUARD) 322 return false; 323 324 if (I.isCopy()) 325 return selectCopy(I, MRI); 326 327 return true; 328 } 329 330 assert(I.getNumOperands() == I.getNumExplicitOperands() && 331 "Generic instruction has unexpected implicit operands\n"); 332 333 if (selectImpl(I, CoverageInfo)) 334 return true; 335 336 LLVM_DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs())); 337 338 // TODO: This should be implemented by tblgen. 339 switch (I.getOpcode()) { 340 default: 341 return false; 342 case TargetOpcode::G_STORE: 343 case TargetOpcode::G_LOAD: 344 return selectLoadStoreOp(I, MRI, MF); 345 case TargetOpcode::G_GEP: 346 case TargetOpcode::G_FRAME_INDEX: 347 return selectFrameIndexOrGep(I, MRI, MF); 348 case TargetOpcode::G_GLOBAL_VALUE: 349 return selectGlobalValue(I, MRI, MF); 350 case TargetOpcode::G_CONSTANT: 351 return selectConstant(I, MRI, MF); 352 case TargetOpcode::G_FCONSTANT: 353 return materializeFP(I, MRI, MF); 354 case TargetOpcode::G_PTRTOINT: 355 case TargetOpcode::G_TRUNC: 356 return selectTruncOrPtrToInt(I, MRI, MF); 357 case TargetOpcode::G_INTTOPTR: 358 return selectCopy(I, MRI); 359 case TargetOpcode::G_ZEXT: 360 return selectZext(I, MRI, MF); 361 case TargetOpcode::G_ANYEXT: 362 return selectAnyext(I, MRI, MF); 363 case TargetOpcode::G_ICMP: 364 return selectCmp(I, MRI, MF); 365 case TargetOpcode::G_UADDE: 366 return selectUadde(I, MRI, MF); 367 case TargetOpcode::G_UNMERGE_VALUES: 368 return selectUnmergeValues(I, MRI, MF, CoverageInfo); 369 case TargetOpcode::G_MERGE_VALUES: 370 return selectMergeValues(I, MRI, MF, CoverageInfo); 371 case TargetOpcode::G_EXTRACT: 372 return selectExtract(I, MRI, MF); 373 case TargetOpcode::G_INSERT: 374 return selectInsert(I, MRI, MF); 375 case TargetOpcode::G_BRCOND: 376 return selectCondBranch(I, MRI, MF); 377 case TargetOpcode::G_IMPLICIT_DEF: 378 case TargetOpcode::G_PHI: 379 return selectImplicitDefOrPHI(I, MRI); 380 case TargetOpcode::G_SHL: 381 case TargetOpcode::G_ASHR: 382 case TargetOpcode::G_LSHR: 383 return selectShift(I, MRI, MF); 384 case TargetOpcode::G_SDIV: 385 return selectSDiv(I, MRI, MF); 386 } 387 388 return false; 389 } 390 391 unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty, 392 const RegisterBank &RB, 393 unsigned Opc, 394 uint64_t Alignment) const { 395 bool Isload = (Opc == TargetOpcode::G_LOAD); 396 bool HasAVX = STI.hasAVX(); 397 bool HasAVX512 = STI.hasAVX512(); 398 bool HasVLX = STI.hasVLX(); 399 400 if (Ty == LLT::scalar(8)) { 401 if (X86::GPRRegBankID == RB.getID()) 402 return Isload ? X86::MOV8rm : X86::MOV8mr; 403 } else if (Ty == LLT::scalar(16)) { 404 if (X86::GPRRegBankID == RB.getID()) 405 return Isload ? X86::MOV16rm : X86::MOV16mr; 406 } else if (Ty == LLT::scalar(32) || Ty == LLT::pointer(0, 32)) { 407 if (X86::GPRRegBankID == RB.getID()) 408 return Isload ? X86::MOV32rm : X86::MOV32mr; 409 if (X86::VECRRegBankID == RB.getID()) 410 return Isload ? (HasAVX512 ? X86::VMOVSSZrm 411 : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm) 412 : (HasAVX512 ? X86::VMOVSSZmr 413 : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr); 414 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) { 415 if (X86::GPRRegBankID == RB.getID()) 416 return Isload ? X86::MOV64rm : X86::MOV64mr; 417 if (X86::VECRRegBankID == RB.getID()) 418 return Isload ? (HasAVX512 ? X86::VMOVSDZrm 419 : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm) 420 : (HasAVX512 ? X86::VMOVSDZmr 421 : HasAVX ? X86::VMOVSDmr : X86::MOVSDmr); 422 } else if (Ty.isVector() && Ty.getSizeInBits() == 128) { 423 if (Alignment >= 16) 424 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm 425 : HasAVX512 426 ? X86::VMOVAPSZ128rm_NOVLX 427 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm) 428 : (HasVLX ? X86::VMOVAPSZ128mr 429 : HasAVX512 430 ? X86::VMOVAPSZ128mr_NOVLX 431 : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr); 432 else 433 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm 434 : HasAVX512 435 ? X86::VMOVUPSZ128rm_NOVLX 436 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm) 437 : (HasVLX ? X86::VMOVUPSZ128mr 438 : HasAVX512 439 ? X86::VMOVUPSZ128mr_NOVLX 440 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr); 441 } else if (Ty.isVector() && Ty.getSizeInBits() == 256) { 442 if (Alignment >= 32) 443 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm 444 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX 445 : X86::VMOVAPSYrm) 446 : (HasVLX ? X86::VMOVAPSZ256mr 447 : HasAVX512 ? X86::VMOVAPSZ256mr_NOVLX 448 : X86::VMOVAPSYmr); 449 else 450 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm 451 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX 452 : X86::VMOVUPSYrm) 453 : (HasVLX ? X86::VMOVUPSZ256mr 454 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX 455 : X86::VMOVUPSYmr); 456 } else if (Ty.isVector() && Ty.getSizeInBits() == 512) { 457 if (Alignment >= 64) 458 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr; 459 else 460 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr; 461 } 462 return Opc; 463 } 464 465 // Fill in an address from the given instruction. 466 static void X86SelectAddress(const MachineInstr &I, 467 const MachineRegisterInfo &MRI, 468 X86AddressMode &AM) { 469 assert(I.getOperand(0).isReg() && "unsupported opperand."); 470 assert(MRI.getType(I.getOperand(0).getReg()).isPointer() && 471 "unsupported type."); 472 473 if (I.getOpcode() == TargetOpcode::G_GEP) { 474 if (auto COff = getConstantVRegVal(I.getOperand(2).getReg(), MRI)) { 475 int64_t Imm = *COff; 476 if (isInt<32>(Imm)) { // Check for displacement overflow. 477 AM.Disp = static_cast<int32_t>(Imm); 478 AM.Base.Reg = I.getOperand(1).getReg(); 479 return; 480 } 481 } 482 } else if (I.getOpcode() == TargetOpcode::G_FRAME_INDEX) { 483 AM.Base.FrameIndex = I.getOperand(1).getIndex(); 484 AM.BaseType = X86AddressMode::FrameIndexBase; 485 return; 486 } 487 488 // Default behavior. 489 AM.Base.Reg = I.getOperand(0).getReg(); 490 } 491 492 bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I, 493 MachineRegisterInfo &MRI, 494 MachineFunction &MF) const { 495 unsigned Opc = I.getOpcode(); 496 497 assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) && 498 "unexpected instruction"); 499 500 const unsigned DefReg = I.getOperand(0).getReg(); 501 LLT Ty = MRI.getType(DefReg); 502 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); 503 504 auto &MemOp = **I.memoperands_begin(); 505 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { 506 LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n"); 507 return false; 508 } 509 510 unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment()); 511 if (NewOpc == Opc) 512 return false; 513 514 X86AddressMode AM; 515 X86SelectAddress(*MRI.getVRegDef(I.getOperand(1).getReg()), MRI, AM); 516 517 I.setDesc(TII.get(NewOpc)); 518 MachineInstrBuilder MIB(MF, I); 519 if (Opc == TargetOpcode::G_LOAD) { 520 I.RemoveOperand(1); 521 addFullAddress(MIB, AM); 522 } else { 523 // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL) 524 I.RemoveOperand(1); 525 I.RemoveOperand(0); 526 addFullAddress(MIB, AM).addUse(DefReg); 527 } 528 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 529 } 530 531 static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) { 532 if (Ty == LLT::pointer(0, 64)) 533 return X86::LEA64r; 534 else if (Ty == LLT::pointer(0, 32)) 535 return STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r; 536 else 537 llvm_unreachable("Can't get LEA opcode. Unsupported type."); 538 } 539 540 bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I, 541 MachineRegisterInfo &MRI, 542 MachineFunction &MF) const { 543 unsigned Opc = I.getOpcode(); 544 545 assert((Opc == TargetOpcode::G_FRAME_INDEX || Opc == TargetOpcode::G_GEP) && 546 "unexpected instruction"); 547 548 const unsigned DefReg = I.getOperand(0).getReg(); 549 LLT Ty = MRI.getType(DefReg); 550 551 // Use LEA to calculate frame index and GEP 552 unsigned NewOpc = getLeaOP(Ty, STI); 553 I.setDesc(TII.get(NewOpc)); 554 MachineInstrBuilder MIB(MF, I); 555 556 if (Opc == TargetOpcode::G_FRAME_INDEX) { 557 addOffset(MIB, 0); 558 } else { 559 MachineOperand &InxOp = I.getOperand(2); 560 I.addOperand(InxOp); // set IndexReg 561 InxOp.ChangeToImmediate(1); // set Scale 562 MIB.addImm(0).addReg(0); 563 } 564 565 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 566 } 567 568 bool X86InstructionSelector::selectGlobalValue(MachineInstr &I, 569 MachineRegisterInfo &MRI, 570 MachineFunction &MF) const { 571 assert((I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) && 572 "unexpected instruction"); 573 574 auto GV = I.getOperand(1).getGlobal(); 575 if (GV->isThreadLocal()) { 576 return false; // TODO: we don't support TLS yet. 577 } 578 579 // Can't handle alternate code models yet. 580 if (TM.getCodeModel() != CodeModel::Small) 581 return false; 582 583 X86AddressMode AM; 584 AM.GV = GV; 585 AM.GVOpFlags = STI.classifyGlobalReference(GV); 586 587 // TODO: The ABI requires an extra load. not supported yet. 588 if (isGlobalStubReference(AM.GVOpFlags)) 589 return false; 590 591 // TODO: This reference is relative to the pic base. not supported yet. 592 if (isGlobalRelativeToPICBase(AM.GVOpFlags)) 593 return false; 594 595 if (STI.isPICStyleRIPRel()) { 596 // Use rip-relative addressing. 597 assert(AM.Base.Reg == 0 && AM.IndexReg == 0); 598 AM.Base.Reg = X86::RIP; 599 } 600 601 const unsigned DefReg = I.getOperand(0).getReg(); 602 LLT Ty = MRI.getType(DefReg); 603 unsigned NewOpc = getLeaOP(Ty, STI); 604 605 I.setDesc(TII.get(NewOpc)); 606 MachineInstrBuilder MIB(MF, I); 607 608 I.RemoveOperand(1); 609 addFullAddress(MIB, AM); 610 611 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 612 } 613 614 bool X86InstructionSelector::selectConstant(MachineInstr &I, 615 MachineRegisterInfo &MRI, 616 MachineFunction &MF) const { 617 assert((I.getOpcode() == TargetOpcode::G_CONSTANT) && 618 "unexpected instruction"); 619 620 const unsigned DefReg = I.getOperand(0).getReg(); 621 LLT Ty = MRI.getType(DefReg); 622 623 if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID) 624 return false; 625 626 uint64_t Val = 0; 627 if (I.getOperand(1).isCImm()) { 628 Val = I.getOperand(1).getCImm()->getZExtValue(); 629 I.getOperand(1).ChangeToImmediate(Val); 630 } else if (I.getOperand(1).isImm()) { 631 Val = I.getOperand(1).getImm(); 632 } else 633 llvm_unreachable("Unsupported operand type."); 634 635 unsigned NewOpc; 636 switch (Ty.getSizeInBits()) { 637 case 8: 638 NewOpc = X86::MOV8ri; 639 break; 640 case 16: 641 NewOpc = X86::MOV16ri; 642 break; 643 case 32: 644 NewOpc = X86::MOV32ri; 645 break; 646 case 64: 647 // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used 648 if (isInt<32>(Val)) 649 NewOpc = X86::MOV64ri32; 650 else 651 NewOpc = X86::MOV64ri; 652 break; 653 default: 654 llvm_unreachable("Can't select G_CONSTANT, unsupported type."); 655 } 656 657 I.setDesc(TII.get(NewOpc)); 658 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 659 } 660 661 // Helper function for selectTruncOrPtrToInt and selectAnyext. 662 // Returns true if DstRC lives on a floating register class and 663 // SrcRC lives on a 128-bit vector class. 664 static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC, 665 const TargetRegisterClass *SrcRC) { 666 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass || 667 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) && 668 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass); 669 } 670 671 bool X86InstructionSelector::selectTurnIntoCOPY( 672 MachineInstr &I, MachineRegisterInfo &MRI, const unsigned DstReg, 673 const TargetRegisterClass *DstRC, const unsigned SrcReg, 674 const TargetRegisterClass *SrcRC) const { 675 676 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || 677 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { 678 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 679 << " operand\n"); 680 return false; 681 } 682 I.setDesc(TII.get(X86::COPY)); 683 return true; 684 } 685 686 bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &I, 687 MachineRegisterInfo &MRI, 688 MachineFunction &MF) const { 689 assert((I.getOpcode() == TargetOpcode::G_TRUNC || 690 I.getOpcode() == TargetOpcode::G_PTRTOINT) && 691 "unexpected instruction"); 692 693 const unsigned DstReg = I.getOperand(0).getReg(); 694 const unsigned SrcReg = I.getOperand(1).getReg(); 695 696 const LLT DstTy = MRI.getType(DstReg); 697 const LLT SrcTy = MRI.getType(SrcReg); 698 699 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI); 700 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI); 701 702 if (DstRB.getID() != SrcRB.getID()) { 703 LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode()) 704 << " input/output on different banks\n"); 705 return false; 706 } 707 708 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB); 709 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB); 710 711 if (!DstRC || !SrcRC) 712 return false; 713 714 // If that's truncation of the value that lives on the vector class and goes 715 // into the floating class, just replace it with copy, as we are able to 716 // select it as a regular move. 717 if (canTurnIntoCOPY(DstRC, SrcRC)) 718 return selectTurnIntoCOPY(I, MRI, DstReg, DstRC, SrcReg, SrcRC); 719 720 if (DstRB.getID() != X86::GPRRegBankID) 721 return false; 722 723 unsigned SubIdx; 724 if (DstRC == SrcRC) { 725 // Nothing to be done 726 SubIdx = X86::NoSubRegister; 727 } else if (DstRC == &X86::GR32RegClass) { 728 SubIdx = X86::sub_32bit; 729 } else if (DstRC == &X86::GR16RegClass) { 730 SubIdx = X86::sub_16bit; 731 } else if (DstRC == &X86::GR8RegClass) { 732 SubIdx = X86::sub_8bit; 733 } else { 734 return false; 735 } 736 737 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx); 738 739 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || 740 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { 741 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 742 << "\n"); 743 return false; 744 } 745 746 I.getOperand(1).setSubReg(SubIdx); 747 748 I.setDesc(TII.get(X86::COPY)); 749 return true; 750 } 751 752 bool X86InstructionSelector::selectZext(MachineInstr &I, 753 MachineRegisterInfo &MRI, 754 MachineFunction &MF) const { 755 assert((I.getOpcode() == TargetOpcode::G_ZEXT) && "unexpected instruction"); 756 757 const unsigned DstReg = I.getOperand(0).getReg(); 758 const unsigned SrcReg = I.getOperand(1).getReg(); 759 760 const LLT DstTy = MRI.getType(DstReg); 761 const LLT SrcTy = MRI.getType(SrcReg); 762 763 assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(32)) && 764 "8=>32 Zext is handled by tablegen"); 765 assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(32)) && 766 "16=>32 Zext is handled by tablegen"); 767 768 const static struct ZextEntry { 769 LLT SrcTy; 770 LLT DstTy; 771 unsigned MovOp; 772 bool NeedSubregToReg; 773 } OpTable[] = { 774 {LLT::scalar(8), LLT::scalar(16), X86::MOVZX16rr8, false}, // i8 => i16 775 {LLT::scalar(8), LLT::scalar(64), X86::MOVZX32rr8, true}, // i8 => i64 776 {LLT::scalar(16), LLT::scalar(64), X86::MOVZX32rr16, true}, // i16 => i64 777 {LLT::scalar(32), LLT::scalar(64), 0, true} // i32 => i64 778 }; 779 780 auto ZextEntryIt = 781 std::find_if(std::begin(OpTable), std::end(OpTable), 782 [SrcTy, DstTy](const ZextEntry &El) { 783 return El.DstTy == DstTy && El.SrcTy == SrcTy; 784 }); 785 786 // Here we try to select Zext into a MOVZ and/or SUBREG_TO_REG instruction. 787 if (ZextEntryIt != std::end(OpTable)) { 788 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI); 789 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI); 790 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB); 791 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB); 792 793 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || 794 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { 795 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 796 << " operand\n"); 797 return false; 798 } 799 800 unsigned TransitRegTo = DstReg; 801 unsigned TransitRegFrom = SrcReg; 802 if (ZextEntryIt->MovOp) { 803 // If we select Zext into MOVZ + SUBREG_TO_REG, we need to have 804 // a transit register in between: create it here. 805 if (ZextEntryIt->NeedSubregToReg) { 806 TransitRegFrom = MRI.createVirtualRegister( 807 getRegClass(LLT::scalar(32), DstReg, MRI)); 808 TransitRegTo = TransitRegFrom; 809 } 810 811 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ZextEntryIt->MovOp)) 812 .addDef(TransitRegTo) 813 .addReg(SrcReg); 814 } 815 if (ZextEntryIt->NeedSubregToReg) { 816 BuildMI(*I.getParent(), I, I.getDebugLoc(), 817 TII.get(TargetOpcode::SUBREG_TO_REG)) 818 .addDef(DstReg) 819 .addImm(0) 820 .addReg(TransitRegFrom) 821 .addImm(X86::sub_32bit); 822 } 823 I.eraseFromParent(); 824 return true; 825 } 826 827 if (SrcTy != LLT::scalar(1)) 828 return false; 829 830 unsigned AndOpc; 831 if (DstTy == LLT::scalar(8)) 832 AndOpc = X86::AND8ri; 833 else if (DstTy == LLT::scalar(16)) 834 AndOpc = X86::AND16ri8; 835 else if (DstTy == LLT::scalar(32)) 836 AndOpc = X86::AND32ri8; 837 else if (DstTy == LLT::scalar(64)) 838 AndOpc = X86::AND64ri8; 839 else 840 return false; 841 842 unsigned DefReg = SrcReg; 843 if (DstTy != LLT::scalar(8)) { 844 DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI)); 845 BuildMI(*I.getParent(), I, I.getDebugLoc(), 846 TII.get(TargetOpcode::SUBREG_TO_REG), DefReg) 847 .addImm(0) 848 .addReg(SrcReg) 849 .addImm(X86::sub_8bit); 850 } 851 852 MachineInstr &AndInst = 853 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg) 854 .addReg(DefReg) 855 .addImm(1); 856 857 constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI); 858 859 I.eraseFromParent(); 860 return true; 861 } 862 863 bool X86InstructionSelector::selectAnyext(MachineInstr &I, 864 MachineRegisterInfo &MRI, 865 MachineFunction &MF) const { 866 assert((I.getOpcode() == TargetOpcode::G_ANYEXT) && "unexpected instruction"); 867 868 const unsigned DstReg = I.getOperand(0).getReg(); 869 const unsigned SrcReg = I.getOperand(1).getReg(); 870 871 const LLT DstTy = MRI.getType(DstReg); 872 const LLT SrcTy = MRI.getType(SrcReg); 873 874 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI); 875 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI); 876 877 assert(DstRB.getID() == SrcRB.getID() && 878 "G_ANYEXT input/output on different banks\n"); 879 880 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() && 881 "G_ANYEXT incorrect operand size"); 882 883 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB); 884 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB); 885 886 // If that's ANY_EXT of the value that lives on the floating class and goes 887 // into the vector class, just replace it with copy, as we are able to select 888 // it as a regular move. 889 if (canTurnIntoCOPY(SrcRC, DstRC)) 890 return selectTurnIntoCOPY(I, MRI, SrcReg, SrcRC, DstReg, DstRC); 891 892 if (DstRB.getID() != X86::GPRRegBankID) 893 return false; 894 895 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || 896 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { 897 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 898 << " operand\n"); 899 return false; 900 } 901 902 if (SrcRC == DstRC) { 903 I.setDesc(TII.get(X86::COPY)); 904 return true; 905 } 906 907 BuildMI(*I.getParent(), I, I.getDebugLoc(), 908 TII.get(TargetOpcode::SUBREG_TO_REG)) 909 .addDef(DstReg) 910 .addImm(0) 911 .addReg(SrcReg) 912 .addImm(getSubRegIndex(SrcRC)); 913 914 I.eraseFromParent(); 915 return true; 916 } 917 918 bool X86InstructionSelector::selectCmp(MachineInstr &I, 919 MachineRegisterInfo &MRI, 920 MachineFunction &MF) const { 921 assert((I.getOpcode() == TargetOpcode::G_ICMP) && "unexpected instruction"); 922 923 X86::CondCode CC; 924 bool SwapArgs; 925 std::tie(CC, SwapArgs) = X86::getX86ConditionCode( 926 (CmpInst::Predicate)I.getOperand(1).getPredicate()); 927 unsigned OpSet = X86::getSETFromCond(CC); 928 929 unsigned LHS = I.getOperand(2).getReg(); 930 unsigned RHS = I.getOperand(3).getReg(); 931 932 if (SwapArgs) 933 std::swap(LHS, RHS); 934 935 unsigned OpCmp; 936 LLT Ty = MRI.getType(LHS); 937 938 switch (Ty.getSizeInBits()) { 939 default: 940 return false; 941 case 8: 942 OpCmp = X86::CMP8rr; 943 break; 944 case 16: 945 OpCmp = X86::CMP16rr; 946 break; 947 case 32: 948 OpCmp = X86::CMP32rr; 949 break; 950 case 64: 951 OpCmp = X86::CMP64rr; 952 break; 953 } 954 955 MachineInstr &CmpInst = 956 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp)) 957 .addReg(LHS) 958 .addReg(RHS); 959 960 MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(), 961 TII.get(OpSet), I.getOperand(0).getReg()); 962 963 constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI); 964 constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI); 965 966 I.eraseFromParent(); 967 return true; 968 } 969 970 bool X86InstructionSelector::selectUadde(MachineInstr &I, 971 MachineRegisterInfo &MRI, 972 MachineFunction &MF) const { 973 assert((I.getOpcode() == TargetOpcode::G_UADDE) && "unexpected instruction"); 974 975 const unsigned DstReg = I.getOperand(0).getReg(); 976 const unsigned CarryOutReg = I.getOperand(1).getReg(); 977 const unsigned Op0Reg = I.getOperand(2).getReg(); 978 const unsigned Op1Reg = I.getOperand(3).getReg(); 979 unsigned CarryInReg = I.getOperand(4).getReg(); 980 981 const LLT DstTy = MRI.getType(DstReg); 982 983 if (DstTy != LLT::scalar(32)) 984 return false; 985 986 // find CarryIn def instruction. 987 MachineInstr *Def = MRI.getVRegDef(CarryInReg); 988 while (Def->getOpcode() == TargetOpcode::G_TRUNC) { 989 CarryInReg = Def->getOperand(1).getReg(); 990 Def = MRI.getVRegDef(CarryInReg); 991 } 992 993 unsigned Opcode; 994 if (Def->getOpcode() == TargetOpcode::G_UADDE) { 995 // carry set by prev ADD. 996 997 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS) 998 .addReg(CarryInReg); 999 1000 if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI)) 1001 return false; 1002 1003 Opcode = X86::ADC32rr; 1004 } else if (auto val = getConstantVRegVal(CarryInReg, MRI)) { 1005 // carry is constant, support only 0. 1006 if (*val != 0) 1007 return false; 1008 1009 Opcode = X86::ADD32rr; 1010 } else 1011 return false; 1012 1013 MachineInstr &AddInst = 1014 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg) 1015 .addReg(Op0Reg) 1016 .addReg(Op1Reg); 1017 1018 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg) 1019 .addReg(X86::EFLAGS); 1020 1021 if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) || 1022 !RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI)) 1023 return false; 1024 1025 I.eraseFromParent(); 1026 return true; 1027 } 1028 1029 bool X86InstructionSelector::selectExtract(MachineInstr &I, 1030 MachineRegisterInfo &MRI, 1031 MachineFunction &MF) const { 1032 assert((I.getOpcode() == TargetOpcode::G_EXTRACT) && 1033 "unexpected instruction"); 1034 1035 const unsigned DstReg = I.getOperand(0).getReg(); 1036 const unsigned SrcReg = I.getOperand(1).getReg(); 1037 int64_t Index = I.getOperand(2).getImm(); 1038 1039 const LLT DstTy = MRI.getType(DstReg); 1040 const LLT SrcTy = MRI.getType(SrcReg); 1041 1042 // Meanwile handle vector type only. 1043 if (!DstTy.isVector()) 1044 return false; 1045 1046 if (Index % DstTy.getSizeInBits() != 0) 1047 return false; // Not extract subvector. 1048 1049 if (Index == 0) { 1050 // Replace by extract subreg copy. 1051 if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF)) 1052 return false; 1053 1054 I.eraseFromParent(); 1055 return true; 1056 } 1057 1058 bool HasAVX = STI.hasAVX(); 1059 bool HasAVX512 = STI.hasAVX512(); 1060 bool HasVLX = STI.hasVLX(); 1061 1062 if (SrcTy.getSizeInBits() == 256 && DstTy.getSizeInBits() == 128) { 1063 if (HasVLX) 1064 I.setDesc(TII.get(X86::VEXTRACTF32x4Z256rr)); 1065 else if (HasAVX) 1066 I.setDesc(TII.get(X86::VEXTRACTF128rr)); 1067 else 1068 return false; 1069 } else if (SrcTy.getSizeInBits() == 512 && HasAVX512) { 1070 if (DstTy.getSizeInBits() == 128) 1071 I.setDesc(TII.get(X86::VEXTRACTF32x4Zrr)); 1072 else if (DstTy.getSizeInBits() == 256) 1073 I.setDesc(TII.get(X86::VEXTRACTF64x4Zrr)); 1074 else 1075 return false; 1076 } else 1077 return false; 1078 1079 // Convert to X86 VEXTRACT immediate. 1080 Index = Index / DstTy.getSizeInBits(); 1081 I.getOperand(2).setImm(Index); 1082 1083 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1084 } 1085 1086 bool X86InstructionSelector::emitExtractSubreg(unsigned DstReg, unsigned SrcReg, 1087 MachineInstr &I, 1088 MachineRegisterInfo &MRI, 1089 MachineFunction &MF) const { 1090 const LLT DstTy = MRI.getType(DstReg); 1091 const LLT SrcTy = MRI.getType(SrcReg); 1092 unsigned SubIdx = X86::NoSubRegister; 1093 1094 if (!DstTy.isVector() || !SrcTy.isVector()) 1095 return false; 1096 1097 assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() && 1098 "Incorrect Src/Dst register size"); 1099 1100 if (DstTy.getSizeInBits() == 128) 1101 SubIdx = X86::sub_xmm; 1102 else if (DstTy.getSizeInBits() == 256) 1103 SubIdx = X86::sub_ymm; 1104 else 1105 return false; 1106 1107 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI); 1108 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI); 1109 1110 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx); 1111 1112 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || 1113 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { 1114 LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC\n"); 1115 return false; 1116 } 1117 1118 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg) 1119 .addReg(SrcReg, 0, SubIdx); 1120 1121 return true; 1122 } 1123 1124 bool X86InstructionSelector::emitInsertSubreg(unsigned DstReg, unsigned SrcReg, 1125 MachineInstr &I, 1126 MachineRegisterInfo &MRI, 1127 MachineFunction &MF) const { 1128 const LLT DstTy = MRI.getType(DstReg); 1129 const LLT SrcTy = MRI.getType(SrcReg); 1130 unsigned SubIdx = X86::NoSubRegister; 1131 1132 // TODO: support scalar types 1133 if (!DstTy.isVector() || !SrcTy.isVector()) 1134 return false; 1135 1136 assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() && 1137 "Incorrect Src/Dst register size"); 1138 1139 if (SrcTy.getSizeInBits() == 128) 1140 SubIdx = X86::sub_xmm; 1141 else if (SrcTy.getSizeInBits() == 256) 1142 SubIdx = X86::sub_ymm; 1143 else 1144 return false; 1145 1146 const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI); 1147 const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI); 1148 1149 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || 1150 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { 1151 LLVM_DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n"); 1152 return false; 1153 } 1154 1155 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY)) 1156 .addReg(DstReg, RegState::DefineNoRead, SubIdx) 1157 .addReg(SrcReg); 1158 1159 return true; 1160 } 1161 1162 bool X86InstructionSelector::selectInsert(MachineInstr &I, 1163 MachineRegisterInfo &MRI, 1164 MachineFunction &MF) const { 1165 assert((I.getOpcode() == TargetOpcode::G_INSERT) && "unexpected instruction"); 1166 1167 const unsigned DstReg = I.getOperand(0).getReg(); 1168 const unsigned SrcReg = I.getOperand(1).getReg(); 1169 const unsigned InsertReg = I.getOperand(2).getReg(); 1170 int64_t Index = I.getOperand(3).getImm(); 1171 1172 const LLT DstTy = MRI.getType(DstReg); 1173 const LLT InsertRegTy = MRI.getType(InsertReg); 1174 1175 // Meanwile handle vector type only. 1176 if (!DstTy.isVector()) 1177 return false; 1178 1179 if (Index % InsertRegTy.getSizeInBits() != 0) 1180 return false; // Not insert subvector. 1181 1182 if (Index == 0 && MRI.getVRegDef(SrcReg)->isImplicitDef()) { 1183 // Replace by subreg copy. 1184 if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF)) 1185 return false; 1186 1187 I.eraseFromParent(); 1188 return true; 1189 } 1190 1191 bool HasAVX = STI.hasAVX(); 1192 bool HasAVX512 = STI.hasAVX512(); 1193 bool HasVLX = STI.hasVLX(); 1194 1195 if (DstTy.getSizeInBits() == 256 && InsertRegTy.getSizeInBits() == 128) { 1196 if (HasVLX) 1197 I.setDesc(TII.get(X86::VINSERTF32x4Z256rr)); 1198 else if (HasAVX) 1199 I.setDesc(TII.get(X86::VINSERTF128rr)); 1200 else 1201 return false; 1202 } else if (DstTy.getSizeInBits() == 512 && HasAVX512) { 1203 if (InsertRegTy.getSizeInBits() == 128) 1204 I.setDesc(TII.get(X86::VINSERTF32x4Zrr)); 1205 else if (InsertRegTy.getSizeInBits() == 256) 1206 I.setDesc(TII.get(X86::VINSERTF64x4Zrr)); 1207 else 1208 return false; 1209 } else 1210 return false; 1211 1212 // Convert to X86 VINSERT immediate. 1213 Index = Index / InsertRegTy.getSizeInBits(); 1214 1215 I.getOperand(3).setImm(Index); 1216 1217 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1218 } 1219 1220 bool X86InstructionSelector::selectUnmergeValues( 1221 MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF, 1222 CodeGenCoverage &CoverageInfo) const { 1223 assert((I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) && 1224 "unexpected instruction"); 1225 1226 // Split to extracts. 1227 unsigned NumDefs = I.getNumOperands() - 1; 1228 unsigned SrcReg = I.getOperand(NumDefs).getReg(); 1229 unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits(); 1230 1231 for (unsigned Idx = 0; Idx < NumDefs; ++Idx) { 1232 MachineInstr &ExtrInst = 1233 *BuildMI(*I.getParent(), I, I.getDebugLoc(), 1234 TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg()) 1235 .addReg(SrcReg) 1236 .addImm(Idx * DefSize); 1237 1238 if (!select(ExtrInst, CoverageInfo)) 1239 return false; 1240 } 1241 1242 I.eraseFromParent(); 1243 return true; 1244 } 1245 1246 bool X86InstructionSelector::selectMergeValues( 1247 MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF, 1248 CodeGenCoverage &CoverageInfo) const { 1249 assert((I.getOpcode() == TargetOpcode::G_MERGE_VALUES) && 1250 "unexpected instruction"); 1251 1252 // Split to inserts. 1253 unsigned DstReg = I.getOperand(0).getReg(); 1254 unsigned SrcReg0 = I.getOperand(1).getReg(); 1255 1256 const LLT DstTy = MRI.getType(DstReg); 1257 const LLT SrcTy = MRI.getType(SrcReg0); 1258 unsigned SrcSize = SrcTy.getSizeInBits(); 1259 1260 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); 1261 1262 // For the first src use insertSubReg. 1263 unsigned DefReg = MRI.createGenericVirtualRegister(DstTy); 1264 MRI.setRegBank(DefReg, RegBank); 1265 if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF)) 1266 return false; 1267 1268 for (unsigned Idx = 2; Idx < I.getNumOperands(); ++Idx) { 1269 unsigned Tmp = MRI.createGenericVirtualRegister(DstTy); 1270 MRI.setRegBank(Tmp, RegBank); 1271 1272 MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(), 1273 TII.get(TargetOpcode::G_INSERT), Tmp) 1274 .addReg(DefReg) 1275 .addReg(I.getOperand(Idx).getReg()) 1276 .addImm((Idx - 1) * SrcSize); 1277 1278 DefReg = Tmp; 1279 1280 if (!select(InsertInst, CoverageInfo)) 1281 return false; 1282 } 1283 1284 MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(), 1285 TII.get(TargetOpcode::COPY), DstReg) 1286 .addReg(DefReg); 1287 1288 if (!select(CopyInst, CoverageInfo)) 1289 return false; 1290 1291 I.eraseFromParent(); 1292 return true; 1293 } 1294 1295 bool X86InstructionSelector::selectCondBranch(MachineInstr &I, 1296 MachineRegisterInfo &MRI, 1297 MachineFunction &MF) const { 1298 assert((I.getOpcode() == TargetOpcode::G_BRCOND) && "unexpected instruction"); 1299 1300 const unsigned CondReg = I.getOperand(0).getReg(); 1301 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB(); 1302 1303 MachineInstr &TestInst = 1304 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri)) 1305 .addReg(CondReg) 1306 .addImm(1); 1307 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JNE_1)) 1308 .addMBB(DestMBB); 1309 1310 constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI); 1311 1312 I.eraseFromParent(); 1313 return true; 1314 } 1315 1316 bool X86InstructionSelector::materializeFP(MachineInstr &I, 1317 MachineRegisterInfo &MRI, 1318 MachineFunction &MF) const { 1319 assert((I.getOpcode() == TargetOpcode::G_FCONSTANT) && 1320 "unexpected instruction"); 1321 1322 // Can't handle alternate code models yet. 1323 CodeModel::Model CM = TM.getCodeModel(); 1324 if (CM != CodeModel::Small && CM != CodeModel::Large) 1325 return false; 1326 1327 const unsigned DstReg = I.getOperand(0).getReg(); 1328 const LLT DstTy = MRI.getType(DstReg); 1329 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); 1330 unsigned Align = DstTy.getSizeInBits(); 1331 const DebugLoc &DbgLoc = I.getDebugLoc(); 1332 1333 unsigned Opc = getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Align); 1334 1335 // Create the load from the constant pool. 1336 const ConstantFP *CFP = I.getOperand(1).getFPImm(); 1337 unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Align); 1338 MachineInstr *LoadInst = nullptr; 1339 unsigned char OpFlag = STI.classifyLocalReference(nullptr); 1340 1341 if (CM == CodeModel::Large && STI.is64Bit()) { 1342 // Under X86-64 non-small code model, GV (and friends) are 64-bits, so 1343 // they cannot be folded into immediate fields. 1344 1345 unsigned AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass); 1346 BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg) 1347 .addConstantPoolIndex(CPI, 0, OpFlag); 1348 1349 MachineMemOperand *MMO = MF.getMachineMemOperand( 1350 MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad, 1351 MF.getDataLayout().getPointerSize(), Align); 1352 1353 LoadInst = 1354 addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), 1355 AddrReg) 1356 .addMemOperand(MMO); 1357 1358 } else if (CM == CodeModel::Small || !STI.is64Bit()) { 1359 // Handle the case when globals fit in our immediate field. 1360 // This is true for X86-32 always and X86-64 when in -mcmodel=small mode. 1361 1362 // x86-32 PIC requires a PIC base register for constant pools. 1363 unsigned PICBase = 0; 1364 if (OpFlag == X86II::MO_PIC_BASE_OFFSET || OpFlag == X86II::MO_GOTOFF) { 1365 // PICBase can be allocated by TII.getGlobalBaseReg(&MF). 1366 // In DAGISEL the code that initialize it generated by the CGBR pass. 1367 return false; // TODO support the mode. 1368 } else if (STI.is64Bit() && TM.getCodeModel() == CodeModel::Small) 1369 PICBase = X86::RIP; 1370 1371 LoadInst = addConstantPoolReference( 1372 BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase, 1373 OpFlag); 1374 } else 1375 return false; 1376 1377 constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI); 1378 I.eraseFromParent(); 1379 return true; 1380 } 1381 1382 bool X86InstructionSelector::selectImplicitDefOrPHI( 1383 MachineInstr &I, MachineRegisterInfo &MRI) const { 1384 assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF || 1385 I.getOpcode() == TargetOpcode::G_PHI) && 1386 "unexpected instruction"); 1387 1388 unsigned DstReg = I.getOperand(0).getReg(); 1389 1390 if (!MRI.getRegClassOrNull(DstReg)) { 1391 const LLT DstTy = MRI.getType(DstReg); 1392 const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI); 1393 1394 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { 1395 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 1396 << " operand\n"); 1397 return false; 1398 } 1399 } 1400 1401 if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF) 1402 I.setDesc(TII.get(X86::IMPLICIT_DEF)); 1403 else 1404 I.setDesc(TII.get(X86::PHI)); 1405 1406 return true; 1407 } 1408 1409 // Currently GlobalIsel TableGen generates patterns for shift imm and shift 1, 1410 // but with shiftCount i8. In G_LSHR/G_ASHR/G_SHL like LLVM-IR both arguments 1411 // has the same type, so for now only shift i8 can use auto generated 1412 // TableGen patterns. 1413 bool X86InstructionSelector::selectShift(MachineInstr &I, 1414 MachineRegisterInfo &MRI, 1415 MachineFunction &MF) const { 1416 1417 assert((I.getOpcode() == TargetOpcode::G_SHL || 1418 I.getOpcode() == TargetOpcode::G_ASHR || 1419 I.getOpcode() == TargetOpcode::G_LSHR) && 1420 "unexpected instruction"); 1421 1422 unsigned DstReg = I.getOperand(0).getReg(); 1423 const LLT DstTy = MRI.getType(DstReg); 1424 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI); 1425 1426 const static struct ShiftEntry { 1427 unsigned SizeInBits; 1428 unsigned CReg; 1429 unsigned OpLSHR; 1430 unsigned OpASHR; 1431 unsigned OpSHL; 1432 } OpTable[] = { 1433 {8, X86::CL, X86::SHR8rCL, X86::SAR8rCL, X86::SHL8rCL}, // i8 1434 {16, X86::CX, X86::SHR16rCL, X86::SAR16rCL, X86::SHL16rCL}, // i16 1435 {32, X86::ECX, X86::SHR32rCL, X86::SAR32rCL, X86::SHL32rCL}, // i32 1436 {64, X86::RCX, X86::SHR64rCL, X86::SAR64rCL, X86::SHL64rCL} // i64 1437 }; 1438 1439 if (DstRB.getID() != X86::GPRRegBankID) 1440 return false; 1441 1442 auto ShiftEntryIt = std::find_if( 1443 std::begin(OpTable), std::end(OpTable), [DstTy](const ShiftEntry &El) { 1444 return El.SizeInBits == DstTy.getSizeInBits(); 1445 }); 1446 if (ShiftEntryIt == std::end(OpTable)) 1447 return false; 1448 1449 unsigned CReg = ShiftEntryIt->CReg; 1450 unsigned Opcode = 0; 1451 switch (I.getOpcode()) { 1452 case TargetOpcode::G_SHL: 1453 Opcode = ShiftEntryIt->OpSHL; 1454 break; 1455 case TargetOpcode::G_ASHR: 1456 Opcode = ShiftEntryIt->OpASHR; 1457 break; 1458 case TargetOpcode::G_LSHR: 1459 Opcode = ShiftEntryIt->OpLSHR; 1460 break; 1461 default: 1462 return false; 1463 } 1464 1465 unsigned Op0Reg = I.getOperand(1).getReg(); 1466 unsigned Op1Reg = I.getOperand(2).getReg(); 1467 1468 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY), 1469 ShiftEntryIt->CReg) 1470 .addReg(Op1Reg); 1471 1472 // The shift instruction uses X86::CL. If we defined a super-register 1473 // of X86::CL, emit a subreg KILL to precisely describe what we're doing here. 1474 if (CReg != X86::CL) 1475 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::KILL), 1476 X86::CL) 1477 .addReg(CReg, RegState::Kill); 1478 1479 MachineInstr &ShiftInst = 1480 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg) 1481 .addReg(Op0Reg); 1482 1483 constrainSelectedInstRegOperands(ShiftInst, TII, TRI, RBI); 1484 I.eraseFromParent(); 1485 return true; 1486 } 1487 1488 bool X86InstructionSelector::selectSDiv(MachineInstr &I, 1489 MachineRegisterInfo &MRI, 1490 MachineFunction &MF) const { 1491 1492 assert(I.getOpcode() == TargetOpcode::G_SDIV && "unexpected instruction"); 1493 1494 const unsigned DstReg = I.getOperand(0).getReg(); 1495 const unsigned DividentReg = I.getOperand(1).getReg(); 1496 const unsigned DiviserReg = I.getOperand(2).getReg(); 1497 1498 const LLT RegTy = MRI.getType(DstReg); 1499 assert(RegTy == MRI.getType(DividentReg) && 1500 RegTy == MRI.getType(DiviserReg) && 1501 "Arguments and return value types must match"); 1502 1503 const RegisterBank &RegRB = *RBI.getRegBank(DstReg, MRI, TRI); 1504 1505 // For the X86 IDIV instruction, in most cases the dividend 1506 // (numerator) must be in a specific register pair highreg:lowreg, 1507 // producing the quotient in lowreg and the remainder in highreg. 1508 // For most data types, to set up the instruction, the dividend is 1509 // copied into lowreg, and lowreg is sign-extended into highreg. The 1510 // exception is i8, where the dividend is defined as a single register rather 1511 // than a register pair, and we therefore directly sign-extend the dividend 1512 // into lowreg, instead of copying, and ignore the highreg. 1513 const static struct SDivEntry { 1514 unsigned SizeInBits; 1515 unsigned QuotientReg; 1516 unsigned DividentRegUpper; 1517 unsigned DividentRegLower; 1518 unsigned OpSignExtend; 1519 unsigned OpCopy; 1520 unsigned OpDiv; 1521 } OpTable[] = { 1522 {8, X86::AL, X86::NoRegister, X86::AX, 0, X86::MOVSX16rr8, 1523 X86::IDIV8r}, // i8 1524 {16, X86::AX, X86::DX, X86::AX, X86::CWD, TargetOpcode::COPY, 1525 X86::IDIV16r}, // i16 1526 {32, X86::EAX, X86::EDX, X86::EAX, X86::CDQ, TargetOpcode::COPY, 1527 X86::IDIV32r}, // i32 1528 {64, X86::RAX, X86::RDX, X86::RAX, X86::CQO, TargetOpcode::COPY, 1529 X86::IDIV64r} // i64 1530 }; 1531 1532 if (RegRB.getID() != X86::GPRRegBankID) 1533 return false; 1534 1535 auto SDivEntryIt = std::find_if( 1536 std::begin(OpTable), std::end(OpTable), [RegTy](const SDivEntry &El) { 1537 return El.SizeInBits == RegTy.getSizeInBits(); 1538 }); 1539 1540 if (SDivEntryIt == std::end(OpTable)) 1541 return false; 1542 1543 const TargetRegisterClass *RegRC = getRegClass(RegTy, RegRB); 1544 if (!RBI.constrainGenericRegister(DividentReg, *RegRC, MRI) || 1545 !RBI.constrainGenericRegister(DiviserReg, *RegRC, MRI) || 1546 !RBI.constrainGenericRegister(DstReg, *RegRC, MRI)) { 1547 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 1548 << " operand\n"); 1549 return false; 1550 } 1551 1552 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SDivEntryIt->OpCopy), 1553 SDivEntryIt->DividentRegLower) 1554 .addReg(DividentReg); 1555 if (SDivEntryIt->DividentRegUpper != X86::NoRegister) 1556 BuildMI(*I.getParent(), I, I.getDebugLoc(), 1557 TII.get(SDivEntryIt->OpSignExtend)); 1558 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SDivEntryIt->OpDiv)) 1559 .addReg(DiviserReg); 1560 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY), 1561 DstReg) 1562 .addReg(SDivEntryIt->QuotientReg); 1563 1564 I.eraseFromParent(); 1565 return true; 1566 } 1567 1568 InstructionSelector * 1569 llvm::createX86InstructionSelector(const X86TargetMachine &TM, 1570 X86Subtarget &Subtarget, 1571 X86RegisterBankInfo &RBI) { 1572 return new X86InstructionSelector(TM, Subtarget, RBI); 1573 } 1574