Path: blob/main/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUGlobalISelUtils.cpp
35269 views
//===- AMDGPUGlobalISelUtils.cpp ---------------------------------*- C++ -*-==//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "AMDGPUGlobalISelUtils.h"9#include "GCNSubtarget.h"10#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"11#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"12#include "llvm/CodeGenTypes/LowLevelType.h"13#include "llvm/IR/Constants.h"1415using namespace llvm;16using namespace MIPatternMatch;1718std::pair<Register, unsigned>19AMDGPU::getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg,20GISelKnownBits *KnownBits, bool CheckNUW) {21MachineInstr *Def = getDefIgnoringCopies(Reg, MRI);22if (Def->getOpcode() == TargetOpcode::G_CONSTANT) {23unsigned Offset;24const MachineOperand &Op = Def->getOperand(1);25if (Op.isImm())26Offset = Op.getImm();27else28Offset = Op.getCImm()->getZExtValue();2930return std::pair(Register(), Offset);31}3233int64_t Offset;34if (Def->getOpcode() == TargetOpcode::G_ADD) {35// A 32-bit (address + offset) should not cause unsigned 32-bit integer36// wraparound, because s_load instructions perform the addition in 64 bits.37if (CheckNUW && !Def->getFlag(MachineInstr::NoUWrap)) {38assert(MRI.getType(Reg).getScalarSizeInBits() == 32);39return std::pair(Reg, 0);40}41// TODO: Handle G_OR used for add case42if (mi_match(Def->getOperand(2).getReg(), MRI, m_ICst(Offset)))43return std::pair(Def->getOperand(1).getReg(), Offset);4445// FIXME: matcher should ignore copies46if (mi_match(Def->getOperand(2).getReg(), MRI, m_Copy(m_ICst(Offset))))47return std::pair(Def->getOperand(1).getReg(), Offset);48}4950Register Base;51if (KnownBits && mi_match(Reg, MRI, m_GOr(m_Reg(Base), m_ICst(Offset))) &&52KnownBits->maskedValueIsZero(Base, APInt(32, Offset)))53return std::pair(Base, Offset);5455// Handle G_PTRTOINT (G_PTR_ADD base, const) case56if (Def->getOpcode() == TargetOpcode::G_PTRTOINT) {57MachineInstr *Base;58if (mi_match(Def->getOperand(1).getReg(), MRI,59m_GPtrAdd(m_MInstr(Base), m_ICst(Offset)))) {60// If Base was int converted to pointer, simply return int and offset.61if (Base->getOpcode() == TargetOpcode::G_INTTOPTR)62return std::pair(Base->getOperand(1).getReg(), Offset);6364// Register returned here will be of pointer type.65return std::pair(Base->getOperand(0).getReg(), Offset);66}67}6869return std::pair(Reg, 0);70}717273