1 //===- AMDGPUGlobalISelUtils.cpp ---------------------------------*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "AMDGPUGlobalISelUtils.h" 10 #include "GCNSubtarget.h" 11 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 12 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 13 #include "llvm/IR/Constants.h" 14 #include "llvm/Support/LowLevelTypeImpl.h" 15 16 using namespace llvm; 17 using namespace MIPatternMatch; 18 19 std::pair<Register, unsigned> 20 AMDGPU::getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg, 21 GISelKnownBits *KnownBits) { 22 MachineInstr *Def = getDefIgnoringCopies(Reg, MRI); 23 if (Def->getOpcode() == TargetOpcode::G_CONSTANT) { 24 unsigned Offset; 25 const MachineOperand &Op = Def->getOperand(1); 26 if (Op.isImm()) 27 Offset = Op.getImm(); 28 else 29 Offset = Op.getCImm()->getZExtValue(); 30 31 return std::pair(Register(), Offset); 32 } 33 34 int64_t Offset; 35 if (Def->getOpcode() == TargetOpcode::G_ADD) { 36 // TODO: Handle G_OR used for add case 37 if (mi_match(Def->getOperand(2).getReg(), MRI, m_ICst(Offset))) 38 return std::pair(Def->getOperand(1).getReg(), Offset); 39 40 // FIXME: matcher should ignore copies 41 if (mi_match(Def->getOperand(2).getReg(), MRI, m_Copy(m_ICst(Offset)))) 42 return std::pair(Def->getOperand(1).getReg(), Offset); 43 } 44 45 Register Base; 46 if (KnownBits && mi_match(Reg, MRI, m_GOr(m_Reg(Base), m_ICst(Offset))) && 47 KnownBits->maskedValueIsZero(Base, APInt(32, Offset))) 48 return std::pair(Base, Offset); 49 50 // Handle G_PTRTOINT (G_PTR_ADD base, const) case 51 if (Def->getOpcode() == TargetOpcode::G_PTRTOINT) { 52 MachineInstr *Base; 53 if (mi_match(Def->getOperand(1).getReg(), MRI, 54 m_GPtrAdd(m_MInstr(Base), m_ICst(Offset)))) { 55 // If Base was int converted to pointer, simply return int and offset. 56 if (Base->getOpcode() == TargetOpcode::G_INTTOPTR) 57 return std::pair(Base->getOperand(1).getReg(), Offset); 58 59 // Register returned here will be of pointer type. 60 return std::pair(Base->getOperand(0).getReg(), Offset); 61 } 62 } 63 64 return std::pair(Reg, 0); 65 } 66 67 bool AMDGPU::hasAtomicFaddRtnForTy(const GCNSubtarget &Subtarget, 68 const LLT &Ty) { 69 if (Ty == LLT::scalar(32)) 70 return Subtarget.hasAtomicFaddRtnInsts(); 71 if (Ty == LLT::fixed_vector(2, 16) || Ty == LLT::scalar(64)) 72 return Subtarget.hasGFX90AInsts(); 73 return false; 74 } 75