1480093f4SDimitry Andric //===- AMDGPUGlobalISelUtils.cpp ---------------------------------*- C++ -*-==// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric 9480093f4SDimitry Andric #include "AMDGPUGlobalISelUtils.h" 1081ad6265SDimitry Andric #include "GCNSubtarget.h" 11*bdd1243dSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 12480093f4SDimitry Andric #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 13480093f4SDimitry Andric #include "llvm/IR/Constants.h" 1481ad6265SDimitry Andric #include "llvm/Support/LowLevelTypeImpl.h" 15480093f4SDimitry Andric 16480093f4SDimitry Andric using namespace llvm; 17480093f4SDimitry Andric using namespace MIPatternMatch; 18480093f4SDimitry Andric 19e8d8bef9SDimitry Andric std::pair<Register, unsigned> 20*bdd1243dSDimitry Andric AMDGPU::getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg, 21*bdd1243dSDimitry Andric GISelKnownBits *KnownBits) { 22480093f4SDimitry Andric MachineInstr *Def = getDefIgnoringCopies(Reg, MRI); 23480093f4SDimitry Andric if (Def->getOpcode() == TargetOpcode::G_CONSTANT) { 24480093f4SDimitry Andric unsigned Offset; 25480093f4SDimitry Andric const MachineOperand &Op = Def->getOperand(1); 26480093f4SDimitry Andric if (Op.isImm()) 27480093f4SDimitry Andric Offset = Op.getImm(); 28480093f4SDimitry Andric else 29480093f4SDimitry Andric Offset = Op.getCImm()->getZExtValue(); 30480093f4SDimitry Andric 31*bdd1243dSDimitry Andric return std::pair(Register(), Offset); 32480093f4SDimitry Andric } 33480093f4SDimitry Andric 34480093f4SDimitry Andric int64_t Offset; 35480093f4SDimitry Andric if (Def->getOpcode() == TargetOpcode::G_ADD) { 36480093f4SDimitry Andric // TODO: Handle G_OR used for add case 37480093f4SDimitry Andric if (mi_match(Def->getOperand(2).getReg(), MRI, m_ICst(Offset))) 38*bdd1243dSDimitry Andric return std::pair(Def->getOperand(1).getReg(), Offset); 39480093f4SDimitry Andric 40480093f4SDimitry Andric // FIXME: matcher should ignore copies 41480093f4SDimitry Andric if (mi_match(Def->getOperand(2).getReg(), MRI, m_Copy(m_ICst(Offset)))) 42*bdd1243dSDimitry Andric return std::pair(Def->getOperand(1).getReg(), Offset); 43480093f4SDimitry Andric } 44480093f4SDimitry Andric 45*bdd1243dSDimitry Andric Register Base; 46*bdd1243dSDimitry Andric if (KnownBits && mi_match(Reg, MRI, m_GOr(m_Reg(Base), m_ICst(Offset))) && 47*bdd1243dSDimitry Andric KnownBits->maskedValueIsZero(Base, APInt(32, Offset))) 48*bdd1243dSDimitry Andric return std::pair(Base, Offset); 49*bdd1243dSDimitry Andric 50fe6060f1SDimitry Andric // Handle G_PTRTOINT (G_PTR_ADD base, const) case 51fe6060f1SDimitry Andric if (Def->getOpcode() == TargetOpcode::G_PTRTOINT) { 52fe6060f1SDimitry Andric MachineInstr *Base; 53fe6060f1SDimitry Andric if (mi_match(Def->getOperand(1).getReg(), MRI, 54fe6060f1SDimitry Andric m_GPtrAdd(m_MInstr(Base), m_ICst(Offset)))) { 55fe6060f1SDimitry Andric // If Base was int converted to pointer, simply return int and offset. 56fe6060f1SDimitry Andric if (Base->getOpcode() == TargetOpcode::G_INTTOPTR) 57*bdd1243dSDimitry Andric return std::pair(Base->getOperand(1).getReg(), Offset); 58fe6060f1SDimitry Andric 59fe6060f1SDimitry Andric // Register returned here will be of pointer type. 60*bdd1243dSDimitry Andric return std::pair(Base->getOperand(0).getReg(), Offset); 61fe6060f1SDimitry Andric } 62fe6060f1SDimitry Andric } 63fe6060f1SDimitry Andric 64*bdd1243dSDimitry Andric return std::pair(Reg, 0); 655ffd83dbSDimitry Andric } 6681ad6265SDimitry Andric 6781ad6265SDimitry Andric bool AMDGPU::hasAtomicFaddRtnForTy(const GCNSubtarget &Subtarget, 6881ad6265SDimitry Andric const LLT &Ty) { 6981ad6265SDimitry Andric if (Ty == LLT::scalar(32)) 7081ad6265SDimitry Andric return Subtarget.hasAtomicFaddRtnInsts(); 7181ad6265SDimitry Andric if (Ty == LLT::fixed_vector(2, 16) || Ty == LLT::scalar(64)) 7281ad6265SDimitry Andric return Subtarget.hasGFX90AInsts(); 7381ad6265SDimitry Andric return false; 7481ad6265SDimitry Andric } 75