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