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>
getBaseWithConstantOffset(MachineRegisterInfo & MRI,Register Reg,GISelKnownBits * KnownBits)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
hasAtomicFaddRtnForTy(const GCNSubtarget & Subtarget,const LLT & Ty)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