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 MachineInstrBuilder MachineIRBuilder::buildPtrMask(unsigned Res, unsigned Op0, 195 uint32_t NumBits) { 196 assert(MRI->getType(Res).isPointer() && 197 MRI->getType(Res) == MRI->getType(Op0) && "type mismatch"); 198 199 return buildInstr(TargetOpcode::G_PTR_MASK) 200 .addDef(Res) 201 .addUse(Op0) 202 .addImm(NumBits); 203 } 204 205 MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0, 206 unsigned Op1) { 207 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) && 208 "invalid operand type"); 209 assert(MRI->getType(Res) == MRI->getType(Op0) && 210 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch"); 211 212 return buildInstr(TargetOpcode::G_SUB) 213 .addDef(Res) 214 .addUse(Op0) 215 .addUse(Op1); 216 } 217 218 MachineInstrBuilder MachineIRBuilder::buildMul(unsigned Res, unsigned Op0, 219 unsigned Op1) { 220 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) && 221 "invalid operand type"); 222 assert(MRI->getType(Res) == MRI->getType(Op0) && 223 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch"); 224 225 return buildInstr(TargetOpcode::G_MUL) 226 .addDef(Res) 227 .addUse(Op0) 228 .addUse(Op1); 229 } 230 231 MachineInstrBuilder MachineIRBuilder::buildAnd(unsigned Res, unsigned Op0, 232 unsigned Op1) { 233 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) && 234 "invalid operand type"); 235 assert(MRI->getType(Res) == MRI->getType(Op0) && 236 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch"); 237 238 return buildInstr(TargetOpcode::G_AND) 239 .addDef(Res) 240 .addUse(Op0) 241 .addUse(Op1); 242 } 243 244 MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) { 245 return buildInstr(TargetOpcode::G_BR).addMBB(&Dest); 246 } 247 248 MachineInstrBuilder MachineIRBuilder::buildBrIndirect(unsigned Tgt) { 249 return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt); 250 } 251 252 MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) { 253 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op); 254 } 255 256 MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res, 257 const ConstantInt &Val) { 258 LLT Ty = MRI->getType(Res); 259 260 assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type"); 261 262 const ConstantInt *NewVal = &Val; 263 if (Ty.getSizeInBits() != Val.getBitWidth()) 264 NewVal = ConstantInt::get(MF->getFunction()->getContext(), 265 Val.getValue().sextOrTrunc(Ty.getSizeInBits())); 266 267 return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal); 268 } 269 270 MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res, 271 int64_t Val) { 272 auto IntN = IntegerType::get(MF->getFunction()->getContext(), 273 MRI->getType(Res).getSizeInBits()); 274 ConstantInt *CI = ConstantInt::get(IntN, Val, true); 275 return buildConstant(Res, *CI); 276 } 277 278 MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res, 279 const ConstantFP &Val) { 280 assert(MRI->getType(Res).isScalar() && "invalid operand type"); 281 282 return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val); 283 } 284 285 MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst, 286 MachineBasicBlock &Dest) { 287 assert(MRI->getType(Tst).isScalar() && "invalid operand type"); 288 289 return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest); 290 } 291 292 MachineInstrBuilder MachineIRBuilder::buildLoad(unsigned Res, unsigned Addr, 293 MachineMemOperand &MMO) { 294 assert(MRI->getType(Res).isValid() && "invalid operand type"); 295 assert(MRI->getType(Addr).isPointer() && "invalid operand type"); 296 297 return buildInstr(TargetOpcode::G_LOAD) 298 .addDef(Res) 299 .addUse(Addr) 300 .addMemOperand(&MMO); 301 } 302 303 MachineInstrBuilder MachineIRBuilder::buildStore(unsigned Val, unsigned Addr, 304 MachineMemOperand &MMO) { 305 assert(MRI->getType(Val).isValid() && "invalid operand type"); 306 assert(MRI->getType(Addr).isPointer() && "invalid operand type"); 307 308 return buildInstr(TargetOpcode::G_STORE) 309 .addUse(Val) 310 .addUse(Addr) 311 .addMemOperand(&MMO); 312 } 313 314 MachineInstrBuilder MachineIRBuilder::buildUAdde(unsigned Res, 315 unsigned CarryOut, 316 unsigned Op0, unsigned Op1, 317 unsigned CarryIn) { 318 assert(MRI->getType(Res).isScalar() && "invalid operand type"); 319 assert(MRI->getType(Res) == MRI->getType(Op0) && 320 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch"); 321 assert(MRI->getType(CarryOut).isScalar() && "invalid operand type"); 322 assert(MRI->getType(CarryOut) == MRI->getType(CarryIn) && "type mismatch"); 323 324 return buildInstr(TargetOpcode::G_UADDE) 325 .addDef(Res) 326 .addDef(CarryOut) 327 .addUse(Op0) 328 .addUse(Op1) 329 .addUse(CarryIn); 330 } 331 332 MachineInstrBuilder MachineIRBuilder::buildAnyExt(unsigned Res, unsigned Op) { 333 validateTruncExt(Res, Op, true); 334 return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op); 335 } 336 337 MachineInstrBuilder MachineIRBuilder::buildSExt(unsigned Res, unsigned Op) { 338 validateTruncExt(Res, Op, true); 339 return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op); 340 } 341 342 MachineInstrBuilder MachineIRBuilder::buildZExt(unsigned Res, unsigned Op) { 343 validateTruncExt(Res, Op, true); 344 return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op); 345 } 346 347 MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(unsigned Res, 348 unsigned Op) { 349 unsigned Opcode = TargetOpcode::COPY; 350 if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits()) 351 Opcode = TargetOpcode::G_SEXT; 352 else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits()) 353 Opcode = TargetOpcode::G_TRUNC; 354 355 return buildInstr(Opcode).addDef(Res).addUse(Op); 356 } 357 358 MachineInstrBuilder MachineIRBuilder::buildZExtOrTrunc(unsigned Res, 359 unsigned Op) { 360 unsigned Opcode = TargetOpcode::COPY; 361 if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits()) 362 Opcode = TargetOpcode::G_ZEXT; 363 else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits()) 364 Opcode = TargetOpcode::G_TRUNC; 365 366 return buildInstr(Opcode).addDef(Res).addUse(Op); 367 } 368 369 370 MachineInstrBuilder MachineIRBuilder::buildCast(unsigned Dst, unsigned Src) { 371 LLT SrcTy = MRI->getType(Src); 372 LLT DstTy = MRI->getType(Dst); 373 if (SrcTy == DstTy) 374 return buildCopy(Dst, Src); 375 376 unsigned Opcode; 377 if (SrcTy.isPointer() && DstTy.isScalar()) 378 Opcode = TargetOpcode::G_PTRTOINT; 379 else if (DstTy.isPointer() && SrcTy.isScalar()) 380 Opcode = TargetOpcode::G_INTTOPTR; 381 else { 382 assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet"); 383 Opcode = TargetOpcode::G_BITCAST; 384 } 385 386 return buildInstr(Opcode).addDef(Dst).addUse(Src); 387 } 388 389 MachineInstrBuilder MachineIRBuilder::buildExtract(unsigned Res, unsigned Src, 390 uint64_t Index) { 391 #ifndef NDEBUG 392 assert(MRI->getType(Src).isValid() && "invalid operand type"); 393 assert(MRI->getType(Res).isValid() && "invalid operand type"); 394 assert(Index + MRI->getType(Res).getSizeInBits() <= 395 MRI->getType(Src).getSizeInBits() && 396 "extracting off end of register"); 397 #endif 398 399 if (MRI->getType(Res).getSizeInBits() == MRI->getType(Src).getSizeInBits()) { 400 assert(Index == 0 && "insertion past the end of a register"); 401 return buildCast(Res, Src); 402 } 403 404 return buildInstr(TargetOpcode::G_EXTRACT) 405 .addDef(Res) 406 .addUse(Src) 407 .addImm(Index); 408 } 409 410 MachineInstrBuilder 411 MachineIRBuilder::buildSequence(unsigned Res, 412 ArrayRef<unsigned> Ops, 413 ArrayRef<uint64_t> Indices) { 414 #ifndef NDEBUG 415 assert(Ops.size() == Indices.size() && "incompatible args"); 416 assert(!Ops.empty() && "invalid trivial sequence"); 417 assert(std::is_sorted(Indices.begin(), Indices.end()) && 418 "sequence offsets must be in ascending order"); 419 420 assert(MRI->getType(Res).isValid() && "invalid operand type"); 421 for (auto Op : Ops) 422 assert(MRI->getType(Op).isValid() && "invalid operand type"); 423 #endif 424 425 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_SEQUENCE); 426 MIB.addDef(Res); 427 for (unsigned i = 0; i < Ops.size(); ++i) { 428 MIB.addUse(Ops[i]); 429 MIB.addImm(Indices[i]); 430 } 431 return MIB; 432 } 433 434 MachineInstrBuilder MachineIRBuilder::buildUndef(unsigned Res) { 435 return buildInstr(TargetOpcode::IMPLICIT_DEF).addDef(Res); 436 } 437 438 MachineInstrBuilder MachineIRBuilder::buildMerge(unsigned Res, 439 ArrayRef<unsigned> Ops) { 440 441 #ifndef NDEBUG 442 assert(!Ops.empty() && "invalid trivial sequence"); 443 LLT Ty = MRI->getType(Ops[0]); 444 for (auto Reg : Ops) 445 assert(MRI->getType(Reg) == Ty && "type mismatch in input list"); 446 assert(Ops.size() * MRI->getType(Ops[0]).getSizeInBits() == 447 MRI->getType(Res).getSizeInBits() && 448 "input operands do not cover output register"); 449 #endif 450 451 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES); 452 MIB.addDef(Res); 453 for (unsigned i = 0; i < Ops.size(); ++i) 454 MIB.addUse(Ops[i]); 455 return MIB; 456 } 457 458 MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<unsigned> Res, 459 unsigned Op) { 460 461 #ifndef NDEBUG 462 assert(!Res.empty() && "invalid trivial sequence"); 463 LLT Ty = MRI->getType(Res[0]); 464 for (auto Reg : Res) 465 assert(MRI->getType(Reg) == Ty && "type mismatch in input list"); 466 assert(Res.size() * MRI->getType(Res[0]).getSizeInBits() == 467 MRI->getType(Op).getSizeInBits() && 468 "input operands do not cover output register"); 469 #endif 470 471 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES); 472 for (unsigned i = 0; i < Res.size(); ++i) 473 MIB.addDef(Res[i]); 474 MIB.addUse(Op); 475 return MIB; 476 } 477 478 MachineInstrBuilder MachineIRBuilder::buildInsert(unsigned Res, unsigned Src, 479 unsigned Op, unsigned Index) { 480 if (MRI->getType(Res).getSizeInBits() == MRI->getType(Op).getSizeInBits()) { 481 assert(Index == 0 && "insertion past the end of a register"); 482 return buildCast(Res, Op); 483 } 484 485 return buildInstr(TargetOpcode::G_INSERT) 486 .addDef(Res) 487 .addUse(Src) 488 .addUse(Op) 489 .addImm(Index); 490 } 491 492 MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID, 493 unsigned Res, 494 bool HasSideEffects) { 495 auto MIB = 496 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS 497 : TargetOpcode::G_INTRINSIC); 498 if (Res) 499 MIB.addDef(Res); 500 MIB.addIntrinsicID(ID); 501 return MIB; 502 } 503 504 MachineInstrBuilder MachineIRBuilder::buildTrunc(unsigned Res, unsigned Op) { 505 validateTruncExt(Res, Op, false); 506 return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op); 507 } 508 509 MachineInstrBuilder MachineIRBuilder::buildFPTrunc(unsigned Res, unsigned Op) { 510 validateTruncExt(Res, Op, false); 511 return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op); 512 } 513 514 MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred, 515 unsigned Res, unsigned Op0, 516 unsigned Op1) { 517 #ifndef NDEBUG 518 assert(MRI->getType(Op0) == MRI->getType(Op0) && "type mismatch"); 519 assert(CmpInst::isIntPredicate(Pred) && "invalid predicate"); 520 if (MRI->getType(Op0).isScalar() || MRI->getType(Op0).isPointer()) 521 assert(MRI->getType(Res).isScalar() && "type mismatch"); 522 else 523 assert(MRI->getType(Res).isVector() && 524 MRI->getType(Res).getNumElements() == 525 MRI->getType(Op0).getNumElements() && 526 "type mismatch"); 527 #endif 528 529 return buildInstr(TargetOpcode::G_ICMP) 530 .addDef(Res) 531 .addPredicate(Pred) 532 .addUse(Op0) 533 .addUse(Op1); 534 } 535 536 MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred, 537 unsigned Res, unsigned Op0, 538 unsigned Op1) { 539 #ifndef NDEBUG 540 assert((MRI->getType(Op0).isScalar() || MRI->getType(Op0).isVector()) && 541 "invalid operand type"); 542 assert(MRI->getType(Op0) == MRI->getType(Op1) && "type mismatch"); 543 assert(CmpInst::isFPPredicate(Pred) && "invalid predicate"); 544 if (MRI->getType(Op0).isScalar()) 545 assert(MRI->getType(Res).isScalar() && "type mismatch"); 546 else 547 assert(MRI->getType(Res).isVector() && 548 MRI->getType(Res).getNumElements() == 549 MRI->getType(Op0).getNumElements() && 550 "type mismatch"); 551 #endif 552 553 return buildInstr(TargetOpcode::G_FCMP) 554 .addDef(Res) 555 .addPredicate(Pred) 556 .addUse(Op0) 557 .addUse(Op1); 558 } 559 560 MachineInstrBuilder MachineIRBuilder::buildSelect(unsigned Res, unsigned Tst, 561 unsigned Op0, unsigned Op1) { 562 #ifndef NDEBUG 563 LLT ResTy = MRI->getType(Res); 564 assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) && 565 "invalid operand type"); 566 assert(ResTy == MRI->getType(Op0) && ResTy == MRI->getType(Op1) && 567 "type mismatch"); 568 if (ResTy.isScalar() || ResTy.isPointer()) 569 assert(MRI->getType(Tst).isScalar() && "type mismatch"); 570 else 571 assert((MRI->getType(Tst).isScalar() || 572 (MRI->getType(Tst).isVector() && 573 MRI->getType(Tst).getNumElements() == 574 MRI->getType(Op0).getNumElements())) && 575 "type mismatch"); 576 #endif 577 578 return buildInstr(TargetOpcode::G_SELECT) 579 .addDef(Res) 580 .addUse(Tst) 581 .addUse(Op0) 582 .addUse(Op1); 583 } 584 585 MachineInstrBuilder MachineIRBuilder::buildInsertVectorElement(unsigned Res, 586 unsigned Val, 587 unsigned Elt, 588 unsigned Idx) { 589 #ifndef NDEBUG 590 LLT ResTy = MRI->getType(Res); 591 LLT ValTy = MRI->getType(Val); 592 LLT EltTy = MRI->getType(Elt); 593 LLT IdxTy = MRI->getType(Idx); 594 assert(ResTy.isVector() && ValTy.isVector() && "invalid operand type"); 595 assert(IdxTy.isScalar() && "invalid operand type"); 596 assert(ResTy.getNumElements() == ValTy.getNumElements() && "type mismatch"); 597 assert(ResTy.getElementType() == EltTy && "type mismatch"); 598 #endif 599 600 return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT) 601 .addDef(Res) 602 .addUse(Val) 603 .addUse(Elt) 604 .addUse(Idx); 605 } 606 607 MachineInstrBuilder MachineIRBuilder::buildExtractVectorElement(unsigned Res, 608 unsigned Val, 609 unsigned Idx) { 610 #ifndef NDEBUG 611 LLT ResTy = MRI->getType(Res); 612 LLT ValTy = MRI->getType(Val); 613 LLT IdxTy = MRI->getType(Idx); 614 assert(ValTy.isVector() && "invalid operand type"); 615 assert((ResTy.isScalar() || ResTy.isPointer()) && "invalid operand type"); 616 assert(IdxTy.isScalar() && "invalid operand type"); 617 assert(ValTy.getElementType() == ResTy && "type mismatch"); 618 #endif 619 620 return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT) 621 .addDef(Res) 622 .addUse(Val) 623 .addUse(Idx); 624 } 625 626 void MachineIRBuilder::validateTruncExt(unsigned Dst, unsigned Src, 627 bool IsExtend) { 628 #ifndef NDEBUG 629 LLT SrcTy = MRI->getType(Src); 630 LLT DstTy = MRI->getType(Dst); 631 632 if (DstTy.isVector()) { 633 assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector"); 634 assert(SrcTy.getNumElements() == DstTy.getNumElements() && 635 "different number of elements in a trunc/ext"); 636 } else 637 assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc"); 638 639 if (IsExtend) 640 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() && 641 "invalid narrowing extend"); 642 else 643 assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() && 644 "invalid widening trunc"); 645 #endif 646 } 647