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/IR/DebugInfo.h" 19 #include "llvm/Target/TargetInstrInfo.h" 20 #include "llvm/Target/TargetOpcodes.h" 21 #include "llvm/Target/TargetSubtargetInfo.h" 22 23 using namespace llvm; 24 25 void MachineIRBuilder::setMF(MachineFunction &MF) { 26 this->MF = &MF; 27 this->MBB = nullptr; 28 this->MRI = &MF.getRegInfo(); 29 this->TII = MF.getSubtarget().getInstrInfo(); 30 this->DL = DebugLoc(); 31 this->II = MachineBasicBlock::iterator(); 32 this->InsertedInstr = nullptr; 33 } 34 35 void MachineIRBuilder::setMBB(MachineBasicBlock &MBB) { 36 this->MBB = &MBB; 37 this->II = MBB.end(); 38 assert(&getMF() == MBB.getParent() && 39 "Basic block is in a different function"); 40 } 41 42 void MachineIRBuilder::setInstr(MachineInstr &MI) { 43 assert(MI.getParent() && "Instruction is not part of a basic block"); 44 setMBB(*MI.getParent()); 45 this->II = MI.getIterator(); 46 } 47 48 void MachineIRBuilder::setInsertPt(MachineBasicBlock &MBB, 49 MachineBasicBlock::iterator II) { 50 assert(MBB.getParent() == &getMF() && 51 "Basic block is in a different function"); 52 this->MBB = &MBB; 53 this->II = II; 54 } 55 56 void MachineIRBuilder::recordInsertions( 57 std::function<void(MachineInstr *)> Inserted) { 58 InsertedInstr = std::move(Inserted); 59 } 60 61 void MachineIRBuilder::stopRecordingInsertions() { 62 InsertedInstr = nullptr; 63 } 64 65 //------------------------------------------------------------------------------ 66 // Build instruction variants. 67 //------------------------------------------------------------------------------ 68 69 MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode) { 70 return insertInstr(buildInstrNoInsert(Opcode)); 71 } 72 73 MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) { 74 MachineInstrBuilder MIB = BuildMI(getMF(), DL, getTII().get(Opcode)); 75 return MIB; 76 } 77 78 79 MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) { 80 getMBB().insert(getInsertPt(), MIB); 81 if (InsertedInstr) 82 InsertedInstr(MIB); 83 return MIB; 84 } 85 86 MachineInstrBuilder MachineIRBuilder::buildDirectDbgValue( 87 unsigned Reg, const MDNode *Variable, const MDNode *Expr) { 88 assert(isa<DILocalVariable>(Variable) && "not a variable"); 89 assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 90 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 91 "Expected inlined-at fields to agree"); 92 return buildInstr(TargetOpcode::DBG_VALUE) 93 .addReg(Reg, RegState::Debug) 94 .addReg(0, RegState::Debug) 95 .addMetadata(Variable) 96 .addMetadata(Expr); 97 } 98 99 MachineInstrBuilder MachineIRBuilder::buildIndirectDbgValue( 100 unsigned Reg, unsigned Offset, const MDNode *Variable, const MDNode *Expr) { 101 assert(isa<DILocalVariable>(Variable) && "not a variable"); 102 assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 103 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 104 "Expected inlined-at fields to agree"); 105 return buildInstr(TargetOpcode::DBG_VALUE) 106 .addReg(Reg, RegState::Debug) 107 .addImm(Offset) 108 .addMetadata(Variable) 109 .addMetadata(Expr); 110 } 111 112 MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI, 113 const MDNode *Variable, 114 const MDNode *Expr) { 115 assert(isa<DILocalVariable>(Variable) && "not a variable"); 116 assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 117 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 118 "Expected inlined-at fields to agree"); 119 return buildInstr(TargetOpcode::DBG_VALUE) 120 .addFrameIndex(FI) 121 .addImm(0) 122 .addMetadata(Variable) 123 .addMetadata(Expr); 124 } 125 126 MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C, 127 unsigned Offset, 128 const MDNode *Variable, 129 const MDNode *Expr) { 130 assert(isa<DILocalVariable>(Variable) && "not a variable"); 131 assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 132 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 133 "Expected inlined-at fields to agree"); 134 auto MIB = buildInstr(TargetOpcode::DBG_VALUE); 135 if (auto *CI = dyn_cast<ConstantInt>(&C)) { 136 if (CI->getBitWidth() > 64) 137 MIB.addCImm(CI); 138 else 139 MIB.addImm(CI->getZExtValue()); 140 } else if (auto *CFP = dyn_cast<ConstantFP>(&C)) { 141 MIB.addFPImm(CFP); 142 } else { 143 // Insert %noreg if we didn't find a usable constant and had to drop it. 144 MIB.addReg(0U); 145 } 146 147 return MIB.addImm(Offset).addMetadata(Variable).addMetadata(Expr); 148 } 149 150 MachineInstrBuilder MachineIRBuilder::buildFrameIndex(unsigned Res, int Idx) { 151 assert(MRI->getType(Res).isPointer() && "invalid operand type"); 152 return buildInstr(TargetOpcode::G_FRAME_INDEX) 153 .addDef(Res) 154 .addFrameIndex(Idx); 155 } 156 157 MachineInstrBuilder MachineIRBuilder::buildGlobalValue(unsigned Res, 158 const GlobalValue *GV) { 159 assert(MRI->getType(Res).isPointer() && "invalid operand type"); 160 assert(MRI->getType(Res).getAddressSpace() == 161 GV->getType()->getAddressSpace() && 162 "address space mismatch"); 163 164 return buildInstr(TargetOpcode::G_GLOBAL_VALUE) 165 .addDef(Res) 166 .addGlobalAddress(GV); 167 } 168 169 MachineInstrBuilder MachineIRBuilder::buildAdd(unsigned Res, unsigned Op0, 170 unsigned Op1) { 171 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) && 172 "invalid operand type"); 173 assert(MRI->getType(Res) == MRI->getType(Op0) && 174 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch"); 175 176 return buildInstr(TargetOpcode::G_ADD) 177 .addDef(Res) 178 .addUse(Op0) 179 .addUse(Op1); 180 } 181 182 MachineInstrBuilder MachineIRBuilder::buildGEP(unsigned Res, unsigned Op0, 183 unsigned Op1) { 184 assert(MRI->getType(Res).isPointer() && 185 MRI->getType(Res) == MRI->getType(Op0) && "type mismatch"); 186 assert(MRI->getType(Op1).isScalar() && "invalid offset type"); 187 188 return buildInstr(TargetOpcode::G_GEP) 189 .addDef(Res) 190 .addUse(Op0) 191 .addUse(Op1); 192 } 193 194 Optional<MachineInstrBuilder> 195 MachineIRBuilder::materializeGEP(unsigned &Res, unsigned Op0, 196 const LLT &ValueTy, uint64_t Value) { 197 assert(Res == 0 && "Res is a result argument"); 198 assert(ValueTy.isScalar() && "invalid offset type"); 199 200 if (Value == 0) { 201 Res = Op0; 202 return None; 203 } 204 205 Res = MRI->createGenericVirtualRegister(MRI->getType(Op0)); 206 unsigned TmpReg = MRI->createGenericVirtualRegister(ValueTy); 207 208 buildConstant(TmpReg, Value); 209 return buildGEP(Res, Op0, TmpReg); 210 } 211 212 MachineInstrBuilder MachineIRBuilder::buildPtrMask(unsigned Res, unsigned Op0, 213 uint32_t NumBits) { 214 assert(MRI->getType(Res).isPointer() && 215 MRI->getType(Res) == MRI->getType(Op0) && "type mismatch"); 216 217 return buildInstr(TargetOpcode::G_PTR_MASK) 218 .addDef(Res) 219 .addUse(Op0) 220 .addImm(NumBits); 221 } 222 223 MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0, 224 unsigned Op1) { 225 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) && 226 "invalid operand type"); 227 assert(MRI->getType(Res) == MRI->getType(Op0) && 228 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch"); 229 230 return buildInstr(TargetOpcode::G_SUB) 231 .addDef(Res) 232 .addUse(Op0) 233 .addUse(Op1); 234 } 235 236 MachineInstrBuilder MachineIRBuilder::buildMul(unsigned Res, unsigned Op0, 237 unsigned Op1) { 238 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) && 239 "invalid operand type"); 240 assert(MRI->getType(Res) == MRI->getType(Op0) && 241 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch"); 242 243 return buildInstr(TargetOpcode::G_MUL) 244 .addDef(Res) 245 .addUse(Op0) 246 .addUse(Op1); 247 } 248 249 MachineInstrBuilder MachineIRBuilder::buildAnd(unsigned Res, unsigned Op0, 250 unsigned Op1) { 251 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) && 252 "invalid operand type"); 253 assert(MRI->getType(Res) == MRI->getType(Op0) && 254 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch"); 255 256 return buildInstr(TargetOpcode::G_AND) 257 .addDef(Res) 258 .addUse(Op0) 259 .addUse(Op1); 260 } 261 262 MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) { 263 return buildInstr(TargetOpcode::G_BR).addMBB(&Dest); 264 } 265 266 MachineInstrBuilder MachineIRBuilder::buildBrIndirect(unsigned Tgt) { 267 return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt); 268 } 269 270 MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) { 271 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op); 272 } 273 274 MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res, 275 const ConstantInt &Val) { 276 LLT Ty = MRI->getType(Res); 277 278 assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type"); 279 280 const ConstantInt *NewVal = &Val; 281 if (Ty.getSizeInBits() != Val.getBitWidth()) 282 NewVal = ConstantInt::get(MF->getFunction()->getContext(), 283 Val.getValue().sextOrTrunc(Ty.getSizeInBits())); 284 285 return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal); 286 } 287 288 MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res, 289 int64_t Val) { 290 auto IntN = IntegerType::get(MF->getFunction()->getContext(), 291 MRI->getType(Res).getSizeInBits()); 292 ConstantInt *CI = ConstantInt::get(IntN, Val, true); 293 return buildConstant(Res, *CI); 294 } 295 296 MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res, 297 const ConstantFP &Val) { 298 assert(MRI->getType(Res).isScalar() && "invalid operand type"); 299 300 return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val); 301 } 302 303 MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst, 304 MachineBasicBlock &Dest) { 305 assert(MRI->getType(Tst).isScalar() && "invalid operand type"); 306 307 return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest); 308 } 309 310 MachineInstrBuilder MachineIRBuilder::buildLoad(unsigned Res, unsigned Addr, 311 MachineMemOperand &MMO) { 312 assert(MRI->getType(Res).isValid() && "invalid operand type"); 313 assert(MRI->getType(Addr).isPointer() && "invalid operand type"); 314 315 return buildInstr(TargetOpcode::G_LOAD) 316 .addDef(Res) 317 .addUse(Addr) 318 .addMemOperand(&MMO); 319 } 320 321 MachineInstrBuilder MachineIRBuilder::buildStore(unsigned Val, unsigned Addr, 322 MachineMemOperand &MMO) { 323 assert(MRI->getType(Val).isValid() && "invalid operand type"); 324 assert(MRI->getType(Addr).isPointer() && "invalid operand type"); 325 326 return buildInstr(TargetOpcode::G_STORE) 327 .addUse(Val) 328 .addUse(Addr) 329 .addMemOperand(&MMO); 330 } 331 332 MachineInstrBuilder MachineIRBuilder::buildUAdde(unsigned Res, 333 unsigned CarryOut, 334 unsigned Op0, unsigned Op1, 335 unsigned CarryIn) { 336 assert(MRI->getType(Res).isScalar() && "invalid operand type"); 337 assert(MRI->getType(Res) == MRI->getType(Op0) && 338 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch"); 339 assert(MRI->getType(CarryOut).isScalar() && "invalid operand type"); 340 assert(MRI->getType(CarryOut) == MRI->getType(CarryIn) && "type mismatch"); 341 342 return buildInstr(TargetOpcode::G_UADDE) 343 .addDef(Res) 344 .addDef(CarryOut) 345 .addUse(Op0) 346 .addUse(Op1) 347 .addUse(CarryIn); 348 } 349 350 MachineInstrBuilder MachineIRBuilder::buildAnyExt(unsigned Res, unsigned Op) { 351 validateTruncExt(Res, Op, true); 352 return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op); 353 } 354 355 MachineInstrBuilder MachineIRBuilder::buildSExt(unsigned Res, unsigned Op) { 356 validateTruncExt(Res, Op, true); 357 return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op); 358 } 359 360 MachineInstrBuilder MachineIRBuilder::buildZExt(unsigned Res, unsigned Op) { 361 validateTruncExt(Res, Op, true); 362 return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op); 363 } 364 365 MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(unsigned Res, 366 unsigned Op) { 367 unsigned Opcode = TargetOpcode::COPY; 368 if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits()) 369 Opcode = TargetOpcode::G_SEXT; 370 else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits()) 371 Opcode = TargetOpcode::G_TRUNC; 372 373 return buildInstr(Opcode).addDef(Res).addUse(Op); 374 } 375 376 MachineInstrBuilder MachineIRBuilder::buildZExtOrTrunc(unsigned Res, 377 unsigned Op) { 378 unsigned Opcode = TargetOpcode::COPY; 379 if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits()) 380 Opcode = TargetOpcode::G_ZEXT; 381 else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits()) 382 Opcode = TargetOpcode::G_TRUNC; 383 384 return buildInstr(Opcode).addDef(Res).addUse(Op); 385 } 386 387 388 MachineInstrBuilder MachineIRBuilder::buildCast(unsigned Dst, unsigned Src) { 389 LLT SrcTy = MRI->getType(Src); 390 LLT DstTy = MRI->getType(Dst); 391 if (SrcTy == DstTy) 392 return buildCopy(Dst, Src); 393 394 unsigned Opcode; 395 if (SrcTy.isPointer() && DstTy.isScalar()) 396 Opcode = TargetOpcode::G_PTRTOINT; 397 else if (DstTy.isPointer() && SrcTy.isScalar()) 398 Opcode = TargetOpcode::G_INTTOPTR; 399 else { 400 assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet"); 401 Opcode = TargetOpcode::G_BITCAST; 402 } 403 404 return buildInstr(Opcode).addDef(Dst).addUse(Src); 405 } 406 407 MachineInstrBuilder MachineIRBuilder::buildExtract(unsigned Res, unsigned Src, 408 uint64_t Index) { 409 #ifndef NDEBUG 410 assert(MRI->getType(Src).isValid() && "invalid operand type"); 411 assert(MRI->getType(Res).isValid() && "invalid operand type"); 412 assert(Index + MRI->getType(Res).getSizeInBits() <= 413 MRI->getType(Src).getSizeInBits() && 414 "extracting off end of register"); 415 #endif 416 417 if (MRI->getType(Res).getSizeInBits() == MRI->getType(Src).getSizeInBits()) { 418 assert(Index == 0 && "insertion past the end of a register"); 419 return buildCast(Res, Src); 420 } 421 422 return buildInstr(TargetOpcode::G_EXTRACT) 423 .addDef(Res) 424 .addUse(Src) 425 .addImm(Index); 426 } 427 428 void MachineIRBuilder::buildSequence(unsigned Res, ArrayRef<unsigned> Ops, 429 ArrayRef<uint64_t> Indices) { 430 #ifndef NDEBUG 431 assert(Ops.size() == Indices.size() && "incompatible args"); 432 assert(!Ops.empty() && "invalid trivial sequence"); 433 assert(std::is_sorted(Indices.begin(), Indices.end()) && 434 "sequence offsets must be in ascending order"); 435 436 assert(MRI->getType(Res).isValid() && "invalid operand type"); 437 for (auto Op : Ops) 438 assert(MRI->getType(Op).isValid() && "invalid operand type"); 439 #endif 440 441 LLT ResTy = MRI->getType(Res); 442 LLT OpTy = MRI->getType(Ops[0]); 443 unsigned OpSize = OpTy.getSizeInBits(); 444 bool MaybeMerge = true; 445 for (unsigned i = 0; i < Ops.size(); ++i) { 446 if (MRI->getType(Ops[i]) != OpTy || Indices[i] != i * OpSize) { 447 MaybeMerge = false; 448 break; 449 } 450 } 451 452 if (MaybeMerge && Ops.size() * OpSize == ResTy.getSizeInBits()) { 453 buildMerge(Res, Ops); 454 return; 455 } 456 457 unsigned ResIn = MRI->createGenericVirtualRegister(ResTy); 458 buildUndef(ResIn); 459 460 for (unsigned i = 0; i < Ops.size(); ++i) { 461 unsigned ResOut = 462 i + 1 == Ops.size() ? Res : MRI->createGenericVirtualRegister(ResTy); 463 buildInsert(ResOut, ResIn, Ops[i], Indices[i]); 464 ResIn = ResOut; 465 } 466 } 467 468 MachineInstrBuilder MachineIRBuilder::buildUndef(unsigned Res) { 469 return buildInstr(TargetOpcode::IMPLICIT_DEF).addDef(Res); 470 } 471 472 MachineInstrBuilder MachineIRBuilder::buildMerge(unsigned Res, 473 ArrayRef<unsigned> Ops) { 474 475 #ifndef NDEBUG 476 assert(!Ops.empty() && "invalid trivial sequence"); 477 LLT Ty = MRI->getType(Ops[0]); 478 for (auto Reg : Ops) 479 assert(MRI->getType(Reg) == Ty && "type mismatch in input list"); 480 assert(Ops.size() * MRI->getType(Ops[0]).getSizeInBits() == 481 MRI->getType(Res).getSizeInBits() && 482 "input operands do not cover output register"); 483 #endif 484 485 if (Ops.size() == 1) 486 return buildCopy(Res, Ops[0]); 487 488 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES); 489 MIB.addDef(Res); 490 for (unsigned i = 0; i < Ops.size(); ++i) 491 MIB.addUse(Ops[i]); 492 return MIB; 493 } 494 495 MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<unsigned> Res, 496 unsigned Op) { 497 498 #ifndef NDEBUG 499 assert(!Res.empty() && "invalid trivial sequence"); 500 LLT Ty = MRI->getType(Res[0]); 501 for (auto Reg : Res) 502 assert(MRI->getType(Reg) == Ty && "type mismatch in input list"); 503 assert(Res.size() * MRI->getType(Res[0]).getSizeInBits() == 504 MRI->getType(Op).getSizeInBits() && 505 "input operands do not cover output register"); 506 #endif 507 508 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES); 509 for (unsigned i = 0; i < Res.size(); ++i) 510 MIB.addDef(Res[i]); 511 MIB.addUse(Op); 512 return MIB; 513 } 514 515 MachineInstrBuilder MachineIRBuilder::buildInsert(unsigned Res, unsigned Src, 516 unsigned Op, unsigned Index) { 517 if (MRI->getType(Res).getSizeInBits() == MRI->getType(Op).getSizeInBits()) { 518 assert(Index == 0 && "insertion past the end of a register"); 519 return buildCast(Res, Op); 520 } 521 522 return buildInstr(TargetOpcode::G_INSERT) 523 .addDef(Res) 524 .addUse(Src) 525 .addUse(Op) 526 .addImm(Index); 527 } 528 529 MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID, 530 unsigned Res, 531 bool HasSideEffects) { 532 auto MIB = 533 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS 534 : TargetOpcode::G_INTRINSIC); 535 if (Res) 536 MIB.addDef(Res); 537 MIB.addIntrinsicID(ID); 538 return MIB; 539 } 540 541 MachineInstrBuilder MachineIRBuilder::buildTrunc(unsigned Res, unsigned Op) { 542 validateTruncExt(Res, Op, false); 543 return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op); 544 } 545 546 MachineInstrBuilder MachineIRBuilder::buildFPTrunc(unsigned Res, unsigned Op) { 547 validateTruncExt(Res, Op, false); 548 return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op); 549 } 550 551 MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred, 552 unsigned Res, unsigned Op0, 553 unsigned Op1) { 554 #ifndef NDEBUG 555 assert(MRI->getType(Op0) == MRI->getType(Op0) && "type mismatch"); 556 assert(CmpInst::isIntPredicate(Pred) && "invalid predicate"); 557 if (MRI->getType(Op0).isScalar() || MRI->getType(Op0).isPointer()) 558 assert(MRI->getType(Res).isScalar() && "type mismatch"); 559 else 560 assert(MRI->getType(Res).isVector() && 561 MRI->getType(Res).getNumElements() == 562 MRI->getType(Op0).getNumElements() && 563 "type mismatch"); 564 #endif 565 566 return buildInstr(TargetOpcode::G_ICMP) 567 .addDef(Res) 568 .addPredicate(Pred) 569 .addUse(Op0) 570 .addUse(Op1); 571 } 572 573 MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred, 574 unsigned Res, unsigned Op0, 575 unsigned Op1) { 576 #ifndef NDEBUG 577 assert((MRI->getType(Op0).isScalar() || MRI->getType(Op0).isVector()) && 578 "invalid operand type"); 579 assert(MRI->getType(Op0) == MRI->getType(Op1) && "type mismatch"); 580 assert(CmpInst::isFPPredicate(Pred) && "invalid predicate"); 581 if (MRI->getType(Op0).isScalar()) 582 assert(MRI->getType(Res).isScalar() && "type mismatch"); 583 else 584 assert(MRI->getType(Res).isVector() && 585 MRI->getType(Res).getNumElements() == 586 MRI->getType(Op0).getNumElements() && 587 "type mismatch"); 588 #endif 589 590 return buildInstr(TargetOpcode::G_FCMP) 591 .addDef(Res) 592 .addPredicate(Pred) 593 .addUse(Op0) 594 .addUse(Op1); 595 } 596 597 MachineInstrBuilder MachineIRBuilder::buildSelect(unsigned Res, unsigned Tst, 598 unsigned Op0, unsigned Op1) { 599 #ifndef NDEBUG 600 LLT ResTy = MRI->getType(Res); 601 assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) && 602 "invalid operand type"); 603 assert(ResTy == MRI->getType(Op0) && ResTy == MRI->getType(Op1) && 604 "type mismatch"); 605 if (ResTy.isScalar() || ResTy.isPointer()) 606 assert(MRI->getType(Tst).isScalar() && "type mismatch"); 607 else 608 assert((MRI->getType(Tst).isScalar() || 609 (MRI->getType(Tst).isVector() && 610 MRI->getType(Tst).getNumElements() == 611 MRI->getType(Op0).getNumElements())) && 612 "type mismatch"); 613 #endif 614 615 return buildInstr(TargetOpcode::G_SELECT) 616 .addDef(Res) 617 .addUse(Tst) 618 .addUse(Op0) 619 .addUse(Op1); 620 } 621 622 MachineInstrBuilder MachineIRBuilder::buildInsertVectorElement(unsigned Res, 623 unsigned Val, 624 unsigned Elt, 625 unsigned Idx) { 626 #ifndef NDEBUG 627 LLT ResTy = MRI->getType(Res); 628 LLT ValTy = MRI->getType(Val); 629 LLT EltTy = MRI->getType(Elt); 630 LLT IdxTy = MRI->getType(Idx); 631 assert(ResTy.isVector() && ValTy.isVector() && "invalid operand type"); 632 assert(IdxTy.isScalar() && "invalid operand type"); 633 assert(ResTy.getNumElements() == ValTy.getNumElements() && "type mismatch"); 634 assert(ResTy.getElementType() == EltTy && "type mismatch"); 635 #endif 636 637 return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT) 638 .addDef(Res) 639 .addUse(Val) 640 .addUse(Elt) 641 .addUse(Idx); 642 } 643 644 MachineInstrBuilder MachineIRBuilder::buildExtractVectorElement(unsigned Res, 645 unsigned Val, 646 unsigned Idx) { 647 #ifndef NDEBUG 648 LLT ResTy = MRI->getType(Res); 649 LLT ValTy = MRI->getType(Val); 650 LLT IdxTy = MRI->getType(Idx); 651 assert(ValTy.isVector() && "invalid operand type"); 652 assert((ResTy.isScalar() || ResTy.isPointer()) && "invalid operand type"); 653 assert(IdxTy.isScalar() && "invalid operand type"); 654 assert(ValTy.getElementType() == ResTy && "type mismatch"); 655 #endif 656 657 return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT) 658 .addDef(Res) 659 .addUse(Val) 660 .addUse(Idx); 661 } 662 663 void MachineIRBuilder::validateTruncExt(unsigned Dst, unsigned Src, 664 bool IsExtend) { 665 #ifndef NDEBUG 666 LLT SrcTy = MRI->getType(Src); 667 LLT DstTy = MRI->getType(Dst); 668 669 if (DstTy.isVector()) { 670 assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector"); 671 assert(SrcTy.getNumElements() == DstTy.getNumElements() && 672 "different number of elements in a trunc/ext"); 673 } else 674 assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc"); 675 676 if (IsExtend) 677 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() && 678 "invalid narrowing extend"); 679 else 680 assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() && 681 "invalid widening trunc"); 682 #endif 683 } 684