1 //===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.cpp - MIBuilder--*- C++ -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// This file implements the MachineIRBuidler class. 11 //===----------------------------------------------------------------------===// 12 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 13 14 #include "llvm/CodeGen/MachineFunction.h" 15 #include "llvm/CodeGen/MachineInstr.h" 16 #include "llvm/CodeGen/MachineInstrBuilder.h" 17 #include "llvm/CodeGen/MachineRegisterInfo.h" 18 #include "llvm/CodeGen/TargetInstrInfo.h" 19 #include "llvm/CodeGen/TargetOpcodes.h" 20 #include "llvm/CodeGen/TargetSubtargetInfo.h" 21 #include "llvm/IR/DebugInfo.h" 22 23 using namespace llvm; 24 25 void MachineIRBuilderBase::setMF(MachineFunction &MF) { 26 State.MF = &MF; 27 State.MBB = nullptr; 28 State.MRI = &MF.getRegInfo(); 29 State.TII = MF.getSubtarget().getInstrInfo(); 30 State.DL = DebugLoc(); 31 State.II = MachineBasicBlock::iterator(); 32 State.InsertedInstr = nullptr; 33 } 34 35 void MachineIRBuilderBase::setMBB(MachineBasicBlock &MBB) { 36 State.MBB = &MBB; 37 State.II = MBB.end(); 38 assert(&getMF() == MBB.getParent() && 39 "Basic block is in a different function"); 40 } 41 42 void MachineIRBuilderBase::setInstr(MachineInstr &MI) { 43 assert(MI.getParent() && "Instruction is not part of a basic block"); 44 setMBB(*MI.getParent()); 45 State.II = MI.getIterator(); 46 } 47 48 void MachineIRBuilderBase::setInsertPt(MachineBasicBlock &MBB, 49 MachineBasicBlock::iterator II) { 50 assert(MBB.getParent() == &getMF() && 51 "Basic block is in a different function"); 52 State.MBB = &MBB; 53 State.II = II; 54 } 55 56 void MachineIRBuilderBase::recordInsertion(MachineInstr *InsertedInstr) const { 57 if (State.InsertedInstr) 58 State.InsertedInstr(InsertedInstr); 59 } 60 61 void MachineIRBuilderBase::recordInsertions( 62 std::function<void(MachineInstr *)> Inserted) { 63 State.InsertedInstr = std::move(Inserted); 64 } 65 66 void MachineIRBuilderBase::stopRecordingInsertions() { 67 State.InsertedInstr = nullptr; 68 } 69 70 //------------------------------------------------------------------------------ 71 // Build instruction variants. 72 //------------------------------------------------------------------------------ 73 74 MachineInstrBuilder MachineIRBuilderBase::buildInstr(unsigned Opcode) { 75 return insertInstr(buildInstrNoInsert(Opcode)); 76 } 77 78 MachineInstrBuilder MachineIRBuilderBase::buildInstrNoInsert(unsigned Opcode) { 79 MachineInstrBuilder MIB = BuildMI(getMF(), getDL(), getTII().get(Opcode)); 80 return MIB; 81 } 82 83 MachineInstrBuilder MachineIRBuilderBase::insertInstr(MachineInstrBuilder MIB) { 84 getMBB().insert(getInsertPt(), MIB); 85 recordInsertion(MIB); 86 return MIB; 87 } 88 89 MachineInstrBuilder 90 MachineIRBuilderBase::buildDirectDbgValue(unsigned Reg, const MDNode *Variable, 91 const MDNode *Expr) { 92 assert(isa<DILocalVariable>(Variable) && "not a variable"); 93 assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 94 assert( 95 cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) && 96 "Expected inlined-at fields to agree"); 97 return insertInstr(BuildMI(getMF(), getDL(), 98 getTII().get(TargetOpcode::DBG_VALUE), 99 /*IsIndirect*/ false, Reg, Variable, Expr)); 100 } 101 102 MachineInstrBuilder MachineIRBuilderBase::buildIndirectDbgValue( 103 unsigned Reg, const MDNode *Variable, const MDNode *Expr) { 104 assert(isa<DILocalVariable>(Variable) && "not a variable"); 105 assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 106 assert( 107 cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) && 108 "Expected inlined-at fields to agree"); 109 return insertInstr(BuildMI(getMF(), getDL(), 110 getTII().get(TargetOpcode::DBG_VALUE), 111 /*IsIndirect*/ true, Reg, Variable, Expr)); 112 } 113 114 MachineInstrBuilder 115 MachineIRBuilderBase::buildFIDbgValue(int FI, const MDNode *Variable, 116 const MDNode *Expr) { 117 assert(isa<DILocalVariable>(Variable) && "not a variable"); 118 assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 119 assert( 120 cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) && 121 "Expected inlined-at fields to agree"); 122 return buildInstr(TargetOpcode::DBG_VALUE) 123 .addFrameIndex(FI) 124 .addImm(0) 125 .addMetadata(Variable) 126 .addMetadata(Expr); 127 } 128 129 MachineInstrBuilder MachineIRBuilderBase::buildConstDbgValue( 130 const Constant &C, const MDNode *Variable, const MDNode *Expr) { 131 assert(isa<DILocalVariable>(Variable) && "not a variable"); 132 assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 133 assert( 134 cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) && 135 "Expected inlined-at fields to agree"); 136 auto MIB = buildInstr(TargetOpcode::DBG_VALUE); 137 if (auto *CI = dyn_cast<ConstantInt>(&C)) { 138 if (CI->getBitWidth() > 64) 139 MIB.addCImm(CI); 140 else 141 MIB.addImm(CI->getZExtValue()); 142 } else if (auto *CFP = dyn_cast<ConstantFP>(&C)) { 143 MIB.addFPImm(CFP); 144 } else { 145 // Insert %noreg if we didn't find a usable constant and had to drop it. 146 MIB.addReg(0U); 147 } 148 149 return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr); 150 } 151 152 MachineInstrBuilder MachineIRBuilderBase::buildDbgLabel(const MDNode *Label) { 153 assert(isa<DILabel>(Label) && "not a label"); 154 assert(cast<DILabel>(Label)->isValidLocationForIntrinsic(State.DL) && 155 "Expected inlined-at fields to agree"); 156 auto MIB = buildInstr(TargetOpcode::DBG_LABEL); 157 158 return MIB.addMetadata(Label); 159 } 160 161 MachineInstrBuilder MachineIRBuilderBase::buildFrameIndex(unsigned Res, 162 int Idx) { 163 assert(getMRI()->getType(Res).isPointer() && "invalid operand type"); 164 return buildInstr(TargetOpcode::G_FRAME_INDEX) 165 .addDef(Res) 166 .addFrameIndex(Idx); 167 } 168 169 MachineInstrBuilder 170 MachineIRBuilderBase::buildGlobalValue(unsigned Res, const GlobalValue *GV) { 171 assert(getMRI()->getType(Res).isPointer() && "invalid operand type"); 172 assert(getMRI()->getType(Res).getAddressSpace() == 173 GV->getType()->getAddressSpace() && 174 "address space mismatch"); 175 176 return buildInstr(TargetOpcode::G_GLOBAL_VALUE) 177 .addDef(Res) 178 .addGlobalAddress(GV); 179 } 180 181 void MachineIRBuilderBase::validateBinaryOp(unsigned Res, unsigned Op0, 182 unsigned Op1) { 183 assert((getMRI()->getType(Res).isScalar() || 184 getMRI()->getType(Res).isVector()) && 185 "invalid operand type"); 186 assert(getMRI()->getType(Res) == getMRI()->getType(Op0) && 187 getMRI()->getType(Res) == getMRI()->getType(Op1) && "type mismatch"); 188 } 189 190 MachineInstrBuilder MachineIRBuilderBase::buildGEP(unsigned Res, unsigned Op0, 191 unsigned Op1) { 192 assert(getMRI()->getType(Res).isPointer() && 193 getMRI()->getType(Res) == getMRI()->getType(Op0) && "type mismatch"); 194 assert(getMRI()->getType(Op1).isScalar() && "invalid offset type"); 195 196 return buildInstr(TargetOpcode::G_GEP) 197 .addDef(Res) 198 .addUse(Op0) 199 .addUse(Op1); 200 } 201 202 Optional<MachineInstrBuilder> 203 MachineIRBuilderBase::materializeGEP(unsigned &Res, unsigned Op0, 204 const LLT &ValueTy, uint64_t Value) { 205 assert(Res == 0 && "Res is a result argument"); 206 assert(ValueTy.isScalar() && "invalid offset type"); 207 208 if (Value == 0) { 209 Res = Op0; 210 return None; 211 } 212 213 Res = getMRI()->createGenericVirtualRegister(getMRI()->getType(Op0)); 214 unsigned TmpReg = getMRI()->createGenericVirtualRegister(ValueTy); 215 216 buildConstant(TmpReg, Value); 217 return buildGEP(Res, Op0, TmpReg); 218 } 219 220 MachineInstrBuilder MachineIRBuilderBase::buildPtrMask(unsigned Res, 221 unsigned Op0, 222 uint32_t NumBits) { 223 assert(getMRI()->getType(Res).isPointer() && 224 getMRI()->getType(Res) == getMRI()->getType(Op0) && "type mismatch"); 225 226 return buildInstr(TargetOpcode::G_PTR_MASK) 227 .addDef(Res) 228 .addUse(Op0) 229 .addImm(NumBits); 230 } 231 232 MachineInstrBuilder MachineIRBuilderBase::buildBr(MachineBasicBlock &Dest) { 233 return buildInstr(TargetOpcode::G_BR).addMBB(&Dest); 234 } 235 236 MachineInstrBuilder MachineIRBuilderBase::buildBrIndirect(unsigned Tgt) { 237 assert(getMRI()->getType(Tgt).isPointer() && "invalid branch destination"); 238 return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt); 239 } 240 241 MachineInstrBuilder MachineIRBuilderBase::buildCopy(unsigned Res, unsigned Op) { 242 assert(getMRI()->getType(Res) == LLT() || getMRI()->getType(Op) == LLT() || 243 getMRI()->getType(Res) == getMRI()->getType(Op)); 244 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op); 245 } 246 247 MachineInstrBuilder 248 MachineIRBuilderBase::buildConstant(unsigned Res, const ConstantInt &Val) { 249 LLT Ty = getMRI()->getType(Res); 250 251 assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type"); 252 253 const ConstantInt *NewVal = &Val; 254 if (Ty.getSizeInBits() != Val.getBitWidth()) 255 NewVal = ConstantInt::get(getMF().getFunction().getContext(), 256 Val.getValue().sextOrTrunc(Ty.getSizeInBits())); 257 258 return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal); 259 } 260 261 MachineInstrBuilder MachineIRBuilderBase::buildConstant(unsigned Res, 262 int64_t Val) { 263 auto IntN = IntegerType::get(getMF().getFunction().getContext(), 264 getMRI()->getType(Res).getSizeInBits()); 265 ConstantInt *CI = ConstantInt::get(IntN, Val, true); 266 return buildConstant(Res, *CI); 267 } 268 269 MachineInstrBuilder 270 MachineIRBuilderBase::buildFConstant(unsigned Res, const ConstantFP &Val) { 271 assert(getMRI()->getType(Res).isScalar() && "invalid operand type"); 272 273 return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val); 274 } 275 276 MachineInstrBuilder MachineIRBuilderBase::buildFConstant(unsigned Res, 277 double Val) { 278 LLT DstTy = getMRI()->getType(Res); 279 auto &Ctx = getMF().getFunction().getContext(); 280 auto *CFP = 281 ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getSizeInBits())); 282 return buildFConstant(Res, *CFP); 283 } 284 285 MachineInstrBuilder MachineIRBuilderBase::buildBrCond(unsigned Tst, 286 MachineBasicBlock &Dest) { 287 assert(getMRI()->getType(Tst).isScalar() && "invalid operand type"); 288 289 return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest); 290 } 291 292 MachineInstrBuilder MachineIRBuilderBase::buildLoad(unsigned Res, unsigned Addr, 293 MachineMemOperand &MMO) { 294 return buildLoadInstr(TargetOpcode::G_LOAD, Res, Addr, MMO); 295 } 296 297 MachineInstrBuilder 298 MachineIRBuilderBase::buildLoadInstr(unsigned Opcode, unsigned Res, 299 unsigned Addr, MachineMemOperand &MMO) { 300 assert(getMRI()->getType(Res).isValid() && "invalid operand type"); 301 assert(getMRI()->getType(Addr).isPointer() && "invalid operand type"); 302 303 return buildInstr(Opcode) 304 .addDef(Res) 305 .addUse(Addr) 306 .addMemOperand(&MMO); 307 } 308 309 MachineInstrBuilder MachineIRBuilderBase::buildStore(unsigned Val, 310 unsigned Addr, 311 MachineMemOperand &MMO) { 312 assert(getMRI()->getType(Val).isValid() && "invalid operand type"); 313 assert(getMRI()->getType(Addr).isPointer() && "invalid operand type"); 314 315 return buildInstr(TargetOpcode::G_STORE) 316 .addUse(Val) 317 .addUse(Addr) 318 .addMemOperand(&MMO); 319 } 320 321 MachineInstrBuilder MachineIRBuilderBase::buildUAdde(unsigned Res, 322 unsigned CarryOut, 323 unsigned Op0, unsigned Op1, 324 unsigned CarryIn) { 325 assert(getMRI()->getType(Res).isScalar() && "invalid operand type"); 326 assert(getMRI()->getType(Res) == getMRI()->getType(Op0) && 327 getMRI()->getType(Res) == getMRI()->getType(Op1) && "type mismatch"); 328 assert(getMRI()->getType(CarryOut).isScalar() && "invalid operand type"); 329 assert(getMRI()->getType(CarryOut) == getMRI()->getType(CarryIn) && 330 "type mismatch"); 331 332 return buildInstr(TargetOpcode::G_UADDE) 333 .addDef(Res) 334 .addDef(CarryOut) 335 .addUse(Op0) 336 .addUse(Op1) 337 .addUse(CarryIn); 338 } 339 340 MachineInstrBuilder MachineIRBuilderBase::buildAnyExt(unsigned Res, 341 unsigned Op) { 342 validateTruncExt(Res, Op, true); 343 return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op); 344 } 345 346 MachineInstrBuilder MachineIRBuilderBase::buildSExt(unsigned Res, unsigned Op) { 347 validateTruncExt(Res, Op, true); 348 return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op); 349 } 350 351 MachineInstrBuilder MachineIRBuilderBase::buildZExt(unsigned Res, unsigned Op) { 352 validateTruncExt(Res, Op, true); 353 return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op); 354 } 355 356 MachineInstrBuilder MachineIRBuilderBase::buildExtOrTrunc(unsigned ExtOpc, 357 unsigned Res, 358 unsigned Op) { 359 assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc || 360 TargetOpcode::G_SEXT == ExtOpc) && 361 "Expecting Extending Opc"); 362 assert(getMRI()->getType(Res).isScalar() || 363 getMRI()->getType(Res).isVector()); 364 assert(getMRI()->getType(Res).isScalar() == getMRI()->getType(Op).isScalar()); 365 366 unsigned Opcode = TargetOpcode::COPY; 367 if (getMRI()->getType(Res).getSizeInBits() > 368 getMRI()->getType(Op).getSizeInBits()) 369 Opcode = ExtOpc; 370 else if (getMRI()->getType(Res).getSizeInBits() < 371 getMRI()->getType(Op).getSizeInBits()) 372 Opcode = TargetOpcode::G_TRUNC; 373 else 374 assert(getMRI()->getType(Res) == getMRI()->getType(Op)); 375 376 return buildInstr(Opcode).addDef(Res).addUse(Op); 377 } 378 379 MachineInstrBuilder MachineIRBuilderBase::buildSExtOrTrunc(unsigned Res, 380 unsigned Op) { 381 return buildExtOrTrunc(TargetOpcode::G_SEXT, Res, Op); 382 } 383 384 MachineInstrBuilder MachineIRBuilderBase::buildZExtOrTrunc(unsigned Res, 385 unsigned Op) { 386 return buildExtOrTrunc(TargetOpcode::G_ZEXT, Res, Op); 387 } 388 389 MachineInstrBuilder MachineIRBuilderBase::buildAnyExtOrTrunc(unsigned Res, 390 unsigned Op) { 391 return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op); 392 } 393 394 MachineInstrBuilder MachineIRBuilderBase::buildCast(unsigned Dst, 395 unsigned Src) { 396 LLT SrcTy = getMRI()->getType(Src); 397 LLT DstTy = getMRI()->getType(Dst); 398 if (SrcTy == DstTy) 399 return buildCopy(Dst, Src); 400 401 unsigned Opcode; 402 if (SrcTy.isPointer() && DstTy.isScalar()) 403 Opcode = TargetOpcode::G_PTRTOINT; 404 else if (DstTy.isPointer() && SrcTy.isScalar()) 405 Opcode = TargetOpcode::G_INTTOPTR; 406 else { 407 assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet"); 408 Opcode = TargetOpcode::G_BITCAST; 409 } 410 411 return buildInstr(Opcode).addDef(Dst).addUse(Src); 412 } 413 414 MachineInstrBuilder 415 MachineIRBuilderBase::buildExtract(unsigned Res, unsigned Src, uint64_t Index) { 416 #ifndef NDEBUG 417 assert(getMRI()->getType(Src).isValid() && "invalid operand type"); 418 assert(getMRI()->getType(Res).isValid() && "invalid operand type"); 419 assert(Index + getMRI()->getType(Res).getSizeInBits() <= 420 getMRI()->getType(Src).getSizeInBits() && 421 "extracting off end of register"); 422 #endif 423 424 if (getMRI()->getType(Res).getSizeInBits() == 425 getMRI()->getType(Src).getSizeInBits()) { 426 assert(Index == 0 && "insertion past the end of a register"); 427 return buildCast(Res, Src); 428 } 429 430 return buildInstr(TargetOpcode::G_EXTRACT) 431 .addDef(Res) 432 .addUse(Src) 433 .addImm(Index); 434 } 435 436 void MachineIRBuilderBase::buildSequence(unsigned Res, ArrayRef<unsigned> Ops, 437 ArrayRef<uint64_t> Indices) { 438 #ifndef NDEBUG 439 assert(Ops.size() == Indices.size() && "incompatible args"); 440 assert(!Ops.empty() && "invalid trivial sequence"); 441 assert(std::is_sorted(Indices.begin(), Indices.end()) && 442 "sequence offsets must be in ascending order"); 443 444 assert(getMRI()->getType(Res).isValid() && "invalid operand type"); 445 for (auto Op : Ops) 446 assert(getMRI()->getType(Op).isValid() && "invalid operand type"); 447 #endif 448 449 LLT ResTy = getMRI()->getType(Res); 450 LLT OpTy = getMRI()->getType(Ops[0]); 451 unsigned OpSize = OpTy.getSizeInBits(); 452 bool MaybeMerge = true; 453 for (unsigned i = 0; i < Ops.size(); ++i) { 454 if (getMRI()->getType(Ops[i]) != OpTy || Indices[i] != i * OpSize) { 455 MaybeMerge = false; 456 break; 457 } 458 } 459 460 if (MaybeMerge && Ops.size() * OpSize == ResTy.getSizeInBits()) { 461 buildMerge(Res, Ops); 462 return; 463 } 464 465 unsigned ResIn = getMRI()->createGenericVirtualRegister(ResTy); 466 buildUndef(ResIn); 467 468 for (unsigned i = 0; i < Ops.size(); ++i) { 469 unsigned ResOut = i + 1 == Ops.size() 470 ? Res 471 : getMRI()->createGenericVirtualRegister(ResTy); 472 buildInsert(ResOut, ResIn, Ops[i], Indices[i]); 473 ResIn = ResOut; 474 } 475 } 476 477 MachineInstrBuilder MachineIRBuilderBase::buildUndef(unsigned Res) { 478 return buildInstr(TargetOpcode::G_IMPLICIT_DEF).addDef(Res); 479 } 480 481 MachineInstrBuilder MachineIRBuilderBase::buildMerge(unsigned Res, 482 ArrayRef<unsigned> Ops) { 483 484 #ifndef NDEBUG 485 assert(!Ops.empty() && "invalid trivial sequence"); 486 LLT Ty = getMRI()->getType(Ops[0]); 487 for (auto Reg : Ops) 488 assert(getMRI()->getType(Reg) == Ty && "type mismatch in input list"); 489 assert(Ops.size() * getMRI()->getType(Ops[0]).getSizeInBits() == 490 getMRI()->getType(Res).getSizeInBits() && 491 "input operands do not cover output register"); 492 #endif 493 494 if (Ops.size() == 1) 495 return buildCast(Res, Ops[0]); 496 497 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES); 498 MIB.addDef(Res); 499 for (unsigned i = 0; i < Ops.size(); ++i) 500 MIB.addUse(Ops[i]); 501 return MIB; 502 } 503 504 MachineInstrBuilder MachineIRBuilderBase::buildUnmerge(ArrayRef<unsigned> Res, 505 unsigned Op) { 506 507 #ifndef NDEBUG 508 assert(!Res.empty() && "invalid trivial sequence"); 509 LLT Ty = getMRI()->getType(Res[0]); 510 for (auto Reg : Res) 511 assert(getMRI()->getType(Reg) == Ty && "type mismatch in input list"); 512 assert(Res.size() * getMRI()->getType(Res[0]).getSizeInBits() == 513 getMRI()->getType(Op).getSizeInBits() && 514 "input operands do not cover output register"); 515 #endif 516 517 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES); 518 for (unsigned i = 0; i < Res.size(); ++i) 519 MIB.addDef(Res[i]); 520 MIB.addUse(Op); 521 return MIB; 522 } 523 524 MachineInstrBuilder MachineIRBuilderBase::buildInsert(unsigned Res, 525 unsigned Src, unsigned Op, 526 unsigned Index) { 527 assert(Index + getMRI()->getType(Op).getSizeInBits() <= 528 getMRI()->getType(Res).getSizeInBits() && 529 "insertion past the end of a register"); 530 531 if (getMRI()->getType(Res).getSizeInBits() == 532 getMRI()->getType(Op).getSizeInBits()) { 533 return buildCast(Res, Op); 534 } 535 536 return buildInstr(TargetOpcode::G_INSERT) 537 .addDef(Res) 538 .addUse(Src) 539 .addUse(Op) 540 .addImm(Index); 541 } 542 543 MachineInstrBuilder MachineIRBuilderBase::buildIntrinsic(Intrinsic::ID ID, 544 unsigned Res, 545 bool HasSideEffects) { 546 auto MIB = 547 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS 548 : TargetOpcode::G_INTRINSIC); 549 if (Res) 550 MIB.addDef(Res); 551 MIB.addIntrinsicID(ID); 552 return MIB; 553 } 554 555 MachineInstrBuilder MachineIRBuilderBase::buildTrunc(unsigned Res, 556 unsigned Op) { 557 validateTruncExt(Res, Op, false); 558 return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op); 559 } 560 561 MachineInstrBuilder MachineIRBuilderBase::buildFPTrunc(unsigned Res, 562 unsigned Op) { 563 validateTruncExt(Res, Op, false); 564 return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op); 565 } 566 567 MachineInstrBuilder MachineIRBuilderBase::buildICmp(CmpInst::Predicate Pred, 568 unsigned Res, unsigned Op0, 569 unsigned Op1) { 570 #ifndef NDEBUG 571 assert(getMRI()->getType(Op0) == getMRI()->getType(Op0) && "type mismatch"); 572 assert(CmpInst::isIntPredicate(Pred) && "invalid predicate"); 573 if (getMRI()->getType(Op0).isScalar() || getMRI()->getType(Op0).isPointer()) 574 assert(getMRI()->getType(Res).isScalar() && "type mismatch"); 575 else 576 assert(getMRI()->getType(Res).isVector() && 577 getMRI()->getType(Res).getNumElements() == 578 getMRI()->getType(Op0).getNumElements() && 579 "type mismatch"); 580 #endif 581 582 return buildInstr(TargetOpcode::G_ICMP) 583 .addDef(Res) 584 .addPredicate(Pred) 585 .addUse(Op0) 586 .addUse(Op1); 587 } 588 589 MachineInstrBuilder MachineIRBuilderBase::buildFCmp(CmpInst::Predicate Pred, 590 unsigned Res, unsigned Op0, 591 unsigned Op1) { 592 #ifndef NDEBUG 593 assert((getMRI()->getType(Op0).isScalar() || 594 getMRI()->getType(Op0).isVector()) && 595 "invalid operand type"); 596 assert(getMRI()->getType(Op0) == getMRI()->getType(Op1) && "type mismatch"); 597 assert(CmpInst::isFPPredicate(Pred) && "invalid predicate"); 598 if (getMRI()->getType(Op0).isScalar()) 599 assert(getMRI()->getType(Res).isScalar() && "type mismatch"); 600 else 601 assert(getMRI()->getType(Res).isVector() && 602 getMRI()->getType(Res).getNumElements() == 603 getMRI()->getType(Op0).getNumElements() && 604 "type mismatch"); 605 #endif 606 607 return buildInstr(TargetOpcode::G_FCMP) 608 .addDef(Res) 609 .addPredicate(Pred) 610 .addUse(Op0) 611 .addUse(Op1); 612 } 613 614 MachineInstrBuilder MachineIRBuilderBase::buildSelect(unsigned Res, 615 unsigned Tst, 616 unsigned Op0, 617 unsigned Op1) { 618 #ifndef NDEBUG 619 LLT ResTy = getMRI()->getType(Res); 620 assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) && 621 "invalid operand type"); 622 assert(ResTy == getMRI()->getType(Op0) && ResTy == getMRI()->getType(Op1) && 623 "type mismatch"); 624 if (ResTy.isScalar() || ResTy.isPointer()) 625 assert(getMRI()->getType(Tst).isScalar() && "type mismatch"); 626 else 627 assert((getMRI()->getType(Tst).isScalar() || 628 (getMRI()->getType(Tst).isVector() && 629 getMRI()->getType(Tst).getNumElements() == 630 getMRI()->getType(Op0).getNumElements())) && 631 "type mismatch"); 632 #endif 633 634 return buildInstr(TargetOpcode::G_SELECT) 635 .addDef(Res) 636 .addUse(Tst) 637 .addUse(Op0) 638 .addUse(Op1); 639 } 640 641 MachineInstrBuilder 642 MachineIRBuilderBase::buildInsertVectorElement(unsigned Res, unsigned Val, 643 unsigned Elt, unsigned Idx) { 644 #ifndef NDEBUG 645 LLT ResTy = getMRI()->getType(Res); 646 LLT ValTy = getMRI()->getType(Val); 647 LLT EltTy = getMRI()->getType(Elt); 648 LLT IdxTy = getMRI()->getType(Idx); 649 assert(ResTy.isVector() && ValTy.isVector() && "invalid operand type"); 650 assert(IdxTy.isScalar() && "invalid operand type"); 651 assert(ResTy.getNumElements() == ValTy.getNumElements() && "type mismatch"); 652 assert(ResTy.getElementType() == EltTy && "type mismatch"); 653 #endif 654 655 return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT) 656 .addDef(Res) 657 .addUse(Val) 658 .addUse(Elt) 659 .addUse(Idx); 660 } 661 662 MachineInstrBuilder 663 MachineIRBuilderBase::buildExtractVectorElement(unsigned Res, unsigned Val, 664 unsigned Idx) { 665 #ifndef NDEBUG 666 LLT ResTy = getMRI()->getType(Res); 667 LLT ValTy = getMRI()->getType(Val); 668 LLT IdxTy = getMRI()->getType(Idx); 669 assert(ValTy.isVector() && "invalid operand type"); 670 assert((ResTy.isScalar() || ResTy.isPointer()) && "invalid operand type"); 671 assert(IdxTy.isScalar() && "invalid operand type"); 672 assert(ValTy.getElementType() == ResTy && "type mismatch"); 673 #endif 674 675 return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT) 676 .addDef(Res) 677 .addUse(Val) 678 .addUse(Idx); 679 } 680 681 MachineInstrBuilder MachineIRBuilderBase::buildAtomicCmpXchgWithSuccess( 682 unsigned OldValRes, unsigned SuccessRes, unsigned Addr, unsigned CmpVal, 683 unsigned NewVal, MachineMemOperand &MMO) { 684 #ifndef NDEBUG 685 LLT OldValResTy = getMRI()->getType(OldValRes); 686 LLT SuccessResTy = getMRI()->getType(SuccessRes); 687 LLT AddrTy = getMRI()->getType(Addr); 688 LLT CmpValTy = getMRI()->getType(CmpVal); 689 LLT NewValTy = getMRI()->getType(NewVal); 690 assert(OldValResTy.isScalar() && "invalid operand type"); 691 assert(SuccessResTy.isScalar() && "invalid operand type"); 692 assert(AddrTy.isPointer() && "invalid operand type"); 693 assert(CmpValTy.isValid() && "invalid operand type"); 694 assert(NewValTy.isValid() && "invalid operand type"); 695 assert(OldValResTy == CmpValTy && "type mismatch"); 696 assert(OldValResTy == NewValTy && "type mismatch"); 697 #endif 698 699 return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS) 700 .addDef(OldValRes) 701 .addDef(SuccessRes) 702 .addUse(Addr) 703 .addUse(CmpVal) 704 .addUse(NewVal) 705 .addMemOperand(&MMO); 706 } 707 708 MachineInstrBuilder 709 MachineIRBuilderBase::buildAtomicCmpXchg(unsigned OldValRes, unsigned Addr, 710 unsigned CmpVal, unsigned NewVal, 711 MachineMemOperand &MMO) { 712 #ifndef NDEBUG 713 LLT OldValResTy = getMRI()->getType(OldValRes); 714 LLT AddrTy = getMRI()->getType(Addr); 715 LLT CmpValTy = getMRI()->getType(CmpVal); 716 LLT NewValTy = getMRI()->getType(NewVal); 717 assert(OldValResTy.isScalar() && "invalid operand type"); 718 assert(AddrTy.isPointer() && "invalid operand type"); 719 assert(CmpValTy.isValid() && "invalid operand type"); 720 assert(NewValTy.isValid() && "invalid operand type"); 721 assert(OldValResTy == CmpValTy && "type mismatch"); 722 assert(OldValResTy == NewValTy && "type mismatch"); 723 #endif 724 725 return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG) 726 .addDef(OldValRes) 727 .addUse(Addr) 728 .addUse(CmpVal) 729 .addUse(NewVal) 730 .addMemOperand(&MMO); 731 } 732 733 MachineInstrBuilder 734 MachineIRBuilderBase::buildAtomicRMW(unsigned Opcode, unsigned OldValRes, 735 unsigned Addr, unsigned Val, 736 MachineMemOperand &MMO) { 737 #ifndef NDEBUG 738 LLT OldValResTy = getMRI()->getType(OldValRes); 739 LLT AddrTy = getMRI()->getType(Addr); 740 LLT ValTy = getMRI()->getType(Val); 741 assert(OldValResTy.isScalar() && "invalid operand type"); 742 assert(AddrTy.isPointer() && "invalid operand type"); 743 assert(ValTy.isValid() && "invalid operand type"); 744 assert(OldValResTy == ValTy && "type mismatch"); 745 #endif 746 747 return buildInstr(Opcode) 748 .addDef(OldValRes) 749 .addUse(Addr) 750 .addUse(Val) 751 .addMemOperand(&MMO); 752 } 753 754 MachineInstrBuilder 755 MachineIRBuilderBase::buildAtomicRMWXchg(unsigned OldValRes, unsigned Addr, 756 unsigned Val, MachineMemOperand &MMO) { 757 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XCHG, OldValRes, Addr, Val, 758 MMO); 759 } 760 MachineInstrBuilder 761 MachineIRBuilderBase::buildAtomicRMWAdd(unsigned OldValRes, unsigned Addr, 762 unsigned Val, MachineMemOperand &MMO) { 763 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_ADD, OldValRes, Addr, Val, 764 MMO); 765 } 766 MachineInstrBuilder 767 MachineIRBuilderBase::buildAtomicRMWSub(unsigned OldValRes, unsigned Addr, 768 unsigned Val, MachineMemOperand &MMO) { 769 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_SUB, OldValRes, Addr, Val, 770 MMO); 771 } 772 MachineInstrBuilder 773 MachineIRBuilderBase::buildAtomicRMWAnd(unsigned OldValRes, unsigned Addr, 774 unsigned Val, MachineMemOperand &MMO) { 775 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_AND, OldValRes, Addr, Val, 776 MMO); 777 } 778 MachineInstrBuilder 779 MachineIRBuilderBase::buildAtomicRMWNand(unsigned OldValRes, unsigned Addr, 780 unsigned Val, MachineMemOperand &MMO) { 781 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_NAND, OldValRes, Addr, Val, 782 MMO); 783 } 784 MachineInstrBuilder 785 MachineIRBuilderBase::buildAtomicRMWOr(unsigned OldValRes, unsigned Addr, 786 unsigned Val, MachineMemOperand &MMO) { 787 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_OR, OldValRes, Addr, Val, 788 MMO); 789 } 790 MachineInstrBuilder 791 MachineIRBuilderBase::buildAtomicRMWXor(unsigned OldValRes, unsigned Addr, 792 unsigned Val, MachineMemOperand &MMO) { 793 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XOR, OldValRes, Addr, Val, 794 MMO); 795 } 796 MachineInstrBuilder 797 MachineIRBuilderBase::buildAtomicRMWMax(unsigned OldValRes, unsigned Addr, 798 unsigned Val, MachineMemOperand &MMO) { 799 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MAX, OldValRes, Addr, Val, 800 MMO); 801 } 802 MachineInstrBuilder 803 MachineIRBuilderBase::buildAtomicRMWMin(unsigned OldValRes, unsigned Addr, 804 unsigned Val, MachineMemOperand &MMO) { 805 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MIN, OldValRes, Addr, Val, 806 MMO); 807 } 808 MachineInstrBuilder 809 MachineIRBuilderBase::buildAtomicRMWUmax(unsigned OldValRes, unsigned Addr, 810 unsigned Val, MachineMemOperand &MMO) { 811 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMAX, OldValRes, Addr, Val, 812 MMO); 813 } 814 MachineInstrBuilder 815 MachineIRBuilderBase::buildAtomicRMWUmin(unsigned OldValRes, unsigned Addr, 816 unsigned Val, MachineMemOperand &MMO) { 817 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMIN, OldValRes, Addr, Val, 818 MMO); 819 } 820 821 MachineInstrBuilder 822 MachineIRBuilderBase::buildBlockAddress(unsigned Res, const BlockAddress *BA) { 823 #ifndef NDEBUG 824 assert(getMRI()->getType(Res).isPointer() && "invalid res type"); 825 #endif 826 827 return buildInstr(TargetOpcode::G_BLOCK_ADDR).addDef(Res).addBlockAddress(BA); 828 } 829 830 void MachineIRBuilderBase::validateTruncExt(unsigned Dst, unsigned Src, 831 bool IsExtend) { 832 #ifndef NDEBUG 833 LLT SrcTy = getMRI()->getType(Src); 834 LLT DstTy = getMRI()->getType(Dst); 835 836 if (DstTy.isVector()) { 837 assert(SrcTy.isVector() && "mismatched cast between vector and non-vector"); 838 assert(SrcTy.getNumElements() == DstTy.getNumElements() && 839 "different number of elements in a trunc/ext"); 840 } else 841 assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc"); 842 843 if (IsExtend) 844 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() && 845 "invalid narrowing extend"); 846 else 847 assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() && 848 "invalid widening trunc"); 849 #endif 850 } 851