1 //===-- llvm/CodeGen/GlobalISel/LegalizerHelper.cpp -----------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 /// \file This file implements the LegalizerHelper class to legalize 11 /// individual instructions and the LegalizeMachineIR wrapper pass for the 12 /// primary legalization. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 17 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 18 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 #include "llvm/CodeGen/TargetLowering.h" 21 #include "llvm/CodeGen/TargetSubtargetInfo.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Support/raw_ostream.h" 24 25 #include <sstream> 26 27 #define DEBUG_TYPE "legalizer" 28 29 using namespace llvm; 30 31 LegalizerHelper::LegalizerHelper(MachineFunction &MF) 32 : MRI(MF.getRegInfo()), LI(*MF.getSubtarget().getLegalizerInfo()) { 33 MIRBuilder.setMF(MF); 34 } 35 36 LegalizerHelper::LegalizeResult 37 LegalizerHelper::legalizeInstrStep(MachineInstr &MI) { 38 DEBUG(dbgs() << "Legalizing: "; MI.print(dbgs())); 39 40 auto Action = LI.getAction(MI, MRI); 41 switch (std::get<0>(Action)) { 42 case LegalizerInfo::Legal: 43 DEBUG(dbgs() << ".. Already legal\n"); 44 return AlreadyLegal; 45 case LegalizerInfo::Libcall: 46 DEBUG(dbgs() << ".. Convert to libcall\n"); 47 return libcall(MI); 48 case LegalizerInfo::NarrowScalar: 49 DEBUG(dbgs() << ".. Narrow scalar\n"); 50 return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action)); 51 case LegalizerInfo::WidenScalar: 52 DEBUG(dbgs() << ".. Widen scalar\n"); 53 return widenScalar(MI, std::get<1>(Action), std::get<2>(Action)); 54 case LegalizerInfo::Lower: 55 DEBUG(dbgs() << ".. Lower\n"); 56 return lower(MI, std::get<1>(Action), std::get<2>(Action)); 57 case LegalizerInfo::FewerElements: 58 DEBUG(dbgs() << ".. Reduce number of elements\n"); 59 return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action)); 60 case LegalizerInfo::Custom: 61 DEBUG(dbgs() << ".. Custom legalization\n"); 62 return LI.legalizeCustom(MI, MRI, MIRBuilder) ? Legalized 63 : UnableToLegalize; 64 default: 65 DEBUG(dbgs() << ".. Unable to legalize\n"); 66 return UnableToLegalize; 67 } 68 } 69 70 void LegalizerHelper::extractParts(unsigned Reg, LLT Ty, int NumParts, 71 SmallVectorImpl<unsigned> &VRegs) { 72 for (int i = 0; i < NumParts; ++i) 73 VRegs.push_back(MRI.createGenericVirtualRegister(Ty)); 74 MIRBuilder.buildUnmerge(VRegs, Reg); 75 } 76 77 static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) { 78 switch (Opcode) { 79 case TargetOpcode::G_SDIV: 80 assert(Size == 32 && "Unsupported size"); 81 return RTLIB::SDIV_I32; 82 case TargetOpcode::G_UDIV: 83 assert(Size == 32 && "Unsupported size"); 84 return RTLIB::UDIV_I32; 85 case TargetOpcode::G_SREM: 86 assert(Size == 32 && "Unsupported size"); 87 return RTLIB::SREM_I32; 88 case TargetOpcode::G_UREM: 89 assert(Size == 32 && "Unsupported size"); 90 return RTLIB::UREM_I32; 91 case TargetOpcode::G_FADD: 92 assert((Size == 32 || Size == 64) && "Unsupported size"); 93 return Size == 64 ? RTLIB::ADD_F64 : RTLIB::ADD_F32; 94 case TargetOpcode::G_FSUB: 95 assert((Size == 32 || Size == 64) && "Unsupported size"); 96 return Size == 64 ? RTLIB::SUB_F64 : RTLIB::SUB_F32; 97 case TargetOpcode::G_FMUL: 98 assert((Size == 32 || Size == 64) && "Unsupported size"); 99 return Size == 64 ? RTLIB::MUL_F64 : RTLIB::MUL_F32; 100 case TargetOpcode::G_FDIV: 101 assert((Size == 32 || Size == 64) && "Unsupported size"); 102 return Size == 64 ? RTLIB::DIV_F64 : RTLIB::DIV_F32; 103 case TargetOpcode::G_FREM: 104 return Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32; 105 case TargetOpcode::G_FPOW: 106 return Size == 64 ? RTLIB::POW_F64 : RTLIB::POW_F32; 107 } 108 llvm_unreachable("Unknown libcall function"); 109 } 110 111 LegalizerHelper::LegalizeResult 112 llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, 113 const CallLowering::ArgInfo &Result, 114 ArrayRef<CallLowering::ArgInfo> Args) { 115 auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering(); 116 auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering(); 117 const char *Name = TLI.getLibcallName(Libcall); 118 119 MIRBuilder.getMF().getFrameInfo().setHasCalls(true); 120 if (!CLI.lowerCall(MIRBuilder, TLI.getLibcallCallingConv(Libcall), 121 MachineOperand::CreateES(Name), Result, Args)) 122 return LegalizerHelper::UnableToLegalize; 123 124 return LegalizerHelper::Legalized; 125 } 126 127 static LegalizerHelper::LegalizeResult 128 simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size, 129 Type *OpType) { 130 auto Libcall = getRTLibDesc(MI.getOpcode(), Size); 131 return createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), OpType}, 132 {{MI.getOperand(1).getReg(), OpType}, 133 {MI.getOperand(2).getReg(), OpType}}); 134 } 135 136 LegalizerHelper::LegalizeResult 137 LegalizerHelper::libcall(MachineInstr &MI) { 138 LLT LLTy = MRI.getType(MI.getOperand(0).getReg()); 139 unsigned Size = LLTy.getSizeInBits(); 140 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext(); 141 142 MIRBuilder.setInstr(MI); 143 144 switch (MI.getOpcode()) { 145 default: 146 return UnableToLegalize; 147 case TargetOpcode::G_SDIV: 148 case TargetOpcode::G_UDIV: 149 case TargetOpcode::G_SREM: 150 case TargetOpcode::G_UREM: { 151 Type *HLTy = Type::getInt32Ty(Ctx); 152 auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy); 153 if (Status != Legalized) 154 return Status; 155 break; 156 } 157 case TargetOpcode::G_FADD: 158 case TargetOpcode::G_FSUB: 159 case TargetOpcode::G_FMUL: 160 case TargetOpcode::G_FDIV: 161 case TargetOpcode::G_FPOW: 162 case TargetOpcode::G_FREM: { 163 Type *HLTy = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx); 164 auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy); 165 if (Status != Legalized) 166 return Status; 167 break; 168 } 169 } 170 171 MI.eraseFromParent(); 172 return Legalized; 173 } 174 175 LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, 176 unsigned TypeIdx, 177 LLT NarrowTy) { 178 // FIXME: Don't know how to handle secondary types yet. 179 if (TypeIdx != 0 && MI.getOpcode() != TargetOpcode::G_EXTRACT) 180 return UnableToLegalize; 181 182 MIRBuilder.setInstr(MI); 183 184 int64_t SizeOp0 = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 185 int64_t NarrowSize = NarrowTy.getSizeInBits(); 186 187 switch (MI.getOpcode()) { 188 default: 189 return UnableToLegalize; 190 case TargetOpcode::G_IMPLICIT_DEF: { 191 // FIXME: add support for when SizeOp0 isn't an exact multiple of 192 // NarrowSize. 193 if (SizeOp0 % NarrowSize != 0) 194 return UnableToLegalize; 195 int NumParts = SizeOp0 / NarrowSize; 196 197 SmallVector<unsigned, 2> DstRegs; 198 for (int i = 0; i < NumParts; ++i) { 199 unsigned Dst = MRI.createGenericVirtualRegister(NarrowTy); 200 MIRBuilder.buildUndef(Dst); 201 DstRegs.push_back(Dst); 202 } 203 MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs); 204 MI.eraseFromParent(); 205 return Legalized; 206 } 207 case TargetOpcode::G_ADD: { 208 // FIXME: add support for when SizeOp0 isn't an exact multiple of 209 // NarrowSize. 210 if (SizeOp0 % NarrowSize != 0) 211 return UnableToLegalize; 212 // Expand in terms of carry-setting/consuming G_ADDE instructions. 213 int NumParts = SizeOp0 / NarrowTy.getSizeInBits(); 214 215 SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs; 216 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs); 217 extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs); 218 219 unsigned CarryIn = MRI.createGenericVirtualRegister(LLT::scalar(1)); 220 MIRBuilder.buildConstant(CarryIn, 0); 221 222 for (int i = 0; i < NumParts; ++i) { 223 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); 224 unsigned CarryOut = MRI.createGenericVirtualRegister(LLT::scalar(1)); 225 226 MIRBuilder.buildUAdde(DstReg, CarryOut, Src1Regs[i], 227 Src2Regs[i], CarryIn); 228 229 DstRegs.push_back(DstReg); 230 CarryIn = CarryOut; 231 } 232 unsigned DstReg = MI.getOperand(0).getReg(); 233 MIRBuilder.buildMerge(DstReg, DstRegs); 234 MI.eraseFromParent(); 235 return Legalized; 236 } 237 case TargetOpcode::G_EXTRACT: { 238 if (TypeIdx != 1) 239 return UnableToLegalize; 240 241 int64_t SizeOp1 = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 242 // FIXME: add support for when SizeOp1 isn't an exact multiple of 243 // NarrowSize. 244 if (SizeOp1 % NarrowSize != 0) 245 return UnableToLegalize; 246 int NumParts = SizeOp1 / NarrowSize; 247 248 SmallVector<unsigned, 2> SrcRegs, DstRegs; 249 SmallVector<uint64_t, 2> Indexes; 250 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs); 251 252 unsigned OpReg = MI.getOperand(0).getReg(); 253 int64_t OpStart = MI.getOperand(2).getImm(); 254 int64_t OpSize = MRI.getType(OpReg).getSizeInBits(); 255 for (int i = 0; i < NumParts; ++i) { 256 unsigned SrcStart = i * NarrowSize; 257 258 if (SrcStart + NarrowSize <= OpStart || SrcStart >= OpStart + OpSize) { 259 // No part of the extract uses this subregister, ignore it. 260 continue; 261 } else if (SrcStart == OpStart && NarrowTy == MRI.getType(OpReg)) { 262 // The entire subregister is extracted, forward the value. 263 DstRegs.push_back(SrcRegs[i]); 264 continue; 265 } 266 267 // OpSegStart is where this destination segment would start in OpReg if it 268 // extended infinitely in both directions. 269 int64_t ExtractOffset, SegSize; 270 if (OpStart < SrcStart) { 271 ExtractOffset = 0; 272 SegSize = std::min(NarrowSize, OpStart + OpSize - SrcStart); 273 } else { 274 ExtractOffset = OpStart - SrcStart; 275 SegSize = std::min(SrcStart + NarrowSize - OpStart, OpSize); 276 } 277 278 unsigned SegReg = SrcRegs[i]; 279 if (ExtractOffset != 0 || SegSize != NarrowSize) { 280 // A genuine extract is needed. 281 SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize)); 282 MIRBuilder.buildExtract(SegReg, SrcRegs[i], ExtractOffset); 283 } 284 285 DstRegs.push_back(SegReg); 286 } 287 288 MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs); 289 MI.eraseFromParent(); 290 return Legalized; 291 } 292 case TargetOpcode::G_INSERT: { 293 // FIXME: add support for when SizeOp0 isn't an exact multiple of 294 // NarrowSize. 295 if (SizeOp0 % NarrowSize != 0) 296 return UnableToLegalize; 297 298 int NumParts = SizeOp0 / NarrowSize; 299 300 SmallVector<unsigned, 2> SrcRegs, DstRegs; 301 SmallVector<uint64_t, 2> Indexes; 302 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs); 303 304 unsigned OpReg = MI.getOperand(2).getReg(); 305 int64_t OpStart = MI.getOperand(3).getImm(); 306 int64_t OpSize = MRI.getType(OpReg).getSizeInBits(); 307 for (int i = 0; i < NumParts; ++i) { 308 unsigned DstStart = i * NarrowSize; 309 310 if (DstStart + NarrowSize <= OpStart || DstStart >= OpStart + OpSize) { 311 // No part of the insert affects this subregister, forward the original. 312 DstRegs.push_back(SrcRegs[i]); 313 continue; 314 } else if (DstStart == OpStart && NarrowTy == MRI.getType(OpReg)) { 315 // The entire subregister is defined by this insert, forward the new 316 // value. 317 DstRegs.push_back(OpReg); 318 continue; 319 } 320 321 // OpSegStart is where this destination segment would start in OpReg if it 322 // extended infinitely in both directions. 323 int64_t ExtractOffset, InsertOffset, SegSize; 324 if (OpStart < DstStart) { 325 InsertOffset = 0; 326 ExtractOffset = DstStart - OpStart; 327 SegSize = std::min(NarrowSize, OpStart + OpSize - DstStart); 328 } else { 329 InsertOffset = OpStart - DstStart; 330 ExtractOffset = 0; 331 SegSize = 332 std::min(NarrowSize - InsertOffset, OpStart + OpSize - DstStart); 333 } 334 335 unsigned SegReg = OpReg; 336 if (ExtractOffset != 0 || SegSize != OpSize) { 337 // A genuine extract is needed. 338 SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize)); 339 MIRBuilder.buildExtract(SegReg, OpReg, ExtractOffset); 340 } 341 342 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); 343 MIRBuilder.buildInsert(DstReg, SrcRegs[i], SegReg, InsertOffset); 344 DstRegs.push_back(DstReg); 345 } 346 347 assert(DstRegs.size() == (unsigned)NumParts && "not all parts covered"); 348 MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs); 349 MI.eraseFromParent(); 350 return Legalized; 351 } 352 case TargetOpcode::G_LOAD: { 353 // FIXME: add support for when SizeOp0 isn't an exact multiple of 354 // NarrowSize. 355 if (SizeOp0 % NarrowSize != 0) 356 return UnableToLegalize; 357 int NumParts = SizeOp0 / NarrowSize; 358 LLT OffsetTy = LLT::scalar( 359 MRI.getType(MI.getOperand(1).getReg()).getScalarSizeInBits()); 360 361 SmallVector<unsigned, 2> DstRegs; 362 for (int i = 0; i < NumParts; ++i) { 363 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); 364 unsigned SrcReg = 0; 365 unsigned Adjustment = i * NarrowSize / 8; 366 367 MIRBuilder.materializeGEP(SrcReg, MI.getOperand(1).getReg(), OffsetTy, 368 Adjustment); 369 370 // TODO: This is conservatively correct, but we probably want to split the 371 // memory operands in the future. 372 MIRBuilder.buildLoad(DstReg, SrcReg, **MI.memoperands_begin()); 373 374 DstRegs.push_back(DstReg); 375 } 376 unsigned DstReg = MI.getOperand(0).getReg(); 377 MIRBuilder.buildMerge(DstReg, DstRegs); 378 MI.eraseFromParent(); 379 return Legalized; 380 } 381 case TargetOpcode::G_STORE: { 382 // FIXME: add support for when SizeOp0 isn't an exact multiple of 383 // NarrowSize. 384 if (SizeOp0 % NarrowSize != 0) 385 return UnableToLegalize; 386 int NumParts = SizeOp0 / NarrowSize; 387 LLT OffsetTy = LLT::scalar( 388 MRI.getType(MI.getOperand(1).getReg()).getScalarSizeInBits()); 389 390 SmallVector<unsigned, 2> SrcRegs; 391 extractParts(MI.getOperand(0).getReg(), NarrowTy, NumParts, SrcRegs); 392 393 for (int i = 0; i < NumParts; ++i) { 394 unsigned DstReg = 0; 395 unsigned Adjustment = i * NarrowSize / 8; 396 397 MIRBuilder.materializeGEP(DstReg, MI.getOperand(1).getReg(), OffsetTy, 398 Adjustment); 399 400 // TODO: This is conservatively correct, but we probably want to split the 401 // memory operands in the future. 402 MIRBuilder.buildStore(SrcRegs[i], DstReg, **MI.memoperands_begin()); 403 } 404 MI.eraseFromParent(); 405 return Legalized; 406 } 407 case TargetOpcode::G_CONSTANT: { 408 // FIXME: add support for when SizeOp0 isn't an exact multiple of 409 // NarrowSize. 410 if (SizeOp0 % NarrowSize != 0) 411 return UnableToLegalize; 412 int NumParts = SizeOp0 / NarrowSize; 413 const APInt &Cst = MI.getOperand(1).getCImm()->getValue(); 414 LLVMContext &Ctx = MIRBuilder.getMF().getFunction()->getContext(); 415 416 SmallVector<unsigned, 2> DstRegs; 417 for (int i = 0; i < NumParts; ++i) { 418 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); 419 ConstantInt *CI = 420 ConstantInt::get(Ctx, Cst.lshr(NarrowSize * i).trunc(NarrowSize)); 421 MIRBuilder.buildConstant(DstReg, *CI); 422 DstRegs.push_back(DstReg); 423 } 424 unsigned DstReg = MI.getOperand(0).getReg(); 425 MIRBuilder.buildMerge(DstReg, DstRegs); 426 MI.eraseFromParent(); 427 return Legalized; 428 } 429 case TargetOpcode::G_OR: { 430 // Legalize bitwise operation: 431 // A = BinOp<Ty> B, C 432 // into: 433 // B1, ..., BN = G_UNMERGE_VALUES B 434 // C1, ..., CN = G_UNMERGE_VALUES C 435 // A1 = BinOp<Ty/N> B1, C2 436 // ... 437 // AN = BinOp<Ty/N> BN, CN 438 // A = G_MERGE_VALUES A1, ..., AN 439 440 // FIXME: add support for when SizeOp0 isn't an exact multiple of 441 // NarrowSize. 442 if (SizeOp0 % NarrowSize != 0) 443 return UnableToLegalize; 444 int NumParts = SizeOp0 / NarrowSize; 445 446 // List the registers where the destination will be scattered. 447 SmallVector<unsigned, 2> DstRegs; 448 // List the registers where the first argument will be split. 449 SmallVector<unsigned, 2> SrcsReg1; 450 // List the registers where the second argument will be split. 451 SmallVector<unsigned, 2> SrcsReg2; 452 // Create all the temporary registers. 453 for (int i = 0; i < NumParts; ++i) { 454 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); 455 unsigned SrcReg1 = MRI.createGenericVirtualRegister(NarrowTy); 456 unsigned SrcReg2 = MRI.createGenericVirtualRegister(NarrowTy); 457 458 DstRegs.push_back(DstReg); 459 SrcsReg1.push_back(SrcReg1); 460 SrcsReg2.push_back(SrcReg2); 461 } 462 // Explode the big arguments into smaller chunks. 463 MIRBuilder.buildUnmerge(SrcsReg1, MI.getOperand(1).getReg()); 464 MIRBuilder.buildUnmerge(SrcsReg2, MI.getOperand(2).getReg()); 465 466 // Do the operation on each small part. 467 for (int i = 0; i < NumParts; ++i) 468 MIRBuilder.buildOr(DstRegs[i], SrcsReg1[i], SrcsReg2[i]); 469 470 // Gather the destination registers into the final destination. 471 unsigned DstReg = MI.getOperand(0).getReg(); 472 MIRBuilder.buildMerge(DstReg, DstRegs); 473 MI.eraseFromParent(); 474 return Legalized; 475 } 476 } 477 } 478 479 LegalizerHelper::LegalizeResult 480 LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) { 481 MIRBuilder.setInstr(MI); 482 483 switch (MI.getOpcode()) { 484 default: 485 return UnableToLegalize; 486 case TargetOpcode::G_ADD: 487 case TargetOpcode::G_AND: 488 case TargetOpcode::G_MUL: 489 case TargetOpcode::G_OR: 490 case TargetOpcode::G_XOR: 491 case TargetOpcode::G_SUB: 492 case TargetOpcode::G_SHL: { 493 // Perform operation at larger width (any extension is fine here, high bits 494 // don't affect the result) and then truncate the result back to the 495 // original type. 496 unsigned Src1Ext = MRI.createGenericVirtualRegister(WideTy); 497 unsigned Src2Ext = MRI.createGenericVirtualRegister(WideTy); 498 MIRBuilder.buildAnyExt(Src1Ext, MI.getOperand(1).getReg()); 499 MIRBuilder.buildAnyExt(Src2Ext, MI.getOperand(2).getReg()); 500 501 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy); 502 MIRBuilder.buildInstr(MI.getOpcode()) 503 .addDef(DstExt) 504 .addUse(Src1Ext) 505 .addUse(Src2Ext); 506 507 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt); 508 MI.eraseFromParent(); 509 return Legalized; 510 } 511 case TargetOpcode::G_SDIV: 512 case TargetOpcode::G_UDIV: 513 case TargetOpcode::G_SREM: 514 case TargetOpcode::G_UREM: 515 case TargetOpcode::G_ASHR: 516 case TargetOpcode::G_LSHR: { 517 unsigned ExtOp = MI.getOpcode() == TargetOpcode::G_SDIV || 518 MI.getOpcode() == TargetOpcode::G_SREM || 519 MI.getOpcode() == TargetOpcode::G_ASHR 520 ? TargetOpcode::G_SEXT 521 : TargetOpcode::G_ZEXT; 522 523 unsigned LHSExt = MRI.createGenericVirtualRegister(WideTy); 524 MIRBuilder.buildInstr(ExtOp).addDef(LHSExt).addUse( 525 MI.getOperand(1).getReg()); 526 527 unsigned RHSExt = MRI.createGenericVirtualRegister(WideTy); 528 MIRBuilder.buildInstr(ExtOp).addDef(RHSExt).addUse( 529 MI.getOperand(2).getReg()); 530 531 unsigned ResExt = MRI.createGenericVirtualRegister(WideTy); 532 MIRBuilder.buildInstr(MI.getOpcode()) 533 .addDef(ResExt) 534 .addUse(LHSExt) 535 .addUse(RHSExt); 536 537 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), ResExt); 538 MI.eraseFromParent(); 539 return Legalized; 540 } 541 case TargetOpcode::G_SELECT: { 542 if (TypeIdx != 0) 543 return UnableToLegalize; 544 545 // Perform operation at larger width (any extension is fine here, high bits 546 // don't affect the result) and then truncate the result back to the 547 // original type. 548 unsigned Src1Ext = MRI.createGenericVirtualRegister(WideTy); 549 unsigned Src2Ext = MRI.createGenericVirtualRegister(WideTy); 550 MIRBuilder.buildAnyExt(Src1Ext, MI.getOperand(2).getReg()); 551 MIRBuilder.buildAnyExt(Src2Ext, MI.getOperand(3).getReg()); 552 553 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy); 554 MIRBuilder.buildInstr(TargetOpcode::G_SELECT) 555 .addDef(DstExt) 556 .addReg(MI.getOperand(1).getReg()) 557 .addUse(Src1Ext) 558 .addUse(Src2Ext); 559 560 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt); 561 MI.eraseFromParent(); 562 return Legalized; 563 } 564 case TargetOpcode::G_FPTOSI: 565 case TargetOpcode::G_FPTOUI: { 566 if (TypeIdx != 0) 567 return UnableToLegalize; 568 569 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy); 570 MIRBuilder.buildInstr(MI.getOpcode()) 571 .addDef(DstExt) 572 .addUse(MI.getOperand(1).getReg()); 573 574 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt); 575 MI.eraseFromParent(); 576 return Legalized; 577 } 578 case TargetOpcode::G_SITOFP: 579 case TargetOpcode::G_UITOFP: { 580 if (TypeIdx != 1) 581 return UnableToLegalize; 582 583 unsigned Src = MI.getOperand(1).getReg(); 584 unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy); 585 586 if (MI.getOpcode() == TargetOpcode::G_SITOFP) { 587 MIRBuilder.buildSExt(SrcExt, Src); 588 } else { 589 assert(MI.getOpcode() == TargetOpcode::G_UITOFP && "Unexpected conv op"); 590 MIRBuilder.buildZExt(SrcExt, Src); 591 } 592 593 MIRBuilder.buildInstr(MI.getOpcode()) 594 .addDef(MI.getOperand(0).getReg()) 595 .addUse(SrcExt); 596 597 MI.eraseFromParent(); 598 return Legalized; 599 } 600 case TargetOpcode::G_INSERT: { 601 if (TypeIdx != 0) 602 return UnableToLegalize; 603 604 unsigned Src = MI.getOperand(1).getReg(); 605 unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy); 606 MIRBuilder.buildAnyExt(SrcExt, Src); 607 608 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy); 609 auto MIB = MIRBuilder.buildInsert(DstExt, SrcExt, MI.getOperand(2).getReg(), 610 MI.getOperand(3).getImm()); 611 for (unsigned OpNum = 4; OpNum < MI.getNumOperands(); OpNum += 2) { 612 MIB.addReg(MI.getOperand(OpNum).getReg()); 613 MIB.addImm(MI.getOperand(OpNum + 1).getImm()); 614 } 615 616 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt); 617 MI.eraseFromParent(); 618 return Legalized; 619 } 620 case TargetOpcode::G_LOAD: { 621 assert(alignTo(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(), 8) == 622 WideTy.getSizeInBits() && 623 "illegal to increase number of bytes loaded"); 624 625 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy); 626 MIRBuilder.buildLoad(DstExt, MI.getOperand(1).getReg(), 627 **MI.memoperands_begin()); 628 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt); 629 MI.eraseFromParent(); 630 return Legalized; 631 } 632 case TargetOpcode::G_STORE: { 633 if (MRI.getType(MI.getOperand(0).getReg()) != LLT::scalar(1) || 634 WideTy != LLT::scalar(8)) 635 return UnableToLegalize; 636 637 auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering(); 638 auto Content = TLI.getBooleanContents(false, false); 639 640 unsigned ExtOp = TargetOpcode::G_ANYEXT; 641 if (Content == TargetLoweringBase::ZeroOrOneBooleanContent) 642 ExtOp = TargetOpcode::G_ZEXT; 643 else if (Content == TargetLoweringBase::ZeroOrNegativeOneBooleanContent) 644 ExtOp = TargetOpcode::G_SEXT; 645 else 646 ExtOp = TargetOpcode::G_ANYEXT; 647 648 unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy); 649 MIRBuilder.buildInstr(ExtOp).addDef(SrcExt).addUse( 650 MI.getOperand(0).getReg()); 651 MIRBuilder.buildStore(SrcExt, MI.getOperand(1).getReg(), 652 **MI.memoperands_begin()); 653 MI.eraseFromParent(); 654 return Legalized; 655 } 656 case TargetOpcode::G_CONSTANT: { 657 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy); 658 MIRBuilder.buildConstant(DstExt, *MI.getOperand(1).getCImm()); 659 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt); 660 MI.eraseFromParent(); 661 return Legalized; 662 } 663 case TargetOpcode::G_FCONSTANT: { 664 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy); 665 MIRBuilder.buildFConstant(DstExt, *MI.getOperand(1).getFPImm()); 666 MIRBuilder.buildFPTrunc(MI.getOperand(0).getReg(), DstExt); 667 MI.eraseFromParent(); 668 return Legalized; 669 } 670 case TargetOpcode::G_BRCOND: { 671 unsigned TstExt = MRI.createGenericVirtualRegister(WideTy); 672 MIRBuilder.buildAnyExt(TstExt, MI.getOperand(0).getReg()); 673 MIRBuilder.buildBrCond(TstExt, *MI.getOperand(1).getMBB()); 674 MI.eraseFromParent(); 675 return Legalized; 676 } 677 case TargetOpcode::G_FCMP: { 678 unsigned Op0Ext, Op1Ext, DstReg; 679 unsigned Cmp1 = MI.getOperand(2).getReg(); 680 unsigned Cmp2 = MI.getOperand(3).getReg(); 681 if (TypeIdx == 0) { 682 Op0Ext = Cmp1; 683 Op1Ext = Cmp2; 684 DstReg = MRI.createGenericVirtualRegister(WideTy); 685 } else { 686 Op0Ext = MRI.createGenericVirtualRegister(WideTy); 687 Op1Ext = MRI.createGenericVirtualRegister(WideTy); 688 DstReg = MI.getOperand(0).getReg(); 689 MIRBuilder.buildInstr(TargetOpcode::G_FPEXT, Op0Ext, Cmp1); 690 MIRBuilder.buildInstr(TargetOpcode::G_FPEXT, Op1Ext, Cmp2); 691 } 692 MIRBuilder.buildFCmp( 693 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()), 694 DstReg, Op0Ext, Op1Ext); 695 if (TypeIdx == 0) 696 MIRBuilder.buildInstr(TargetOpcode::G_TRUNC, MI.getOperand(0).getReg(), 697 DstReg); 698 MI.eraseFromParent(); 699 return Legalized; 700 } 701 case TargetOpcode::G_ICMP: { 702 bool IsSigned = CmpInst::isSigned( 703 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate())); 704 unsigned Cmp1 = MI.getOperand(2).getReg(); 705 unsigned Cmp2 = MI.getOperand(3).getReg(); 706 unsigned Op0Ext, Op1Ext, DstReg; 707 if (TypeIdx == 0) { 708 Op0Ext = Cmp1; 709 Op1Ext = Cmp2; 710 DstReg = MRI.createGenericVirtualRegister(WideTy); 711 } else { 712 Op0Ext = MRI.createGenericVirtualRegister(WideTy); 713 Op1Ext = MRI.createGenericVirtualRegister(WideTy); 714 DstReg = MI.getOperand(0).getReg(); 715 if (IsSigned) { 716 MIRBuilder.buildSExt(Op0Ext, Cmp1); 717 MIRBuilder.buildSExt(Op1Ext, Cmp2); 718 } else { 719 MIRBuilder.buildZExt(Op0Ext, Cmp1); 720 MIRBuilder.buildZExt(Op1Ext, Cmp2); 721 } 722 } 723 MIRBuilder.buildICmp( 724 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()), 725 DstReg, Op0Ext, Op1Ext); 726 if (TypeIdx == 0) 727 MIRBuilder.buildInstr(TargetOpcode::G_TRUNC, MI.getOperand(0).getReg(), 728 DstReg); 729 MI.eraseFromParent(); 730 return Legalized; 731 } 732 case TargetOpcode::G_GEP: { 733 assert(TypeIdx == 1 && "unable to legalize pointer of GEP"); 734 unsigned OffsetExt = MRI.createGenericVirtualRegister(WideTy); 735 MIRBuilder.buildSExt(OffsetExt, MI.getOperand(2).getReg()); 736 MI.getOperand(2).setReg(OffsetExt); 737 return Legalized; 738 } 739 case TargetOpcode::G_PHI: { 740 assert(TypeIdx == 0 && "Expecting only Idx 0"); 741 auto getExtendedReg = [&](unsigned Reg, MachineBasicBlock &MBB) { 742 auto FirstTermIt = MBB.getFirstTerminator(); 743 MIRBuilder.setInsertPt(MBB, FirstTermIt); 744 MachineInstr *DefMI = MRI.getVRegDef(Reg); 745 MachineInstrBuilder MIB; 746 if (DefMI->getOpcode() == TargetOpcode::G_TRUNC) 747 MIB = MIRBuilder.buildAnyExtOrTrunc(WideTy, 748 DefMI->getOperand(1).getReg()); 749 else 750 MIB = MIRBuilder.buildAnyExt(WideTy, Reg); 751 return MIB->getOperand(0).getReg(); 752 }; 753 auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI, WideTy); 754 for (auto OpIt = MI.operands_begin() + 1, OpE = MI.operands_end(); 755 OpIt != OpE;) { 756 unsigned Reg = OpIt++->getReg(); 757 MachineBasicBlock *OpMBB = OpIt++->getMBB(); 758 MIB.addReg(getExtendedReg(Reg, *OpMBB)); 759 MIB.addMBB(OpMBB); 760 } 761 auto *MBB = MI.getParent(); 762 MIRBuilder.setInsertPt(*MBB, MBB->getFirstNonPHI()); 763 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), 764 MIB->getOperand(0).getReg()); 765 MI.eraseFromParent(); 766 return Legalized; 767 } 768 } 769 } 770 771 LegalizerHelper::LegalizeResult 772 LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) { 773 using namespace TargetOpcode; 774 MIRBuilder.setInstr(MI); 775 776 switch(MI.getOpcode()) { 777 default: 778 return UnableToLegalize; 779 case TargetOpcode::G_SREM: 780 case TargetOpcode::G_UREM: { 781 unsigned QuotReg = MRI.createGenericVirtualRegister(Ty); 782 MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV) 783 .addDef(QuotReg) 784 .addUse(MI.getOperand(1).getReg()) 785 .addUse(MI.getOperand(2).getReg()); 786 787 unsigned ProdReg = MRI.createGenericVirtualRegister(Ty); 788 MIRBuilder.buildMul(ProdReg, QuotReg, MI.getOperand(2).getReg()); 789 MIRBuilder.buildSub(MI.getOperand(0).getReg(), MI.getOperand(1).getReg(), 790 ProdReg); 791 MI.eraseFromParent(); 792 return Legalized; 793 } 794 case TargetOpcode::G_SMULO: 795 case TargetOpcode::G_UMULO: { 796 // Generate G_UMULH/G_SMULH to check for overflow and a normal G_MUL for the 797 // result. 798 unsigned Res = MI.getOperand(0).getReg(); 799 unsigned Overflow = MI.getOperand(1).getReg(); 800 unsigned LHS = MI.getOperand(2).getReg(); 801 unsigned RHS = MI.getOperand(3).getReg(); 802 803 MIRBuilder.buildMul(Res, LHS, RHS); 804 805 unsigned Opcode = MI.getOpcode() == TargetOpcode::G_SMULO 806 ? TargetOpcode::G_SMULH 807 : TargetOpcode::G_UMULH; 808 809 unsigned HiPart = MRI.createGenericVirtualRegister(Ty); 810 MIRBuilder.buildInstr(Opcode) 811 .addDef(HiPart) 812 .addUse(LHS) 813 .addUse(RHS); 814 815 unsigned Zero = MRI.createGenericVirtualRegister(Ty); 816 MIRBuilder.buildConstant(Zero, 0); 817 MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Zero); 818 MI.eraseFromParent(); 819 return Legalized; 820 } 821 case TargetOpcode::G_FNEG: { 822 // TODO: Handle vector types once we are able to 823 // represent them. 824 if (Ty.isVector()) 825 return UnableToLegalize; 826 unsigned Res = MI.getOperand(0).getReg(); 827 Type *ZeroTy; 828 LLVMContext &Ctx = MIRBuilder.getMF().getFunction()->getContext(); 829 switch (Ty.getSizeInBits()) { 830 case 16: 831 ZeroTy = Type::getHalfTy(Ctx); 832 break; 833 case 32: 834 ZeroTy = Type::getFloatTy(Ctx); 835 break; 836 case 64: 837 ZeroTy = Type::getDoubleTy(Ctx); 838 break; 839 default: 840 llvm_unreachable("unexpected floating-point type"); 841 } 842 ConstantFP &ZeroForNegation = 843 *cast<ConstantFP>(ConstantFP::getZeroValueForNegation(ZeroTy)); 844 unsigned Zero = MRI.createGenericVirtualRegister(Ty); 845 MIRBuilder.buildFConstant(Zero, ZeroForNegation); 846 MIRBuilder.buildInstr(TargetOpcode::G_FSUB) 847 .addDef(Res) 848 .addUse(Zero) 849 .addUse(MI.getOperand(1).getReg()); 850 MI.eraseFromParent(); 851 return Legalized; 852 } 853 case TargetOpcode::G_FSUB: { 854 // Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)). 855 // First, check if G_FNEG is marked as Lower. If so, we may 856 // end up with an infinite loop as G_FSUB is used to legalize G_FNEG. 857 if (LI.getAction({G_FNEG, Ty}).first == LegalizerInfo::Lower) 858 return UnableToLegalize; 859 unsigned Res = MI.getOperand(0).getReg(); 860 unsigned LHS = MI.getOperand(1).getReg(); 861 unsigned RHS = MI.getOperand(2).getReg(); 862 unsigned Neg = MRI.createGenericVirtualRegister(Ty); 863 MIRBuilder.buildInstr(TargetOpcode::G_FNEG).addDef(Neg).addUse(RHS); 864 MIRBuilder.buildInstr(TargetOpcode::G_FADD) 865 .addDef(Res) 866 .addUse(LHS) 867 .addUse(Neg); 868 MI.eraseFromParent(); 869 return Legalized; 870 } 871 case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: { 872 unsigned OldValRes = MI.getOperand(0).getReg(); 873 unsigned SuccessRes = MI.getOperand(1).getReg(); 874 unsigned Addr = MI.getOperand(2).getReg(); 875 unsigned CmpVal = MI.getOperand(3).getReg(); 876 unsigned NewVal = MI.getOperand(4).getReg(); 877 MIRBuilder.buildAtomicCmpXchg(OldValRes, Addr, CmpVal, NewVal, 878 **MI.memoperands_begin()); 879 MIRBuilder.buildICmp(CmpInst::ICMP_EQ, SuccessRes, OldValRes, CmpVal); 880 MI.eraseFromParent(); 881 return Legalized; 882 } 883 } 884 } 885 886 LegalizerHelper::LegalizeResult 887 LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, 888 LLT NarrowTy) { 889 // FIXME: Don't know how to handle secondary types yet. 890 if (TypeIdx != 0) 891 return UnableToLegalize; 892 switch (MI.getOpcode()) { 893 default: 894 return UnableToLegalize; 895 case TargetOpcode::G_ADD: { 896 unsigned NarrowSize = NarrowTy.getSizeInBits(); 897 unsigned DstReg = MI.getOperand(0).getReg(); 898 unsigned Size = MRI.getType(DstReg).getSizeInBits(); 899 int NumParts = Size / NarrowSize; 900 // FIXME: Don't know how to handle the situation where the small vectors 901 // aren't all the same size yet. 902 if (Size % NarrowSize != 0) 903 return UnableToLegalize; 904 905 MIRBuilder.setInstr(MI); 906 907 SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs; 908 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs); 909 extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs); 910 911 for (int i = 0; i < NumParts; ++i) { 912 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); 913 MIRBuilder.buildAdd(DstReg, Src1Regs[i], Src2Regs[i]); 914 DstRegs.push_back(DstReg); 915 } 916 917 MIRBuilder.buildMerge(DstReg, DstRegs); 918 MI.eraseFromParent(); 919 return Legalized; 920 } 921 } 922 } 923