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 "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
11#include "llvm/IR/Constants.h"
12
13using namespace llvm;
14using namespace MIPatternMatch;
15
16std::tuple<Register, unsigned, MachineInstr *>
17AMDGPU::getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg) {
18  MachineInstr *Def = getDefIgnoringCopies(Reg, MRI);
19  if (!Def)
20    return std::make_tuple(Reg, 0, nullptr);
21
22  if (Def->getOpcode() == TargetOpcode::G_CONSTANT) {
23    unsigned Offset;
24    const MachineOperand &Op = Def->getOperand(1);
25    if (Op.isImm())
26      Offset = Op.getImm();
27    else
28      Offset = Op.getCImm()->getZExtValue();
29
30    return std::make_tuple(Register(), Offset, Def);
31  }
32
33  int64_t Offset;
34  if (Def->getOpcode() == TargetOpcode::G_ADD) {
35    // TODO: Handle G_OR used for add case
36    if (mi_match(Def->getOperand(2).getReg(), MRI, m_ICst(Offset)))
37      return std::make_tuple(Def->getOperand(1).getReg(), Offset, Def);
38
39    // FIXME: matcher should ignore copies
40    if (mi_match(Def->getOperand(2).getReg(), MRI, m_Copy(m_ICst(Offset))))
41      return std::make_tuple(Def->getOperand(1).getReg(), Offset, Def);
42  }
43
44  return std::make_tuple(Reg, 0, Def);
45}
46
47bool AMDGPU::isLegalVOP3PShuffleMask(ArrayRef<int> Mask) {
48  assert(Mask.size() == 2);
49
50  // If one half is undef, the other is trivially in the same reg.
51  if (Mask[0] == -1 || Mask[1] == -1)
52    return true;
53  return (Mask[0] & 2) == (Mask[1] & 2);
54}
55