//===- AMDGPULegalizerInfo.cpp -----------------------------------*- C++ -*-==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
/// This file implements the targeting of the Machinelegalizer class for
/// AMDGPU.
/// \todo This should be generated by TableGen.
//===----------------------------------------------------------------------===//

#include "AMDGPULegalizerInfo.h"

#include "AMDGPU.h"
#include "AMDGPUGlobalISelUtils.h"
#include "AMDGPUInstrInfo.h"
#include "AMDGPUMemoryUtils.h"
#include "AMDGPUTargetMachine.h"
#include "SIInstrInfo.h"
#include "SIMachineFunctionInfo.h"
#include "SIRegisterInfo.h"
#include "Utils/AMDGPUBaseInfo.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/PseudoSourceValueManager.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsR600.h"
#include "llvm/Support/AMDGPUAddrSpace.h"

#define DEBUG_TYPE "amdgpu-legalinfo"

using namespace llvm;
using namespace LegalizeActions;
using namespace LegalizeMutations;
using namespace LegalityPredicates;
using namespace MIPatternMatch;

// Hack until load/store selection patterns support any tuple of legal types.
static cl::opt<bool> EnableNewLegality(
  "amdgpu-global-isel-new-legality",
  cl::desc("Use GlobalISel desired legality, rather than try to use"
           "rules compatible with selection patterns"),
  cl::init(false),
  cl::ReallyHidden);

static constexpr unsigned MaxRegisterSize = 1024;

// Round the number of elements to the next power of two elements
static LLT getPow2VectorType(LLT Ty) {
  unsigned NElts = Ty.getNumElements();
  unsigned Pow2NElts = 1 <<  Log2_32_Ceil(NElts);
  return Ty.changeElementCount(ElementCount::getFixed(Pow2NElts));
}

// Round the number of bits to the next power of two bits
static LLT getPow2ScalarType(LLT Ty) {
  unsigned Bits = Ty.getSizeInBits();
  unsigned Pow2Bits = 1 <<  Log2_32_Ceil(Bits);
  return LLT::scalar(Pow2Bits);
}

/// \returns true if this is an odd sized vector which should widen by adding an
/// additional element. This is mostly to handle <3 x s16> -> <4 x s16>. This
/// excludes s1 vectors, which should always be scalarized.
static LegalityPredicate isSmallOddVector(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];
    if (!Ty.isVector())
      return false;

    const LLT EltTy = Ty.getElementType();
    const unsigned EltSize = EltTy.getSizeInBits();
    return Ty.getNumElements() % 2 != 0 &&
           EltSize > 1 && EltSize < 32 &&
           Ty.getSizeInBits() % 32 != 0;
  };
}

static LegalityPredicate sizeIsMultipleOf32(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];
    return Ty.getSizeInBits() % 32 == 0;
  };
}

static LegalityPredicate isWideVec16(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];
    const LLT EltTy = Ty.getScalarType();
    return EltTy.getSizeInBits() == 16 && Ty.getNumElements() > 2;
  };
}

static LegalizeMutation oneMoreElement(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];
    const LLT EltTy = Ty.getElementType();
    return std::pair(TypeIdx,
                     LLT::fixed_vector(Ty.getNumElements() + 1, EltTy));
  };
}

static LegalizeMutation fewerEltsToSize64Vector(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];
    const LLT EltTy = Ty.getElementType();
    unsigned Size = Ty.getSizeInBits();
    unsigned Pieces = (Size + 63) / 64;
    unsigned NewNumElts = (Ty.getNumElements() + 1) / Pieces;
    return std::pair(TypeIdx, LLT::scalarOrVector(
                                  ElementCount::getFixed(NewNumElts), EltTy));
  };
}

// Increase the number of vector elements to reach the next multiple of 32-bit
// type.
static LegalizeMutation moreEltsToNext32Bit(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];

    const LLT EltTy = Ty.getElementType();
    const int Size = Ty.getSizeInBits();
    const int EltSize = EltTy.getSizeInBits();
    const int NextMul32 = (Size + 31) / 32;

    assert(EltSize < 32);

    const int NewNumElts = (32 * NextMul32 + EltSize - 1) / EltSize;
    return std::pair(TypeIdx, LLT::fixed_vector(NewNumElts, EltTy));
  };
}

// Retrieves the scalar type that's the same size as the mem desc
static LegalizeMutation getScalarTypeFromMemDesc(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    unsigned MemSize = Query.MMODescrs[0].MemoryTy.getSizeInBits();
    return std::make_pair(TypeIdx, LLT::integer(MemSize));
  };
}

// Increase the number of vector elements to reach the next legal RegClass.
static LegalizeMutation moreElementsToNextExistingRegClass(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];
    const unsigned NumElts = Ty.getNumElements();
    const unsigned EltSize = Ty.getElementType().getSizeInBits();
    const unsigned MaxNumElts = MaxRegisterSize / EltSize;

    assert(EltSize == 32 || EltSize == 64);
    assert(Ty.getSizeInBits() < MaxRegisterSize);

    unsigned NewNumElts;
    // Find the nearest legal RegClass that is larger than the current type.
    for (NewNumElts = NumElts; NewNumElts < MaxNumElts; ++NewNumElts) {
      if (SIRegisterInfo::getSGPRClassForBitWidth(NewNumElts * EltSize))
        break;
    }
    return std::pair(TypeIdx,
                     LLT::fixed_vector(NewNumElts, Ty.getElementType()));
  };
}

static LLT getBufferRsrcScalarType(const LLT Ty) {
  if (!Ty.isVector())
    return LLT::scalar(128);
  const ElementCount NumElems = Ty.getElementCount();
  return LLT::vector(NumElems, LLT::scalar(128));
}

static LLT getBufferRsrcRegisterType(const LLT Ty) {
  if (!Ty.isVector())
    return LLT::fixed_vector(4, LLT::integer(32));
  const unsigned NumElems = Ty.getElementCount().getFixedValue();
  return LLT::fixed_vector(NumElems * 4, LLT::integer(32));
}

static LLT getBitcastRegisterType(const LLT Ty) {
  const unsigned Size = Ty.getSizeInBits();

  if (Size <= 32) {
    // <2 x i8> -> i16
    // <4 x i8> -> i32
    return LLT::integer(Size);
  }

  return LLT::fixed_vector(Size / 32, LLT::integer(32));
}

static LegalizeMutation bitcastToRegisterType(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];
    return std::pair(TypeIdx, getBitcastRegisterType(Ty));
  };
}

static LegalizeMutation bitcastToVectorElement32(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];
    unsigned Size = Ty.getSizeInBits();
    assert(Size % 32 == 0);
    return std::pair(TypeIdx,
                     LLT::scalarOrVector(ElementCount::getFixed(Size / 32),
                                         LLT::integer(32)));
  };
}

static LegalityPredicate vectorSmallerThan(unsigned TypeIdx, unsigned Size) {
  return [=](const LegalityQuery &Query) {
    const LLT QueryTy = Query.Types[TypeIdx];
    return QueryTy.isVector() && QueryTy.getSizeInBits() < Size;
  };
}

static LegalityPredicate vectorWiderThan(unsigned TypeIdx, unsigned Size) {
  return [=](const LegalityQuery &Query) {
    const LLT QueryTy = Query.Types[TypeIdx];
    return QueryTy.isVector() && QueryTy.getSizeInBits() > Size;
  };
}

static LegalityPredicate numElementsNotEven(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT QueryTy = Query.Types[TypeIdx];
    return QueryTy.isVector() && QueryTy.getNumElements() % 2 != 0;
  };
}

static bool isRegisterSize(const GCNSubtarget &ST, unsigned Size) {
  return ((ST.useRealTrue16Insts() && Size == 16) || Size % 32 == 0) &&
         Size <= MaxRegisterSize;
}

static bool isRegisterVectorElementType(LLT EltTy) {
  const int EltSize = EltTy.getSizeInBits();
  return EltSize == 16 || EltSize % 32 == 0;
}

static bool isRegisterVectorType(LLT Ty) {
  const int EltSize = Ty.getElementType().getSizeInBits();
  return EltSize == 32 || EltSize == 64 ||
         (EltSize == 16 && Ty.getNumElements() % 2 == 0) ||
         EltSize == 128 || EltSize == 256;
}

// TODO: replace all uses of isRegisterType with isRegisterClassType
static bool isRegisterType(const GCNSubtarget &ST, LLT Ty) {
  if (!isRegisterSize(ST, Ty.getSizeInBits()))
    return false;

  if (Ty.isVector())
    return isRegisterVectorType(Ty);

  return true;
}

// Any combination of 32 or 64-bit elements up the maximum register size, and
// multiples of v2s16.
static LegalityPredicate isRegisterType(const GCNSubtarget &ST,
                                        unsigned TypeIdx) {
  return [=, &ST](const LegalityQuery &Query) {
    return isRegisterType(ST, Query.Types[TypeIdx]);
  };
}

// RegisterType that doesn't have a corresponding RegClass.
// TODO: Once `isRegisterType` is replaced with `isRegisterClassType` this
// should be removed.
static LegalityPredicate isIllegalRegisterType(const GCNSubtarget &ST,
                                               unsigned TypeIdx) {
  return [=, &ST](const LegalityQuery &Query) {
    LLT Ty = Query.Types[TypeIdx];
    return isRegisterType(ST, Ty) &&
           !SIRegisterInfo::getSGPRClassForBitWidth(Ty.getSizeInBits());
  };
}

static LegalityPredicate elementTypeIsLegal(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT QueryTy = Query.Types[TypeIdx];
    if (!QueryTy.isVector())
      return false;
    const LLT EltTy = QueryTy.getElementType();
    return EltTy == LLT::scalar(16) || EltTy.getSizeInBits() >= 32;
  };
}

constexpr LLT F16 = LLT::float16();
constexpr LLT BF16 = LLT::bfloat16();
constexpr LLT F32 = LLT::float32();
constexpr LLT F64 = LLT::float64();
constexpr LLT V2F16 = LLT::fixed_vector(2, F16);
constexpr LLT V2BF16 = LLT::fixed_vector(2, BF16);
constexpr LLT V2F32 = LLT::fixed_vector(2, F32);
constexpr LLT V2F64 = LLT::fixed_vector(2, F64);

constexpr LLT S1 = LLT::scalar(1);
constexpr LLT S8 = LLT::scalar(8);
constexpr LLT S16 = LLT::scalar(16);
constexpr LLT S32 = LLT::scalar(32);
constexpr LLT S64 = LLT::scalar(64);
constexpr LLT S96 = LLT::scalar(96);
constexpr LLT S128 = LLT::scalar(128);
constexpr LLT S160 = LLT::scalar(160);
constexpr LLT S192 = LLT::scalar(192);
constexpr LLT S224 = LLT::scalar(224);
constexpr LLT S256 = LLT::scalar(256);
constexpr LLT S512 = LLT::scalar(512);
constexpr LLT S1024 = LLT::scalar(1024);
constexpr LLT MaxScalar = LLT::scalar(MaxRegisterSize);

constexpr LLT V2S8 = LLT::fixed_vector(2, 8);
constexpr LLT V2S16 = LLT::fixed_vector(2, 16);
constexpr LLT V4S16 = LLT::fixed_vector(4, 16);
constexpr LLT V6S16 = LLT::fixed_vector(6, 16);
constexpr LLT V8S16 = LLT::fixed_vector(8, 16);
constexpr LLT V10S16 = LLT::fixed_vector(10, 16);
constexpr LLT V12S16 = LLT::fixed_vector(12, 16);
constexpr LLT V16S16 = LLT::fixed_vector(16, 16);

constexpr LLT V2S32 = LLT::fixed_vector(2, 32);
constexpr LLT V3S32 = LLT::fixed_vector(3, 32);
constexpr LLT V4S32 = LLT::fixed_vector(4, 32);
constexpr LLT V5S32 = LLT::fixed_vector(5, 32);
constexpr LLT V6S32 = LLT::fixed_vector(6, 32);
constexpr LLT V7S32 = LLT::fixed_vector(7, 32);
constexpr LLT V8S32 = LLT::fixed_vector(8, 32);
constexpr LLT V9S32 = LLT::fixed_vector(9, 32);
constexpr LLT V10S32 = LLT::fixed_vector(10, 32);
constexpr LLT V11S32 = LLT::fixed_vector(11, 32);
constexpr LLT V12S32 = LLT::fixed_vector(12, 32);
constexpr LLT V16S32 = LLT::fixed_vector(16, 32);
constexpr LLT V32S32 = LLT::fixed_vector(32, 32);

constexpr LLT V2S64 = LLT::fixed_vector(2, 64);
constexpr LLT V3S64 = LLT::fixed_vector(3, 64);
constexpr LLT V4S64 = LLT::fixed_vector(4, 64);
constexpr LLT V5S64 = LLT::fixed_vector(5, 64);
constexpr LLT V6S64 = LLT::fixed_vector(6, 64);
constexpr LLT V7S64 = LLT::fixed_vector(7, 64);
constexpr LLT V8S64 = LLT::fixed_vector(8, 64);
constexpr LLT V16S64 = LLT::fixed_vector(16, 64);

constexpr LLT V2S128 = LLT::fixed_vector(2, 128);
constexpr LLT V4S128 = LLT::fixed_vector(4, 128);

constexpr std::initializer_list<LLT> AllScalarTypes = {
    S32, S64, S96, S128, S160, S192, S224, S256, S512, S1024};

constexpr std::initializer_list<LLT> AllS16Vectors{
    V2S16, V4S16, V6S16, V8S16, V10S16, V12S16, V16S16, V2S128, V4S128};

constexpr std::initializer_list<LLT> AllS32Vectors = {
    V2S32, V3S32,  V4S32,  V5S32,  V6S32,  V7S32, V8S32,
    V9S32, V10S32, V11S32, V12S32, V16S32, V32S32};

constexpr std::initializer_list<LLT> AllS64Vectors = {
    V2S64, V3S64, V4S64, V5S64, V6S64, V7S64, V8S64, V16S64};

constexpr std::initializer_list<LLT> AllVectors{
    V2S16,  V4S16,  V6S16,  V8S16,  V10S16, V12S16, V16S16, V2S128,
    V4S128, V2S32,  V3S32,  V4S32,  V5S32,  V6S32,  V7S32,  V8S32,
    V9S32,  V10S32, V11S32, V12S32, V16S32, V32S32, V2S64,  V3S64,
    V4S64,  V5S64,  V6S64,  V7S64,  V8S64,  V16S64};

// Checks whether a type is in the list of legal register types.
static bool isRegisterClassType(const GCNSubtarget &ST, LLT Ty) {
  if (Ty.isPointerOrPointerVector())
    Ty = Ty.changeElementType(LLT::scalar(Ty.getScalarSizeInBits()));

  return is_contained(AllS32Vectors, Ty) || is_contained(AllS64Vectors, Ty) ||
         is_contained(AllScalarTypes, Ty) ||
         (ST.useRealTrue16Insts() && Ty == S16) ||
         is_contained(AllS16Vectors, Ty);
}

static LegalityPredicate isRegisterClassType(const GCNSubtarget &ST,
                                             unsigned TypeIdx) {
  return [&ST, TypeIdx](const LegalityQuery &Query) {
    return isRegisterClassType(ST, Query.Types[TypeIdx]);
  };
}

// If we have a truncating store or an extending load with a data size larger
// than 32-bits, we need to reduce to a 32-bit type.
static LegalityPredicate isWideScalarExtLoadTruncStore(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    const LLT Ty = Query.Types[TypeIdx];
    return !Ty.isVector() && Ty.getSizeInBits() > 32 &&
           Query.MMODescrs[0].MemoryTy.getSizeInBits() < Ty.getSizeInBits();
  };
}

// If we have a truncating store or an extending load with a data size larger
// than 32-bits and mem location is a power of 2
static LegalityPredicate isTruncStoreToSizePowerOf2(unsigned TypeIdx) {
  return [=](const LegalityQuery &Query) {
    unsigned MemSize = Query.MMODescrs[0].MemoryTy.getSizeInBits();
    return isWideScalarExtLoadTruncStore(TypeIdx)(Query) &&
           isPowerOf2_64(MemSize);
  };
}

// TODO: Should load to s16 be legal? Most loads extend to 32-bits, but we
// handle some operations by just promoting the register during
// selection. There are also d16 loads on GFX9+ which preserve the high bits.
static unsigned maxSizeForAddrSpace(const GCNSubtarget &ST, unsigned AS,
                                    bool IsLoad, bool IsAtomic) {
  switch (AS) {
  case AMDGPUAS::PRIVATE_ADDRESS:
    // FIXME: Private element size.
    return ST.hasFlatScratchEnabled() ? 128 : 32;
  case AMDGPUAS::LOCAL_ADDRESS:
    return ST.useDS128() ? 128 : 64;
  case AMDGPUAS::GLOBAL_ADDRESS:
  case AMDGPUAS::CONSTANT_ADDRESS:
  case AMDGPUAS::CONSTANT_ADDRESS_32BIT:
  case AMDGPUAS::BUFFER_RESOURCE:
    // Treat constant and global as identical. SMRD loads are sometimes usable for
    // global loads (ideally constant address space should be eliminated)
    // depending on the context. Legality cannot be context dependent, but
    // RegBankSelect can split the load as necessary depending on the pointer
    // register bank/uniformity and if the memory is invariant or not written in a
    // kernel.
    return IsLoad ? 512 : 128;
  default:
    // FIXME: Flat addresses may contextually need to be split to 32-bit parts
    // if they may alias scratch depending on the subtarget.  This needs to be
    // moved to custom handling to use addressMayBeAccessedAsPrivate
    return ST.hasMultiDwordFlatScratchAddressing() || IsAtomic ? 128 : 32;
  }
}

static bool isLoadStoreSizeLegal(const GCNSubtarget &ST,
                                 const LegalityQuery &Query) {
  const LLT Ty = Query.Types[0];

  // Handle G_LOAD, G_ZEXTLOAD, G_SEXTLOAD
  const bool IsLoad = Query.Opcode != AMDGPU::G_STORE;

  unsigned RegSize = Ty.getSizeInBits();
  uint64_t MemSize = Query.MMODescrs[0].MemoryTy.getSizeInBits();
  uint64_t AlignBits = Query.MMODescrs[0].AlignInBits;
  unsigned AS = Query.Types[1].getAddressSpace();

  // All of these need to be custom lowered to cast the pointer operand.
  if (AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT)
    return false;

  // Do not handle extending vector loads.
  if (Ty.isVector() && MemSize != RegSize)
    return false;

  // TODO: We should be able to widen loads if the alignment is high enough, but
  // we also need to modify the memory access size.
#if 0
  // Accept widening loads based on alignment.
  if (IsLoad && MemSize < Size)
    MemSize = std::max(MemSize, Align);
#endif

  // Only 1-byte and 2-byte to 32-bit extloads are valid.
  if (MemSize != RegSize && RegSize != 32)
    return false;

  if (IsLoad && RegSize == 16 && !ST.d16PreservesUnusedBits())
    return false;

  if (MemSize > maxSizeForAddrSpace(ST, AS, IsLoad,
                                    Query.MMODescrs[0].Ordering !=
                                        AtomicOrdering::NotAtomic))
    return false;

  switch (MemSize) {
  case 8:
  case 16:
  case 32:
  case 64:
  case 128:
    break;
  case 96:
    if (!ST.hasDwordx3LoadStores())
      return false;
    break;
  case 256:
  case 512:
    // These may contextually need to be broken down.
    break;
  default:
    return false;
  }

  assert(RegSize >= MemSize);

  if (AlignBits < MemSize) {
    const SITargetLowering *TLI = ST.getTargetLowering();
    if (!TLI->allowsMisalignedMemoryAccessesImpl(MemSize, AS,
                                                 Align(AlignBits / 8)))
      return false;
  }

  return true;
}

// The newer buffer intrinsic forms take their resource arguments as
// pointers in address space 8, aka s128 values. However, in order to not break
// SelectionDAG, the underlying operations have to continue to take v4i32
// arguments. Therefore, we convert resource pointers - or vectors of them
// to integer values here.
static bool hasBufferRsrcWorkaround(const LLT Ty) {
  if (Ty.isPointer() && Ty.getAddressSpace() == AMDGPUAS::BUFFER_RESOURCE)
    return true;
  if (Ty.isVector()) {
    const LLT ElemTy = Ty.getElementType();
    return hasBufferRsrcWorkaround(ElemTy);
  }
  return false;
}

// The current selector can't handle <6 x s16>, <8 x s16>, s96, s128 etc, so
// workaround this. Eventually it should ignore the type for loads and only care
// about the size. Return true in cases where we will workaround this for now by
// bitcasting.
static bool loadStoreBitcastWorkaround(const LLT Ty) {
  if (EnableNewLegality)
    return false;

  const unsigned Size = Ty.getSizeInBits();
  if (Ty.isPointerVector())
    return true;
  if (Size <= 64)
    return false;
  // Address space 8 pointers get their own workaround.
  if (hasBufferRsrcWorkaround(Ty))
    return false;
  if (!Ty.isVector())
    return true;

  unsigned EltSize = Ty.getScalarSizeInBits();
  return EltSize != 32 && EltSize != 64;
}

static bool isLoadStoreLegal(const GCNSubtarget &ST, const LegalityQuery &Query) {
  const LLT Ty = Query.Types[0];
  return isRegisterType(ST, Ty) && isLoadStoreSizeLegal(ST, Query) &&
         !hasBufferRsrcWorkaround(Ty) && !loadStoreBitcastWorkaround(Ty);
}

/// Return true if a load or store of the type should be lowered with a bitcast
/// to a different type.
static bool shouldBitcastLoadStoreType(const GCNSubtarget &ST, const LLT Ty,
                                       const LLT MemTy) {
  const unsigned MemSizeInBits = MemTy.getSizeInBits();
  const unsigned Size = Ty.getSizeInBits();
  if (Size != MemSizeInBits)
    return Size <= 32 && Ty.isVector();

  if (loadStoreBitcastWorkaround(Ty) && isRegisterType(ST, Ty))
    return true;

  // Don't try to handle bitcasting vector ext loads for now.
  return Ty.isVector() && (!MemTy.isVector() || MemTy == Ty) &&
         (Size <= 32 || isRegisterSize(ST, Size)) &&
         !isRegisterVectorElementType(Ty.getElementType());
}

/// Return true if we should legalize a load by widening an odd sized memory
/// access up to the alignment. Note this case when the memory access itself
/// changes, not the size of the result register.
static bool shouldWidenLoad(const GCNSubtarget &ST, LLT MemoryTy,
                            uint64_t AlignInBits, unsigned AddrSpace,
                            unsigned Opcode) {
  unsigned SizeInBits = MemoryTy.getSizeInBits();
  // We don't want to widen cases that are naturally legal.
  if (isPowerOf2_32(SizeInBits))
    return false;

  // If we have 96-bit memory operations, we shouldn't touch them. Note we may
  // end up widening these for a scalar load during RegBankSelect, if we don't
  // have 96-bit scalar loads.
  if (SizeInBits == 96 && ST.hasDwordx3LoadStores())
    return false;

  if (SizeInBits >= maxSizeForAddrSpace(ST, AddrSpace, Opcode, false))
    return false;

  // A load is known dereferenceable up to the alignment, so it's legal to widen
  // to it.
  //
  // TODO: Could check dereferenceable for less aligned cases.
  unsigned RoundedSize = NextPowerOf2(SizeInBits);
  if (AlignInBits < RoundedSize)
    return false;

  // Do not widen if it would introduce a slow unaligned load.
  const SITargetLowering *TLI = ST.getTargetLowering();
  unsigned Fast = 0;
  return TLI->allowsMisalignedMemoryAccessesImpl(
             RoundedSize, AddrSpace, Align(AlignInBits / 8),
             MachineMemOperand::MOLoad, &Fast) &&
         Fast;
}

static bool shouldWidenLoad(const GCNSubtarget &ST, const LegalityQuery &Query,
                            unsigned Opcode) {
  if (Query.MMODescrs[0].Ordering != AtomicOrdering::NotAtomic)
    return false;

  return shouldWidenLoad(ST, Query.MMODescrs[0].MemoryTy,
                         Query.MMODescrs[0].AlignInBits,
                         Query.Types[1].getAddressSpace(), Opcode);
}

/// Mutates IR (typicaly a load instruction) to use a <4 x s32> as the initial
/// type of the operand `idx` and then to transform it to a `p8` via bitcasts
/// and inttoptr. In addition, handle vectors of p8. Returns the new type.
static LLT castBufferRsrcFromV4I32(MachineInstr &MI, MachineIRBuilder &B,
                                   MachineRegisterInfo &MRI, unsigned Idx) {
  MachineOperand &MO = MI.getOperand(Idx);

  const LLT PointerTy = MRI.getType(MO.getReg());

  // Paranoidly prevent us from doing this multiple times.
  if (!hasBufferRsrcWorkaround(PointerTy))
    return PointerTy;

  const LLT ScalarTy = getBufferRsrcScalarType(PointerTy);
  const LLT VectorTy = getBufferRsrcRegisterType(PointerTy);
  if (!PointerTy.isVector()) {
    // Happy path: (4 x s32) -> (s32, s32, s32, s32) -> (p8)
    const unsigned NumParts = PointerTy.getSizeInBits() / 32;
    const LLT I32 = LLT::integer(32);

    Register VectorReg = MRI.createGenericVirtualRegister(VectorTy);
    std::array<Register, 4> VectorElems;
    B.setInsertPt(B.getMBB(), ++B.getInsertPt());
    for (unsigned I = 0; I < NumParts; ++I)
      VectorElems[I] =
          B.buildExtractVectorElementConstant(I32, VectorReg, I).getReg(0);
    B.buildMergeValues(MO, VectorElems);
    MO.setReg(VectorReg);
    return VectorTy;
  }
  Register BitcastReg = MRI.createGenericVirtualRegister(VectorTy);
  B.setInsertPt(B.getMBB(), ++B.getInsertPt());
  auto Scalar = B.buildBitcast(ScalarTy, BitcastReg);
  B.buildIntToPtr(MO, Scalar);
  MO.setReg(BitcastReg);

  return VectorTy;
}

/// Cast a buffer resource (an address space 8 pointer) into a 4xi32, which is
/// the form in which the value must be in order to be passed to the low-level
/// representations used for MUBUF/MTBUF intrinsics. This is a hack, which is
/// needed in order to account for the fact that we can't define a register
/// class for s128 without breaking SelectionDAG.
static Register castBufferRsrcToV4I32(Register Pointer, MachineIRBuilder &B) {
  MachineRegisterInfo &MRI = *B.getMRI();
  const LLT PointerTy = MRI.getType(Pointer);
  const LLT ScalarTy = getBufferRsrcScalarType(PointerTy);
  const LLT VectorTy = getBufferRsrcRegisterType(PointerTy);

  if (!PointerTy.isVector()) {
    // Special case: p8 -> (s32, s32, s32, s32) -> (4xs32)
    SmallVector<Register, 4> PointerParts;
    const unsigned NumParts = PointerTy.getSizeInBits() / 32;
    auto Unmerged = B.buildUnmerge(LLT::integer(32), Pointer);
    for (unsigned I = 0; I < NumParts; ++I)
      PointerParts.push_back(Unmerged.getReg(I));
    return B.buildBuildVector(VectorTy, PointerParts).getReg(0);
  }
  Register Scalar = B.buildPtrToInt(ScalarTy, Pointer).getReg(0);
  return B.buildBitcast(VectorTy, Scalar).getReg(0);
}

static void castBufferRsrcArgToV4I32(MachineInstr &MI, MachineIRBuilder &B,
                                     unsigned Idx) {
  MachineOperand &MO = MI.getOperand(Idx);

  const LLT PointerTy = B.getMRI()->getType(MO.getReg());
  // Paranoidly prevent us from doing this multiple times.
  if (!hasBufferRsrcWorkaround(PointerTy))
    return;
  MO.setReg(castBufferRsrcToV4I32(MO.getReg(), B));
}

AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
                                         const GCNTargetMachine &TM)
  :  ST(ST_) {
  using namespace TargetOpcode;

  const LLT GlobalPtr = LLT::pointer(AMDGPUAS::GLOBAL_ADDRESS, 64);
  const LLT ConstantPtr = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64);
  const LLT Constant32Ptr = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS_32BIT, 32);
  const LLT LocalPtr = LLT::pointer(AMDGPUAS::LOCAL_ADDRESS, 32);
  const LLT RegionPtr = LLT::pointer(AMDGPUAS::REGION_ADDRESS, 32);
  const LLT FlatPtr = LLT::pointer(AMDGPUAS::FLAT_ADDRESS, 64);
  const LLT PrivatePtr = LLT::pointer(AMDGPUAS::PRIVATE_ADDRESS, 32);
  const LLT BufferFatPtr = LLT::pointer(AMDGPUAS::BUFFER_FAT_POINTER, 160);
  const LLT RsrcPtr = LLT::pointer(AMDGPUAS::BUFFER_RESOURCE, 128);
  const LLT BufferStridedPtr =
      LLT::pointer(AMDGPUAS::BUFFER_STRIDED_POINTER, 192);

  const LLT CodePtr = FlatPtr;

  const std::initializer_list<LLT> AddrSpaces64 = {
    GlobalPtr, ConstantPtr, FlatPtr
  };

  const std::initializer_list<LLT> AddrSpaces32 = {
    LocalPtr, PrivatePtr, Constant32Ptr, RegionPtr
  };

  const std::initializer_list<LLT> AddrSpaces128 = {RsrcPtr};

  const std::initializer_list<LLT> FPTypesBase = {F32, F64};
  const std::initializer_list<LLT> FPTypes16 = {F32, F64, F16};
  const std::initializer_list<LLT> FPTypesPK16 = {F32, F64, F16, V2F16};

  const LLT I1 = LLT::integer(1);
  const LLT I16 = LLT::integer(16);
  const LLT I32 = LLT::integer(32);
  const LLT I64 = LLT::integer(64);
  const LLT V2I16 = LLT::fixed_vector(2, I16);

  getActionDefinitionsBuilder(G_BR).alwaysLegal();

  // s1 for VCC branches, s32 for SCC branches.
  getActionDefinitionsBuilder(G_BRCOND).legalFor({S1, S32});

  // TODO: All multiples of 32, vectors of pointers, all v2s16 pairs, more
  // elements for v3s16
  getActionDefinitionsBuilder(G_PHI)
      .legalFor({S32, S64, V2S16, S16, V4S16, S1, S128, S256})
      .legalFor(AllS32Vectors)
      .legalFor(AllS64Vectors)
      .legalFor(AddrSpaces64)
      .legalFor(AddrSpaces32)
      .legalFor(AddrSpaces128)
      .legalIf(isPointer(0))
      .clampScalar(0, S16, S256)
      .widenScalarToNextPow2(0, 32)
      .clampMaxNumElements(0, S32, 16)
      .moreElementsIf(isSmallOddVector(0), oneMoreElement(0))
      .scalarize(0);

  if (ST.hasVOP3PInsts() && ST.hasAddNoCarryInsts() && ST.hasIntClamp()) {
    // Full set of gfx9 features.
    if (ST.hasAnyPackedU64Ops()) {
      getActionDefinitionsBuilder({G_ADD, G_SUB})
          .legalFor({S64, S32, S16, V2S16, V2S64})
          .clampMaxNumElementsStrict(0, S16, 2)
          .clampMaxNumElementsStrict(0, S64, 2)
          .scalarize(0)
          .minScalar(0, S16)
          .widenScalarToNextMultipleOf(0, 32)
          .maxScalar(0, S32);
    } else if (ST.hasScalarAddSub64()) {
      getActionDefinitionsBuilder({G_ADD, G_SUB})
          .legalFor({S64, S32, S16, V2S16})
          .clampMaxNumElementsStrict(0, S16, 2)
          .scalarize(0)
          .minScalar(0, S16)
          .widenScalarToNextMultipleOf(0, 32)
          .maxScalar(0, S32);
    } else {
      getActionDefinitionsBuilder({G_ADD, G_SUB})
          .legalFor({S32, S16, V2S16})
          .clampMaxNumElementsStrict(0, S16, 2)
          .scalarize(0)
          .minScalar(0, S16)
          .widenScalarToNextMultipleOf(0, 32)
          .maxScalar(0, S32);
    }

    if (ST.hasScalarSMulU64()) {
      getActionDefinitionsBuilder(G_MUL)
          .legalFor({S64, S32, S16, V2S16})
          .clampMaxNumElementsStrict(0, S16, 2)
          .scalarize(0)
          .minScalar(0, S16)
          .widenScalarToNextMultipleOf(0, 32)
          .custom();
    } else {
      getActionDefinitionsBuilder(G_MUL)
          .legalFor({S32, S16, V2S16})
          .clampMaxNumElementsStrict(0, S16, 2)
          .scalarize(0)
          .minScalar(0, S16)
          .widenScalarToNextMultipleOf(0, 32)
          .custom();
    }
    assert(ST.hasMad64_32());

    getActionDefinitionsBuilder({G_UADDSAT, G_USUBSAT, G_SADDSAT, G_SSUBSAT})
      .legalFor({S32, S16, V2S16}) // Clamp modifier
      .minScalarOrElt(0, S16)
      .clampMaxNumElementsStrict(0, S16, 2)
      .scalarize(0)
      .widenScalarToNextPow2(0, 32)
      .lower();
  } else if (ST.has16BitInsts()) {
    getActionDefinitionsBuilder({G_ADD, G_SUB})
      .legalFor({S32, S16})
      .minScalar(0, S16)
      .widenScalarToNextMultipleOf(0, 32)
      .maxScalar(0, S32)
      .scalarize(0);

    getActionDefinitionsBuilder(G_MUL)
      .legalFor({S32, S16})
      .scalarize(0)
      .minScalar(0, S16)
      .widenScalarToNextMultipleOf(0, 32)
      .custom();
    assert(ST.hasMad64_32());

    // Technically the saturating operations require clamp bit support, but this
    // was introduced at the same time as 16-bit operations.
    getActionDefinitionsBuilder({G_UADDSAT, G_USUBSAT})
      .legalFor({S32, S16}) // Clamp modifier
      .minScalar(0, S16)
      .scalarize(0)
      .widenScalarToNextPow2(0, 16)
      .lower();

    // We're just lowering this, but it helps get a better result to try to
    // coerce to the desired type first.
    getActionDefinitionsBuilder({G_SADDSAT, G_SSUBSAT})
      .minScalar(0, S16)
      .scalarize(0)
      .lower();
  } else {
    getActionDefinitionsBuilder({G_ADD, G_SUB})
      .legalFor({S32})
      .widenScalarToNextMultipleOf(0, 32)
      .clampScalar(0, S32, S32)
      .scalarize(0);

    auto &Mul = getActionDefinitionsBuilder(G_MUL)
      .legalFor({S32})
      .scalarize(0)
      .minScalar(0, S32)
      .widenScalarToNextMultipleOf(0, 32);

    if (ST.hasMad64_32())
      Mul.custom();
    else
      Mul.maxScalar(0, S32);

    if (ST.hasIntClamp()) {
      getActionDefinitionsBuilder({G_UADDSAT, G_USUBSAT})
        .legalFor({S32}) // Clamp modifier.
        .scalarize(0)
        .minScalarOrElt(0, S32)
        .lower();
    } else {
      // Clamp bit support was added in VI, along with 16-bit operations.
      getActionDefinitionsBuilder({G_UADDSAT, G_USUBSAT})
        .minScalar(0, S32)
        .scalarize(0)
        .lower();
    }

    // FIXME: DAG expansion gets better results. The widening uses the smaller
    // range values and goes for the min/max lowering directly.
    getActionDefinitionsBuilder({G_SADDSAT, G_SSUBSAT})
      .minScalar(0, S32)
      .scalarize(0)
      .lower();
  }

  getActionDefinitionsBuilder(
      {G_SDIV, G_UDIV, G_SREM, G_UREM, G_SDIVREM, G_UDIVREM})
      .customFor({S32, S64})
      .clampScalar(0, S32, S64)
      .widenScalarToNextPow2(0, 32)
      .scalarize(0);

  auto &Mulh = getActionDefinitionsBuilder({G_UMULH, G_SMULH})
                   .legalFor({S32})
                   .maxScalar(0, S32);

  if (ST.hasVOP3PInsts()) {
    Mulh
      .clampMaxNumElements(0, S8, 2)
      .lowerFor({V2S8});
  }

  Mulh
    .scalarize(0)
    .lower();

  // Report legal for any types we can handle anywhere. For the cases only legal
  // on the SALU, RegBankSelect will be able to re-legalize.
  getActionDefinitionsBuilder({G_AND, G_OR, G_XOR})
      .legalFor({S32, S1, S64, V2S32, S16, V2S16, V4S16})
      .clampScalar(0, S32, S64)
      .moreElementsIf(isSmallOddVector(0), oneMoreElement(0))
      .fewerElementsIf(
          all(vectorWiderThan(0, 64), scalarOrEltNarrowerThan(0, 64)),
          fewerEltsToSize64Vector(0))
      .widenScalarToNextPow2(0)
      .scalarize(0);

  getActionDefinitionsBuilder(
      {G_UADDO, G_USUBO, G_UADDE, G_SADDE, G_USUBE, G_SSUBE})
      .legalFor({{S32, S1}, {S32, S32}})
      .clampScalar(0, S32, S32)
      .scalarize(0);

  getActionDefinitionsBuilder(G_BITCAST)
      // Don't worry about the size constraint.
      .legalIf(all(isRegisterClassType(ST, 0), isRegisterClassType(ST, 1)))
      .widenScalarIf(all(typeInSet(0, {I16, F16, BF16}), isScalar(1)),
                     changeTo(0, LLT::integer(32)))
      .widenScalarIf(all(isScalar(0), typeInSet(1, {I16, F16, BF16})),
                     changeTo(1, LLT::integer(32)))
      .lower();

  getActionDefinitionsBuilder(G_CONSTANT)
    .legalFor({S1, S32, S64, S16, GlobalPtr,
               LocalPtr, ConstantPtr, PrivatePtr, FlatPtr })
    .legalIf(isPointer(0))
    .clampScalar(0, S32, S64)
    .widenScalarToNextPow2(0);

  getActionDefinitionsBuilder(G_FCONSTANT).legalFor({F32, F64, F16, BF16});

  getActionDefinitionsBuilder({G_IMPLICIT_DEF, G_FREEZE})
      .legalIf(isRegisterClassType(ST, 0))
      // s1 and s16 are special cases because they have legal operations on
      // them, but don't really occupy registers in the normal way.
      .legalFor({S1, S16})
      .clampNumElements(0, V16S32, V32S32)
      .moreElementsIf(isSmallOddVector(0), oneMoreElement(0))
      .clampScalarOrElt(0, S32, MaxScalar)
      .widenScalarToNextPow2(0, 32)
      .clampMaxNumElements(0, S32, 16);

  getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({PrivatePtr});

  // If the amount is divergent, we have to do a wave reduction to get the
  // maximum value, so this is expanded during RegBankSelect.
  getActionDefinitionsBuilder(G_DYN_STACKALLOC)
    .legalFor({{PrivatePtr, S32}});

  getActionDefinitionsBuilder(G_STACKSAVE)
    .customFor({PrivatePtr});
  getActionDefinitionsBuilder(G_STACKRESTORE)
    .legalFor({PrivatePtr});

  getActionDefinitionsBuilder(G_WRITE_REGISTER).legalFor({S32, S64});

  getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV}).customFor({S64});

  getActionDefinitionsBuilder({G_GET_ROUNDING, G_SET_ROUNDING}).legalFor({S32});

  getActionDefinitionsBuilder(G_GLOBAL_VALUE)
    .customIf(typeIsNot(0, PrivatePtr));

  getActionDefinitionsBuilder(G_BLOCK_ADDR).legalFor({CodePtr});

  auto &FPOpActions =
      getActionDefinitionsBuilder({G_FADD, G_FMUL, G_FMA}).legalFor({F32, F64});
  auto &FCanonicalizeActions =
      getActionDefinitionsBuilder(G_FCANONICALIZE).legalFor({F32, F64});
  auto &StrictFPOpActions =
      getActionDefinitionsBuilder({G_STRICT_FADD, G_STRICT_FMUL, G_STRICT_FMA})
          .legalFor({F32, F64});
  auto &TrigActions =
      getActionDefinitionsBuilder({G_FSIN, G_FCOS}).customFor({F32, F64});
  auto &FDIVActions = getActionDefinitionsBuilder(G_FDIV).customFor({F32, F64});

  if (ST.has16BitInsts()) {
    if (ST.hasVOP3PInsts()) {
      FPOpActions.legalFor({F16, V2F16});
      FCanonicalizeActions.legalFor({F16, V2F16});
      StrictFPOpActions.legalFor({F16, V2F16});
    } else {
      FPOpActions.legalFor({F16});
      FCanonicalizeActions.legalFor({F16});
      StrictFPOpActions.legalFor({F16});
    }

    TrigActions.customFor({F16});
    FDIVActions.customFor({F16});
  }

  if (ST.hasBF16PackedInsts()) {
    // Promote scalar bf16 operations to v2bf16 (packed) operations
    FPOpActions.moreElementsIf(typeIs(0, BF16), changeTo(0, V2BF16))
        .legalFor({V2BF16})
        .clampMaxNumElementsStrict(0, BF16, 2);
    FCanonicalizeActions.moreElementsIf(typeIs(0, BF16), changeTo(0, V2BF16))
        .legalFor({V2BF16})
        .clampMaxNumElementsStrict(0, BF16, 2);
    StrictFPOpActions.moreElementsIf(typeIs(0, BF16), changeTo(0, V2BF16))
        .legalFor({V2BF16})
        .clampMaxNumElementsStrict(0, BF16, 2);
  } else {
    FPOpActions.widenScalarFor({BF16}, changeElementTo(0, F32));
    FCanonicalizeActions.widenScalarFor({BF16}, changeElementTo(0, F32));
  }

  if (ST.hasAnyPackedFP32Ops()) {
    FPOpActions.legalFor({V2F32});
    FCanonicalizeActions.legalFor({V2F32});
    StrictFPOpActions.legalFor({V2F32});
    FPOpActions.clampMaxNumElementsStrict(0, F32, 2);
    FCanonicalizeActions.clampMaxNumElementsStrict(0, F32, 2);
    StrictFPOpActions.clampMaxNumElementsStrict(0, F32, 2);
  }

  if (ST.hasAnyPackedFP64Ops()) {
    FPOpActions.legalFor({V2F64});
    FCanonicalizeActions.legalFor({V2F64});
    StrictFPOpActions.legalFor({V2F64});
    FPOpActions.clampMaxNumElementsStrict(0, F64, 2);
    FCanonicalizeActions.clampMaxNumElementsStrict(0, F64, 2);
    StrictFPOpActions.clampMaxNumElementsStrict(0, F64, 2);
  }

  auto &MinNumMaxNumIeee =
      getActionDefinitionsBuilder({G_FMINNUM_IEEE, G_FMAXNUM_IEEE});
  auto &MinNumMaxNum = getActionDefinitionsBuilder(
      {G_FMINNUM, G_FMAXNUM, G_FMINIMUMNUM, G_FMAXIMUMNUM});

  MinNumMaxNumIeee.legalFor(!ST.hasIEEEMinimumMaximumInsts(), {F32, F64});
  MinNumMaxNum.legalFor(ST.hasIEEEMinimumMaximumInsts(), {F32, F64})
      .customFor({F32, F64});

  if (ST.has16BitInsts()) {
    MinNumMaxNumIeee.legalFor(!ST.hasIEEEMinimumMaximumInsts(), {F16});
    MinNumMaxNum.legalFor(ST.hasIEEEMinimumMaximumInsts(), {F16})
        .customFor({F16});
  }

  // V2F16
  if (ST.hasVOP3PInsts()) {
    MinNumMaxNumIeee.legalFor(!ST.hasIEEEMinimumMaximumInsts(), {V2F16})
        .moreElementsIf(all(elementTypeIs(0, F16), isSmallOddVector(0)),
                        oneMoreElement(0))
        .clampMaxNumElements(0, F16, 2);
    MinNumMaxNum.legalFor(ST.hasIEEEMinimumMaximumInsts(), {V2F16})
        .customFor({V2F16})
        .moreElementsIf(all(elementTypeIs(0, F16), isSmallOddVector(0)),
                        oneMoreElement(0))
        .clampMaxNumElements(0, F16, 2);
  }

  // V2F64
  if (ST.hasAnyPackedFP64Ops()) {
    MinNumMaxNum.legalFor(ST.hasIEEEMinimumMaximumInsts(), {V2F64})
        .customFor({V2F64})
        .moreElementsIf(all(elementTypeIs(0, F64), isSmallOddVector(0)),
                        oneMoreElement(0))
        .clampMaxNumElements(0, F64, 2);
  }

  // V2BF16
  if (ST.hasBF16PackedInsts()) {
    MinNumMaxNumIeee.legalFor(!ST.hasIEEEMinimumMaximumInsts(), {V2BF16})
        .clampMaxNumElementsStrict(0, BF16, 2);

    MinNumMaxNum.legalFor(ST.hasIEEEMinimumMaximumInsts(), {V2BF16})
        .moreElementsIf(typeIs(0, BF16), changeTo(0, V2BF16))
        .customFor({V2BF16})
        .clampMaxNumElementsStrict(0, BF16, 2);
  } else {
    MinNumMaxNum.widenScalarFor({BF16}, changeElementTo(0, F32));
  }

  MinNumMaxNumIeee.scalarize(0);
  MinNumMaxNum.scalarize(0);

  if (!ST.has16BitInsts()) {
    MinNumMaxNumIeee.minScalar(0, F32);
    MinNumMaxNum.minScalar(0, F32);
  }

  if (ST.hasVOP3PInsts()) {
    FPOpActions.clampMaxNumElementsStrict(0, F16, 2);
    FCanonicalizeActions.clampMaxNumElementsStrict(0, F16, 2);
    StrictFPOpActions.clampMaxNumElementsStrict(0, F16, 2);
  }

  FPOpActions.scalarize(0);
  FCanonicalizeActions.scalarize(0);
  StrictFPOpActions.scalarize(0);
  TrigActions.scalarize(0);
  FDIVActions.scalarize(0);
  if (!ST.has16BitInsts()) {
    FPOpActions.widenScalarFor({F16}, changeElementTo(0, F32));
    FCanonicalizeActions.widenScalarFor({F16}, changeElementTo(0, F32));
    StrictFPOpActions.widenScalarFor({F16}, changeElementTo(0, F32));
    TrigActions.widenScalarFor({F16}, changeElementTo(0, F32));
    FDIVActions.widenScalarFor({F16}, changeElementTo(0, F32));
  }

  auto &FNegAbs = getActionDefinitionsBuilder({G_FNEG, G_FABS});
  FNegAbs.legalFor(FPTypesPK16)
      .legalFor({BF16, V2BF16})
      .legalFor(ST.hasAnyPackedFP32Ops(), {V2F32})
      .clampMaxNumElementsStrict(0, F16, 2)
      .clampMaxNumElementsStrict(0, BF16, 2);
  if (ST.hasAnyPackedFP32Ops())
    FNegAbs.clampMaxNumElementsStrict(0, F32, 2);
  FNegAbs.scalarize(0);

  if (ST.has16BitInsts()) {
    getActionDefinitionsBuilder(G_FSQRT)
        .legalFor({F16})
        .legalFor(ST.hasBF16TransInsts(), {BF16})
        .customFor({F32, F64})
        .scalarize(0)
        .widenScalarFor({BF16}, changeElementTo(0, F32))
        .unsupported();
    getActionDefinitionsBuilder(G_FFLOOR)
        .legalFor({F32, F64, F16})
        .scalarize(0);

    getActionDefinitionsBuilder({G_FLDEXP, G_STRICT_FLDEXP})
        .legalFor({{F32, I32}, {F64, I32}, {F16, I16}})
        .scalarize(0)
        .maxScalarIf(typeIs(0, F16), 1, I16)
        .clampScalar(1, I32, I32)
        .lower();

    getActionDefinitionsBuilder(G_FFREXP)
        .customFor({{F32, I32}, {F64, I32}, {F16, I16}, {F16, I32}})
        .scalarize(0)
        .lower();

    getActionDefinitionsBuilder(G_FMODF)
        .lowerFor({F16, F32, F64})
        .scalarize(0)
        .lower();
  } else {
    getActionDefinitionsBuilder(G_FSQRT)
        .customFor({F32, F64, F16})
        .scalarize(0)
        .widenScalarFor({BF16}, changeElementTo(0, F32))
        .unsupported();

    if (ST.hasFractBug()) {
      getActionDefinitionsBuilder(G_FFLOOR)
          .customFor({F64})
          .legalFor({F32, F64})
          .scalarize(0)
          .minScalar(0, F32);
    } else {
      getActionDefinitionsBuilder(G_FFLOOR)
          .legalFor({F32, F64})
          .scalarize(0)
          .minScalar(0, F32);
    }

    getActionDefinitionsBuilder({G_FLDEXP, G_STRICT_FLDEXP})
        .legalFor({{F32, I32}, {F64, I32}})
        .scalarize(0)
        .minScalar(0, F32)
        .clampScalar(1, I32, I32)
        .lower();

    getActionDefinitionsBuilder(G_FFREXP)
        .customFor({{F32, I32}, {F64, I32}})
        .scalarize(0)
        .minScalar(0, F32)
        .clampScalar(1, I32, I32)
        .lower();

    getActionDefinitionsBuilder(G_FMODF)
        .lowerFor({F32, F64})
        .scalarize(0)
        .lower();
  }

  auto &FPTruncActions = getActionDefinitionsBuilder(G_FPTRUNC);
  if (ST.hasCvtPkF16F32Inst()) {
    FPTruncActions.legalFor({{F32, F64}, {F16, F32}, {V2F16, V2F32}})
        .clampMaxNumElements(0, F16, 2);
  } else {
    FPTruncActions.legalFor({{F32, F64}, {F16, F32}});
  }
  FPTruncActions.lowerFor({{BF16, F32}, {BF16, F64}, {F16, F64}}).scalarize(0);

  getActionDefinitionsBuilder(G_FPEXT)
      .legalFor({{F64, F32}, {F32, F16}})
      .narrowScalarFor({{F64, F16}}, changeElementSizeTo(0, F32))
      .lowerFor({{F32, BF16}, {F64, BF16}})
      .scalarize(0);

  auto &FSubActions = getActionDefinitionsBuilder({G_FSUB, G_STRICT_FSUB});
  if (ST.has16BitInsts()) {
    FSubActions
        // Use actual fsub instruction
        .legalFor({F32, F16})
        // Must use fadd + fneg
        .lowerFor({F64, V2F16});
  } else {
    FSubActions
        // Use actual fsub instruction
        .legalFor({F32})
        // Must use fadd + fneg
        .lowerFor({F64, F16, V2F16});
  }

  if (ST.hasBF16PackedInsts()) {
    FSubActions.moreElementsIf(typeIs(0, BF16), changeTo(0, V2BF16))
        .lowerFor({V2BF16})
        .clampMaxNumElementsStrict(0, BF16, 2);
  } else {
    FSubActions.widenScalarFor({BF16}, changeElementTo(0, F32));
  }

  if (ST.hasAnyPackedFP32Ops())
    FSubActions.lowerFor({V2F32}).clampMaxNumElements(0, F32, 2);

  FSubActions.clampMaxNumElements(0, F16, 2).scalarize(0).clampScalar(0, F32,
                                                                      F64);

  // Whether this is legal depends on the floating point mode for the function.
  auto &FMad = getActionDefinitionsBuilder(G_FMAD);
  if (ST.hasMadF16() && ST.hasMadMacF32Insts())
    FMad.customFor({F32, F16});
  else if (ST.hasMadMacF32Insts())
    FMad.customFor({F32});
  else if (ST.hasMadF16())
    FMad.customFor({F16});
  FMad.scalarize(0)
      .lower();

  auto &FRem = getActionDefinitionsBuilder(G_FREM);
  if (ST.has16BitInsts()) {
    FRem.customFor({F16, F32, F64});
  } else {
    FRem.minScalar(0, F32).customFor({F32, F64});
  }
  FRem.scalarize(0);

  // TODO: Do we need to clamp maximum bitwidth?
  getActionDefinitionsBuilder(G_TRUNC)
    .legalIf(isScalar(0))
    .legalFor({{V2S16, V2S32}})
    .clampMaxNumElements(0, S16, 2)
    // Avoid scalarizing in cases that should be truly illegal. In unresolvable
    // situations (like an invalid implicit use), we don't want to infinite loop
    // in the legalizer.
    .fewerElementsIf(elementTypeIsLegal(0), LegalizeMutations::scalarize(0))
    .alwaysLegal();

  getActionDefinitionsBuilder({G_SEXT, G_ZEXT, G_ANYEXT})
    .legalFor({{S64, S32}, {S32, S16}, {S64, S16},
               {S32, S1}, {S64, S1}, {S16, S1}})
    .scalarize(0)
    .clampScalar(0, S32, S64)
    .widenScalarToNextPow2(1, 32);

  // TODO: Split s1->s64 during regbankselect for VALU.
  auto &IToFP = getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
                    .legalFor({{F32, I32}, {F64, I32}})
                    .widenScalarFor({{F16, I32}}, changeElementSizeTo(0, F32))
                    .lowerIf(typeIs(1, I1))
                    .customFor({{F32, I64}, {F64, I64}});
  if (ST.has16BitInsts())
    IToFP.legalFor({{F16, I16}});
  IToFP.clampScalar(1, I32, I64)
      .minScalar(0, F32)
      .scalarize(0)
      .widenScalarToNextPow2(1);

  auto &FPToI = getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
                    .legalFor({{I32, F32}, {I32, F64}})
                    .customFor({{I64, F32}, {I64, F64}})
                    .widenScalarFor({{I32, F16}}, changeElementSizeTo(1, F32))
                    .narrowScalarFor({{I64, F16}}, changeElementSizeTo(0, I32))
                    .widenScalarFor({{I16, BF16}, {I32, BF16}, {I64, BF16}},
                                    changeElementTo(1, F32));
  if (ST.has16BitInsts())
    FPToI.legalFor({{I16, F16}});
  else
    FPToI.minScalar(1, F32);

  FPToI.minScalar(0, I32).widenScalarToNextPow2(0, 32).scalarize(0).lower();

  // clang-format off
  auto &FPToISat = getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
    .legalFor({{I32, F32}, {I32, F64}, {I16, F32}})
    .legalFor(ST.has16BitInsts(), {{I16, F16}})
    .legalFor(ST.hasVCvtPkIU16F32(), {{V2I16, V2F32}})
    .narrowScalarFor({{I64, F16}}, changeElementSizeTo(0, I32));

  // If available, widen width <16 to i16, intead of i32 so v_cvt_i16/u16_f16 can be used.
  if (ST.has16BitInsts())
    FPToISat.minScalarIf(typeIs(1, F16), 0, I16);

  if (ST.hasVCvtPkIU16F32())
    FPToISat.clampMaxNumElements(0, I16, 2);

  FPToISat.minScalar(1, F32);
  FPToISat.minScalar(0, I32)
       .widenScalarToNextPow2(0, 32)
       .scalarize(0)
       .lower();
  // clang-format on

  getActionDefinitionsBuilder({G_LROUND, G_LLROUND})
      .clampScalar(0, I16, I64)
      .scalarize(0)
      .lower();

  getActionDefinitionsBuilder(G_INTRINSIC_FPTRUNC_ROUND)
      .legalFor({F16, F32})
      .scalarize(0)
      .lower();

  // Lower G_FNEARBYINT and G_FRINT into G_INTRINSIC_ROUNDEVEN
  getActionDefinitionsBuilder({G_INTRINSIC_ROUND, G_FRINT, G_FNEARBYINT})
      .scalarize(0)
      .lower();

  getActionDefinitionsBuilder({G_INTRINSIC_LRINT, G_INTRINSIC_LLRINT})
      .clampScalar(0, I16, I64)
      .scalarize(0)
      .lower();

  auto &RoundingActions = getActionDefinitionsBuilder(
      {G_INTRINSIC_TRUNC, G_FCEIL, G_INTRINSIC_ROUNDEVEN});
  if (ST.has16BitInsts())
    RoundingActions.legalFor({F16, F32, F64});
  else if (ST.getGeneration() >= AMDGPUSubtarget::SEA_ISLANDS)
    RoundingActions.legalFor({F32, F64});
  else
    RoundingActions.legalFor({F32}).customFor({F64});

  RoundingActions.scalarize(0);
  if (!ST.has16BitInsts())
    RoundingActions.minScalar(0, F32);

  getActionDefinitionsBuilder(G_PTR_ADD)
      .unsupportedFor({BufferFatPtr, BufferStridedPtr, RsrcPtr})
      .legalIf(all(isPointer(0), sameSize(0, 1)))
      .scalarize(0)
      .scalarSameSizeAs(1, 0);

  getActionDefinitionsBuilder(G_PTRMASK)
    .legalIf(all(sameSize(0, 1), typeInSet(1, {S64, S32})))
    .scalarSameSizeAs(1, 0)
    .scalarize(0);

  auto &CmpBuilder =
    getActionDefinitionsBuilder(G_ICMP)
    // The compare output type differs based on the register bank of the output,
    // so make both s1 and s32 legal.
    //
    // Scalar compares producing output in scc will be promoted to s32, as that
    // is the allocatable register type that will be needed for the copy from
    // scc. This will be promoted during RegBankSelect, and we assume something
    // before that won't try to use s32 result types.
    //
    // Vector compares producing an output in vcc/SGPR will use s1 in VCC reg
    // bank.
    .legalForCartesianProduct(
      {S1}, {S32, S64, GlobalPtr, LocalPtr, ConstantPtr, PrivatePtr, FlatPtr})
    .legalForCartesianProduct(
      {S32}, {S32, S64, GlobalPtr, LocalPtr, ConstantPtr, PrivatePtr, FlatPtr});
  if (ST.has16BitInsts()) {
    CmpBuilder.legalFor({{S1, S16}});
  }

  CmpBuilder
    .widenScalarToNextPow2(1)
    .clampScalar(1, S32, S64)
    .scalarize(0)
    .legalIf(all(typeInSet(0, {S1, S32}), isPointer(1)));

  getActionDefinitionsBuilder({G_SCMP, G_UCMP}).lower();

  auto &FCmpBuilder =
      getActionDefinitionsBuilder(G_FCMP).legalForCartesianProduct(
          {I1}, ST.has16BitInsts() ? FPTypes16 : FPTypesBase);

  if (ST.hasSALUFloatInsts())
    FCmpBuilder.legalForCartesianProduct({I32}, {F16, F32});

  FCmpBuilder.widenScalarFor({{I1, BF16}}, changeElementTo(1, F32))
      .widenScalarToNextPow2(1)
      .minScalar(1, F32)
      .scalarize(0);

  getActionDefinitionsBuilder(G_FPOW)
      .customFor({F32})
      .clampScalar(0, F32, F32)
      .scalarize(0);

  getActionDefinitionsBuilder(G_FPOWI).clampScalar(0, F32, F32).lower();

  getActionDefinitionsBuilder(G_FLOG2)
      .legalFor(ST.has16BitInsts(), {F16})
      .legalFor(ST.hasBF16TransInsts(), {BF16})
      .customFor({F32, F16})
      .scalarize(0)
      .widenScalarFor({BF16}, changeElementTo(0, F32))
      .lower();

  getActionDefinitionsBuilder(G_FEXP2)
      .legalFor(ST.has16BitInsts(), {F16})
      .legalFor(ST.hasBF16TransInsts(), {BF16})
      .customFor({F32, F64, F16})
      .scalarize(0)
      .widenScalarFor({BF16}, changeElementTo(0, F32))
      .lower();

  getActionDefinitionsBuilder({G_FLOG, G_FLOG10})
      .customFor({F16, F32})
      .scalarize(0);

  getActionDefinitionsBuilder({G_FEXP, G_FEXP10})
      .customFor({F16, F32, F64})
      .scalarize(0);

  // The 64-bit versions produce 32-bit results, but only on the SALU.
  getActionDefinitionsBuilder(G_CTPOP)
    .legalFor({{S32, S32}, {S32, S64}})
    .clampScalar(0, S32, S32)
    .widenScalarToNextPow2(1, 32)
    .clampScalar(1, S32, S64)
    .scalarize(0)
    .widenScalarToNextPow2(0, 32);

  // If no 16 bit instr is available, lower into different instructions.
  if (ST.has16BitInsts())
    getActionDefinitionsBuilder(G_IS_FPCLASS)
        .legalForCartesianProduct({I1}, FPTypes16)
        .widenScalarToNextPow2(1)
        .scalarize(0)
        .lower();
  else
    getActionDefinitionsBuilder(G_IS_FPCLASS)
        .legalForCartesianProduct({I1}, FPTypesBase)
        .lowerFor({I1, F16})
        .widenScalarToNextPow2(1)
        .scalarize(0)
        .lower();

  // The hardware instructions return a different result on 0 than the generic
  // instructions expect. The hardware produces -1, but these produce the
  // bitwidth.
  getActionDefinitionsBuilder({G_CTLZ, G_CTTZ})
    .scalarize(0)
    .clampScalar(0, S32, S32)
    .clampScalar(1, S32, S64)
    .widenScalarToNextPow2(0, 32)
    .widenScalarToNextPow2(1, 32)
    .custom();

  // The 64-bit versions produce 32-bit results, but only on the SALU.
  getActionDefinitionsBuilder(G_CTLZ_ZERO_POISON)
      .legalFor({{S32, S32}, {S32, S64}})
      .customIf(scalarNarrowerThan(1, 32))
      .clampScalar(0, S32, S32)
      .clampScalar(1, S32, S64)
      .scalarize(0)
      .widenScalarToNextPow2(0, 32)
      .widenScalarToNextPow2(1, 32);

  getActionDefinitionsBuilder(G_CTTZ_ZERO_POISON)
      .legalFor({{S32, S32}, {S32, S64}})
      .clampScalar(0, S32, S32)
      .clampScalar(1, S32, S64)
      .scalarize(0)
      .widenScalarToNextPow2(0, 32)
      .widenScalarToNextPow2(1, 32);

  getActionDefinitionsBuilder(G_CTLS)
      .customFor({{S32, S32}})
      .scalarize(0)
      .clampScalar(0, S32, S32)
      .clampScalar(1, S32, S32);

  // S64 is only legal on SALU, and needs to be broken into 32-bit elements in
  // RegBankSelect.
  getActionDefinitionsBuilder(G_BITREVERSE)
    .legalFor({S32, S64})
    .clampScalar(0, S32, S64)
    .scalarize(0)
    .widenScalarToNextPow2(0);

  if (ST.has16BitInsts()) {
    getActionDefinitionsBuilder(G_BSWAP)
      .legalFor({S16, S32, V2S16})
      .clampMaxNumElementsStrict(0, S16, 2)
      // FIXME: Fixing non-power-of-2 before clamp is workaround for
      // narrowScalar limitation.
      .widenScalarToNextPow2(0)
      .clampScalar(0, S16, S32)
      .scalarize(0);

    if (ST.hasVOP3PInsts()) {
      getActionDefinitionsBuilder(G_ABS)
          .legalFor({S32, S16, V2S16})
          .clampMaxNumElements(0, S16, 2)
          .minScalar(0, S16)
          .widenScalarToNextPow2(0)
          .scalarize(0)
          .lower();
      if (ST.useMinMaxI64Insts()) {
        getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
            .legalFor({S32, S16, S64, V2S16})
            .clampMaxNumElements(0, S16, 2)
            .minScalar(0, S16)
            .widenScalarToNextPow2(0)
            .scalarize(0)
            .lower();
      } else {
        getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
            .legalFor({S32, S16, V2S16})
            .clampMaxNumElements(0, S16, 2)
            .minScalar(0, S16)
            .widenScalarToNextPow2(0)
            .scalarize(0)
            .lower();
      }
    } else {
      getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX, G_ABS})
        .legalFor({S32, S16})
        .widenScalarToNextPow2(0)
        .minScalar(0, S16)
        .scalarize(0)
        .lower();
    }
  } else {
    // TODO: Should have same legality without v_perm_b32
    getActionDefinitionsBuilder(G_BSWAP)
      .legalFor({S32})
      .lowerIf(scalarNarrowerThan(0, 32))
      // FIXME: Fixing non-power-of-2 before clamp is workaround for
      // narrowScalar limitation.
      .widenScalarToNextPow2(0)
      .maxScalar(0, S32)
      .scalarize(0)
      .lower();

    getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX, G_ABS})
      .legalFor({S32})
      .minScalar(0, S32)
      .widenScalarToNextPow2(0)
      .scalarize(0)
      .lower();
  }

  getActionDefinitionsBuilder(G_INTTOPTR)
      // List the common cases
      .legalForCartesianProduct(AddrSpaces64, {S64})
      .legalForCartesianProduct(AddrSpaces32, {S32})
      .scalarize(0)
      // Accept any address space as long as the size matches
      .legalIf(sameSize(0, 1))
      .widenScalarIf(smallerThan(1, 0),
                     [](const LegalityQuery &Query) {
                       return std::pair(
                           1, LLT::scalar(Query.Types[0].getSizeInBits()));
                     })
      .narrowScalarIf(largerThan(1, 0), [](const LegalityQuery &Query) {
        return std::pair(1, LLT::scalar(Query.Types[0].getSizeInBits()));
      });

  getActionDefinitionsBuilder(G_PTRTOINT)
      // List the common cases
      .legalForCartesianProduct(AddrSpaces64, {S64})
      .legalForCartesianProduct(AddrSpaces32, {S32})
      .scalarize(0)
      // Accept any address space as long as the size matches
      .legalIf(sameSize(0, 1))
      .widenScalarIf(smallerThan(0, 1),
                     [](const LegalityQuery &Query) {
                       return std::pair(
                           0, LLT::scalar(Query.Types[1].getSizeInBits()));
                     })
      .narrowScalarIf(largerThan(0, 1), [](const LegalityQuery &Query) {
        return std::pair(0, LLT::scalar(Query.Types[1].getSizeInBits()));
      });

  getActionDefinitionsBuilder(G_ADDRSPACE_CAST)
    .scalarize(0)
    .custom();

  const auto needToSplitMemOp = [=](const LegalityQuery &Query,
                                    bool IsLoad) -> bool {
    const LLT DstTy = Query.Types[0];

    // Split vector extloads.
    unsigned MemSize = Query.MMODescrs[0].MemoryTy.getSizeInBits();

    if (DstTy.isVector() && DstTy.getSizeInBits() > MemSize)
      return true;

    const LLT PtrTy = Query.Types[1];
    unsigned AS = PtrTy.getAddressSpace();
    if (MemSize > maxSizeForAddrSpace(ST, AS, IsLoad,
                                      Query.MMODescrs[0].Ordering !=
                                          AtomicOrdering::NotAtomic))
      return true;

    if (AS == AMDGPUAS::LOCAL_ADDRESS && MemSize == 64 &&
        !ST.hasUsableDSOffset() && Query.MMODescrs[0].AlignInBits == 32)
      return true;

    // Catch weird sized loads that don't evenly divide into the access sizes
    // TODO: May be able to widen depending on alignment etc.
    unsigned NumRegs = (MemSize + 31) / 32;
    if (NumRegs == 3) {
      if (!ST.hasDwordx3LoadStores())
        return true;
    } else {
      // If the alignment allows, these should have been widened.
      if (!isPowerOf2_32(NumRegs))
        return true;
    }

    return false;
  };

  unsigned GlobalAlign32 = ST.hasUnalignedBufferAccessEnabled() ? 0 : 32;
  unsigned GlobalAlign16 = ST.hasUnalignedBufferAccessEnabled() ? 0 : 16;
  unsigned GlobalAlign8 = ST.hasUnalignedBufferAccessEnabled() ? 0 : 8;
  unsigned LocalAlign64 = ST.hasUsableDSOffset() ? 32 : 64;

  // TODO: Refine based on subtargets which support unaligned access or 128-bit
  // LDS
  // TODO: Unsupported flat for SI.

  for (unsigned Op : {G_LOAD, G_STORE}) {
    const bool IsStore = Op == G_STORE;

    auto &Actions = getActionDefinitionsBuilder(Op);
    // Explicitly list some common cases.
    // TODO: Does this help compile time at all?
    Actions.legalForTypesWithMemDesc(
        {{S32, GlobalPtr, S32, GlobalAlign32},
         {V2S32, GlobalPtr, V2S32, GlobalAlign32},
         {V4S32, GlobalPtr, V4S32, GlobalAlign32},
         {S64, GlobalPtr, S64, GlobalAlign32},
         {V2S64, GlobalPtr, V2S64, GlobalAlign32},
         {V2S16, GlobalPtr, V2S16, GlobalAlign32},
         {S32, GlobalPtr, S8, GlobalAlign8},
         {S32, GlobalPtr, S16, GlobalAlign16},

         {S32, LocalPtr, S32, 32},
         {S64, LocalPtr, S64, LocalAlign64},
         {V2S32, LocalPtr, V2S32, LocalAlign64},
         {S32, LocalPtr, S8, 8},
         {S32, LocalPtr, S16, 16},
         {V2S16, LocalPtr, S32, 32},

         {S32, PrivatePtr, S32, 32},
         {S32, PrivatePtr, S8, 8},
         {S32, PrivatePtr, S16, 16},
         {V2S16, PrivatePtr, S32, 32},

         {S32, ConstantPtr, S32, GlobalAlign32},
         {V2S32, ConstantPtr, V2S32, GlobalAlign32},
         {V4S32, ConstantPtr, V4S32, GlobalAlign32},
         {S64, ConstantPtr, S64, GlobalAlign32}});

    if (IsStore || ST.d16PreservesUnusedBits()) {
      Actions.legalForTypesWithMemDesc(ST.useRealTrue16Insts(), /* Pred */
                                       {{S16, GlobalPtr, S8, GlobalAlign8},
                                        {S16, GlobalPtr, S16, GlobalAlign16},
                                        {S16, LocalPtr, S8, 8},
                                        {S16, LocalPtr, S16, 16},
                                        {S16, PrivatePtr, S8, 8},
                                        {S16, PrivatePtr, S16, 16}});
    }

    Actions.legalIf(
      [=](const LegalityQuery &Query) -> bool {
        return isLoadStoreLegal(ST, Query);
      });

    // The custom pointers (fat pointers, buffer resources) don't work with load
    // and store at this level. Fat pointers should have been lowered to
    // intrinsics before the translation to MIR.
    Actions.unsupportedIf(
        typeInSet(1, {BufferFatPtr, BufferStridedPtr, RsrcPtr}));

    // Address space 8 pointers are handled by a 4xs32 load, bitcast, and
    // ptrtoint. This is needed to account for the fact that we can't have i128
    // as a register class for SelectionDAG reasons.
    Actions.customIf([=](const LegalityQuery &Query) -> bool {
      return hasBufferRsrcWorkaround(Query.Types[0]);
    });

    // Constant 32-bit is handled by addrspacecasting the 32-bit pointer to
    // 64-bits.
    //
    // TODO: Should generalize bitcast action into coerce, which will also cover
    // inserting addrspacecasts.
    Actions.customIf(typeIs(1, Constant32Ptr));

    // Turn any illegal element vectors into something easier to deal
    // with. These will ultimately produce 32-bit scalar shifts to extract the
    // parts anyway.
    //
    // For odd 16-bit element vectors, prefer to split those into pieces with
    // 16-bit vector parts.
    Actions.bitcastIf(
      [=](const LegalityQuery &Query) -> bool {
        return shouldBitcastLoadStoreType(ST, Query.Types[0],
                                          Query.MMODescrs[0].MemoryTy);
      }, bitcastToRegisterType(0));

    if (!IsStore) {
      // Widen suitably aligned loads by loading extra bytes. The standard
      // legalization actions can't properly express widening memory operands.
      Actions.customIf([=](const LegalityQuery &Query) -> bool {
        return shouldWidenLoad(ST, Query, G_LOAD);
      });
    }

    // FIXME: load/store narrowing should be moved to lower action
    Actions
        .narrowScalarIf(
            [=](const LegalityQuery &Query) -> bool {
              return !Query.Types[0].isVector() &&
                     needToSplitMemOp(Query, Op == G_LOAD);
            },
            [=](const LegalityQuery &Query) -> std::pair<unsigned, LLT> {
              const LLT DstTy = Query.Types[0];
              const LLT PtrTy = Query.Types[1];

              const unsigned DstSize = DstTy.getSizeInBits();
              unsigned MemSize = Query.MMODescrs[0].MemoryTy.getSizeInBits();

              // Split extloads.
              if (DstSize > MemSize)
                return std::pair(0, LLT::integer(MemSize));

              unsigned MaxSize = maxSizeForAddrSpace(
                  ST, PtrTy.getAddressSpace(), Op == G_LOAD,
                  Query.MMODescrs[0].Ordering != AtomicOrdering::NotAtomic);
              if (MemSize > MaxSize)
                return std::pair(0, LLT::integer(MaxSize));

              uint64_t Align = Query.MMODescrs[0].AlignInBits;
              return std::pair(0, LLT::integer(Align));
            })
        .fewerElementsIf(
            [=](const LegalityQuery &Query) -> bool {
              return Query.Types[0].isVector() &&
                     needToSplitMemOp(Query, Op == G_LOAD);
            },
            [=](const LegalityQuery &Query) -> std::pair<unsigned, LLT> {
              const LLT DstTy = Query.Types[0];
              const LLT PtrTy = Query.Types[1];

              LLT EltTy = DstTy.getElementType();
              unsigned MaxSize = maxSizeForAddrSpace(
                  ST, PtrTy.getAddressSpace(), Op == G_LOAD,
                  Query.MMODescrs[0].Ordering != AtomicOrdering::NotAtomic);

              // FIXME: Handle widened to power of 2 results better. This ends
              // up scalarizing.
              // FIXME: 3 element stores scalarized on SI

              // Split if it's too large for the address space.
              unsigned MemSize = Query.MMODescrs[0].MemoryTy.getSizeInBits();
              if (MemSize > MaxSize) {
                unsigned NumElts = DstTy.getNumElements();
                unsigned EltSize = EltTy.getSizeInBits();

                if (MaxSize % EltSize == 0) {
                  return std::pair(
                      0, LLT::scalarOrVector(
                             ElementCount::getFixed(MaxSize / EltSize), EltTy));
                }

                unsigned NumPieces = MemSize / MaxSize;

                // FIXME: Refine when odd breakdowns handled
                // The scalars will need to be re-legalized.
                if (NumPieces == 1 || NumPieces >= NumElts ||
                    NumElts % NumPieces != 0)
                  return std::pair(0, EltTy);

                return std::pair(0,
                                 LLT::fixed_vector(NumElts / NumPieces, EltTy));
              }

              // FIXME: We could probably handle weird extending loads better.
              if (DstTy.getSizeInBits() > MemSize)
                return std::pair(0, EltTy);

              unsigned EltSize = EltTy.getSizeInBits();
              unsigned DstSize = DstTy.getSizeInBits();
              if (!isPowerOf2_32(DstSize)) {
                // We're probably decomposing an odd sized store. Try to split
                // to the widest type. TODO: Account for alignment. As-is it
                // should be OK, since the new parts will be further legalized.
                unsigned FloorSize = llvm::bit_floor(DstSize);
                return std::pair(
                    0, LLT::scalarOrVector(
                           ElementCount::getFixed(FloorSize / EltSize), EltTy));
              }

              // May need relegalization for the scalars.
              return std::pair(0, EltTy);
            })
        .widenScalarIf(scalarNarrowerThan(0, 32), changeTo(0, LLT::integer(32)))
        .narrowScalarIf(isTruncStoreToSizePowerOf2(0),
                        getScalarTypeFromMemDesc(0))
        .widenScalarToNextPow2(0)
        .moreElementsIf(vectorSmallerThan(0, 32), moreEltsToNext32Bit(0))
        .lower();
  }

  // FIXME: Unaligned accesses not lowered.
  auto &ExtLoads =
      getActionDefinitionsBuilder({G_SEXTLOAD, G_ZEXTLOAD})
          .legalForTypesWithMemDesc({{S32, GlobalPtr, S8, 8},
                                     {S32, GlobalPtr, S16, 2 * 8},
                                     {S32, LocalPtr, S8, 8},
                                     {S32, LocalPtr, S16, 16},
                                     {S32, PrivatePtr, S8, 8},
                                     {S32, PrivatePtr, S16, 16},
                                     {S32, ConstantPtr, S8, 8},
                                     {S32, ConstantPtr, S16, 2 * 8}})
          .legalForTypesWithMemDesc(ST.useRealTrue16Insts(),
                                    {{S16, GlobalPtr, S8, GlobalAlign8},
                                     {S16, LocalPtr, S8, GlobalAlign8},
                                     {S16, PrivatePtr, S8, GlobalAlign8},
                                     {S16, ConstantPtr, S8, GlobalAlign8}})
          .legalIf([=](const LegalityQuery &Query) -> bool {
            return isLoadStoreLegal(ST, Query);
          });

  if (ST.hasFlatAddressSpace()) {
    ExtLoads.legalForTypesWithMemDesc(
        {{S32, FlatPtr, S8, 8}, {S32, FlatPtr, S16, 16}});

    ExtLoads.legalForTypesWithMemDesc(ST.useRealTrue16Insts(),
                                      {{S16, FlatPtr, S8, GlobalAlign8}});
  }

  // Constant 32-bit is handled by addrspacecasting the 32-bit pointer to
  // 64-bits.
  //
  // TODO: Should generalize bitcast action into coerce, which will also cover
  // inserting addrspacecasts.
  ExtLoads.customIf(typeIs(1, Constant32Ptr));

  ExtLoads.narrowScalarIf(
      [](const LegalityQuery &Query) {
        LLT MemTy = Query.MMODescrs[0].MemoryTy;
        return MemTy.isScalar() && MemTy.getSizeInBits() > 32 &&
               Query.Types[0].getSizeInBits() > MemTy.getSizeInBits();
      }, // For large MemSize, narrowscalar to MemSize (load MemSize + ext)
      getScalarTypeFromMemDesc(0));
  ExtLoads.clampScalar(0, S32, S32)
          .widenScalarToNextPow2(0)
          .lower();

  auto &Atomics = getActionDefinitionsBuilder(
    {G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD, G_ATOMICRMW_SUB,
     G_ATOMICRMW_AND, G_ATOMICRMW_OR, G_ATOMICRMW_XOR,
     G_ATOMICRMW_MAX, G_ATOMICRMW_MIN, G_ATOMICRMW_UMAX,
     G_ATOMICRMW_UMIN, G_ATOMICRMW_UINC_WRAP, G_ATOMICRMW_UDEC_WRAP})
    .legalFor({{S32, GlobalPtr}, {S32, LocalPtr},
               {S64, GlobalPtr}, {S64, LocalPtr},
               {S32, RegionPtr}, {S64, RegionPtr}});
  if (ST.hasFlatAddressSpace()) {
    Atomics.legalFor({{S32, FlatPtr}, {S64, FlatPtr}});
  }

  auto &Atomics32 =
      getActionDefinitionsBuilder({G_ATOMICRMW_USUB_COND, G_ATOMICRMW_USUB_SAT})
          .legalFor({{S32, GlobalPtr}, {S32, LocalPtr}, {S32, RegionPtr}});
  if (ST.hasFlatAddressSpace()) {
    Atomics32.legalFor({{S32, FlatPtr}});
  }

  // TODO: v2bf16 operations, and fat buffer pointer support.
  auto &Atomic = getActionDefinitionsBuilder(G_ATOMICRMW_FADD);
  if (ST.hasLDSFPAtomicAddF32()) {
    Atomic.legalFor({{F32, LocalPtr}, {F32, RegionPtr}});
    if (ST.hasLdsAtomicAddF64())
      Atomic.legalFor({{F64, LocalPtr}});
    if (ST.hasAtomicDsPkAdd16Insts())
      Atomic.legalFor({{V2F16, LocalPtr}, {V2BF16, LocalPtr}});
  }
  if (ST.hasAtomicFaddInsts())
    Atomic.legalFor({{F32, GlobalPtr}});
  if (ST.hasFlatAtomicFaddF32Inst())
    Atomic.legalFor({{F32, FlatPtr}});

  if (ST.hasGFX90AInsts() || ST.hasGFX1250Insts()) {
    // These are legal with some caveats, and should have undergone expansion in
    // the IR in most situations
    // TODO: Move atomic expansion into legalizer
    Atomic.legalFor({{F32, GlobalPtr}, {F64, GlobalPtr}, {F64, FlatPtr}});
  }

  if (ST.hasAtomicBufferGlobalPkAddF16NoRtnInsts() ||
      ST.hasAtomicBufferGlobalPkAddF16Insts())
    Atomic.legalFor({{V2F16, GlobalPtr}, {V2F16, BufferFatPtr}});
  if (ST.hasAtomicGlobalPkAddBF16Inst())
    Atomic.legalFor({{V2BF16, GlobalPtr}});
  if (ST.hasAtomicFlatPkAdd16Insts())
    Atomic.legalFor({{V2F16, FlatPtr}, {V2BF16, FlatPtr}});


  // Most of the legalization work here is done by AtomicExpand. We could
  // probably use a simpler legality rule that just assumes anything is OK.
  auto &AtomicFMinFMax =
    getActionDefinitionsBuilder({G_ATOMICRMW_FMIN, G_ATOMICRMW_FMAX})
    .legalFor({{F32, LocalPtr}, {F64, LocalPtr}});

  if (ST.hasAtomicFMinFMaxF32GlobalInsts())
    AtomicFMinFMax.legalFor({{F32, GlobalPtr},{F32, BufferFatPtr}});
  if (ST.hasAtomicFMinFMaxF64GlobalInsts())
    AtomicFMinFMax.legalFor({{F64, GlobalPtr}, {F64, BufferFatPtr}});
  if (ST.hasAtomicFMinFMaxF32FlatInsts())
    AtomicFMinFMax.legalFor({F32, FlatPtr});
  if (ST.hasAtomicFMinFMaxF64FlatInsts())
    AtomicFMinFMax.legalFor({F64, FlatPtr});

  // BUFFER/FLAT_ATOMIC_CMP_SWAP on GCN GPUs needs input marshalling, and output
  // demarshalling
  getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG)
    .customFor({{S32, GlobalPtr}, {S64, GlobalPtr},
                {S32, FlatPtr}, {S64, FlatPtr}})
    .legalFor({{S32, LocalPtr}, {S64, LocalPtr},
               {S32, RegionPtr}, {S64, RegionPtr}});
  // TODO: Pointer types, any 32-bit or 64-bit vector

  // Condition should be s32 for scalar, s1 for vector.
  getActionDefinitionsBuilder(G_SELECT)
      .legalForCartesianProduct({S32, S64, S16, V2S32, V2S16, V4S16, GlobalPtr,
                                 LocalPtr, FlatPtr, PrivatePtr,
                                 LLT::fixed_vector(2, LocalPtr),
                                 LLT::fixed_vector(2, PrivatePtr)},
                                {S1, S32})
      .clampScalar(0, S16, S64)
      .scalarize(1)
      .moreElementsIf(isSmallOddVector(0), oneMoreElement(0))
      .fewerElementsIf(numElementsNotEven(0), scalarize(0))
      .clampMaxNumElements(0, S32, 2)
      .clampMaxNumElements(0, LocalPtr, 2)
      .clampMaxNumElements(0, PrivatePtr, 2)
      .scalarize(0)
      .widenScalarToNextPow2(0)
      .legalIf(all(isPointer(0), typeInSet(1, {S1, S32})));

  // TODO: Only the low 4/5/6 bits of the shift amount are observed, so we can
  // be more flexible with the shift amount type.
  auto &Shifts = getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR})
    .legalFor({{S32, S32}, {S64, S32}});
  if (ST.has16BitInsts()) {
    if (ST.hasVOP3PInsts()) {
      Shifts.legalFor({{S16, S16}, {V2S16, V2S16}})
            .clampMaxNumElements(0, S16, 2);
    } else
      Shifts.legalFor({{S16, S16}});

    // TODO: Support 16-bit shift amounts for all types
    Shifts.widenScalarIf(
        [=](const LegalityQuery &Query) {
          // Use 16-bit shift amounts for any 16-bit shift. Otherwise we want a
          // 32-bit amount.
          const LLT ValTy = Query.Types[0];
          const LLT AmountTy = Query.Types[1];
          return ValTy.isScalar() && ValTy.getSizeInBits() <= 16 &&
                 AmountTy.getSizeInBits() < 16;
        },
        changeElementSizeTo(1, S16));
    Shifts.maxScalarIf(typeIs(0, S16), 1, S16);
    Shifts.clampScalar(1, S32, S32);
    Shifts.widenScalarToNextPow2(0, 16);
    Shifts.clampScalar(0, S16, S64);

    getActionDefinitionsBuilder({G_SSHLSAT, G_USHLSAT})
      .minScalar(0, S16)
      .scalarize(0)
      .lower();
  } else {
    // Make sure we legalize the shift amount type first, as the general
    // expansion for the shifted type will produce much worse code if it hasn't
    // been truncated already.
    Shifts.clampScalar(1, S32, S32);
    Shifts.widenScalarToNextPow2(0, 32);
    Shifts.clampScalar(0, S32, S64);

    getActionDefinitionsBuilder({G_SSHLSAT, G_USHLSAT})
      .minScalar(0, S32)
      .scalarize(0)
      .lower();
  }
  Shifts.scalarize(0);

  for (unsigned Op : {G_EXTRACT_VECTOR_ELT, G_INSERT_VECTOR_ELT}) {
    unsigned VecTypeIdx = Op == G_EXTRACT_VECTOR_ELT ? 1 : 0;
    unsigned EltTypeIdx = Op == G_EXTRACT_VECTOR_ELT ? 0 : 1;
    unsigned IdxTypeIdx = 2;

    getActionDefinitionsBuilder(Op)
        .customIf([=](const LegalityQuery &Query) {
          const LLT EltTy = Query.Types[EltTypeIdx];
          const LLT VecTy = Query.Types[VecTypeIdx];
          const LLT IdxTy = Query.Types[IdxTypeIdx];
          const unsigned EltSize = EltTy.getSizeInBits();
          const bool isLegalVecType =
              !!SIRegisterInfo::getSGPRClassForBitWidth(VecTy.getSizeInBits());
          // Address space 8 pointers are 128-bit wide values, but the logic
          // below will try to bitcast them to 2N x s64, which will fail.
          // Therefore, as an intermediate step, wrap extracts/insertions from a
          // ptrtoint-ing the vector and scalar arguments (or inttoptring the
          // extraction result) in order to produce a vector operation that can
          // be handled by the logic below.
          if (EltTy.isPointer() && EltSize > 64)
            return true;
          return (EltSize == 32 || EltSize == 64) &&
                  VecTy.getSizeInBits() % 32 == 0 &&
                  VecTy.getSizeInBits() <= MaxRegisterSize &&
                  IdxTy.getSizeInBits() == 32 &&
                  isLegalVecType;
        })
        .bitcastIf(all(sizeIsMultipleOf32(VecTypeIdx),
                       scalarOrEltNarrowerThan(VecTypeIdx, 32)),
                   bitcastToVectorElement32(VecTypeIdx))
        //.bitcastIf(vectorSmallerThan(1, 32), bitcastToScalar(1))
        .bitcastIf(all(sizeIsMultipleOf32(VecTypeIdx),
                       scalarOrEltWiderThan(VecTypeIdx, 64)),
                   [=](const LegalityQuery &Query) {
                     // For > 64-bit element types, try to turn this into a
                     // 64-bit element vector since we may be able to do better
                     // indexing if this is scalar. If not, fall back to 32.
                     const LLT EltTy = Query.Types[EltTypeIdx];
                     const LLT VecTy = Query.Types[VecTypeIdx];
                     const unsigned DstEltSize = EltTy.getSizeInBits();
                     const unsigned VecSize = VecTy.getSizeInBits();

                     const unsigned TargetEltSize =
                         DstEltSize % 64 == 0 ? 64 : 32;
                     return std::pair(VecTypeIdx,
                                      LLT::fixed_vector(VecSize / TargetEltSize,
                                                        TargetEltSize));
                   })
        .clampScalar(EltTypeIdx, S32, S64)
        .clampScalar(VecTypeIdx, S32, S64)
        .clampScalar(IdxTypeIdx, S32, S32)
        .clampMaxNumElements(VecTypeIdx, S32, 32)
        // TODO: Clamp elements for 64-bit vectors?
        .moreElementsIf(isIllegalRegisterType(ST, VecTypeIdx),
                        moreElementsToNextExistingRegClass(VecTypeIdx))
        // It should only be necessary with variable indexes.
        // As a last resort, lower to the stack
        .lower();
  }

  getActionDefinitionsBuilder(G_EXTRACT_VECTOR_ELT)
    .unsupportedIf([=](const LegalityQuery &Query) {
        const LLT &EltTy = Query.Types[1].getElementType();
        return Query.Types[0] != EltTy;
      });

  for (unsigned Op : {G_EXTRACT, G_INSERT}) {
    unsigned BigTyIdx = Op == G_EXTRACT ? 1 : 0;
    unsigned LitTyIdx = Op == G_EXTRACT ? 0 : 1;
    getActionDefinitionsBuilder(Op)
        .widenScalarIf(
            [=](const LegalityQuery &Query) {
              const LLT BigTy = Query.Types[BigTyIdx];
              return (BigTy.getScalarSizeInBits() < 16);
            },
            LegalizeMutations::widenScalarOrEltToNextPow2(BigTyIdx, 16))
        .widenScalarIf(
            [=](const LegalityQuery &Query) {
              const LLT LitTy = Query.Types[LitTyIdx];
              return (LitTy.getScalarSizeInBits() < 16);
            },
            LegalizeMutations::widenScalarOrEltToNextPow2(LitTyIdx, 16))
        .moreElementsIf(isSmallOddVector(BigTyIdx), oneMoreElement(BigTyIdx))
        .widenScalarToNextPow2(BigTyIdx, 32)
        .customIf([=](const LegalityQuery &Query) {
          // Generic lower operates on the full-width value, producing
          // shift+trunc/mask sequences. For simple cases where extract/insert
          // values are 32-bit aligned, we can instead unmerge/merge and work on
          // the 32-bit components. However, we can't check the offset here so
          // custom lower function will have to call generic lowering if offset
          // is not 32-bit aligned.
          const LLT BigTy = Query.Types[BigTyIdx];
          const LLT LitTy = Query.Types[LitTyIdx];
          return !BigTy.isVector() && BigTy.getSizeInBits() % 32 == 0 &&
                 LitTy.getSizeInBits() % 32 == 0;
        })
        .lower();
  }

  auto &BuildVector =
      getActionDefinitionsBuilder(G_BUILD_VECTOR)
          .legalForCartesianProduct(AllS32Vectors, {S32})
          .legalForCartesianProduct(AllS64Vectors, {S64})
          .clampNumElements(0, V16S32, V32S32)
          .clampNumElements(0, V2S64, V16S64)
          .fewerElementsIf(isWideVec16(0),
                           changeElementCountTo(0, ElementCount::getFixed(2)))
          .moreElementsIf(isIllegalRegisterType(ST, 0),
                          moreElementsToNextExistingRegClass(0));

  if (ST.hasScalarPackInsts()) {
    BuildVector
      // FIXME: Should probably widen s1 vectors straight to s32
      .minScalarOrElt(0, S16)
      .minScalar(1, S16);

    getActionDefinitionsBuilder(G_BUILD_VECTOR_TRUNC)
      .legalFor({V2S16, S32})
      .lower();
  } else {
    BuildVector.customFor({V2S16, S16});
    BuildVector.minScalarOrElt(0, S32);

    getActionDefinitionsBuilder(G_BUILD_VECTOR_TRUNC)
      .customFor({V2S16, S32})
      .lower();
  }

  BuildVector.legalIf(isRegisterType(ST, 0));

  // FIXME: Clamp maximum size
  getActionDefinitionsBuilder(G_CONCAT_VECTORS)
      .legalIf(all(isRegisterType(ST, 0), isRegisterType(ST, 1)))
      .clampMaxNumElements(0, S32, 32)
      .clampMaxNumElements(1, S16, 2) // TODO: Make 4?
      .clampMaxNumElements(0, S16, 64);

  getActionDefinitionsBuilder(G_SHUFFLE_VECTOR).lower();

  // Merge/Unmerge
  for (unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
    unsigned BigTyIdx = Op == G_MERGE_VALUES ? 0 : 1;
    unsigned LitTyIdx = Op == G_MERGE_VALUES ? 1 : 0;

    auto notValidElt = [=](const LegalityQuery &Query, unsigned TypeIdx) {
      const LLT Ty = Query.Types[TypeIdx];
      if (Ty.isVector()) {
        const LLT &EltTy = Ty.getElementType();
        if (EltTy.getSizeInBits() < 8 || EltTy.getSizeInBits() > 512)
          return true;
        if (!llvm::has_single_bit<uint32_t>(EltTy.getSizeInBits()))
          return true;
      }
      return false;
    };

    auto &Builder =
        getActionDefinitionsBuilder(Op)
            .legalIf(all(isRegisterType(ST, 0), isRegisterType(ST, 1)))
            .lowerFor({{S16, V2S16}})
            .lowerIf([=](const LegalityQuery &Query) {
              const LLT BigTy = Query.Types[BigTyIdx];
              return BigTy.getSizeInBits() == 32;
            })
            // Try to widen to s16 first for small types.
            // TODO: Only do this on targets with legal s16 shifts
            .minScalarOrEltIf(scalarNarrowerThan(LitTyIdx, 16), LitTyIdx, S16)
            .widenScalarToNextPow2(LitTyIdx, /*Min*/ 16)
            .moreElementsIf(isSmallOddVector(BigTyIdx),
                            oneMoreElement(BigTyIdx))
            .fewerElementsIf(all(typeIs(0, S16), vectorWiderThan(1, 32),
                                 elementTypeIs(1, S16)),
                             changeElementCountTo(1, ElementCount::getFixed(2)))
            // Clamp the little scalar to s8-s256 and make it a power of 2. It's
            // not worth considering the multiples of 64 since 2*192 and 2*384
            // are not valid.
            .clampScalar(LitTyIdx, S32, S512)
            .widenScalarToNextPow2(LitTyIdx, /*Min*/ 32)
            // Break up vectors with weird elements into scalars
            .fewerElementsIf(
                [=](const LegalityQuery &Query) {
                  return notValidElt(Query, LitTyIdx);
                },
                scalarize(0))
            .fewerElementsIf(
                [=](const LegalityQuery &Query) {
                  return notValidElt(Query, BigTyIdx);
                },
                scalarize(1))
            .clampScalar(BigTyIdx, S32, MaxScalar);

    if (Op == G_MERGE_VALUES) {
      Builder.widenScalarIf(
          // TODO: Use 16-bit shifts if legal for 8-bit values?
          [=](const LegalityQuery &Query) {
            const LLT Ty = Query.Types[LitTyIdx];
            return Ty.getSizeInBits() < 32;
          },
          changeElementSizeTo(LitTyIdx, S32));
    }

    Builder.widenScalarIf(
      [=](const LegalityQuery &Query) {
        const LLT Ty = Query.Types[BigTyIdx];
        return Ty.getSizeInBits() % 16 != 0;
      },
      [=](const LegalityQuery &Query) {
        // Pick the next power of 2, or a multiple of 64 over 128.
        // Whichever is smaller.
        const LLT &Ty = Query.Types[BigTyIdx];
        unsigned NewSizeInBits = 1 << Log2_32_Ceil(Ty.getSizeInBits() + 1);
        if (NewSizeInBits >= 256) {
          unsigned RoundedTo = alignTo<64>(Ty.getSizeInBits() + 1);
          if (RoundedTo < NewSizeInBits)
            NewSizeInBits = RoundedTo;
        }
        return std::pair(BigTyIdx, LLT::scalar(NewSizeInBits));
      })
      // Any vectors left are the wrong size. Scalarize them.
      .scalarize(0)
      .scalarize(1);
  }

  // S64 is only legal on SALU, and needs to be broken into 32-bit elements in
  // RegBankSelect.
  auto &SextInReg = getActionDefinitionsBuilder(G_SEXT_INREG)
                        .legalFor({{S32}, {S64}})
                        .clampScalar(0, S32, S64);

  if (ST.hasVOP3PInsts()) {
    SextInReg.lowerFor({{V2S16}})
      // Prefer to reduce vector widths for 16-bit vectors before lowering, to
      // get more vector shift opportunities, since we'll get those when
      // expanded.
      .clampMaxNumElementsStrict(0, S16, 2);
  } else if (ST.has16BitInsts()) {
    SextInReg.lowerFor({{S32}, {S64}, {S16}});
  } else {
    // Prefer to promote to s32 before lowering if we don't have 16-bit
    // shifts. This avoid a lot of intermediate truncate and extend operations.
    SextInReg.lowerFor({{S32}, {S64}});
  }

  SextInReg
    .scalarize(0)
    .clampScalar(0, S32, S64)
    .lower();

  getActionDefinitionsBuilder({G_ROTR, G_ROTL})
    .scalarize(0)
    .lower();

  auto &FSHRActionDefs = getActionDefinitionsBuilder(G_FSHR);
  FSHRActionDefs.legalFor({{S32, S32}})
                              .clampMaxNumElementsStrict(0, S16, 2);
  if (ST.hasVOP3PInsts())
    FSHRActionDefs.lowerFor({{V2S16, V2S16}});
  FSHRActionDefs.scalarize(0).lower();

  if (ST.hasVOP3PInsts()) {
    getActionDefinitionsBuilder(G_FSHL)
      .lowerFor({{V2S16, V2S16}})
      .clampMaxNumElementsStrict(0, S16, 2)
      .scalarize(0)
      .lower();
  } else {
    getActionDefinitionsBuilder(G_FSHL)
      .scalarize(0)
      .lower();
  }

  getActionDefinitionsBuilder(G_READCYCLECOUNTER)
    .legalFor({S64});

  getActionDefinitionsBuilder(G_READSTEADYCOUNTER).legalFor({S64});

  getActionDefinitionsBuilder(G_FENCE)
    .alwaysLegal();

  getActionDefinitionsBuilder({G_SMULO, G_UMULO})
      .scalarize(0)
      .minScalar(0, S32)
      .lower();

  getActionDefinitionsBuilder({G_SBFX, G_UBFX})
      .legalFor({{S32, S32}, {S64, S32}})
      .clampScalar(1, S32, S32)
      .clampScalar(0, S32, S64)
      .widenScalarToNextPow2(0)
      .scalarize(0);

  getActionDefinitionsBuilder(
      {// TODO: Verify V_BFI_B32 is generated from expanded bit ops
       G_FCOPYSIGN,

       G_ATOMIC_CMPXCHG_WITH_SUCCESS, G_ATOMICRMW_NAND, G_ATOMICRMW_FSUB,
       G_READ_REGISTER,

       G_SADDO, G_SSUBO})
      .lower();

  if (ST.hasIEEEMinimumMaximumInsts()) {
    getActionDefinitionsBuilder({G_FMINIMUM, G_FMAXIMUM})
        .legalFor(FPTypesPK16)
        .clampMaxNumElements(0, F16, 2)
        .scalarize(0);
  } else if (ST.hasVOP3PInsts()) {
    getActionDefinitionsBuilder({G_FMINIMUM, G_FMAXIMUM})
        .lowerFor({V2F16})
        .clampMaxNumElementsStrict(0, F16, 2)
        .scalarize(0)
        .lower();
  } else {
    getActionDefinitionsBuilder({G_FMINIMUM, G_FMAXIMUM})
        .scalarize(0)
        .clampScalar(0, F32, F64)
        .lower();
  }

  getActionDefinitionsBuilder(
      {G_MEMCPY, G_MEMCPY_INLINE, G_MEMMOVE, G_MEMSET, G_MEMSET_INLINE})
      .lower();

  getActionDefinitionsBuilder({G_TRAP, G_DEBUGTRAP}).custom();

  getActionDefinitionsBuilder({G_VASTART, G_VAARG, G_BRJT, G_JUMP_TABLE,
        G_INDEXED_LOAD, G_INDEXED_SEXTLOAD,
        G_INDEXED_ZEXTLOAD, G_INDEXED_STORE})
    .unsupported();

  getActionDefinitionsBuilder(G_PREFETCH)
      .customFor({Constant32Ptr})
      .alwaysLegal();

  getActionDefinitionsBuilder(
      {G_VECREDUCE_SMIN, G_VECREDUCE_SMAX, G_VECREDUCE_UMIN, G_VECREDUCE_UMAX,
       G_VECREDUCE_ADD, G_VECREDUCE_MUL, G_VECREDUCE_FADD, G_VECREDUCE_FMUL,
       G_VECREDUCE_FMIN, G_VECREDUCE_FMAX, G_VECREDUCE_FMINIMUM,
       G_VECREDUCE_FMAXIMUM, G_VECREDUCE_OR, G_VECREDUCE_AND, G_VECREDUCE_XOR})
      .legalFor(AllVectors)
      .scalarize(1)
      .lower();

  getActionDefinitionsBuilder({G_INTRINSIC, G_INTRINSIC_W_SIDE_EFFECTS,
                               G_INTRINSIC_CONVERGENT,
                               G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS})
      .alwaysLegal();

  verify(*ST.getInstrInfo());
}

bool AMDGPULegalizerInfo::legalizeCustom(
    LegalizerHelper &Helper, MachineInstr &MI,
    LostDebugLocObserver &LocObserver) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();

  switch (MI.getOpcode()) {
  case TargetOpcode::G_ADDRSPACE_CAST:
    return legalizeAddrSpaceCast(MI, MRI, B);
  case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
    return legalizeFroundeven(MI, MRI, B);
  case TargetOpcode::G_FCEIL:
    return legalizeFceil(MI, MRI, B);
  case TargetOpcode::G_FREM:
    return legalizeFrem(MI, MRI, B);
  case TargetOpcode::G_INTRINSIC_TRUNC:
    return legalizeIntrinsicTrunc(MI, MRI, B);
  case TargetOpcode::G_SITOFP:
    return legalizeITOFP(MI, MRI, B, true);
  case TargetOpcode::G_UITOFP:
    return legalizeITOFP(MI, MRI, B, false);
  case TargetOpcode::G_FPTOSI:
    return legalizeFPTOI(MI, MRI, B, true);
  case TargetOpcode::G_FPTOUI:
    return legalizeFPTOI(MI, MRI, B, false);
  case TargetOpcode::G_FMINNUM:
  case TargetOpcode::G_FMAXNUM:
  case TargetOpcode::G_FMINIMUMNUM:
  case TargetOpcode::G_FMAXIMUMNUM:
    return legalizeMinNumMaxNum(Helper, MI);
  case TargetOpcode::G_EXTRACT:
    return legalizeExtract(Helper, MI);
  case TargetOpcode::G_INSERT:
    return legalizeInsert(Helper, MI);
  case TargetOpcode::G_EXTRACT_VECTOR_ELT:
    return legalizeExtractVectorElt(MI, MRI, B);
  case TargetOpcode::G_INSERT_VECTOR_ELT:
    return legalizeInsertVectorElt(MI, MRI, B);
  case TargetOpcode::G_FSIN:
  case TargetOpcode::G_FCOS:
    return legalizeSinCos(MI, MRI, B);
  case TargetOpcode::G_GLOBAL_VALUE:
    return legalizeGlobalValue(MI, MRI, B);
  case TargetOpcode::G_LOAD:
  case TargetOpcode::G_SEXTLOAD:
  case TargetOpcode::G_ZEXTLOAD:
  case TargetOpcode::G_PREFETCH:
    return legalizeLoad(Helper, MI);
  case TargetOpcode::G_STORE:
    return legalizeStore(Helper, MI);
  case TargetOpcode::G_FMAD:
    return legalizeFMad(MI, MRI, B);
  case TargetOpcode::G_FDIV:
    return legalizeFDIV(MI, MRI, B);
  case TargetOpcode::G_FFREXP:
    return legalizeFFREXP(MI, MRI, B);
  case TargetOpcode::G_FSQRT:
    return legalizeFSQRT(MI, MRI, B);
  case TargetOpcode::G_UDIV:
  case TargetOpcode::G_UREM:
  case TargetOpcode::G_UDIVREM:
    return legalizeUnsignedDIV_REM(MI, MRI, B);
  case TargetOpcode::G_SDIV:
  case TargetOpcode::G_SREM:
  case TargetOpcode::G_SDIVREM:
    return legalizeSignedDIV_REM(MI, MRI, B);
  case TargetOpcode::G_ATOMIC_CMPXCHG:
    return legalizeAtomicCmpXChg(MI, MRI, B);
  case TargetOpcode::G_FLOG2:
    return legalizeFlog2(MI, B);
  case TargetOpcode::G_FLOG:
  case TargetOpcode::G_FLOG10:
    return legalizeFlogCommon(MI, B);
  case TargetOpcode::G_FEXP2:
    return legalizeFExp2(MI, B);
  case TargetOpcode::G_FEXP:
  case TargetOpcode::G_FEXP10:
    return legalizeFExp(MI, B);
  case TargetOpcode::G_FPOW:
    return legalizeFPow(Helper, MI);
  case TargetOpcode::G_FFLOOR:
    return legalizeFFloor(MI, MRI, B);
  case TargetOpcode::G_BUILD_VECTOR:
  case TargetOpcode::G_BUILD_VECTOR_TRUNC:
    return legalizeBuildVector(MI, MRI, B);
  case TargetOpcode::G_MUL:
    return legalizeMul(Helper, MI);
  case TargetOpcode::G_CTLZ:
  case TargetOpcode::G_CTTZ:
    return legalizeCTLZ_CTTZ(MI, MRI, B);
  case TargetOpcode::G_CTLS:
    return legalizeCTLS(MI, MRI, B);
  case TargetOpcode::G_CTLZ_ZERO_POISON:
    return legalizeCTLZ_ZERO_POISON(MI, MRI, B);
  case TargetOpcode::G_STACKSAVE:
    return legalizeStackSave(MI, B);
  case TargetOpcode::G_GET_FPENV:
    return legalizeGetFPEnv(MI, MRI, B);
  case TargetOpcode::G_SET_FPENV:
    return legalizeSetFPEnv(MI, MRI, B);
  case TargetOpcode::G_TRAP:
    return legalizeTrap(Helper, MI);
  case TargetOpcode::G_DEBUGTRAP:
    return legalizeDebugTrap(MI, MRI, B);
  default:
    return false;
  }

  llvm_unreachable("expected switch to return");
}

Register AMDGPULegalizerInfo::getSegmentAperture(unsigned AS,
                                                 MachineRegisterInfo &MRI,
                                                 MachineIRBuilder &B) const {
  unsigned BaseAS = AS;
  unsigned SANum = AMDGPU::getSyntheticApertureNumber(AS);
  if (SANum != AMDGPU::SyntheticAperture::None)
    BaseAS = AMDGPUAS::LOCAL_ADDRESS;

  Register Aperture = getBaseSegmentAperture(BaseAS, MRI, B);

  if (SANum != AMDGPU::SyntheticAperture::None) {
    const LLT S32 = LLT::scalar(32);
    auto Tag = B.buildConstant(S32, SANum);
    return B.buildOr(S32, Aperture, Tag).getReg(0);
  }

  return Aperture;
}

Register AMDGPULegalizerInfo::getBaseSegmentAperture(
    unsigned AS, MachineRegisterInfo &MRI, MachineIRBuilder &B) const {
  MachineFunction &MF = B.getMF();
  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
  const LLT I32 = LLT::integer(32);
  const LLT I64 = LLT::integer(64);

  bool IsLDS = (AS == AMDGPUAS::LOCAL_ADDRESS || AS == AMDGPUAS::BARRIER);
  assert(IsLDS || AS == AMDGPUAS::PRIVATE_ADDRESS);

  if (ST.hasApertureRegs()) {
    // Note: this register is somewhat broken. When used as a 32-bit operand,
    // it only returns zeroes. The real value is in the upper 32 bits.
    // Thus, we must emit extract the high 32 bits.
    const unsigned ApertureRegNo =
        IsLDS ? AMDGPU::SRC_SHARED_BASE : AMDGPU::SRC_PRIVATE_BASE;
    assert((ApertureRegNo != AMDGPU::SRC_PRIVATE_BASE ||
            !ST.hasGloballyAddressableScratch()) &&
           "Cannot use src_private_base with globally addressable scratch!");
    Register Dst = MRI.createGenericVirtualRegister(I64);
    MRI.setRegClass(Dst, &AMDGPU::SReg_64RegClass);
    B.buildCopy({Dst}, {Register(ApertureRegNo)});
    return B.buildUnmerge(I32, Dst).getReg(1);
  }

  Register LoadAddr = MRI.createGenericVirtualRegister(
    LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64));
  // For code object version 5, private_base and shared_base are passed through
  // implicit kernargs.
  if (AMDGPU::getAMDHSACodeObjectVersion(*MF.getFunction().getParent()) >=
      AMDGPU::AMDHSA_COV5) {
    MachinePointerInfo PtrInfo = getKernargSegmentPtrInfo(B.getMF());

    AMDGPUTargetLowering::ImplicitParameter Param =
        AS == AMDGPUAS::LOCAL_ADDRESS ? AMDGPUTargetLowering::SHARED_BASE
                                      : AMDGPUTargetLowering::PRIVATE_BASE;
    uint64_t Offset =
        ST.getTargetLowering()->getImplicitParameterOffset(B.getMF(), Param);

    Register KernargPtrReg = MRI.createGenericVirtualRegister(
        LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64));

    if (!loadInputValue(KernargPtrReg, B,
                        AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR))
      return Register();

    MachineMemOperand *MMO = MF.getMachineMemOperand(
        PtrInfo.getWithOffset(Offset),
        MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
            MachineMemOperand::MOInvariant,
        LLT::integer(32), commonAlignment(Align(64), Offset));

    // Pointer address
    B.buildObjectPtrOffset(LoadAddr, KernargPtrReg,
                           B.buildConstant(LLT::integer(64), Offset).getReg(0));
    // Load address
    return B.buildLoad(I32, LoadAddr, *MMO).getReg(0);
  }

  Register QueuePtr = MRI.createGenericVirtualRegister(
    LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64));

  if (!loadInputValue(QueuePtr, B, AMDGPUFunctionArgInfo::QUEUE_PTR))
    return Register();

  // TODO: Use custom PseudoSourceValue
  MachinePointerInfo PtrInfo(AMDGPUAS::CONSTANT_ADDRESS);

  // Offset into amd_queue_t for group_segment_aperture_base_hi /
  // private_segment_aperture_base_hi.
  uint32_t StructOffset = IsLDS ? 0x40 : 0x44;

  MachineMemOperand *MMO = MF.getMachineMemOperand(
      PtrInfo,
      MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
          MachineMemOperand::MOInvariant,
      LLT::integer(32), commonAlignment(Align(64), StructOffset));

  B.buildObjectPtrOffset(
      LoadAddr, QueuePtr,
      B.buildConstant(LLT::integer(64), StructOffset).getReg(0));
  return B.buildLoad(I32, LoadAddr, *MMO).getReg(0);
}

/// Return true if the value is a known valid address, such that a null check is
/// not necessary.
static bool isKnownNonNull(Register Val, MachineRegisterInfo &MRI,
                           const AMDGPUTargetMachine &TM, unsigned AddrSpace) {
  MachineInstr *Def = MRI.getVRegDef(Val);
  switch (Def->getOpcode()) {
  case AMDGPU::G_FRAME_INDEX:
  case AMDGPU::G_GLOBAL_VALUE:
  case AMDGPU::G_BLOCK_ADDR:
    return true;
  case AMDGPU::G_CONSTANT: {
    const ConstantInt *CI = Def->getOperand(1).getCImm();
    return CI->getSExtValue() != AMDGPU::getNullPointerValue(AddrSpace);
  }
  default:
    return false;
  }

  return false;
}

bool AMDGPULegalizerInfo::legalizeAddrSpaceCast(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B) const {
  MachineFunction &MF = B.getMF();

  assert(MI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST);

  const LLT I32 = LLT::integer(32);
  const LLT I64 = LLT::integer(64);
  Register Dst = MI.getOperand(0).getReg();
  Register Src = MI.getOperand(1).getReg();
  LLT DstTy = MRI.getType(Dst);
  LLT SrcTy = MRI.getType(Src);
  unsigned DestAS = DstTy.getAddressSpace();
  unsigned SrcAS = SrcTy.getAddressSpace();

  // TODO: Avoid reloading from the queue ptr for each cast, or at least each
  // vector element.
  assert(!DstTy.isVector());

  const AMDGPUTargetMachine &TM
    = static_cast<const AMDGPUTargetMachine &>(MF.getTarget());

  // The source is known non-null for a G_ADDRSPACE_CAST carrying the nonnull
  // flag; otherwise we need to guess.
  const bool IsNonNull = MI.getFlag(MachineInstr::MIFlag::NonNull);

  if (TM.isNoopAddrSpaceCast(MF.getDataLayout(), SrcAS, DestAS)) {
    MI.setDesc(B.getTII().get(TargetOpcode::G_BITCAST));
    return true;
  }

  if (SrcAS == AMDGPUAS::FLAT_ADDRESS &&
      (DestAS == AMDGPUAS::LOCAL_ADDRESS || DestAS == AMDGPUAS::BARRIER ||
       DestAS == AMDGPUAS::PRIVATE_ADDRESS)) {
    auto castFlatToLocalOrPrivate = [&](const DstOp &Dst) -> Register {
      if (DestAS == AMDGPUAS::PRIVATE_ADDRESS &&
          ST.hasGloballyAddressableScratch()) {
        // flat -> private with globally addressable scratch: subtract
        // src_flat_scratch_base_lo.
        Register SrcLo = B.buildExtract(I32, Src, 0).getReg(0);
        Register FlatScratchBaseLo =
            B.buildInstr(AMDGPU::S_MOV_B32, {I32},
                         {Register(AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)})
                .getReg(0);
        MRI.setRegClass(FlatScratchBaseLo, &AMDGPU::SReg_32RegClass);
        Register Sub = B.buildSub(I32, SrcLo, FlatScratchBaseLo).getReg(0);
        return B.buildIntToPtr(Dst, Sub).getReg(0);
      }

      return B.buildExtract(Dst, Src, 0).getReg(0);
    };

    if (IsNonNull || isKnownNonNull(Src, MRI, TM, SrcAS)) {
      castFlatToLocalOrPrivate(Dst);
      MI.eraseFromParent();
      return true;
    }

    unsigned NullVal = AMDGPU::getNullPointerValue(DestAS);

    auto SegmentNull = B.buildConstant(DstTy, NullVal);
    auto FlatNull = B.buildConstant(SrcTy, 0);

    // Extract low 32-bits of the pointer.
    auto PtrLo32 = castFlatToLocalOrPrivate(DstTy);

    auto CmpRes =
        B.buildICmp(CmpInst::ICMP_NE, LLT::scalar(1), Src, FlatNull.getReg(0));
    B.buildSelect(Dst, CmpRes, PtrLo32, SegmentNull.getReg(0));

    MI.eraseFromParent();
    return true;
  }

  if (DestAS == AMDGPUAS::FLAT_ADDRESS &&
      (SrcAS == AMDGPUAS::LOCAL_ADDRESS || SrcAS == AMDGPUAS::BARRIER ||
       SrcAS == AMDGPUAS::PRIVATE_ADDRESS)) {
    auto castLocalOrPrivateToFlat = [&](const DstOp &Dst) -> Register {
      // Coerce the type of the low half of the result so we can use
      // merge_values.
      Register SrcAsInt = B.buildPtrToInt(I32, Src).getReg(0);

      if (SrcAS == AMDGPUAS::PRIVATE_ADDRESS &&
          ST.hasGloballyAddressableScratch()) {
        // For wave32: Addr = (TID[4:0] << 52) + FLAT_SCRATCH_BASE + privateAddr
        // For wave64: Addr = (TID[5:0] << 51) + FLAT_SCRATCH_BASE + privateAddr
        Register AllOnes = B.buildConstant(I32, -1).getReg(0);
        Register ThreadID = B.buildConstant(I32, 0).getReg(0);
        ThreadID = B.buildIntrinsic(Intrinsic::amdgcn_mbcnt_lo, {I32})
                       .addUse(AllOnes)
                       .addUse(ThreadID)
                       .getReg(0);
        if (ST.isWave64()) {
          ThreadID = B.buildIntrinsic(Intrinsic::amdgcn_mbcnt_hi, {I32})
                         .addUse(AllOnes)
                         .addUse(ThreadID)
                         .getReg(0);
        }
        Register ShAmt =
            B.buildConstant(I32, 57 - 32 - ST.getWavefrontSizeLog2()).getReg(0);
        Register SrcHi = B.buildShl(I32, ThreadID, ShAmt).getReg(0);
        Register CvtPtr =
            B.buildMergeLikeInstr(DstTy, {SrcAsInt, SrcHi}).getReg(0);
        // Accessing src_flat_scratch_base_lo as a 64-bit operand gives the full
        // 64-bit hi:lo value.
        Register FlatScratchBase =
            B.buildInstr(AMDGPU::S_MOV_B64, {I64},
                         {Register(AMDGPU::SRC_FLAT_SCRATCH_BASE)})
                .getReg(0);
        MRI.setRegClass(FlatScratchBase, &AMDGPU::SReg_64RegClass);
        return B.buildPtrAdd(Dst, CvtPtr, FlatScratchBase).getReg(0);
      }

      Register ApertureReg = getSegmentAperture(SrcAS, MRI, B);
      if (!ApertureReg.isValid())
        return false;

      // TODO: Should we allow mismatched types but matching sizes in merges to
      // avoid the ptrtoint?
      return B.buildMergeLikeInstr(Dst, {SrcAsInt, ApertureReg}).getReg(0);
    };

    if (IsNonNull || isKnownNonNull(Src, MRI, TM, SrcAS)) {
      castLocalOrPrivateToFlat(Dst);
      MI.eraseFromParent();
      return true;
    }

    Register BuildPtr = castLocalOrPrivateToFlat(DstTy);

    auto SegmentNull =
        B.buildConstant(SrcTy, AMDGPU::getNullPointerValue(SrcAS));
    auto FlatNull = B.buildConstant(DstTy, AMDGPU::getNullPointerValue(DestAS));

    auto CmpRes = B.buildICmp(CmpInst::ICMP_NE, LLT::scalar(1), Src,
                              SegmentNull.getReg(0));

    B.buildSelect(Dst, CmpRes, BuildPtr, FlatNull);

    MI.eraseFromParent();
    return true;
  }

  if (DestAS == AMDGPUAS::CONSTANT_ADDRESS_32BIT &&
      SrcTy.getSizeInBits() == 64) {
    // Truncate.
    B.buildExtract(Dst, Src, 0);
    MI.eraseFromParent();
    return true;
  }

  if (SrcAS == AMDGPUAS::CONSTANT_ADDRESS_32BIT &&
      DstTy.getSizeInBits() == 64) {
    const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
    uint32_t AddrHiVal = Info->get32BitAddressHighBits();
    auto PtrLo = B.buildPtrToInt(I32, Src);
    if (AddrHiVal == 0) {
      auto Zext = B.buildZExt(I64, PtrLo);
      B.buildIntToPtr(Dst, Zext);
    } else {
      auto HighAddr = B.buildConstant(I32, AddrHiVal);
      B.buildMergeLikeInstr(Dst, {PtrLo, HighAddr});
    }

    MI.eraseFromParent();
    return true;
  }

  // Invalid casts are poison.
  // TODO: Should return poison
  B.buildUndef(Dst);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFroundeven(MachineInstr &MI,
                                             MachineRegisterInfo &MRI,
                                             MachineIRBuilder &B) const {
  Register Src = MI.getOperand(1).getReg();
  LLT Ty = MRI.getType(Src);
  assert(Ty.isScalar() && Ty.getSizeInBits() == 64);

  APFloat C1Val(APFloat::IEEEdouble(), "0x1.0p+52");
  APFloat C2Val(APFloat::IEEEdouble(), "0x1.fffffffffffffp+51");

  auto C1 = B.buildFConstant(Ty, C1Val);
  auto CopySign = B.buildFCopysign(Ty, C1, Src);

  // TODO: Should this propagate fast-math-flags?
  auto Tmp1 = B.buildFAdd(Ty, Src, CopySign);
  auto Tmp2 = B.buildFSub(Ty, Tmp1, CopySign);

  auto C2 = B.buildFConstant(Ty, C2Val);
  auto Fabs = B.buildFAbs(Ty, Src);

  auto Cond = B.buildFCmp(CmpInst::FCMP_OGT, LLT::scalar(1), Fabs, C2);
  B.buildSelect(MI.getOperand(0).getReg(), Cond, Src, Tmp2);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFceil(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B) const {

  const LLT S1 = LLT::scalar(1);

  Register Src = MI.getOperand(1).getReg();
  assert(MRI.getType(Src) == F64);

  // result = trunc(src)
  // if (src > 0.0 && src != result)
  //   result += 1.0

  auto Trunc = B.buildIntrinsicTrunc(F64, Src);

  const auto Zero = B.buildFConstant(F64, 0.0);
  const auto One = B.buildFConstant(F64, 1.0);
  auto Lt0 = B.buildFCmp(CmpInst::FCMP_OGT, S1, Src, Zero);
  auto NeTrunc = B.buildFCmp(CmpInst::FCMP_ONE, S1, Src, Trunc);
  auto And = B.buildAnd(S1, Lt0, NeTrunc);
  auto Add = B.buildSelect(F64, And, One, Zero);

  // TODO: Should this propagate fast-math-flags?
  B.buildFAdd(MI.getOperand(0).getReg(), Trunc, Add);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFrem(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B) const {
    Register DstReg = MI.getOperand(0).getReg();
    Register Src0Reg = MI.getOperand(1).getReg();
    Register Src1Reg = MI.getOperand(2).getReg();
    auto Flags = MI.getFlags();
    LLT Ty = MRI.getType(DstReg);

    auto Div = B.buildFDiv(Ty, Src0Reg, Src1Reg, Flags);
    auto Trunc = B.buildIntrinsicTrunc(Ty, Div, Flags);
    auto Neg = B.buildFNeg(Ty, Trunc, Flags);
    B.buildFMA(DstReg, Neg, Src1Reg, Src0Reg, Flags);
    MI.eraseFromParent();
    return true;
}

static MachineInstrBuilder extractF64Exponent(Register Hi,
                                              MachineIRBuilder &B) {
  const unsigned FractBits = 52;
  const unsigned ExpBits = 11;
  LLT I32 = LLT::integer(32);

  auto Const0 = B.buildConstant(I32, FractBits - 32);
  auto Const1 = B.buildConstant(I32, ExpBits);

  auto ExpPart = B.buildIntrinsic(Intrinsic::amdgcn_ubfe, {I32})
                     .addUse(Hi)
                     .addUse(Const0.getReg(0))
                     .addUse(Const1.getReg(0));

  return B.buildSub(I32, ExpPart, B.buildConstant(I32, 1023));
}

bool AMDGPULegalizerInfo::legalizeIntrinsicTrunc(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B) const {
  const LLT S1 = LLT::scalar(1);
  const LLT I32 = LLT::integer(32);
  const LLT I64 = LLT::integer(64);

  Register Src = MI.getOperand(1).getReg();
  assert(MRI.getType(Src) == F64);

  auto SrcInt = B.buildBitcast(I64, Src);

  // TODO: Should this use extract since the low half is unused?
  auto Unmerge = B.buildUnmerge({I32, I32}, SrcInt);
  Register Hi = Unmerge.getReg(1);

  // Extract the upper half, since this is where we will find the sign and
  // exponent.
  auto Exp = extractF64Exponent(Hi, B);

  const unsigned FractBits = 52;

  // Extract the sign bit.
  const auto SignBitMask = B.buildConstant(I32, UINT32_C(1) << 31);
  auto SignBit = B.buildAnd(I32, Hi, SignBitMask);

  const auto FractMask = B.buildConstant(I64, (UINT64_C(1) << FractBits) - 1);

  const auto Zero32 = B.buildConstant(I32, 0);

  // Extend back to 64-bits.
  auto SignBit64 = B.buildMergeLikeInstr(I64, {Zero32, SignBit});

  auto Shr = B.buildAShr(I64, FractMask, Exp);
  auto Not = B.buildNot(I64, Shr);
  auto Tmp0 = B.buildAnd(I64, SrcInt, Not);
  auto FiftyOne = B.buildConstant(I32, FractBits - 1);

  auto ExpLt0 = B.buildICmp(CmpInst::ICMP_SLT, S1, Exp, Zero32);
  auto ExpGt51 = B.buildICmp(CmpInst::ICMP_SGT, S1, Exp, FiftyOne);

  auto Tmp1 = B.buildSelect(I64, ExpLt0, SignBit64, Tmp0);
  auto Res = B.buildSelect(I64, ExpGt51, SrcInt, Tmp1);
  B.buildBitcast(MI.getOperand(0).getReg(), Res);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeITOFP(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B, bool Signed) const {

  Register Dst = MI.getOperand(0).getReg();
  Register Src = MI.getOperand(1).getReg();

  const LLT I64 = LLT::integer(64);
  const LLT I32 = LLT::integer(32);

  assert(MRI.getType(Src) == I64);

  auto Unmerge = B.buildUnmerge({I32, I32}, Src);
  auto ThirtyTwo = B.buildConstant(I32, 32);

  if (MRI.getType(Dst) == F64) {
    auto CvtHi = Signed ? B.buildSITOFP(F64, Unmerge.getReg(1))
                        : B.buildUITOFP(F64, Unmerge.getReg(1));

    auto CvtLo = B.buildUITOFP(F64, Unmerge.getReg(0));
    auto LdExp = B.buildFLdexp(F64, CvtHi, ThirtyTwo);

    // TODO: Should this propagate fast-math-flags?
    B.buildFAdd(Dst, LdExp, CvtLo);
    MI.eraseFromParent();
    return true;
  }

  assert(MRI.getType(Dst) == F32);

  auto One = B.buildConstant(I32, 1);

  MachineInstrBuilder ShAmt;
  if (Signed) {
    auto ThirtyOne = B.buildConstant(I32, 31);
    auto X = B.buildXor(I32, Unmerge.getReg(0), Unmerge.getReg(1));
    auto OppositeSign = B.buildAShr(I32, X, ThirtyOne);
    auto MaxShAmt = B.buildAdd(I32, ThirtyTwo, OppositeSign);
    auto LS = B.buildIntrinsic(Intrinsic::amdgcn_sffbh, {I32})
                  .addUse(Unmerge.getReg(1));
    auto LS2 = B.buildSub(I32, LS, One);
    ShAmt = B.buildUMin(I32, LS2, MaxShAmt);
  } else
    ShAmt = B.buildCTLZ(I32, Unmerge.getReg(1));
  auto Norm = B.buildShl(I64, Src, ShAmt);
  auto Unmerge2 = B.buildUnmerge({I32, I32}, Norm);
  auto Adjust = B.buildUMin(I32, One, Unmerge2.getReg(0));
  auto Norm2 = B.buildOr(I32, Unmerge2.getReg(1), Adjust);
  auto FVal = Signed ? B.buildSITOFP(F32, Norm2) : B.buildUITOFP(F32, Norm2);
  auto Scale = B.buildSub(I32, ThirtyTwo, ShAmt);
  B.buildFLdexp(Dst, FVal, Scale);
  MI.eraseFromParent();
  return true;
}

// TODO: Copied from DAG implementation. Verify logic and document how this
// actually works.
bool AMDGPULegalizerInfo::legalizeFPTOI(MachineInstr &MI,
                                        MachineRegisterInfo &MRI,
                                        MachineIRBuilder &B,
                                        bool Signed) const {

  Register Dst = MI.getOperand(0).getReg();
  Register Src = MI.getOperand(1).getReg();

  const LLT I64 = LLT::integer(64);
  const LLT I32 = LLT::integer(32);

  const LLT SrcLT = MRI.getType(Src);
  assert((SrcLT == F32 || SrcLT == F64) && MRI.getType(Dst) == I64);

  unsigned Flags = MI.getFlags();

  // The basic idea of converting a floating point number into a pair of 32-bit
  // integers is illustrated as follows:
  //
  //     tf := trunc(val);
  //    hif := floor(tf * 2^-32);
  //    lof := tf - hif * 2^32; // lof is always positive due to floor.
  //     hi := fptoi(hif);
  //     lo := fptoi(lof);
  //
  auto Trunc = B.buildIntrinsicTrunc(SrcLT, Src, Flags);
  MachineInstrBuilder Sign;
  if (Signed && SrcLT == F32) {
    // However, a 32-bit floating point number has only 23 bits mantissa and
    // it's not enough to hold all the significant bits of `lof` if val is
    // negative. To avoid the loss of precision, We need to take the absolute
    // value after truncating and flip the result back based on the original
    // signedness.
    auto SrcInt = B.buildBitcast(I32, Src);
    Sign = B.buildAShr(I32, SrcInt, B.buildConstant(I32, 31));
    Trunc = B.buildFAbs(F32, Trunc, Flags);
  }
  MachineInstrBuilder K0, K1;
  if (SrcLT == F64) {
    K0 = B.buildFConstant(
        F64, llvm::bit_cast<double>(UINT64_C(/*2^-32*/ 0x3df0000000000000)));
    K1 = B.buildFConstant(
        F64, llvm::bit_cast<double>(UINT64_C(/*-2^32*/ 0xc1f0000000000000)));
  } else {
    K0 = B.buildFConstant(
        F32, llvm::bit_cast<float>(UINT32_C(/*2^-32*/ 0x2f800000)));
    K1 = B.buildFConstant(
        F32, llvm::bit_cast<float>(UINT32_C(/*-2^32*/ 0xcf800000)));
  }

  auto Mul = B.buildFMul(SrcLT, Trunc, K0, Flags);
  auto FloorMul = B.buildFFloor(SrcLT, Mul, Flags);
  auto Fma = B.buildFMA(SrcLT, FloorMul, K1, Trunc, Flags);

  auto Hi = (Signed && SrcLT == F64) ? B.buildFPTOSI(I32, FloorMul)
                                     : B.buildFPTOUI(I32, FloorMul);
  auto Lo = B.buildFPTOUI(I32, Fma);

  if (Signed && SrcLT == F32) {
    // Flip the result based on the signedness, which is either all 0s or 1s.
    Sign = B.buildMergeLikeInstr(I64, {Sign, Sign});
    // r := xor({lo, hi}, sign) - sign;
    B.buildSub(Dst, B.buildXor(I64, B.buildMergeLikeInstr(I64, {Lo, Hi}), Sign),
               Sign);
  } else
    B.buildMergeLikeInstr(Dst, {Lo, Hi});
  MI.eraseFromParent();

  return true;
}

bool AMDGPULegalizerInfo::legalizeMinNumMaxNum(LegalizerHelper &Helper,
                                               MachineInstr &MI) const {
  MachineFunction &MF = Helper.MIRBuilder.getMF();
  const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();

  // With ieee_mode disabled, the instructions have the correct behavior.
  if (!MFI->getMode().IEEE)
    return true;

  return Helper.lowerFMinNumMaxNum(MI) == LegalizerHelper::Legalized;
}

bool AMDGPULegalizerInfo::legalizeExtract(LegalizerHelper &Helper,
                                          MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();
  Register DstReg = MI.getOperand(0).getReg();
  Register SrcReg = MI.getOperand(1).getReg();
  uint64_t Offset = MI.getOperand(2).getImm();

  // Fall back to generic lowering for offset 0 (trivial trunc) and
  // non-32-bit-aligned cases which require shift+trunc sequences
  // that generic code handles correctly.
  if (Offset == 0 || Offset % 32 != 0)
    return Helper.lowerExtract(MI) == LegalizerHelper::Legalized;

  const LLT DstTy = MRI.getType(DstReg);
  unsigned StartIdx = Offset / 32;
  unsigned DstCount = DstTy.getSizeInBits() / 32;
  auto Unmerge = B.buildUnmerge(LLT::integer(32), SrcReg);

  if (DstCount == 1) {
    if (DstTy.isPointer())
      B.buildIntToPtr(DstReg, Unmerge.getReg(StartIdx));
    else {
      Helper.Observer.changingAllUsesOfReg(MRI, DstReg);
      MRI.replaceRegWith(DstReg, Unmerge.getReg(StartIdx));
      Helper.Observer.finishedChangingAllUsesOfReg();
    }
  } else {
    SmallVector<Register, 8> MergeVec;
    for (unsigned I = 0; I < DstCount; ++I)
      MergeVec.push_back(Unmerge.getReg(StartIdx + I));
    B.buildMergeLikeInstr(DstReg, MergeVec);
  }

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeInsert(LegalizerHelper &Helper,
                                         MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();
  Register DstReg = MI.getOperand(0).getReg();
  Register SrcReg = MI.getOperand(1).getReg();
  Register InsertSrc = MI.getOperand(2).getReg();
  uint64_t Offset = MI.getOperand(3).getImm();

  unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
  const LLT InsertTy = MRI.getType(InsertSrc);
  unsigned InsertSize = InsertTy.getSizeInBits();

  // Fall back to generic lowering for non-32-bit-aligned cases which
  // require shift+mask sequences that generic code handles correctly.
  if (Offset % 32 != 0 || DstSize % 32 != 0 || InsertSize % 32 != 0)
    return Helper.lowerInsert(MI) == LegalizerHelper::Legalized;

  const LLT I32 = LLT::integer(32);
  unsigned DstCount = DstSize / 32;
  unsigned InsertCount = InsertSize / 32;
  unsigned StartIdx = Offset / 32;

  auto SrcUnmerge = B.buildUnmerge(I32, SrcReg);

  SmallVector<Register, 8> MergeVec;
  for (unsigned I = 0; I < StartIdx; ++I)
    MergeVec.push_back(SrcUnmerge.getReg(I));

  if (InsertCount == 1) {
    // Merge-like instructions require same source types. Convert pointer
    // to scalar when inserting a pointer value into a scalar.
    if (InsertTy.isPointer())
      InsertSrc = B.buildPtrToInt(I32, InsertSrc).getReg(0);
    MergeVec.push_back(InsertSrc);
  } else {
    auto InsertUnmerge = B.buildUnmerge(I32, InsertSrc);
    for (unsigned I = 0; I < InsertCount; ++I)
      MergeVec.push_back(InsertUnmerge.getReg(I));
  }

  for (unsigned I = StartIdx + InsertCount; I < DstCount; ++I)
    MergeVec.push_back(SrcUnmerge.getReg(I));

  B.buildMergeLikeInstr(DstReg, MergeVec);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeExtractVectorElt(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B) const {
  // TODO: Should move some of this into LegalizerHelper.

  // TODO: Promote dynamic indexing of i16/f16 to i32/f32

  Register Dst = MI.getOperand(0).getReg();
  Register Vec = MI.getOperand(1).getReg();

  LLT VecTy = MRI.getType(Vec);
  LLT EltTy = VecTy.getElementType();
  assert(EltTy == MRI.getType(Dst));

  // Other legalization maps vector<? x [type bigger than 64 bits]> via bitcasts
  // but we can't go directly to that logic becasue you can't bitcast a vector
  // of pointers to a vector of integers. Therefore, introduce an intermediate
  // vector of integers using ptrtoint (and inttoptr on the output) in order to
  // drive the legalization forward.
  if (EltTy.isPointer() && EltTy.getSizeInBits() > 64) {
    LLT IntTy = LLT::integer(EltTy.getSizeInBits());
    LLT IntVecTy = VecTy.changeElementType(IntTy);

    auto IntVec = B.buildPtrToInt(IntVecTy, Vec);
    auto IntElt = B.buildExtractVectorElement(IntTy, IntVec, MI.getOperand(2));
    B.buildIntToPtr(Dst, IntElt);

    MI.eraseFromParent();
    return true;
  }

  // FIXME: Artifact combiner probably should have replaced the truncated
  // constant before this, so we shouldn't need
  // getIConstantVRegValWithLookThrough.
  std::optional<ValueAndVReg> MaybeIdxVal =
      getIConstantVRegValWithLookThrough(MI.getOperand(2).getReg(), MRI);
  if (!MaybeIdxVal) // Dynamic case will be selected to register indexing.
    return true;
  const uint64_t IdxVal = MaybeIdxVal->Value.getZExtValue();

  if (IdxVal < VecTy.getNumElements()) {
    auto Unmerge = B.buildUnmerge(EltTy, Vec);
    B.buildCopy(Dst, Unmerge.getReg(IdxVal));
  } else {
    B.buildUndef(Dst);
  }

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeInsertVectorElt(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B) const {
  // TODO: Should move some of this into LegalizerHelper.

  // TODO: Promote dynamic indexing of i16/f16 to i32/f32

  Register Dst = MI.getOperand(0).getReg();
  Register Vec = MI.getOperand(1).getReg();
  Register Ins = MI.getOperand(2).getReg();

  LLT VecTy = MRI.getType(Vec);
  LLT EltTy = VecTy.getElementType();
  assert(EltTy == MRI.getType(Ins));

  // Other legalization maps vector<? x [type bigger than 64 bits]> via bitcasts
  // but we can't go directly to that logic becasue you can't bitcast a vector
  // of pointers to a vector of integers. Therefore, make the pointer vector
  // into an equivalent vector of integers with ptrtoint, insert the ptrtoint'd
  // new value, and then inttoptr the result vector back. This will then allow
  // the rest of legalization to take over.
  if (EltTy.isPointer() && EltTy.getSizeInBits() > 64) {
    LLT IntTy = LLT::integer(EltTy.getSizeInBits());
    LLT IntVecTy = VecTy.changeElementType(IntTy);

    auto IntVecSource = B.buildPtrToInt(IntVecTy, Vec);
    auto IntIns = B.buildPtrToInt(IntTy, Ins);
    auto IntVecDest = B.buildInsertVectorElement(IntVecTy, IntVecSource, IntIns,
                                                 MI.getOperand(3));
    B.buildIntToPtr(Dst, IntVecDest);
    MI.eraseFromParent();
    return true;
  }

  // FIXME: Artifact combiner probably should have replaced the truncated
  // constant before this, so we shouldn't need
  // getIConstantVRegValWithLookThrough.
  std::optional<ValueAndVReg> MaybeIdxVal =
      getIConstantVRegValWithLookThrough(MI.getOperand(3).getReg(), MRI);
  if (!MaybeIdxVal) // Dynamic case will be selected to register indexing.
    return true;

  const uint64_t IdxVal = MaybeIdxVal->Value.getZExtValue();

  unsigned NumElts = VecTy.getNumElements();
  if (IdxVal < NumElts) {
    SmallVector<Register, 8> SrcRegs;
    for (unsigned i = 0; i < NumElts; ++i)
      SrcRegs.push_back(MRI.createGenericVirtualRegister(EltTy));
    B.buildUnmerge(SrcRegs, Vec);

    SrcRegs[IdxVal] = MI.getOperand(2).getReg();
    B.buildMergeLikeInstr(Dst, SrcRegs);
  } else {
    B.buildUndef(Dst);
  }

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeSinCos(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B) const {

  Register DstReg = MI.getOperand(0).getReg();
  Register SrcReg = MI.getOperand(1).getReg();
  LLT Ty = MRI.getType(DstReg);
  unsigned Flags = MI.getFlags();

  Register TrigVal;
  auto OneOver2Pi = B.buildFConstant(Ty, 0.5 * numbers::inv_pi);
  if (ST.hasTrigReducedRange()) {
    auto MulVal = B.buildFMul(Ty, SrcReg, OneOver2Pi, Flags);
    TrigVal = B.buildIntrinsic(Intrinsic::amdgcn_fract, {Ty})
                  .addUse(MulVal.getReg(0))
                  .setMIFlags(Flags)
                  .getReg(0);
  } else
    TrigVal = B.buildFMul(Ty, SrcReg, OneOver2Pi, Flags).getReg(0);

  Intrinsic::ID TrigIntrin = MI.getOpcode() == AMDGPU::G_FSIN ?
    Intrinsic::amdgcn_sin : Intrinsic::amdgcn_cos;
  B.buildIntrinsic(TrigIntrin, ArrayRef<Register>(DstReg))
      .addUse(TrigVal)
      .setMIFlags(Flags);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::buildPCRelGlobalAddress(Register DstReg, LLT PtrTy,
                                                  MachineIRBuilder &B,
                                                  const GlobalValue *GV,
                                                  int64_t Offset,
                                                  unsigned GAFlags) const {
  assert(isInt<32>(Offset + 4) && "32-bit offset is expected!");
  // In order to support pc-relative addressing, SI_PC_ADD_REL_OFFSET is lowered
  // to the following code sequence:
  //
  // For constant address space:
  //   s_getpc_b64 s[0:1]
  //   s_add_u32 s0, s0, $symbol
  //   s_addc_u32 s1, s1, 0
  //
  //   s_getpc_b64 returns the address of the s_add_u32 instruction and then
  //   a fixup or relocation is emitted to replace $symbol with a literal
  //   constant, which is a pc-relative offset from the encoding of the $symbol
  //   operand to the global variable.
  //
  // For global address space:
  //   s_getpc_b64 s[0:1]
  //   s_add_u32 s0, s0, $symbol@{gotpc}rel32@lo
  //   s_addc_u32 s1, s1, $symbol@{gotpc}rel32@hi
  //
  //   s_getpc_b64 returns the address of the s_add_u32 instruction and then
  //   fixups or relocations are emitted to replace $symbol@*@lo and
  //   $symbol@*@hi with lower 32 bits and higher 32 bits of a literal constant,
  //   which is a 64-bit pc-relative offset from the encoding of the $symbol
  //   operand to the global variable.

  MachineRegisterInfo &MRI = *B.getMRI();
  LLT PCRegTy = PtrTy.getSizeInBits() == 32
                    ? LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64)
                    : PtrTy;
  Register PCReg =
      MRI.createVirtualRegister({&AMDGPU::SReg_64RegClass, PCRegTy});

  if (ST.has64BitLiterals()) {
    assert(GAFlags != SIInstrInfo::MO_NONE);

    MachineInstrBuilder MIB =
        B.buildInstr(AMDGPU::SI_PC_ADD_REL_OFFSET64).addDef(PCReg);
    MIB.addGlobalAddress(GV, Offset, GAFlags + 2);
  } else {
    MachineInstrBuilder MIB =
        B.buildInstr(AMDGPU::SI_PC_ADD_REL_OFFSET).addDef(PCReg);

    MIB.addGlobalAddress(GV, Offset, GAFlags);
    if (GAFlags == SIInstrInfo::MO_NONE)
      MIB.addImm(0);
    else
      MIB.addGlobalAddress(GV, Offset, GAFlags + 1);
    MIB.setOperandDead(3); // $scc
  }

  if (PtrTy.getSizeInBits() == 32)
    B.buildExtract(DstReg, PCReg, 0);
  else
    B.buildCopy(DstReg, PCReg);
  return true;
}

// Emit a ABS32_LO / ABS32_HI relocation stub.
void AMDGPULegalizerInfo::buildAbsGlobalAddress(
    Register DstReg, LLT PtrTy, MachineIRBuilder &B, const GlobalValue *GV,
    MachineRegisterInfo &MRI) const {
  bool RequiresHighHalf = PtrTy.getSizeInBits() != 32;

  if (RequiresHighHalf && ST.has64BitLiterals()) {
    Register Addr =
        MRI.createVirtualRegister({&AMDGPU::SReg_64RegClass, PtrTy});
    B.buildInstr(AMDGPU::S_MOV_B64)
        .addDef(Addr)
        .addGlobalAddress(GV, 0, SIInstrInfo::MO_ABS64);
    B.buildCopy(DstReg, Addr);
    return;
  }

  LLT I32 = LLT::integer(32);
  Register AddrLo = MRI.createVirtualRegister({&AMDGPU::SReg_32RegClass, I32});

  // Write the lower half.
  B.buildInstr(AMDGPU::S_MOV_B32)
      .addDef(AddrLo)
      .addGlobalAddress(GV, 0, SIInstrInfo::MO_ABS32_LO);

  // If required, write the upper half as well.
  if (RequiresHighHalf) {
    assert(PtrTy.getSizeInBits() == 64 &&
           "Must provide a 64-bit pointer type!");

    Register AddrHi =
        MRI.createVirtualRegister({&AMDGPU::SReg_32RegClass, I32});

    B.buildInstr(AMDGPU::S_MOV_B32)
        .addDef(AddrHi)
        .addGlobalAddress(GV, 0, SIInstrInfo::MO_ABS32_HI);

    Register AddrDst =
        MRI.createVirtualRegister({&AMDGPU::SReg_64RegClass, LLT::integer(64)});

    B.buildMergeValues(AddrDst, {AddrLo, AddrHi});
    B.buildCast(DstReg, AddrDst);
  } else {
    B.buildCast(DstReg, AddrLo);
  }
}

bool AMDGPULegalizerInfo::legalizeGlobalValue(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B) const {
  Register DstReg = MI.getOperand(0).getReg();
  LLT Ty = MRI.getType(DstReg);
  unsigned AS = Ty.getAddressSpace();

  const GlobalValue *GV = MI.getOperand(1).getGlobal();
  MachineFunction &MF = B.getMF();
  SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();

  if (AS == AMDGPUAS::BARRIER) {
    const GlobalVariable *GVar = cast<GlobalVariable>(GV);
    if (!AMDGPU::isNamedBarrier(*GVar)) {
      const Function &Fn = MF.getFunction();
      Fn.getContext().diagnose(DiagnosticInfoUnsupported(
          Fn, "unsupported use of BARRIER address space", MI.getDebugLoc(),
          DS_Error));
      B.buildUndef(DstReg);
      MI.eraseFromParent();
      return true;
    }

    B.buildConstant(DstReg,
                    MFI->allocateBarrierGlobal(B.getDataLayout(), *GVar));
    MI.eraseFromParent();
    return true;
  }

  if (AS == AMDGPUAS::LOCAL_ADDRESS || AS == AMDGPUAS::REGION_ADDRESS) {
    if (!MFI->isModuleEntryFunction() &&
        GV->getName() != "llvm.amdgcn.module.lds") {
      const Function &Fn = MF.getFunction();
      Fn.getContext().diagnose(DiagnosticInfoUnsupported(
          Fn, "local memory global used by non-kernel function",
          MI.getDebugLoc(), DS_Warning));

      // We currently don't have a way to correctly allocate LDS objects that
      // aren't directly associated with a kernel. We do force inlining of
      // functions that use local objects. However, if these dead functions are
      // not eliminated, we don't want a compile time error. Just emit a warning
      // and a trap, since there should be no callable path here.
      B.buildTrap();
      B.buildUndef(DstReg);
      MI.eraseFromParent();
      return true;
    }

    // TODO: We could emit code to handle the initialization somewhere.
    // We ignore the initializer for now and legalize it to allow selection.
    // The initializer will anyway get errored out during assembly emission.
    const SITargetLowering *TLI = ST.getTargetLowering();
    if (!TLI->shouldUseLDSConstAddress(GV)) {
      MI.getOperand(1).setTargetFlags(SIInstrInfo::MO_ABS32_LO);
      return true; // Leave in place;
    }

    const GlobalVariable &GVar = *cast<GlobalVariable>(GV);
    if (AS == AMDGPUAS::LOCAL_ADDRESS && GV->hasExternalLinkage()) {
      // HIP uses an unsized array `extern __shared__ T s[]` or similar
      // zero-sized type in other languages to declare the dynamic shared
      // memory which size is not known at the compile time. They will be
      // allocated by the runtime and placed directly after the static
      // allocated ones. They all share the same offset.
      if (GVar.getGlobalSize(GVar.getDataLayout()) == 0) {
        // Adjust alignment for that dynamic shared memory array.
        MFI->setDynLDSAlign(MF.getFunction(), GVar);
        LLT I32 = LLT::integer(32);
        auto Sz = B.buildIntrinsic(Intrinsic::amdgcn_groupstaticsize, {I32});
        B.buildIntToPtr(DstReg, Sz);
        MI.eraseFromParent();
        return true;
      }
    }

    B.buildConstant(DstReg, MFI->allocateLDSGlobal(B.getDataLayout(), GVar));
    MI.eraseFromParent();
    return true;
  }

  if (ST.isAmdPalOS() || ST.isMesa3DOS()) {
    buildAbsGlobalAddress(DstReg, Ty, B, GV, MRI);
    MI.eraseFromParent();
    return true;
  }

  const SITargetLowering *TLI = ST.getTargetLowering();

  if (TLI->shouldEmitFixup(GV)) {
    buildPCRelGlobalAddress(DstReg, Ty, B, GV, 0);
    MI.eraseFromParent();
    return true;
  }

  if (TLI->shouldEmitPCReloc(GV)) {
    buildPCRelGlobalAddress(DstReg, Ty, B, GV, 0, SIInstrInfo::MO_REL32);
    MI.eraseFromParent();
    return true;
  }

  LLT PtrTy = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64);
  Register GOTAddr = MRI.createGenericVirtualRegister(PtrTy);

  LLT LoadTy = Ty.getSizeInBits() == 32 ? PtrTy : Ty;
  MachineMemOperand *GOTMMO = MF.getMachineMemOperand(
      MachinePointerInfo::getGOT(MF),
      MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
          MachineMemOperand::MOInvariant,
      LoadTy, Align(8));

  buildPCRelGlobalAddress(GOTAddr, PtrTy, B, GV, 0, SIInstrInfo::MO_GOTPCREL32);

  if (Ty.getSizeInBits() == 32) {
    // Truncate if this is a 32-bit constant address.
    auto Load = B.buildLoad(PtrTy, GOTAddr, *GOTMMO);
    B.buildExtract(DstReg, Load, 0);
  } else
    B.buildLoad(DstReg, GOTAddr, *GOTMMO);

  MI.eraseFromParent();
  return true;
}

static LLT widenToNextPowerOf2(LLT Ty) {
  if (Ty.isVector())
    return Ty.changeElementCount(
        ElementCount::getFixed(PowerOf2Ceil(Ty.getNumElements())));
  return Ty.changeElementSize(PowerOf2Ceil(Ty.getSizeInBits()));
}

bool AMDGPULegalizerInfo::legalizeLoad(LegalizerHelper &Helper,
                                       MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();
  GISelChangeObserver &Observer = Helper.Observer;

  unsigned PtrIdx = MI.getOpcode() == AMDGPU::G_PREFETCH ? 0 : 1;
  Register PtrReg = MI.getOperand(PtrIdx).getReg();
  LLT PtrTy = MRI.getType(PtrReg);
  unsigned AddrSpace = PtrTy.getAddressSpace();

  if (AddrSpace == AMDGPUAS::CONSTANT_ADDRESS_32BIT) {
    LLT ConstPtr = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64);
    auto Cast = B.buildAddrSpaceCast(ConstPtr, PtrReg);
    Observer.changingInstr(MI);
    MI.getOperand(PtrIdx).setReg(Cast.getReg(0));
    Observer.changedInstr(MI);
    return true;
  }

  if (MI.getOpcode() != AMDGPU::G_LOAD)
    return false;

  Register ValReg = MI.getOperand(0).getReg();
  LLT ValTy = MRI.getType(ValReg);

  if (hasBufferRsrcWorkaround(ValTy)) {
    Observer.changingInstr(MI);
    castBufferRsrcFromV4I32(MI, B, MRI, 0);
    Observer.changedInstr(MI);
    return true;
  }

  MachineMemOperand *MMO = *MI.memoperands_begin();
  const unsigned ValSize = ValTy.getSizeInBits();
  const LLT MemTy = MMO->getMemoryType();
  const Align MemAlign = MMO->getAlign();
  const unsigned MemSize = MemTy.getSizeInBits();
  const uint64_t AlignInBits = 8 * MemAlign.value();

  // Widen non-power-of-2 loads to the alignment if needed
  if (shouldWidenLoad(ST, MemTy, AlignInBits, AddrSpace, MI.getOpcode())) {
    const unsigned WideMemSize = PowerOf2Ceil(MemSize);

    // This was already the correct extending load result type, so just adjust
    // the memory type.
    if (WideMemSize == ValSize) {
      MachineFunction &MF = B.getMF();

      MachineMemOperand *WideMMO =
          MF.getMachineMemOperand(MMO, 0, WideMemSize / 8);
      Observer.changingInstr(MI);
      MI.setMemRefs(MF, {WideMMO});
      Observer.changedInstr(MI);
      return true;
    }

    // Don't bother handling edge case that should probably never be produced.
    if (ValSize > WideMemSize)
      return false;

    LLT WideTy = widenToNextPowerOf2(ValTy);

    Register WideLoad;
    if (!WideTy.isVector()) {
      WideLoad = B.buildLoadFromOffset(WideTy, PtrReg, *MMO, 0).getReg(0);
      B.buildTrunc(ValReg, WideLoad).getReg(0);
    } else {
      // Extract the subvector.

      if (isRegisterType(ST, ValTy)) {
        // If this a case where G_EXTRACT is legal, use it.
        // (e.g. <3 x i32> -> <4 x i32>)
        WideLoad = B.buildLoadFromOffset(WideTy, PtrReg, *MMO, 0).getReg(0);
        B.buildExtract(ValReg, WideLoad, 0);
      } else {
        // For cases where the widened type isn't a nice register value, unmerge
        // from a widened register (e.g. <3 x i16> -> <4 x i16>)
        WideLoad = B.buildLoadFromOffset(WideTy, PtrReg, *MMO, 0).getReg(0);
        B.buildDeleteTrailingVectorElements(ValReg, WideLoad);
      }
    }

    MI.eraseFromParent();
    return true;
  }

  return false;
}

bool AMDGPULegalizerInfo::legalizeStore(LegalizerHelper &Helper,
                                        MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();
  GISelChangeObserver &Observer = Helper.Observer;

  Register DataReg = MI.getOperand(0).getReg();
  LLT DataTy = MRI.getType(DataReg);

  if (hasBufferRsrcWorkaround(DataTy)) {
    Observer.changingInstr(MI);
    castBufferRsrcArgToV4I32(MI, B, 0);
    Observer.changedInstr(MI);
    return true;
  }
  return false;
}

bool AMDGPULegalizerInfo::legalizeFMad(
  MachineInstr &MI, MachineRegisterInfo &MRI,
  MachineIRBuilder &B) const {
  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
  assert(Ty.isScalar());

  MachineFunction &MF = B.getMF();
  const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();

  // TODO: Always legal with future ftz flag.
  // TODO: Type is expected to be LLT::float32()/LLT::float16()
  // FIXME: Do we need just output?
  if (Ty == F32 &&
      MFI->getMode().FP32Denormals == DenormalMode::getPreserveSign())
    return true;
  if (Ty == F16 &&
      MFI->getMode().FP64FP16Denormals == DenormalMode::getPreserveSign())
    return true;

  MachineIRBuilder HelperBuilder(MI);
  GISelObserverWrapper DummyObserver;
  LegalizerHelper Helper(MF, DummyObserver, HelperBuilder);
  return Helper.lowerFMad(MI) == LegalizerHelper::Legalized;
}

bool AMDGPULegalizerInfo::legalizeAtomicCmpXChg(
  MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const {
  Register DstReg = MI.getOperand(0).getReg();
  Register PtrReg = MI.getOperand(1).getReg();
  Register CmpVal = MI.getOperand(2).getReg();
  Register NewVal = MI.getOperand(3).getReg();

  assert(AMDGPU::isFlatGlobalAddrSpace(MRI.getType(PtrReg).getAddressSpace()) &&
         "this should not have been custom lowered");

  LLT ValTy = MRI.getType(CmpVal);
  LLT VecTy = LLT::fixed_vector(2, ValTy);

  Register PackedVal = B.buildBuildVector(VecTy, { NewVal, CmpVal }).getReg(0);

  B.buildInstr(AMDGPU::G_AMDGPU_ATOMIC_CMPXCHG)
    .addDef(DstReg)
    .addUse(PtrReg)
    .addUse(PackedVal)
    .setMemRefs(MI.memoperands());

  MI.eraseFromParent();
  return true;
}

/// Return true if it's known that \p Src can never be an f32 denormal value.
static bool valueIsKnownNeverF32Denorm(const MachineRegisterInfo &MRI,
                                       Register Src) {
  const MachineInstr *DefMI = MRI.getVRegDef(Src);
  switch (DefMI->getOpcode()) {
  case TargetOpcode::G_INTRINSIC: {
    switch (cast<GIntrinsic>(DefMI)->getIntrinsicID()) {
    case Intrinsic::amdgcn_frexp_mant:
    case Intrinsic::amdgcn_log:
    case Intrinsic::amdgcn_log_clamp:
    case Intrinsic::amdgcn_exp2:
    case Intrinsic::amdgcn_sqrt:
      return true;
    default:
      break;
    }

    break;
  }
  case TargetOpcode::G_FSQRT:
    return true;
  case TargetOpcode::G_FFREXP: {
    if (DefMI->getOperand(0).getReg() == Src)
      return true;
    break;
  }
  case TargetOpcode::G_FPEXT: {
    return MRI.getType(DefMI->getOperand(1).getReg()) == F16;
  }
  default:
    return false;
  }

  return false;
}

static bool allowApproxFunc(const MachineFunction &MF, unsigned Flags) {
  return Flags & MachineInstr::FmAfn;
}

static bool needsDenormHandlingF32(const MachineFunction &MF, Register Src,
                                   unsigned Flags) {
  return !valueIsKnownNeverF32Denorm(MF.getRegInfo(), Src) &&
         MF.getDenormalMode(APFloat::IEEEsingle()).Input !=
             DenormalMode::PreserveSign;
}

std::pair<Register, Register>
AMDGPULegalizerInfo::getScaledLogInput(MachineIRBuilder &B, Register Src,
                                       unsigned Flags) const {
  if (!needsDenormHandlingF32(B.getMF(), Src, Flags))
    return {};

  auto SmallestNormal = B.buildFConstant(
      F32, APFloat::getSmallestNormalized(APFloat::IEEEsingle()));
  auto IsLtSmallestNormal =
      B.buildFCmp(CmpInst::FCMP_OLT, LLT::scalar(1), Src, SmallestNormal);

  auto Scale32 = B.buildFConstant(F32, 0x1.0p+32);
  auto One = B.buildFConstant(F32, 1.0);
  auto ScaleFactor =
      B.buildSelect(F32, IsLtSmallestNormal, Scale32, One, Flags);
  auto ScaledInput = B.buildFMul(F32, Src, ScaleFactor, Flags);

  return {ScaledInput.getReg(0), IsLtSmallestNormal.getReg(0)};
}

bool AMDGPULegalizerInfo::legalizeFlog2(MachineInstr &MI,
                                        MachineIRBuilder &B) const {
  // v_log_f32 is good enough for OpenCL, except it doesn't handle denormals.
  // If we have to handle denormals, scale up the input and adjust the result.

  // scaled = x * (is_denormal ? 0x1.0p+32 : 1.0)
  // log2 = amdgpu_log2 - (is_denormal ? 32.0 : 0.0)

  Register Dst = MI.getOperand(0).getReg();
  Register Src = MI.getOperand(1).getReg();
  LLT Ty = B.getMRI()->getType(Dst);
  unsigned Flags = MI.getFlags();

  if (Ty == F16) {
    // Nothing in half is a denormal when promoted to f32.
    auto Ext = B.buildFPExt(F32, Src, Flags);
    auto Log2 = B.buildIntrinsic(Intrinsic::amdgcn_log, {F32})
                    .addUse(Ext.getReg(0))
                    .setMIFlags(Flags);
    B.buildFPTrunc(Dst, Log2, Flags);
    MI.eraseFromParent();
    return true;
  }

  assert(Ty == F32);

  auto [ScaledInput, IsLtSmallestNormal] = getScaledLogInput(B, Src, Flags);
  if (!ScaledInput) {
    B.buildIntrinsic(Intrinsic::amdgcn_log, {MI.getOperand(0)})
        .addUse(Src)
        .setMIFlags(Flags);
    MI.eraseFromParent();
    return true;
  }

  auto Log2 = B.buildIntrinsic(Intrinsic::amdgcn_log, {Ty})
                  .addUse(ScaledInput)
                  .setMIFlags(Flags);

  auto ThirtyTwo = B.buildFConstant(Ty, 32.0);
  auto Zero = B.buildFConstant(Ty, 0.0);
  auto ResultOffset =
      B.buildSelect(Ty, IsLtSmallestNormal, ThirtyTwo, Zero, Flags);
  B.buildFSub(Dst, Log2, ResultOffset, Flags);

  MI.eraseFromParent();
  return true;
}

static Register getMad(MachineIRBuilder &B, LLT Ty, Register X, Register Y,
                       Register Z, unsigned Flags) {
  auto FMul = B.buildFMul(Ty, X, Y, Flags);
  return B.buildFAdd(Ty, FMul, Z, Flags).getReg(0);
}

bool AMDGPULegalizerInfo::legalizeFlogCommon(MachineInstr &MI,
                                             MachineIRBuilder &B) const {
  const bool IsLog10 = MI.getOpcode() == TargetOpcode::G_FLOG10;
  assert(IsLog10 || MI.getOpcode() == TargetOpcode::G_FLOG);

  MachineRegisterInfo &MRI = *B.getMRI();
  Register Dst = MI.getOperand(0).getReg();
  Register X = MI.getOperand(1).getReg();
  unsigned Flags = MI.getFlags();
  const LLT Ty = MRI.getType(X);

  if (Ty == F16 || MI.getFlag(MachineInstr::FmAfn)) {
    // TODO: The direct f16 path is 1.79 ulp for f16. This should be used
    // depending on !fpmath metadata.
    bool PromoteToF32 =
        Ty == F16 && (!MI.getFlag(MachineInstr::FmAfn) || !ST.has16BitInsts());
    if (PromoteToF32) {
      Register LogVal = MRI.createGenericVirtualRegister(F32);
      auto PromoteSrc = B.buildFPExt(F32, X, Flags);
      legalizeFlogUnsafe(B, LogVal, PromoteSrc.getReg(0), IsLog10, Flags);
      B.buildFPTrunc(Dst, LogVal, Flags);
    } else {
      legalizeFlogUnsafe(B, Dst, X, IsLog10, Flags);
    }

    MI.eraseFromParent();
    return true;
  }

  auto [ScaledInput, IsScaled] = getScaledLogInput(B, X, Flags);
  if (ScaledInput)
    X = ScaledInput;

  auto Y =
      B.buildIntrinsic(Intrinsic::amdgcn_log, {Ty}).addUse(X).setMIFlags(Flags);

  Register R;
  if (ST.hasFastFMAF32()) {
    // c+cc are ln(2)/ln(10) to more than 49 bits
    const float c_log10 = 0x1.344134p-2f;
    const float cc_log10 = 0x1.09f79ep-26f;

    // c + cc is ln(2) to more than 49 bits
    const float c_log = 0x1.62e42ep-1f;
    const float cc_log = 0x1.efa39ep-25f;

    auto C = B.buildFConstant(Ty, IsLog10 ? c_log10 : c_log);
    auto CC = B.buildFConstant(Ty, IsLog10 ? cc_log10 : cc_log);
    // This adds correction terms for which contraction may lead to an increase
    // in the error of the approximation, so disable it.
    auto NewFlags = Flags & ~(MachineInstr::FmContract);
    R = B.buildFMul(Ty, Y, C, NewFlags).getReg(0);
    auto NegR = B.buildFNeg(Ty, R, NewFlags);
    auto FMA0 = B.buildFMA(Ty, Y, C, NegR, NewFlags);
    auto FMA1 = B.buildFMA(Ty, Y, CC, FMA0, NewFlags);
    R = B.buildFAdd(Ty, R, FMA1, NewFlags).getReg(0);
  } else {
    // ch+ct is ln(2)/ln(10) to more than 36 bits
    const float ch_log10 = 0x1.344000p-2f;
    const float ct_log10 = 0x1.3509f6p-18f;

    // ch + ct is ln(2) to more than 36 bits
    const float ch_log = 0x1.62e000p-1f;
    const float ct_log = 0x1.0bfbe8p-15f;

    auto CH = B.buildFConstant(Ty, IsLog10 ? ch_log10 : ch_log);
    auto CT = B.buildFConstant(Ty, IsLog10 ? ct_log10 : ct_log);

    const LLT I32 = LLT::integer(32);
    auto YInt = B.buildBitcast(I32, Y);
    auto MaskConst = B.buildConstant(I32, 0xfffff000);
    auto YH = B.buildBitcast(Ty, B.buildAnd(I32, YInt, MaskConst));
    auto YT = B.buildFSub(Ty, Y, YH, Flags);
    // This adds correction terms for which contraction may lead to an increase
    // in the error of the approximation, so disable it.
    auto NewFlags = Flags & ~(MachineInstr::FmContract);
    auto YTCT = B.buildFMul(Ty, YT, CT, NewFlags);

    Register Mad0 =
        getMad(B, Ty, YH.getReg(0), CT.getReg(0), YTCT.getReg(0), NewFlags);
    Register Mad1 = getMad(B, Ty, YT.getReg(0), CH.getReg(0), Mad0, NewFlags);
    R = getMad(B, Ty, YH.getReg(0), CH.getReg(0), Mad1, NewFlags);
  }

  const bool IsFiniteOnly =
      MI.getFlag(MachineInstr::FmNoNans) && MI.getFlag(MachineInstr::FmNoInfs);

  if (!IsFiniteOnly) {
    // Expand isfinite(x) => fabs(x) < inf
    auto Inf = B.buildFConstant(Ty, APFloat::getInf(APFloat::IEEEsingle()));
    auto Fabs = B.buildFAbs(Ty, Y);
    auto IsFinite =
        B.buildFCmp(CmpInst::FCMP_OLT, LLT::scalar(1), Fabs, Inf, Flags);
    R = B.buildSelect(Ty, IsFinite, R, Y, Flags).getReg(0);
  }

  if (ScaledInput) {
    auto Zero = B.buildFConstant(Ty, 0.0);
    auto ShiftK =
        B.buildFConstant(Ty, IsLog10 ? 0x1.344136p+3f : 0x1.62e430p+4f);
    auto Shift = B.buildSelect(Ty, IsScaled, ShiftK, Zero, Flags);
    B.buildFSub(Dst, R, Shift, Flags);
  } else {
    B.buildCopy(Dst, R);
  }

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFlogUnsafe(MachineIRBuilder &B, Register Dst,
                                             Register Src, bool IsLog10,
                                             unsigned Flags) const {
  const double Log2BaseInverted =
      IsLog10 ? numbers::ln2 / numbers::ln10 : numbers::ln2;

  LLT Ty = B.getMRI()->getType(Dst);

  if (Ty == F32) {
    auto [ScaledInput, IsScaled] = getScaledLogInput(B, Src, Flags);
    if (ScaledInput) {
      auto LogSrc = B.buildIntrinsic(Intrinsic::amdgcn_log, {Ty})
                        .addUse(ScaledInput)
                        .setMIFlags(Flags);
      auto ScaledResultOffset = B.buildFConstant(Ty, -32.0 * Log2BaseInverted);
      auto Zero = B.buildFConstant(Ty, 0.0);
      auto ResultOffset =
          B.buildSelect(Ty, IsScaled, ScaledResultOffset, Zero, Flags);
      auto Log2Inv = B.buildFConstant(Ty, Log2BaseInverted);

      if (ST.hasFastFMAF32())
        B.buildFMA(Dst, LogSrc, Log2Inv, ResultOffset, Flags);
      else {
        auto Mul = B.buildFMul(Ty, LogSrc, Log2Inv, Flags);
        B.buildFAdd(Dst, Mul, ResultOffset, Flags);
      }

      return true;
    }
  }

  auto Log2Operand = Ty == F16 ? B.buildFLog2(Ty, Src, Flags)
                               : B.buildIntrinsic(Intrinsic::amdgcn_log, {Ty})
                                     .addUse(Src)
                                     .setMIFlags(Flags);
  auto Log2BaseInvertedOperand = B.buildFConstant(Ty, Log2BaseInverted);
  B.buildFMul(Dst, Log2Operand, Log2BaseInvertedOperand, Flags);
  return true;
}

bool AMDGPULegalizerInfo::legalizeFExp2(MachineInstr &MI,
                                        MachineIRBuilder &B) const {
  // v_exp_f32 is good enough for OpenCL, except it doesn't handle denormals.
  // If we have to handle denormals, scale up the input and adjust the result.

  Register Dst = MI.getOperand(0).getReg();
  Register Src = MI.getOperand(1).getReg();
  unsigned Flags = MI.getFlags();
  LLT Ty = B.getMRI()->getType(Dst);

  if (Ty == F64)
    return legalizeFEXPF64(MI, B);

  if (Ty == F16) {
    // Nothing in half is a denormal when promoted to f32.
    auto Ext = B.buildFPExt(F32, Src, Flags);
    auto Log2 = B.buildIntrinsic(Intrinsic::amdgcn_exp2, {F32})
                    .addUse(Ext.getReg(0))
                    .setMIFlags(Flags);
    B.buildFPTrunc(Dst, Log2, Flags);
    MI.eraseFromParent();
    return true;
  }

  assert(Ty == F32);

  if (!needsDenormHandlingF32(B.getMF(), Src, Flags)) {
    B.buildIntrinsic(Intrinsic::amdgcn_exp2, ArrayRef<Register>{Dst})
        .addUse(Src)
        .setMIFlags(Flags);
    MI.eraseFromParent();
    return true;
  }

  // bool needs_scaling = x < -0x1.f80000p+6f;
  // v_exp_f32(x + (s ? 0x1.0p+6f : 0.0f)) * (s ? 0x1.0p-64f : 1.0f);

  // -nextafter(128.0, -1)
  auto RangeCheckConst = B.buildFConstant(Ty, -0x1.f80000p+6f);
  auto NeedsScaling = B.buildFCmp(CmpInst::FCMP_OLT, LLT::scalar(1), Src,
                                  RangeCheckConst, Flags);

  auto SixtyFour = B.buildFConstant(Ty, 0x1.0p+6f);
  auto Zero = B.buildFConstant(Ty, 0.0);
  auto AddOffset = B.buildSelect(F32, NeedsScaling, SixtyFour, Zero, Flags);
  auto AddInput = B.buildFAdd(F32, Src, AddOffset, Flags);

  auto Exp2 = B.buildIntrinsic(Intrinsic::amdgcn_exp2, {Ty})
                  .addUse(AddInput.getReg(0))
                  .setMIFlags(Flags);

  auto TwoExpNeg64 = B.buildFConstant(Ty, 0x1.0p-64f);
  auto One = B.buildFConstant(Ty, 1.0);
  auto ResultScale = B.buildSelect(F32, NeedsScaling, TwoExpNeg64, One, Flags);
  B.buildFMul(Dst, Exp2, ResultScale, Flags);
  MI.eraseFromParent();
  return true;
}

static MachineInstrBuilder buildExp(MachineIRBuilder &B, const DstOp &Dst,
                                    const SrcOp &Src, unsigned Flags) {
  LLT Ty = Dst.getLLTTy(*B.getMRI());

  if (Ty == F32) {
    return B.buildIntrinsic(Intrinsic::amdgcn_exp2, {Dst})
        .addUse(Src.getReg())
        .setMIFlags(Flags);
  }
  return B.buildFExp2(Dst, Src, Flags);
}

bool AMDGPULegalizerInfo::legalizeFExpUnsafeImpl(MachineIRBuilder &B,
                                                 Register Dst, Register X,
                                                 unsigned Flags,
                                                 bool IsExp10) const {
  LLT Ty = B.getMRI()->getType(X);

  // exp(x) -> exp2(M_LOG2E_F * x);
  // exp10(x) -> exp2(log2(10) * x);
  auto Const = B.buildFConstant(Ty, IsExp10 ? 0x1.a934f0p+1f : numbers::log2e);
  auto Mul = B.buildFMul(Ty, X, Const, Flags);
  buildExp(B, Dst, Mul, Flags);
  return true;
}

bool AMDGPULegalizerInfo::legalizeFExpUnsafe(MachineIRBuilder &B, Register Dst,
                                             Register X, unsigned Flags) const {
  LLT Ty = B.getMRI()->getType(Dst);

  if (Ty != F32 || !needsDenormHandlingF32(B.getMF(), X, Flags)) {
    return legalizeFExpUnsafeImpl(B, Dst, X, Flags, /*IsExp10=*/false);
  }

  auto Threshold = B.buildFConstant(Ty, -0x1.5d58a0p+6f);
  auto NeedsScaling =
      B.buildFCmp(CmpInst::FCMP_OLT, LLT::scalar(1), X, Threshold, Flags);
  auto ScaleOffset = B.buildFConstant(Ty, 0x1.0p+6f);
  auto ScaledX = B.buildFAdd(Ty, X, ScaleOffset, Flags);
  auto AdjustedX = B.buildSelect(Ty, NeedsScaling, ScaledX, X, Flags);

  auto Log2E = B.buildFConstant(Ty, numbers::log2e);
  auto ExpInput = B.buildFMul(Ty, AdjustedX, Log2E, Flags);

  auto Exp2 = B.buildIntrinsic(Intrinsic::amdgcn_exp2, {Ty})
    .addUse(ExpInput.getReg(0))
    .setMIFlags(Flags);

  auto ResultScaleFactor = B.buildFConstant(Ty, 0x1.969d48p-93f);
  auto AdjustedResult = B.buildFMul(Ty, Exp2, ResultScaleFactor, Flags);
  B.buildSelect(Dst, NeedsScaling, AdjustedResult, Exp2, Flags);
  return true;
}

bool AMDGPULegalizerInfo::legalizeFExp10Unsafe(MachineIRBuilder &B,
                                               Register Dst, Register X,
                                               unsigned Flags) const {
  LLT Ty = B.getMRI()->getType(Dst);

  if (Ty != F32 || !needsDenormHandlingF32(B.getMF(), X, Flags)) {
    // exp2(x * 0x1.a92000p+1f) * exp2(x * 0x1.4f0978p-11f);
    auto K0 = B.buildFConstant(Ty, 0x1.a92000p+1f);
    auto K1 = B.buildFConstant(Ty, 0x1.4f0978p-11f);

    auto Mul1 = B.buildFMul(Ty, X, K1, Flags);
    auto Exp2_1 = buildExp(B, Ty, Mul1, Flags);
    auto Mul0 = B.buildFMul(Ty, X, K0, Flags);
    auto Exp2_0 = buildExp(B, Ty, Mul0, Flags);
    B.buildFMul(Dst, Exp2_0, Exp2_1, Flags);
    return true;
  }

  // bool s = x < -0x1.2f7030p+5f;
  // x += s ? 0x1.0p+5f : 0.0f;
  // exp10 = exp2(x * 0x1.a92000p+1f) *
  //        exp2(x * 0x1.4f0978p-11f) *
  //        (s ? 0x1.9f623ep-107f : 1.0f);

  auto Threshold = B.buildFConstant(Ty, -0x1.2f7030p+5f);
  auto NeedsScaling =
      B.buildFCmp(CmpInst::FCMP_OLT, LLT::scalar(1), X, Threshold);

  auto ScaleOffset = B.buildFConstant(Ty, 0x1.0p+5f);
  auto ScaledX = B.buildFAdd(Ty, X, ScaleOffset, Flags);
  auto AdjustedX = B.buildSelect(Ty, NeedsScaling, ScaledX, X);

  auto K0 = B.buildFConstant(Ty, 0x1.a92000p+1f);
  auto K1 = B.buildFConstant(Ty, 0x1.4f0978p-11f);

  auto Mul1 = B.buildFMul(Ty, AdjustedX, K1, Flags);
  auto Exp2_1 = buildExp(B, Ty, Mul1, Flags);
  auto Mul0 = B.buildFMul(Ty, AdjustedX, K0, Flags);
  auto Exp2_0 = buildExp(B, Ty, Mul0, Flags);

  auto MulExps = B.buildFMul(Ty, Exp2_0, Exp2_1, Flags);
  auto ResultScaleFactor = B.buildFConstant(Ty, 0x1.9f623ep-107f);
  auto AdjustedResult = B.buildFMul(Ty, MulExps, ResultScaleFactor, Flags);

  B.buildSelect(Dst, NeedsScaling, AdjustedResult, MulExps);
  return true;
}

// This expansion gives a result slightly better than 1ulp.
bool AMDGPULegalizerInfo::legalizeFEXPF64(MachineInstr &MI,
                                          MachineIRBuilder &B) const {

  Register X = MI.getOperand(1).getReg();
  LLT I32 = LLT::integer(32);
  LLT S1 = LLT::scalar(1);

  // TODO: Check if reassoc is safe. There is an output change in exp2 and
  // exp10, which slightly increases ulp.
  unsigned Flags = MI.getFlags() & ~MachineInstr::FmReassoc;

  Register Dn, F, T;

  if (MI.getOpcode() == TargetOpcode::G_FEXP2) {
    // Dn = rint(X)
    Dn = B.buildFRint(F64, X, Flags).getReg(0);
    // F = X - Dn
    F = B.buildFSub(F64, X, Dn, Flags).getReg(0);
    // T = F*C1 + F*C2
    auto C1 = B.buildFConstant(F64, APFloat(0x1.62e42fefa39efp-1));
    auto C2 = B.buildFConstant(F64, APFloat(0x1.abc9e3b39803fp-56));
    auto Mul2 = B.buildFMul(F64, F, C2, Flags).getReg(0);
    T = B.buildFMA(F64, F, C1, Mul2, Flags).getReg(0);

  } else if (MI.getOpcode() == TargetOpcode::G_FEXP10) {
    auto C1 = B.buildFConstant(F64, APFloat(0x1.a934f0979a371p+1));
    auto Mul = B.buildFMul(F64, X, C1, Flags).getReg(0);
    Dn = B.buildFRint(F64, Mul, Flags).getReg(0);

    auto NegDn = B.buildFNeg(F64, Dn, Flags).getReg(0);
    auto C2 = B.buildFConstant(F64, APFloat(-0x1.9dc1da994fd21p-59));
    auto C3 = B.buildFConstant(F64, APFloat(0x1.34413509f79ffp-2));
    auto Inner = B.buildFMA(F64, NegDn, C3, X, Flags).getReg(0);
    F = B.buildFMA(F64, NegDn, C2, Inner, Flags).getReg(0);

    auto C4 = B.buildFConstant(F64, APFloat(0x1.26bb1bbb55516p+1));
    auto C5 = B.buildFConstant(F64, APFloat(-0x1.f48ad494ea3e9p-53));
    auto MulF = B.buildFMul(F64, F, C5, Flags).getReg(0);
    T = B.buildFMA(F64, F, C4, MulF, Flags).getReg(0);

  } else { // G_FEXP
    auto C1 = B.buildFConstant(F64, APFloat(0x1.71547652b82fep+0));
    auto Mul = B.buildFMul(F64, X, C1, Flags).getReg(0);
    Dn = B.buildFRint(F64, Mul, Flags).getReg(0);

    auto NegDn = B.buildFNeg(F64, Dn, Flags).getReg(0);
    auto C2 = B.buildFConstant(F64, APFloat(0x1.abc9e3b39803fp-56));
    auto C3 = B.buildFConstant(F64, APFloat(0x1.62e42fefa39efp-1));
    auto Inner = B.buildFMA(F64, NegDn, C3, X, Flags).getReg(0);
    T = B.buildFMA(F64, NegDn, C2, Inner, Flags).getReg(0);
  }

  // Polynomial chain for P
  auto P = B.buildFConstant(F64, 0x1.ade156a5dcb37p-26);
  P = B.buildFMA(F64, T, P, B.buildFConstant(F64, 0x1.28af3fca7ab0cp-22),
                 Flags);
  P = B.buildFMA(F64, T, P, B.buildFConstant(F64, 0x1.71dee623fde64p-19),
                 Flags);
  P = B.buildFMA(F64, T, P, B.buildFConstant(F64, 0x1.a01997c89e6b0p-16),
                 Flags);
  P = B.buildFMA(F64, T, P, B.buildFConstant(F64, 0x1.a01a014761f6ep-13),
                 Flags);
  P = B.buildFMA(F64, T, P, B.buildFConstant(F64, 0x1.6c16c1852b7b0p-10),
                 Flags);
  P = B.buildFMA(F64, T, P, B.buildFConstant(F64, 0x1.1111111122322p-7), Flags);
  P = B.buildFMA(F64, T, P, B.buildFConstant(F64, 0x1.55555555502a1p-5), Flags);
  P = B.buildFMA(F64, T, P, B.buildFConstant(F64, 0x1.5555555555511p-3), Flags);
  P = B.buildFMA(F64, T, P, B.buildFConstant(F64, 0x1.000000000000bp-1), Flags);

  auto One = B.buildFConstant(F64, 1.0);
  P = B.buildFMA(F64, T, P, One, Flags);
  P = B.buildFMA(F64, T, P, One, Flags);

  // Z = FLDEXP(P, (int)Dn)
  auto DnInt = B.buildFPTOSI(I32, Dn);
  auto Z = B.buildFLdexp(F64, P, DnInt, Flags);

  if (!(Flags & MachineInstr::FmNoInfs)) {
    // Overflow guard: if X <= 1024.0 then Z else +inf
    auto CondHi = B.buildFCmp(CmpInst::FCMP_ULE, S1, X,
                              B.buildFConstant(F64, APFloat(1024.0)));
    auto PInf = B.buildFConstant(F64, APFloat::getInf(APFloat::IEEEdouble()));
    Z = B.buildSelect(F64, CondHi, Z, PInf, Flags);
  }

  // Underflow guard: if X >= -1075.0 then Z else 0.0
  auto CondLo = B.buildFCmp(CmpInst::FCMP_UGE, S1, X,
                            B.buildFConstant(F64, APFloat(-1075.0)));
  auto Zero = B.buildFConstant(F64, APFloat(0.0));
  B.buildSelect(MI.getOperand(0).getReg(), CondLo, Z, Zero, Flags);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFExp(MachineInstr &MI,
                                       MachineIRBuilder &B) const {
  Register Dst = MI.getOperand(0).getReg();
  Register X = MI.getOperand(1).getReg();
  const unsigned Flags = MI.getFlags();
  MachineFunction &MF = B.getMF();
  MachineRegisterInfo &MRI = *B.getMRI();
  LLT Ty = MRI.getType(Dst);

  if (Ty == F64)
    return legalizeFEXPF64(MI, B);

  const bool IsExp10 = MI.getOpcode() == TargetOpcode::G_FEXP10;

  if (Ty == F16) {
    // v_exp_f16 (fmul x, log2e)
    if (allowApproxFunc(MF, Flags)) {
      // TODO: Does this really require fast?
      IsExp10 ? legalizeFExp10Unsafe(B, Dst, X, Flags)
              : legalizeFExpUnsafe(B, Dst, X, Flags);
      MI.eraseFromParent();
      return true;
    }

    // Nothing in half is a denormal when promoted to f32.
    //
    // exp(f16 x) ->
    //   fptrunc (v_exp_f32 (fmul (fpext x), log2e))
    //
    // exp10(f16 x) ->
    //   fptrunc (v_exp_f32 (fmul (fpext x), log2(10)))
    auto Ext = B.buildFPExt(F32, X, Flags);
    Register Lowered = MRI.createGenericVirtualRegister(F32);
    legalizeFExpUnsafeImpl(B, Lowered, Ext.getReg(0), Flags, IsExp10);
    B.buildFPTrunc(Dst, Lowered, Flags);
    MI.eraseFromParent();
    return true;
  }

  assert(Ty == F32);

  // TODO: Interpret allowApproxFunc as ignoring DAZ. This is currently copying
  // library behavior. Also, is known-not-daz source sufficient?
  if (allowApproxFunc(MF, Flags)) {
    IsExp10 ? legalizeFExp10Unsafe(B, Dst, X, Flags)
            : legalizeFExpUnsafe(B, Dst, X, Flags);
    MI.eraseFromParent();
    return true;
  }

  //    Algorithm:
  //
  //    e^x = 2^(x/ln(2)) = 2^(x*(64/ln(2))/64)
  //
  //    x*(64/ln(2)) = n + f, |f| <= 0.5, n is integer
  //    n = 64*m + j,   0 <= j < 64
  //
  //    e^x = 2^((64*m + j + f)/64)
  //        = (2^m) * (2^(j/64)) * 2^(f/64)
  //        = (2^m) * (2^(j/64)) * e^(f*(ln(2)/64))
  //
  //    f = x*(64/ln(2)) - n
  //    r = f*(ln(2)/64) = x - n*(ln(2)/64)
  //
  //    e^x = (2^m) * (2^(j/64)) * e^r
  //
  //    (2^(j/64)) is precomputed
  //
  //    e^r = 1 + r + (r^2)/2! + (r^3)/3! + (r^4)/4! + (r^5)/5!
  //    e^r = 1 + q
  //
  //    q = r + (r^2)/2! + (r^3)/3! + (r^4)/4! + (r^5)/5!
  //
  //    e^x = (2^m) * ( (2^(j/64)) + q*(2^(j/64)) )
  const unsigned FlagsNoContract = Flags & ~MachineInstr::FmContract;
  Register PH, PL;

  if (ST.hasFastFMAF32()) {
    const float c_exp = numbers::log2ef;
    const float cc_exp = 0x1.4ae0bep-26f; // c+cc are 49 bits
    const float c_exp10 = 0x1.a934f0p+1f;
    const float cc_exp10 = 0x1.2f346ep-24f;

    auto C = B.buildFConstant(Ty, IsExp10 ? c_exp10 : c_exp);
    PH = B.buildFMul(Ty, X, C, Flags).getReg(0);
    auto NegPH = B.buildFNeg(Ty, PH, Flags);
    auto FMA0 = B.buildFMA(Ty, X, C, NegPH, Flags);

    auto CC = B.buildFConstant(Ty, IsExp10 ? cc_exp10 : cc_exp);
    PL = B.buildFMA(Ty, X, CC, FMA0, Flags).getReg(0);
  } else {
    const float ch_exp = 0x1.714000p+0f;
    const float cl_exp = 0x1.47652ap-12f; // ch + cl are 36 bits

    const float ch_exp10 = 0x1.a92000p+1f;
    const float cl_exp10 = 0x1.4f0978p-11f;

    const LLT I32 = LLT::integer(32);
    auto XInt = B.buildBitcast(I32, X);
    auto MaskConst = B.buildConstant(I32, 0xfffff000);
    auto XH = B.buildBitcast(Ty, B.buildAnd(I32, XInt, MaskConst));
    auto XL = B.buildFSub(Ty, X, XH, Flags);

    auto CH = B.buildFConstant(Ty, IsExp10 ? ch_exp10 : ch_exp);
    PH = B.buildFMul(Ty, XH, CH, Flags).getReg(0);

    auto CL = B.buildFConstant(Ty, IsExp10 ? cl_exp10 : cl_exp);
    auto XLCL = B.buildFMul(Ty, XL, CL, Flags);

    Register Mad0 =
        getMad(B, Ty, XL.getReg(0), CH.getReg(0), XLCL.getReg(0), Flags);
    PL = getMad(B, Ty, XH.getReg(0), CL.getReg(0), Mad0, Flags);
  }

  auto E = B.buildIntrinsicRoundeven(Ty, PH, Flags);

  // It is unsafe to contract this fsub into the PH multiply.
  auto PHSubE = B.buildFSub(Ty, PH, E, FlagsNoContract);
  auto A = B.buildFAdd(Ty, PHSubE, PL, Flags);
  const LLT I32 = LLT::integer(32);
  auto IntE = B.buildFPTOSI(I32, E);

  auto Exp2 = B.buildIntrinsic(Intrinsic::amdgcn_exp2, {Ty})
                  .addUse(A.getReg(0))
                  .setMIFlags(Flags);
  auto R = B.buildFLdexp(Ty, Exp2, IntE, Flags);

  auto UnderflowCheckConst =
      B.buildFConstant(Ty, IsExp10 ? -0x1.66d3e8p+5f : -0x1.9d1da0p+6f);
  auto Zero = B.buildFConstant(Ty, 0.0);
  auto Underflow =
      B.buildFCmp(CmpInst::FCMP_OLT, LLT::scalar(1), X, UnderflowCheckConst);

  R = B.buildSelect(Ty, Underflow, Zero, R);

  if (!(Flags & MachineInstr::FmNoInfs)) {
    auto OverflowCheckConst =
        B.buildFConstant(Ty, IsExp10 ? 0x1.344136p+5f : 0x1.62e430p+6f);

    auto Overflow =
        B.buildFCmp(CmpInst::FCMP_OGT, LLT::scalar(1), X, OverflowCheckConst);
    auto Inf = B.buildFConstant(Ty, APFloat::getInf(APFloat::IEEEsingle()));
    R = B.buildSelect(Ty, Overflow, Inf, R, Flags);
  }

  B.buildCopy(Dst, R);
  MI.eraseFromParent();
  return true;
}

// Keep in sync with AMDGPUTargetLowering::lowerFPOW, which documents this.
bool AMDGPULegalizerInfo::legalizeFPow(LegalizerHelper &Helper,
                                       MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  Register Dst = MI.getOperand(0).getReg();
  Register X = MI.getOperand(1).getReg();
  Register Y = MI.getOperand(2).getReg();
  unsigned Flags = MI.getFlags();
  assert(B.getMRI()->getType(Dst) == F32);

  // log2(0) is -inf, which exp2 turns back into a finite result, so the core
  // goes infinite for inputs a ninf fpow still asserts about, like pow(0, 2).
  unsigned CoreFlags = Flags & ~MachineInstr::FmNoInfs;

  // Fast expansion: ignores denormals, NaN for a negative base.
  if (allowApproxFunc(B.getMF(), Flags)) {
    auto Log = B.buildIntrinsic(Intrinsic::amdgcn_log, {F32})
                   .addUse(X)
                   .setMIFlags(CoreFlags);
    auto Mul = B.buildIntrinsic(Intrinsic::amdgcn_fmul_legacy, {F32})
                   .addUse(Y)
                   .addUse(Log.getReg(0))
                   .setMIFlags(CoreFlags);
    buildExp(B, Dst, Mul.getReg(0), CoreFlags);
    MI.eraseFromParent();
    return true;
  }

  auto Abs = B.buildFAbs(F32, X, Flags);
  auto Log = B.buildFLog2(F32, Abs, CoreFlags);
  auto Mul = B.buildIntrinsic(Intrinsic::amdgcn_fmul_legacy, {F32})
                 .addUse(Y)
                 .addUse(Log.getReg(0))
                 .setMIFlags(CoreFlags);

  // A base that is never negative needs neither the sign fixup nor the NaN.
  if (Helper.getValueTracking()
          ->computeKnownFPClass(X, Flags, fcNegative, 0)
          .signBitIsZeroOrNaN()) {
    B.buildFExp2(Dst, Mul, CoreFlags);
    MI.eraseFromParent();
    return true;
  }

  Register R = B.buildFExp2(F32, Mul, CoreFlags).getReg(0);

  auto YTrunc = B.buildIntrinsicTrunc(F32, Y);
  auto YIsInt = B.buildFCmp(CmpInst::FCMP_OEQ, S1, YTrunc, Y);
  auto YHalf = B.buildFMul(F32, Y, B.buildFConstant(F32, 0.5));
  auto YHalfTrunc = B.buildIntrinsicTrunc(F32, YHalf);
  auto YIsOdd = B.buildAnd(
      S1, YIsInt, B.buildFCmp(CmpInst::FCMP_ONE, S1, YHalfTrunc, YHalf));

  // pow(-x, odd y) = -pow(x, y). Selecting the copysign lets even y fold it.
  auto Neg = B.buildFCopysign(F32, R, X);
  if (Flags & MachineInstr::FmNoNans) {
    B.buildSelect(Dst, YIsOdd, Neg, R);
    MI.eraseFromParent();
    return true;
  }
  R = B.buildSelect(F32, YIsOdd, Neg, R).getReg(0);

  // A negative finite base to a non-integral power is NaN. -inf is excluded:
  // the core already gives pow(+inf, y). So are subnormals when flushed.
  FPClassTest NegFiniteMask = fcNegNormal;
  if (!B.getMF().getDenormalMode(APFloat::IEEEsingle()).inputsAreZero())
    NegFiniteMask |= fcNegSubnormal;
  auto XNegFinite = B.buildIsFPClass(S1, X, NegFiniteMask);
  // Not an ONE compare: pow(-1, NaN) needs the NaN-true behavior of !OEQ.
  auto NegNonInt = B.buildAnd(S1, XNegFinite, B.buildNot(S1, YIsInt));
  auto NaN = B.buildFConstant(F32, APFloat::getQNaN(APFloat::IEEEsingle()));
  B.buildSelect(Dst, NegNonInt, NaN, R);

  MI.eraseFromParent();
  return true;
}

// Find a source register, ignoring any possible source modifiers.
static Register stripAnySourceMods(Register OrigSrc, MachineRegisterInfo &MRI) {
  Register ModSrc = OrigSrc;
  if (MachineInstr *SrcFNeg = getOpcodeDef(AMDGPU::G_FNEG, ModSrc, MRI)) {
    ModSrc = SrcFNeg->getOperand(1).getReg();
    if (MachineInstr *SrcFAbs = getOpcodeDef(AMDGPU::G_FABS, ModSrc, MRI))
      ModSrc = SrcFAbs->getOperand(1).getReg();
  } else if (MachineInstr *SrcFAbs = getOpcodeDef(AMDGPU::G_FABS, ModSrc, MRI))
    ModSrc = SrcFAbs->getOperand(1).getReg();
  return ModSrc;
}

bool AMDGPULegalizerInfo::legalizeFFloor(MachineInstr &MI,
                                         MachineRegisterInfo &MRI,
                                         MachineIRBuilder &B) const {

  const LLT S1 = LLT::scalar(1);
  Register Dst = MI.getOperand(0).getReg();
  Register OrigSrc = MI.getOperand(1).getReg();
  unsigned Flags = MI.getFlags();
  assert(ST.hasFractBug() && MRI.getType(Dst) == F64 &&
         "this should not have been custom lowered");

  // V_FRACT is buggy on SI, so the F32 version is never used and (x-floor(x))
  // is used instead. However, SI doesn't have V_FLOOR_F64, so the most
  // efficient way to implement it is using V_FRACT_F64. The workaround for the
  // V_FRACT bug is:
  //    fract(x) = isnan(x) ? x : min(V_FRACT(x), 0.99999999999999999)
  //
  // Convert floor(x) to (x - fract(x))

  auto Fract = B.buildIntrinsic(Intrinsic::amdgcn_fract, {F64})
                   .addUse(OrigSrc)
                   .setMIFlags(Flags);

  // Give source modifier matching some assistance before obscuring a foldable
  // pattern.

  // TODO: We can avoid the neg on the fract? The input sign to fract
  // shouldn't matter?
  Register ModSrc = stripAnySourceMods(OrigSrc, MRI);

  auto Const =
      B.buildFConstant(F64, llvm::bit_cast<double>(0x3fefffffffffffff));

  Register Min = MRI.createGenericVirtualRegister(F64);

  // We don't need to concern ourselves with the snan handling difference, so
  // use the one which will directly select.
  const SIMachineFunctionInfo *MFI = B.getMF().getInfo<SIMachineFunctionInfo>();
  if (MFI->getMode().IEEE && !ST.hasIEEEMinimumMaximumInsts())
    B.buildFMinNumIEEE(Min, Fract, Const, Flags);
  else
    B.buildFMinNum(Min, Fract, Const, Flags);

  Register CorrectedFract = Min;
  if (!MI.getFlag(MachineInstr::FmNoNans)) {
    auto IsNan = B.buildFCmp(CmpInst::FCMP_ORD, S1, ModSrc, ModSrc, Flags);
    CorrectedFract = B.buildSelect(F64, IsNan, ModSrc, Min, Flags).getReg(0);
  }

  auto NegFract = B.buildFNeg(F64, CorrectedFract, Flags);
  B.buildFAdd(Dst, OrigSrc, NegFract, Flags);

  MI.eraseFromParent();
  return true;
}

// Turn an illegal packed v2i16/v2f16 build vector into bit operations.
// TODO: This should probably be a bitcast action in LegalizerHelper.
bool AMDGPULegalizerInfo::legalizeBuildVector(
  MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const {
  Register Dst = MI.getOperand(0).getReg();
  const LLT I32 = LLT::integer(32);
  const LLT I16 = LLT::integer(16);
  assert(MRI.getType(Dst).isVector() &&
         MRI.getType(Dst).getNumElements() == 2 &&
         MRI.getType(Dst).getScalarSizeInBits() == 16);

  Register Src0 = MI.getOperand(1).getReg();
  Register Src1 = MI.getOperand(2).getReg();

  if (MI.getOpcode() == AMDGPU::G_BUILD_VECTOR_TRUNC) {
    assert(MRI.getType(Src0) == I32);
    Src0 = B.buildTrunc(I16, MI.getOperand(1).getReg()).getReg(0);
    Src1 = B.buildTrunc(I16, MI.getOperand(2).getReg()).getReg(0);
  }

  auto Merge = B.buildMergeLikeInstr(I32, {Src0, Src1});
  B.buildBitcast(Dst, Merge);

  MI.eraseFromParent();
  return true;
}

// Build a big integer multiply or multiply-add using MAD_64_32 instructions.
//
// Source and accumulation registers must all be 32-bits.
//
// TODO: When the multiply is uniform, we should produce a code sequence
// that is better suited to instruction selection on the SALU. Instead of
// the outer loop going over parts of the result, the outer loop should go
// over parts of one of the factors. This should result in instruction
// selection that makes full use of S_ADDC_U32 instructions.
void AMDGPULegalizerInfo::buildMultiply(LegalizerHelper &Helper,
                                        MutableArrayRef<Register> Accum,
                                        ArrayRef<Register> Src0,
                                        ArrayRef<Register> Src1,
                                        bool UsePartialMad64_32,
                                        bool SeparateOddAlignedProducts) const {
  // Use (possibly empty) vectors of S1 registers to represent the set of
  // carries from one pair of positions to the next.
  using Carry = SmallVector<Register, 2>;

  MachineIRBuilder &B = Helper.MIRBuilder;
  GISelValueTracking &VT = *Helper.getValueTracking();

  const LLT S1 = LLT::scalar(1);
  const LLT I32 = LLT::integer(32);
  const LLT I64 = LLT::integer(64);

  Register Zero32;
  Register Zero64;

  auto getZero32 = [&]() -> Register {
    if (!Zero32)
      Zero32 = B.buildConstant(I32, 0).getReg(0);
    return Zero32;
  };
  auto getZero64 = [&]() -> Register {
    if (!Zero64)
      Zero64 = B.buildConstant(I64, 0).getReg(0);
    return Zero64;
  };

  SmallVector<bool, 2> Src0KnownZeros, Src1KnownZeros;
  for (unsigned i = 0; i < Src0.size(); ++i) {
    Src0KnownZeros.push_back(VT.getKnownBits(Src0[i]).isZero());
    Src1KnownZeros.push_back(VT.getKnownBits(Src1[i]).isZero());
  }

  // Merge the given carries into the 32-bit LocalAccum, which is modified
  // in-place.
  //
  // Returns the carry-out, which is a single S1 register or null.
  auto mergeCarry =
      [&](Register &LocalAccum, const Carry &CarryIn) -> Register {
        if (CarryIn.empty())
          return Register();

        bool HaveCarryOut = true;
        Register CarryAccum;
        if (CarryIn.size() == 1) {
          if (!LocalAccum) {
            LocalAccum = B.buildZExt(I32, CarryIn[0]).getReg(0);
            return Register();
          }

          CarryAccum = getZero32();
        } else {
          CarryAccum = B.buildZExt(I32, CarryIn[0]).getReg(0);
          for (unsigned i = 1; i + 1 < CarryIn.size(); ++i) {
            CarryAccum =
                B.buildUAdde(I32, S1, CarryAccum, getZero32(), CarryIn[i])
                    .getReg(0);
          }

          if (!LocalAccum) {
            LocalAccum = getZero32();
            HaveCarryOut = false;
          }
        }

        auto Add =
            B.buildUAdde(I32, S1, CarryAccum, LocalAccum, CarryIn.back());
        LocalAccum = Add.getReg(0);
        return HaveCarryOut ? Add.getReg(1) : Register();
      };

  // Build a multiply-add chain to compute
  //
  //   LocalAccum + (partial products at DstIndex)
  //       + (opportunistic subset of CarryIn)
  //
  // LocalAccum is an array of one or two 32-bit registers that are updated
  // in-place. The incoming registers may be null.
  //
  // In some edge cases, carry-ins can be consumed "for free". In that case,
  // the consumed carry bits are removed from CarryIn in-place.
  auto buildMadChain =
      [&](MutableArrayRef<Register> LocalAccum, unsigned DstIndex, Carry &CarryIn)
          -> Carry {
        assert((DstIndex + 1 < Accum.size() && LocalAccum.size() == 2) ||
               (DstIndex + 1 >= Accum.size() && LocalAccum.size() == 1));

        Carry CarryOut;
        unsigned j0 = 0;

        // Use plain 32-bit multiplication for the most significant part of the
        // result by default.
        if (LocalAccum.size() == 1 &&
            (!UsePartialMad64_32 || !CarryIn.empty())) {
          do {
            // Skip multiplication if one of the operands is 0
            unsigned j1 = DstIndex - j0;
            if (Src0KnownZeros[j0] || Src1KnownZeros[j1]) {
              ++j0;
              continue;
            }
            auto Mul = B.buildMul(I32, Src0[j0], Src1[j1]);
            if (!LocalAccum[0] || VT.getKnownBits(LocalAccum[0]).isZero()) {
              LocalAccum[0] = Mul.getReg(0);
            } else {
              if (CarryIn.empty()) {
                LocalAccum[0] = B.buildAdd(I32, LocalAccum[0], Mul).getReg(0);
              } else {
                LocalAccum[0] =
                    B.buildUAdde(I32, S1, LocalAccum[0], Mul, CarryIn.back())
                        .getReg(0);
                CarryIn.pop_back();
              }
            }
            ++j0;
          } while (j0 <= DstIndex && (!UsePartialMad64_32 || !CarryIn.empty()));
        }

        // Build full 64-bit multiplies.
        if (j0 <= DstIndex) {
          bool HaveSmallAccum = false;
          Register Tmp;

          if (LocalAccum[0]) {
            if (LocalAccum.size() == 1) {
              Tmp = B.buildAnyExt(I64, LocalAccum[0]).getReg(0);
              HaveSmallAccum = true;
            } else if (LocalAccum[1]) {
              Tmp = B.buildMergeLikeInstr(I64, LocalAccum).getReg(0);
              HaveSmallAccum = false;
            } else {
              Tmp = B.buildZExt(I64, LocalAccum[0]).getReg(0);
              HaveSmallAccum = true;
            }
          } else {
            assert(LocalAccum.size() == 1 || !LocalAccum[1]);
            Tmp = getZero64();
            HaveSmallAccum = true;
          }

          do {
            unsigned j1 = DstIndex - j0;
            if (Src0KnownZeros[j0] || Src1KnownZeros[j1]) {
              ++j0;
              continue;
            }
            auto Mad = B.buildInstr(AMDGPU::G_AMDGPU_MAD_U64_U32, {I64, S1},
                                    {Src0[j0], Src1[j1], Tmp});
            Tmp = Mad.getReg(0);
            if (!HaveSmallAccum)
              CarryOut.push_back(Mad.getReg(1));
            HaveSmallAccum = false;

            ++j0;
          } while (j0 <= DstIndex);

          auto Unmerge = B.buildUnmerge(I32, Tmp);
          LocalAccum[0] = Unmerge.getReg(0);
          if (LocalAccum.size() > 1)
            LocalAccum[1] = Unmerge.getReg(1);
        }

        // Every partial product contributing to this destination index was
        // skipped because an operand half is known zero, so nothing has been
        // accumulated and the result is zero.
        if (!LocalAccum[0])
          LocalAccum[0] = getZero32();

        // A second element is only ever requested when the full 64-bit multiply
        // block above runs, which always writes it.
        assert((LocalAccum.size() == 1 || LocalAccum[1]) &&
               "Uninitialized accumulator part");

        return CarryOut;
      };

  // Outer multiply loop, iterating over destination parts from least
  // significant to most significant parts.
  //
  // The columns of the following diagram correspond to the destination parts
  // affected by one iteration of the outer loop (ignoring boundary
  // conditions).
  //
  //   Dest index relative to 2 * i:      1 0 -1
  //                                      ------
  //   Carries from previous iteration:     e o
  //   Even-aligned partial product sum:  E E .
  //   Odd-aligned partial product sum:     O O
  //
  // 'o' is OddCarry, 'e' is EvenCarry.
  // EE and OO are computed from partial products via buildMadChain and use
  // accumulation where possible and appropriate.
  //
  Register SeparateOddCarry;
  Carry EvenCarry;
  Carry OddCarry;

  for (unsigned i = 0; i <= Accum.size() / 2; ++i) {
    Carry OddCarryIn = std::move(OddCarry);
    Carry EvenCarryIn = std::move(EvenCarry);
    OddCarry.clear();
    EvenCarry.clear();

    // Partial products at offset 2 * i.
    if (2 * i < Accum.size()) {
      auto LocalAccum = Accum.drop_front(2 * i).take_front(2);
      EvenCarry = buildMadChain(LocalAccum, 2 * i, EvenCarryIn);
    }

    // Partial products at offset 2 * i - 1.
    if (i > 0) {
      if (!SeparateOddAlignedProducts) {
        auto LocalAccum = Accum.drop_front(2 * i - 1).take_front(2);
        OddCarry = buildMadChain(LocalAccum, 2 * i - 1, OddCarryIn);
      } else {
        bool IsHighest = 2 * i >= Accum.size();
        Register SeparateOddOut[2];
        auto LocalAccum = MutableArrayRef(SeparateOddOut)
                              .take_front(IsHighest ? 1 : 2);
        OddCarry = buildMadChain(LocalAccum, 2 * i - 1, OddCarryIn);

        MachineInstr *Lo;

        if (i == 1) {
          if (!IsHighest)
            Lo = B.buildUAddo(I32, S1, Accum[2 * i - 1], SeparateOddOut[0]);
          else
            Lo = B.buildAdd(I32, Accum[2 * i - 1], SeparateOddOut[0]);
        } else {
          Lo = B.buildUAdde(I32, S1, Accum[2 * i - 1], SeparateOddOut[0],
                            SeparateOddCarry);
        }
        Accum[2 * i - 1] = Lo->getOperand(0).getReg();

        if (!IsHighest) {
          auto Hi = B.buildUAdde(I32, S1, Accum[2 * i], SeparateOddOut[1],
                                 Lo->getOperand(1).getReg());
          Accum[2 * i] = Hi.getReg(0);
          SeparateOddCarry = Hi.getReg(1);
        }
      }
    }

    // Add in the carries from the previous iteration
    if (i > 0) {
      if (Register CarryOut = mergeCarry(Accum[2 * i - 1], OddCarryIn))
        EvenCarryIn.push_back(CarryOut);

      if (2 * i < Accum.size()) {
        if (Register CarryOut = mergeCarry(Accum[2 * i], EvenCarryIn))
          OddCarry.push_back(CarryOut);
      }
    }
  }
}

// Custom narrowing of wide multiplies using wide multiply-add instructions.
//
// TODO: If the multiply is followed by an addition, we should attempt to
// integrate it to make better use of V_MAD_U64_U32's multiply-add capabilities.
bool AMDGPULegalizerInfo::legalizeMul(LegalizerHelper &Helper,
                                      MachineInstr &MI) const {
  assert(ST.hasMad64_32());
  assert(MI.getOpcode() == TargetOpcode::G_MUL);

  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();

  Register DstReg = MI.getOperand(0).getReg();
  Register Src0 = MI.getOperand(1).getReg();
  Register Src1 = MI.getOperand(2).getReg();

  LLT Ty = MRI.getType(DstReg);
  assert(Ty.isScalar());

  unsigned Size = Ty.getSizeInBits();
  if (ST.useVMulU64Inst() && Size == 64)
    return true;

  unsigned NumParts = Size / 32;
  assert((Size % 32) == 0);
  assert(NumParts >= 2);

  // Whether to use MAD_64_32 for partial products whose high half is
  // discarded. This avoids some ADD instructions but risks false dependency
  // stalls on some subtargets in some cases.
  const bool UsePartialMad64_32 = ST.getGeneration() < AMDGPUSubtarget::GFX10;

  // Whether to compute odd-aligned partial products separately. This is
  // advisable on subtargets where the accumulator of MAD_64_32 must be placed
  // in an even-aligned VGPR.
  const bool SeparateOddAlignedProducts = ST.hasFullRate64Ops();

  LLT I32 = LLT::integer(32);
  SmallVector<Register, 2> Src0Parts, Src1Parts;
  for (unsigned i = 0; i < NumParts; ++i) {
    Src0Parts.push_back(MRI.createGenericVirtualRegister(I32));
    Src1Parts.push_back(MRI.createGenericVirtualRegister(I32));
  }
  B.buildUnmerge(Src0Parts, Src0);
  B.buildUnmerge(Src1Parts, Src1);

  SmallVector<Register, 2> AccumRegs(NumParts);
  buildMultiply(Helper, AccumRegs, Src0Parts, Src1Parts, UsePartialMad64_32,
                SeparateOddAlignedProducts);

  B.buildMergeLikeInstr(DstReg, AccumRegs);
  MI.eraseFromParent();
  return true;
}

// Legalize ctlz/cttz to ffbh/ffbl instead of the default legalization to
// ctlz/cttz_zero_poison. This allows us to fix up the result for the zero input
// case with a single min instruction instead of a compare+select.
bool AMDGPULegalizerInfo::legalizeCTLZ_CTTZ(MachineInstr &MI,
                                            MachineRegisterInfo &MRI,
                                            MachineIRBuilder &B) const {
  Register Dst = MI.getOperand(0).getReg();
  Register Src = MI.getOperand(1).getReg();
  LLT DstTy = MRI.getType(Dst);
  LLT SrcTy = MRI.getType(Src);

  unsigned NewOpc = MI.getOpcode() == AMDGPU::G_CTLZ
                        ? AMDGPU::G_AMDGPU_FFBH_U32
                        : AMDGPU::G_AMDGPU_FFBL_B32;
  auto Tmp = B.buildInstr(NewOpc, {DstTy}, {Src});
  B.buildUMin(Dst, Tmp, B.buildConstant(DstTy, SrcTy.getSizeInBits()));

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeCTLZ_ZERO_POISON(MachineInstr &MI,
                                                   MachineRegisterInfo &MRI,
                                                   MachineIRBuilder &B) const {
  Register Dst = MI.getOperand(0).getReg();
  Register Src = MI.getOperand(1).getReg();
  LLT SrcTy = MRI.getType(Src);
  TypeSize NumBits = SrcTy.getSizeInBits();

  assert(NumBits < 32u);

  const LLT I32 = LLT::integer(32);
  auto ShiftAmt = B.buildConstant(I32, 32u - NumBits);
  auto Extend = B.buildAnyExt(I32, {Src}).getReg(0u);
  auto Shift = B.buildShl(I32, Extend, ShiftAmt);
  auto Ctlz = B.buildInstr(AMDGPU::G_AMDGPU_FFBH_U32, {I32}, {Shift});
  B.buildTrunc(Dst, Ctlz);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeCTLS(MachineInstr &MI,
                                       MachineRegisterInfo &MRI,
                                       MachineIRBuilder &B) const {
  Register Dst = MI.getOperand(0).getReg();
  Register Src = MI.getOperand(1).getReg();
  LLT SrcTy = MRI.getType(Src);
  const LLT I32 = LLT::integer(32);
  assert(SrcTy == I32 && "legalizeCTLS only supports i32");
  unsigned BitWidth = SrcTy.getSizeInBits();

  auto Sffbh = B.buildIntrinsic(Intrinsic::amdgcn_sffbh, {I32}).addUse(Src);
  auto Clamped = B.buildUMin(I32, Sffbh, B.buildConstant(I32, BitWidth));
  B.buildSub(Dst, Clamped, B.buildConstant(I32, 1));
  MI.eraseFromParent();
  return true;
}

// Check that this is a G_XOR x, -1
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI) {
  if (MI.getOpcode() != TargetOpcode::G_XOR)
    return false;
  auto ConstVal = getIConstantVRegSExtVal(MI.getOperand(2).getReg(), MRI);
  return ConstVal == -1;
}

// Return the use branch instruction, otherwise null if the usage is invalid.
static MachineInstr *
verifyCFIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI, MachineInstr *&Br,
                  MachineBasicBlock *&UncondBrTarget, bool &Negated) {
  Register CondDef = MI.getOperand(0).getReg();
  if (!MRI.hasOneNonDBGUse(CondDef))
    return nullptr;

  MachineBasicBlock *Parent = MI.getParent();
  MachineInstr *UseMI = &*MRI.use_instr_nodbg_begin(CondDef);

  if (isNot(MRI, *UseMI)) {
    Register NegatedCond = UseMI->getOperand(0).getReg();
    if (!MRI.hasOneNonDBGUse(NegatedCond))
      return nullptr;

    // We're deleting the def of this value, so we need to remove it.
    eraseInstr(*UseMI, MRI);

    UseMI = &*MRI.use_instr_nodbg_begin(NegatedCond);
    Negated = true;
  }

  if (UseMI->getParent() != Parent || UseMI->getOpcode() != AMDGPU::G_BRCOND)
    return nullptr;

  // Make sure the cond br is followed by a G_BR, or is the last instruction.
  MachineBasicBlock::iterator Next = std::next(UseMI->getIterator());
  if (Next == Parent->end()) {
    MachineFunction::iterator NextMBB = std::next(Parent->getIterator());
    if (NextMBB == Parent->getParent()->end()) // Illegal intrinsic use.
      return nullptr;
    UncondBrTarget = &*NextMBB;
  } else {
    if (Next->getOpcode() != AMDGPU::G_BR)
      return nullptr;
    Br = &*Next;
    UncondBrTarget = Br->getOperand(0).getMBB();
  }

  return UseMI;
}

void AMDGPULegalizerInfo::buildLoadInputValue(Register DstReg,
                                              MachineIRBuilder &B,
                                              const ArgDescriptor *Arg,
                                              const TargetRegisterClass *ArgRC,
                                              LLT ArgTy) const {
  MCRegister SrcReg = Arg->getRegister();
  assert(SrcReg.isPhysical() && "Physical register expected");
  assert(DstReg.isVirtual() && "Virtual register expected");

  Register LiveIn = getFunctionLiveInPhysReg(B.getMF(), B.getTII(), SrcReg,
                                             *ArgRC, B.getDebugLoc(), ArgTy);
  if (Arg->isMasked()) {
    // TODO: Should we try to emit this once in the entry block?
    const LLT I32 = LLT::integer(32);
    const unsigned Mask = Arg->getMask();
    const unsigned Shift = llvm::countr_zero<unsigned>(Mask);

    Register AndMaskSrc = LiveIn;

    // TODO: Avoid clearing the high bits if we know workitem id y/z are always
    // 0.
    if (Shift != 0) {
      auto ShiftAmt = B.buildConstant(I32, Shift);
      AndMaskSrc = B.buildLShr(I32, LiveIn, ShiftAmt).getReg(0);
    }

    B.buildAnd(DstReg, AndMaskSrc, B.buildConstant(I32, Mask >> Shift));
  } else {
    B.buildCopy(DstReg, LiveIn);
  }
}

bool AMDGPULegalizerInfo::legalizeWorkGroupId(
    MachineInstr &MI, MachineIRBuilder &B,
    AMDGPUFunctionArgInfo::PreloadedValue WorkGroupIdPV,
    AMDGPUFunctionArgInfo::PreloadedValue ClusterMaxIdPV,
    AMDGPUFunctionArgInfo::PreloadedValue ClusterWorkGroupIdPV) const {
  Register DstReg = MI.getOperand(0).getReg();
  if (!ST.hasClusters()) {
    if (!loadInputValue(DstReg, B, WorkGroupIdPV))
      return false;
    MI.eraseFromParent();
    return true;
  }

  // Clusters are supported. Return the global position in the grid. If clusters
  // are enabled, WorkGroupIdPV returns the cluster ID not the workgroup ID.

  // WorkGroupIdXYZ = ClusterId == 0 ?
  //   ClusterIdXYZ :
  //   ClusterIdXYZ * (ClusterMaxIdXYZ + 1) + ClusterWorkGroupIdXYZ
  MachineRegisterInfo &MRI = *B.getMRI();
  const LLT I32 = LLT::integer(32);
  Register ClusterIdXYZ = MRI.createGenericVirtualRegister(I32);
  Register ClusterMaxIdXYZ = MRI.createGenericVirtualRegister(I32);
  Register ClusterWorkGroupIdXYZ = MRI.createGenericVirtualRegister(I32);
  if (!loadInputValue(ClusterIdXYZ, B, WorkGroupIdPV) ||
      !loadInputValue(ClusterWorkGroupIdXYZ, B, ClusterWorkGroupIdPV) ||
      !loadInputValue(ClusterMaxIdXYZ, B, ClusterMaxIdPV))
    return false;

  auto One = B.buildConstant(I32, 1);
  auto ClusterSizeXYZ = B.buildAdd(I32, ClusterMaxIdXYZ, One);
  auto GlobalIdXYZ = B.buildAdd(I32, ClusterWorkGroupIdXYZ,
                                B.buildMul(I32, ClusterIdXYZ, ClusterSizeXYZ));

  const SIMachineFunctionInfo *MFI = B.getMF().getInfo<SIMachineFunctionInfo>();

  switch (MFI->getClusterDims().getKind()) {
  case AMDGPU::ClusterDimsAttr::Kind::FixedDims:
  case AMDGPU::ClusterDimsAttr::Kind::VariableDims: {
    B.buildCopy(DstReg, GlobalIdXYZ);
    MI.eraseFromParent();
    return true;
  }
  case AMDGPU::ClusterDimsAttr::Kind::NoCluster: {
    B.buildCopy(DstReg, ClusterIdXYZ);
    MI.eraseFromParent();
    return true;
  }
  case AMDGPU::ClusterDimsAttr::Kind::Unknown: {
    using namespace AMDGPU::Hwreg;
    unsigned ClusterIdField = HwregEncoding::encode(ID_IB_STS2, 6, 4);
    Register ClusterId = MRI.createGenericVirtualRegister(I32);
    MRI.setRegClass(ClusterId, &AMDGPU::SReg_32RegClass);
    B.buildInstr(AMDGPU::S_GETREG_B32_const)
        .addDef(ClusterId)
        .addImm(ClusterIdField);
    auto Zero = B.buildConstant(I32, 0);
    auto NoClusters =
        B.buildICmp(CmpInst::ICMP_EQ, LLT::scalar(1), ClusterId, Zero);
    B.buildSelect(DstReg, NoClusters, ClusterIdXYZ, GlobalIdXYZ);
    MI.eraseFromParent();
    return true;
  }
  }

  llvm_unreachable("nothing should reach here");
}

bool AMDGPULegalizerInfo::loadInputValue(
    Register DstReg, MachineIRBuilder &B,
    AMDGPUFunctionArgInfo::PreloadedValue ArgType) const {
  const SIMachineFunctionInfo *MFI = B.getMF().getInfo<SIMachineFunctionInfo>();
  const ArgDescriptor *Arg = nullptr;
  const TargetRegisterClass *ArgRC = nullptr;
  LLT ArgTy;

  CallingConv::ID CC = B.getMF().getFunction().getCallingConv();
  const ArgDescriptor WorkGroupIDX =
      ArgDescriptor::createRegister(AMDGPU::TTMP9);
  // If GridZ is not programmed in an entry function then the hardware will set
  // it to all zeros, so there is no need to mask the GridY value in the low
  // order bits.
  const ArgDescriptor WorkGroupIDY = ArgDescriptor::createRegister(
      AMDGPU::TTMP7,
      AMDGPU::isEntryFunctionCC(CC) && !MFI->hasWorkGroupIDZ() ? ~0u : 0xFFFFu);
  const ArgDescriptor WorkGroupIDZ =
      ArgDescriptor::createRegister(AMDGPU::TTMP7, 0xFFFF0000u);
  const ArgDescriptor ClusterWorkGroupIDX =
      ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x0000000Fu);
  const ArgDescriptor ClusterWorkGroupIDY =
      ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x000000F0u);
  const ArgDescriptor ClusterWorkGroupIDZ =
      ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x00000F00u);
  const ArgDescriptor ClusterWorkGroupMaxIDX =
      ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x0000F000u);
  const ArgDescriptor ClusterWorkGroupMaxIDY =
      ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x000F0000u);
  const ArgDescriptor ClusterWorkGroupMaxIDZ =
      ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x00F00000u);
  const ArgDescriptor ClusterWorkGroupMaxFlatID =
      ArgDescriptor::createRegister(AMDGPU::TTMP6, 0x0F000000u);

  auto LoadConstant = [&](unsigned N) {
    B.buildConstant(DstReg, N);
    return true;
  };

  if (ST.hasArchitectedSGPRs() &&
      (AMDGPU::isCompute(CC) || CC == CallingConv::AMDGPU_Gfx)) {
    AMDGPU::ClusterDimsAttr ClusterDims = MFI->getClusterDims();
    bool HasFixedDims = ClusterDims.isFixedDims();

    switch (ArgType) {
    case AMDGPUFunctionArgInfo::WORKGROUP_ID_X:
      Arg = &WorkGroupIDX;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    case AMDGPUFunctionArgInfo::WORKGROUP_ID_Y:
      Arg = &WorkGroupIDY;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    case AMDGPUFunctionArgInfo::WORKGROUP_ID_Z:
      Arg = &WorkGroupIDZ;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    case AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_ID_X:
      if (HasFixedDims && ClusterDims.getDims()[0] == 1)
        return LoadConstant(0);
      Arg = &ClusterWorkGroupIDX;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    case AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_ID_Y:
      if (HasFixedDims && ClusterDims.getDims()[1] == 1)
        return LoadConstant(0);
      Arg = &ClusterWorkGroupIDY;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    case AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_ID_Z:
      if (HasFixedDims && ClusterDims.getDims()[2] == 1)
        return LoadConstant(0);
      Arg = &ClusterWorkGroupIDZ;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    case AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_ID_X:
      if (HasFixedDims)
        return LoadConstant(ClusterDims.getDims()[0] - 1);
      Arg = &ClusterWorkGroupMaxIDX;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    case AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_ID_Y:
      if (HasFixedDims)
        return LoadConstant(ClusterDims.getDims()[1] - 1);
      Arg = &ClusterWorkGroupMaxIDY;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    case AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_ID_Z:
      if (HasFixedDims)
        return LoadConstant(ClusterDims.getDims()[2] - 1);
      Arg = &ClusterWorkGroupMaxIDZ;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    case AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_FLAT_ID:
      Arg = &ClusterWorkGroupMaxFlatID;
      ArgRC = &AMDGPU::SReg_32RegClass;
      ArgTy = LLT::integer(32);
      break;
    default:
      break;
    }
  }

  if (!Arg)
    std::tie(Arg, ArgRC, ArgTy) = MFI->getPreloadedValue(ArgType);

  if (!Arg) {
    if (ArgType == AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR) {
      // The intrinsic may appear when we have a 0 sized kernarg segment, in
      // which case the pointer argument may be missing and we use null.
      return LoadConstant(0);
    }

    // It's undefined behavior if a function marked with the amdgpu-no-*
    // attributes uses the corresponding intrinsic.
    B.buildUndef(DstReg);
    return true;
  }

  if (!Arg->isRegister() || !Arg->getRegister().isValid())
    return false; // TODO: Handle these
  buildLoadInputValue(DstReg, B, Arg, ArgRC, ArgTy);
  return true;
}

bool AMDGPULegalizerInfo::legalizePreloadedArgIntrin(
    MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B,
    AMDGPUFunctionArgInfo::PreloadedValue ArgType) const {
  if (!loadInputValue(MI.getOperand(0).getReg(), B, ArgType))
    return false;

  MI.eraseFromParent();
  return true;
}

static bool replaceWithConstant(MachineIRBuilder &B, MachineInstr &MI,
                                int64_t C) {
  B.buildConstant(MI.getOperand(0).getReg(), C);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeWorkitemIDIntrinsic(
    MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B,
    unsigned Dim, AMDGPUFunctionArgInfo::PreloadedValue ArgType) const {
  unsigned MaxID = ST.getMaxWorkitemID(B.getMF().getFunction(), Dim);
  if (MaxID == 0)
    return replaceWithConstant(B, MI, 0);

  const SIMachineFunctionInfo *MFI = B.getMF().getInfo<SIMachineFunctionInfo>();
  const ArgDescriptor *Arg;
  const TargetRegisterClass *ArgRC;
  LLT ArgTy;
  std::tie(Arg, ArgRC, ArgTy) = MFI->getPreloadedValue(ArgType);

  Register DstReg = MI.getOperand(0).getReg();
  if (!Arg) {
    // It's undefined behavior if a function marked with the amdgpu-no-*
    // attributes uses the corresponding intrinsic.
    B.buildUndef(DstReg);
    MI.eraseFromParent();
    return true;
  }

  if (Arg->isMasked()) {
    // Don't bother inserting AssertZext for packed IDs since we're emitting the
    // masking operations anyway.
    //
    // TODO: We could assert the top bit is 0 for the source copy.
    if (!loadInputValue(DstReg, B, ArgType))
      return false;
  } else {
    Register TmpReg = MRI.createGenericVirtualRegister(LLT::integer(32));
    if (!loadInputValue(TmpReg, B, ArgType))
      return false;
    B.buildAssertZExt(DstReg, TmpReg, llvm::bit_width(MaxID));
  }

  MI.eraseFromParent();
  return true;
}

MachinePointerInfo
AMDGPULegalizerInfo::getKernargSegmentPtrInfo(MachineFunction &MF) const {
  // This isn't really a constant pool but close enough.
  MachinePointerInfo PtrInfo(MF.getPSVManager().getConstantPool());
  PtrInfo.AddrSpace = AMDGPUAS::CONSTANT_ADDRESS;
  return PtrInfo;
}

Register AMDGPULegalizerInfo::getKernargParameterPtr(MachineIRBuilder &B,
                                                     int64_t Offset) const {
  LLT PtrTy = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64);
  Register KernArgReg = B.getMRI()->createGenericVirtualRegister(PtrTy);

  // TODO: If we passed in the base kernel offset we could have a better
  // alignment than 4, but we don't really need it.
  if (!loadInputValue(KernArgReg, B,
                      AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR))
    llvm_unreachable("failed to find kernarg segment ptr");

  auto COffset = B.buildConstant(LLT::integer(64), Offset);
  return B.buildObjectPtrOffset(PtrTy, KernArgReg, COffset).getReg(0);
}

/// Legalize a value that's loaded from kernel arguments. This is only used by
/// legacy intrinsics.
bool AMDGPULegalizerInfo::legalizeKernargMemParameter(MachineInstr &MI,
                                                      MachineIRBuilder &B,
                                                      uint64_t Offset,
                                                      Align Alignment) const {
  Register DstReg = MI.getOperand(0).getReg();

  assert(B.getMRI()->getType(DstReg) == LLT::integer(32) &&
         "unexpected kernarg parameter type");

  Register Ptr = getKernargParameterPtr(B, Offset);
  MachinePointerInfo PtrInfo = getKernargSegmentPtrInfo(B.getMF());
  B.buildLoad(DstReg, Ptr, PtrInfo.getWithOffset(Offset), Align(4),
              MachineMemOperand::MODereferenceable |
                  MachineMemOperand::MOInvariant);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFDIV(MachineInstr &MI,
                                       MachineRegisterInfo &MRI,
                                       MachineIRBuilder &B) const {
  Register Dst = MI.getOperand(0).getReg();
  LLT DstTy = MRI.getType(Dst);

  if (DstTy == F16)
    return legalizeFDIV16(MI, MRI, B);
  if (DstTy == F32)
    return legalizeFDIV32(MI, MRI, B);
  if (DstTy == F64)
    return legalizeFDIV64(MI, MRI, B);

  return false;
}

void AMDGPULegalizerInfo::legalizeUnsignedDIV_REM32Impl(MachineIRBuilder &B,
                                                        Register DstDivReg,
                                                        Register DstRemReg,
                                                        Register X,
                                                        Register Y) const {
  const LLT S1 = LLT::scalar(1);
  const LLT I32 = LLT::integer(32);

  // See AMDGPUCodeGenPrepare::expandDivRem32 for a description of the
  // algorithm used here.

  // Initial estimate of inv(y).
  auto FloatY = B.buildUITOFP(F32, Y);
  auto RcpIFlag = B.buildInstr(AMDGPU::G_AMDGPU_RCP_IFLAG, {F32}, {FloatY});
  auto Scale = B.buildFConstant(F32, llvm::bit_cast<float>(0x4f7ffffe));
  auto ScaledY = B.buildFMul(F32, RcpIFlag, Scale);
  auto Z = B.buildFPTOUI(I32, ScaledY);

  // One round of UNR.
  auto NegY = B.buildSub(I32, B.buildConstant(I32, 0), Y);
  auto NegYZ = B.buildMul(I32, NegY, Z);
  Z = B.buildAdd(I32, Z, B.buildUMulH(I32, Z, NegYZ));

  // Quotient/remainder estimate.
  auto Q = B.buildUMulH(I32, X, Z);
  auto R = B.buildSub(I32, X, B.buildMul(I32, Q, Y));

  // First quotient/remainder refinement.
  auto One = B.buildConstant(I32, 1);
  auto Cond = B.buildICmp(CmpInst::ICMP_UGE, S1, R, Y);
  if (DstDivReg)
    Q = B.buildSelect(I32, Cond, B.buildAdd(I32, Q, One), Q);
  R = B.buildSelect(I32, Cond, B.buildSub(I32, R, Y), R);

  // Second quotient/remainder refinement.
  Cond = B.buildICmp(CmpInst::ICMP_UGE, S1, R, Y);
  if (DstDivReg)
    B.buildSelect(DstDivReg, Cond, B.buildAdd(I32, Q, One), Q);

  if (DstRemReg)
    B.buildSelect(DstRemReg, Cond, B.buildSub(I32, R, Y), R);
}

// Build integer reciprocal sequence around V_RCP_IFLAG_F32
//
// Return lo, hi of result
//
// %cvt.lo = G_UITOFP Val.lo
// %cvt.hi = G_UITOFP Val.hi
// %mad = G_FMAD %cvt.hi, 2**32, %cvt.lo
// %rcp = G_AMDGPU_RCP_IFLAG %mad
// %mul1 = G_FMUL %rcp, 0x5f7ffffc
// %mul2 = G_FMUL %mul1, 2**(-32)
// %trunc = G_INTRINSIC_TRUNC %mul2
// %mad2 = G_FMAD %trunc, -(2**32), %mul1
// return {G_FPTOUI %mad2, G_FPTOUI %trunc}
static std::pair<Register, Register> emitReciprocalU64(MachineIRBuilder &B,
                                                       Register Val) {
  const LLT I32 = LLT::integer(32);
  auto Unmerge = B.buildUnmerge(I32, Val);

  auto CvtLo = B.buildUITOFP(F32, Unmerge.getReg(0));
  auto CvtHi = B.buildUITOFP(F32, Unmerge.getReg(1));

  auto Mad = B.buildFMAD(
      F32, CvtHi, // 2**32
      B.buildFConstant(F32, llvm::bit_cast<float>(0x4f800000)), CvtLo);

  auto Rcp = B.buildInstr(AMDGPU::G_AMDGPU_RCP_IFLAG, {F32}, {Mad});
  auto Mul1 = B.buildFMul(
      F32, Rcp, B.buildFConstant(F32, llvm::bit_cast<float>(0x5f7ffffc)));

  // 2**(-32)
  auto Mul2 = B.buildFMul(
      F32, Mul1, B.buildFConstant(F32, llvm::bit_cast<float>(0x2f800000)));
  auto Trunc = B.buildIntrinsicTrunc(F32, Mul2);

  // -(2**32)
  auto Mad2 = B.buildFMAD(
      F32, Trunc, B.buildFConstant(F32, llvm::bit_cast<float>(0xcf800000)),
      Mul1);

  auto ResultLo = B.buildFPTOUI(I32, Mad2);
  auto ResultHi = B.buildFPTOUI(I32, Trunc);

  return {ResultLo.getReg(0), ResultHi.getReg(0)};
}

void AMDGPULegalizerInfo::legalizeUnsignedDIV_REM64Impl(MachineIRBuilder &B,
                                                        Register DstDivReg,
                                                        Register DstRemReg,
                                                        Register Numer,
                                                        Register Denom) const {
  const LLT I32 = LLT::integer(32);
  const LLT I64 = LLT::integer(64);
  const LLT S1 = LLT::scalar(1);
  Register RcpLo, RcpHi;

  std::tie(RcpLo, RcpHi) = emitReciprocalU64(B, Denom);

  auto Rcp = B.buildMergeLikeInstr(I64, {RcpLo, RcpHi});

  auto Zero64 = B.buildConstant(I64, 0);
  auto NegDenom = B.buildSub(I64, Zero64, Denom);

  auto MulLo1 = B.buildMul(I64, NegDenom, Rcp);
  auto MulHi1 = B.buildUMulH(I64, Rcp, MulLo1);

  auto UnmergeMulHi1 = B.buildUnmerge(I32, MulHi1);
  Register MulHi1_Lo = UnmergeMulHi1.getReg(0);
  Register MulHi1_Hi = UnmergeMulHi1.getReg(1);

  auto Add1_Lo = B.buildUAddo(I32, S1, RcpLo, MulHi1_Lo);
  auto Add1_Hi = B.buildUAdde(I32, S1, RcpHi, MulHi1_Hi, Add1_Lo.getReg(1));
  auto Add1 = B.buildMergeLikeInstr(I64, {Add1_Lo, Add1_Hi});

  auto MulLo2 = B.buildMul(I64, NegDenom, Add1);
  auto MulHi2 = B.buildUMulH(I64, Add1, MulLo2);
  auto UnmergeMulHi2 = B.buildUnmerge(I32, MulHi2);
  Register MulHi2_Lo = UnmergeMulHi2.getReg(0);
  Register MulHi2_Hi = UnmergeMulHi2.getReg(1);

  auto Zero32 = B.buildConstant(I32, 0);
  auto Add2_Lo = B.buildUAddo(I32, S1, Add1_Lo, MulHi2_Lo);
  auto Add2_Hi = B.buildUAdde(I32, S1, Add1_Hi, MulHi2_Hi, Add2_Lo.getReg(1));
  auto Add2 = B.buildMergeLikeInstr(I64, {Add2_Lo, Add2_Hi});

  auto UnmergeNumer = B.buildUnmerge(I32, Numer);
  Register NumerLo = UnmergeNumer.getReg(0);
  Register NumerHi = UnmergeNumer.getReg(1);

  auto MulHi3 = B.buildUMulH(I64, Numer, Add2);
  auto Mul3 = B.buildMul(I64, Denom, MulHi3);
  auto UnmergeMul3 = B.buildUnmerge(I32, Mul3);
  Register Mul3_Lo = UnmergeMul3.getReg(0);
  Register Mul3_Hi = UnmergeMul3.getReg(1);
  auto Sub1_Lo = B.buildUSubo(I32, S1, NumerLo, Mul3_Lo);
  auto Sub1_Hi = B.buildUSube(I32, S1, NumerHi, Mul3_Hi, Sub1_Lo.getReg(1));
  auto Sub1_Mi = B.buildSub(I32, NumerHi, Mul3_Hi);
  auto Sub1 = B.buildMergeLikeInstr(I64, {Sub1_Lo, Sub1_Hi});

  auto UnmergeDenom = B.buildUnmerge(I32, Denom);
  Register DenomLo = UnmergeDenom.getReg(0);
  Register DenomHi = UnmergeDenom.getReg(1);

  auto CmpHi = B.buildICmp(CmpInst::ICMP_UGE, S1, Sub1_Hi, DenomHi);
  auto C1 = B.buildSExt(I32, CmpHi);

  auto CmpLo = B.buildICmp(CmpInst::ICMP_UGE, S1, Sub1_Lo, DenomLo);
  auto C2 = B.buildSExt(I32, CmpLo);

  auto CmpEq = B.buildICmp(CmpInst::ICMP_EQ, S1, Sub1_Hi, DenomHi);
  auto C3 = B.buildSelect(I32, CmpEq, C2, C1);

  // TODO: Here and below portions of the code can be enclosed into if/endif.
  // Currently control flow is unconditional and we have 4 selects after
  // potential endif to substitute PHIs.

  // if C3 != 0 ...
  auto Sub2_Lo = B.buildUSubo(I32, S1, Sub1_Lo, DenomLo);
  auto Sub2_Mi = B.buildUSube(I32, S1, Sub1_Mi, DenomHi, Sub1_Lo.getReg(1));
  auto Sub2_Hi = B.buildUSube(I32, S1, Sub2_Mi, Zero32, Sub2_Lo.getReg(1));
  auto Sub2 = B.buildMergeLikeInstr(I64, {Sub2_Lo, Sub2_Hi});

  auto One64 = B.buildConstant(I64, 1);
  auto Add3 = B.buildAdd(I64, MulHi3, One64);

  auto C4 =
      B.buildSExt(I32, B.buildICmp(CmpInst::ICMP_UGE, S1, Sub2_Hi, DenomHi));
  auto C5 =
      B.buildSExt(I32, B.buildICmp(CmpInst::ICMP_UGE, S1, Sub2_Lo, DenomLo));
  auto C6 = B.buildSelect(
      I32, B.buildICmp(CmpInst::ICMP_EQ, S1, Sub2_Hi, DenomHi), C5, C4);

  // if (C6 != 0)
  auto Add4 = B.buildAdd(I64, Add3, One64);
  auto Sub3_Lo = B.buildUSubo(I32, S1, Sub2_Lo, DenomLo);

  auto Sub3_Mi = B.buildUSube(I32, S1, Sub2_Mi, DenomHi, Sub2_Lo.getReg(1));
  auto Sub3_Hi = B.buildUSube(I32, S1, Sub3_Mi, Zero32, Sub3_Lo.getReg(1));
  auto Sub3 = B.buildMergeLikeInstr(I64, {Sub3_Lo, Sub3_Hi});

  // endif C6
  // endif C3

  if (DstDivReg) {
    auto Sel1 = B.buildSelect(
        I64, B.buildICmp(CmpInst::ICMP_NE, S1, C6, Zero32), Add4, Add3);
    B.buildSelect(DstDivReg, B.buildICmp(CmpInst::ICMP_NE, S1, C3, Zero32),
                  Sel1, MulHi3);
  }

  if (DstRemReg) {
    auto Sel2 = B.buildSelect(
        I64, B.buildICmp(CmpInst::ICMP_NE, S1, C6, Zero32), Sub3, Sub2);
    B.buildSelect(DstRemReg, B.buildICmp(CmpInst::ICMP_NE, S1, C3, Zero32),
                  Sel2, Sub1);
  }
}

bool AMDGPULegalizerInfo::legalizeUnsignedDIV_REM(MachineInstr &MI,
                                                  MachineRegisterInfo &MRI,
                                                  MachineIRBuilder &B) const {
  Register DstDivReg, DstRemReg;
  switch (MI.getOpcode()) {
  default:
    llvm_unreachable("Unexpected opcode!");
  case AMDGPU::G_UDIV: {
    DstDivReg = MI.getOperand(0).getReg();
    break;
  }
  case AMDGPU::G_UREM: {
    DstRemReg = MI.getOperand(0).getReg();
    break;
  }
  case AMDGPU::G_UDIVREM: {
    DstDivReg = MI.getOperand(0).getReg();
    DstRemReg = MI.getOperand(1).getReg();
    break;
  }
  }

  const LLT I64 = LLT::integer(64);
  const LLT I32 = LLT::integer(32);
  const unsigned FirstSrcOpIdx = MI.getNumExplicitDefs();
  Register Num = MI.getOperand(FirstSrcOpIdx).getReg();
  Register Den = MI.getOperand(FirstSrcOpIdx + 1).getReg();
  LLT Ty = MRI.getType(MI.getOperand(0).getReg());

  if (Ty == I32)
    legalizeUnsignedDIV_REM32Impl(B, DstDivReg, DstRemReg, Num, Den);
  else if (Ty == I64)
    legalizeUnsignedDIV_REM64Impl(B, DstDivReg, DstRemReg, Num, Den);
  else
    return false;

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeSignedDIV_REM(MachineInstr &MI,
                                                MachineRegisterInfo &MRI,
                                                MachineIRBuilder &B) const {
  const LLT I64 = LLT::integer(64);
  const LLT I32 = LLT::integer(32);

  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
  if (Ty != I32 && Ty != I64)
    return false;

  const unsigned FirstSrcOpIdx = MI.getNumExplicitDefs();
  Register LHS = MI.getOperand(FirstSrcOpIdx).getReg();
  Register RHS = MI.getOperand(FirstSrcOpIdx + 1).getReg();

  auto SignBitOffset = B.buildConstant(I32, Ty.getSizeInBits() - 1);
  auto LHSign = B.buildAShr(Ty, LHS, SignBitOffset);
  auto RHSign = B.buildAShr(Ty, RHS, SignBitOffset);

  LHS = B.buildAdd(Ty, LHS, LHSign).getReg(0);
  RHS = B.buildAdd(Ty, RHS, RHSign).getReg(0);

  LHS = B.buildXor(Ty, LHS, LHSign).getReg(0);
  RHS = B.buildXor(Ty, RHS, RHSign).getReg(0);

  Register DstDivReg, DstRemReg, TmpDivReg, TmpRemReg;
  switch (MI.getOpcode()) {
  default:
    llvm_unreachable("Unexpected opcode!");
  case AMDGPU::G_SDIV: {
    DstDivReg = MI.getOperand(0).getReg();
    TmpDivReg = MRI.createGenericVirtualRegister(Ty);
    break;
  }
  case AMDGPU::G_SREM: {
    DstRemReg = MI.getOperand(0).getReg();
    TmpRemReg = MRI.createGenericVirtualRegister(Ty);
    break;
  }
  case AMDGPU::G_SDIVREM: {
    DstDivReg = MI.getOperand(0).getReg();
    DstRemReg = MI.getOperand(1).getReg();
    TmpDivReg = MRI.createGenericVirtualRegister(Ty);
    TmpRemReg = MRI.createGenericVirtualRegister(Ty);
    break;
  }
  }

  if (Ty == I32)
    legalizeUnsignedDIV_REM32Impl(B, TmpDivReg, TmpRemReg, LHS, RHS);
  else
    legalizeUnsignedDIV_REM64Impl(B, TmpDivReg, TmpRemReg, LHS, RHS);

  if (DstDivReg) {
    auto Sign = B.buildXor(Ty, LHSign, RHSign).getReg(0);
    auto SignXor = B.buildXor(Ty, TmpDivReg, Sign).getReg(0);
    B.buildSub(DstDivReg, SignXor, Sign);
  }

  if (DstRemReg) {
    auto Sign = LHSign.getReg(0); // Remainder sign is the same as LHS
    auto SignXor = B.buildXor(Ty, TmpRemReg, Sign).getReg(0);
    B.buildSub(DstRemReg, SignXor, Sign);
  }

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFastUnsafeFDIV(MachineInstr &MI,
                                                 MachineRegisterInfo &MRI,
                                                 MachineIRBuilder &B) const {
  Register Res = MI.getOperand(0).getReg();
  Register LHS = MI.getOperand(1).getReg();
  Register RHS = MI.getOperand(2).getReg();
  uint16_t Flags = MI.getFlags();
  LLT ResTy = MRI.getType(Res);

  bool AllowInaccurateRcp = MI.getFlag(MachineInstr::FmAfn);

  if (const auto *CLHS = getConstantFPVRegVal(LHS, MRI)) {
    if (!AllowInaccurateRcp && ResTy != F16)
      return false;

    // v_rcp_f32 and v_rsq_f32 do not support denormals, and according to
    // the CI documentation has a worst case error of 1 ulp.
    // OpenCL requires <= 2.5 ulp for 1.0 / x, so it should always be OK to
    // use it as long as we aren't trying to use denormals.
    //
    // v_rcp_f16 and v_rsq_f16 DO support denormals and 0.51ulp.

    // 1 / x -> RCP(x)
    if (CLHS->isOne()) {
      B.buildIntrinsic(Intrinsic::amdgcn_rcp, Res)
          .addUse(RHS)
          .setMIFlags(Flags);

      MI.eraseFromParent();
      return true;
    }

    // -1 / x -> RCP( FNEG(x) )
    if (CLHS->isMinusOne()) {
      auto FNeg = B.buildFNeg(ResTy, RHS, Flags);
      B.buildIntrinsic(Intrinsic::amdgcn_rcp, Res)
          .addUse(FNeg.getReg(0))
          .setMIFlags(Flags);

      MI.eraseFromParent();
      return true;
    }
  }

  // For f16 require afn or arcp.
  // For f32 require afn.
  if (!AllowInaccurateRcp &&
      (ResTy != F16 || !MI.getFlag(MachineInstr::FmArcp)))
    return false;

  // x / y -> x * (1.0 / y)
  auto RCP = B.buildIntrinsic(Intrinsic::amdgcn_rcp, {ResTy})
                 .addUse(RHS)
                 .setMIFlags(Flags);
  B.buildFMul(Res, LHS, RCP, Flags);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFastUnsafeFDIV64(MachineInstr &MI,
                                                   MachineRegisterInfo &MRI,
                                                   MachineIRBuilder &B) const {
  Register Res = MI.getOperand(0).getReg();
  Register X = MI.getOperand(1).getReg();
  Register Y = MI.getOperand(2).getReg();
  uint16_t Flags = MI.getFlags();
  LLT ResTy = MRI.getType(Res);

  bool AllowInaccurateRcp = MI.getFlag(MachineInstr::FmAfn);

  if (!AllowInaccurateRcp)
    return false;

  const ConstantFP *CLHS = getConstantFPVRegVal(X, MRI);
  bool IsNegRcp = CLHS && CLHS->isMinusOne();

  // Pull out the negation so it folds for free into the source modifiers.
  if (IsNegRcp)
    X = B.buildFConstant(ResTy, 1.0).getReg(0);

  Register NegY = IsNegRcp ? Y : B.buildFNeg(ResTy, Y).getReg(0);
  auto One = B.buildFConstant(ResTy, 1.0);

  auto R = B.buildIntrinsic(Intrinsic::amdgcn_rcp, {ResTy})
               .addUse(Y)
               .setMIFlags(Flags);
  if (IsNegRcp)
    R = B.buildFNeg(ResTy, R);

  auto Tmp0 = B.buildFMA(ResTy, NegY, R, One);
  R = B.buildFMA(ResTy, Tmp0, R, R);

  auto Tmp1 = B.buildFMA(ResTy, NegY, R, One);
  R = B.buildFMA(ResTy, Tmp1, R, R);

  // Skip the last 2 correction terms for reciprocal.
  if (IsNegRcp || (CLHS && CLHS->isOne())) {
    B.buildCopy(Res, R);
    MI.eraseFromParent();
    return true;
  }

  auto Ret = B.buildFMul(ResTy, X, R);
  auto Tmp2 = B.buildFMA(ResTy, NegY, Ret, X);

  B.buildFMA(Res, Tmp2, R, Ret);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFDIV16(MachineInstr &MI,
                                         MachineRegisterInfo &MRI,
                                         MachineIRBuilder &B) const {
  if (legalizeFastUnsafeFDIV(MI, MRI, B))
    return true;

  Register Res = MI.getOperand(0).getReg();
  Register LHS = MI.getOperand(1).getReg();
  Register RHS = MI.getOperand(2).getReg();

  uint16_t Flags = MI.getFlags();

  LLT I32 = LLT::integer(32);

  // a32.u = opx(V_CVT_F32_F16, a.u); // CVT to F32
  // b32.u = opx(V_CVT_F32_F16, b.u); // CVT to F32
  // r32.u = opx(V_RCP_F32, b32.u); // rcp = 1 / d
  // q32.u = opx(V_MUL_F32, a32.u, r32.u); // q = n * rcp
  // e32.u = opx(V_MAD_F32, (b32.u^_neg32), q32.u, a32.u); // err = -d * q + n
  // q32.u = opx(V_MAD_F32, e32.u, r32.u, q32.u); // q = n * rcp
  // e32.u = opx(V_MAD_F32, (b32.u^_neg32), q32.u, a32.u); // err = -d * q + n
  // tmp.u = opx(V_MUL_F32, e32.u, r32.u);
  // tmp.u = opx(V_AND_B32, tmp.u, 0xff800000)
  // q32.u = opx(V_ADD_F32, tmp.u, q32.u);
  // q16.u = opx(V_CVT_F16_F32, q32.u);
  // q16.u = opx(V_DIV_FIXUP_F16, q16.u, b.u, a.u); // q = touchup(q, d, n)

  auto LHSExt = B.buildFPExt(F32, LHS, Flags);
  auto RHSExt = B.buildFPExt(F32, RHS, Flags);
  auto NegRHSExt = B.buildFNeg(F32, RHSExt);
  auto Rcp = B.buildIntrinsic(Intrinsic::amdgcn_rcp, {F32})
                 .addUse(RHSExt.getReg(0))
                 .setMIFlags(Flags);
  auto Quot = B.buildFMul(F32, LHSExt, Rcp, Flags);
  MachineInstrBuilder Err;
  if (ST.hasMadMacF32Insts()) {
    Err = B.buildFMAD(F32, NegRHSExt, Quot, LHSExt, Flags);
    Quot = B.buildFMAD(F32, Err, Rcp, Quot, Flags);
    Err = B.buildFMAD(F32, NegRHSExt, Quot, LHSExt, Flags);
  } else {
    Err = B.buildFMA(F32, NegRHSExt, Quot, LHSExt, Flags);
    Quot = B.buildFMA(F32, Err, Rcp, Quot, Flags);
    Err = B.buildFMA(F32, NegRHSExt, Quot, LHSExt, Flags);
  }
  auto Tmp = B.buildFMul(F32, Err, Rcp, Flags);
  auto TmpInt = B.buildBitcast(I32, Tmp);
  auto MaskedInt = B.buildAnd(I32, TmpInt, B.buildConstant(I32, 0xff800000));
  auto Masked = B.buildBitcast(F32, MaskedInt);
  Quot = B.buildFAdd(F32, Masked, Quot, Flags);
  auto RDst = B.buildFPTrunc(F16, Quot, Flags);
  B.buildIntrinsic(Intrinsic::amdgcn_div_fixup, Res)
      .addUse(RDst.getReg(0))
      .addUse(RHS)
      .addUse(LHS)
      .setMIFlags(Flags);

  MI.eraseFromParent();
  return true;
}

static constexpr unsigned SPDenormModeBitField =
    AMDGPU::Hwreg::HwregEncoding::encode(AMDGPU::Hwreg::ID_MODE, 4, 2);

// Enable or disable FP32 denorm mode. When 'Enable' is true, emit instructions
// to enable denorm mode. When 'Enable' is false, disable denorm mode.
static void toggleSPDenormMode(bool Enable, MachineIRBuilder &B,
                               const GCNSubtarget &ST,
                               SIModeRegisterDefaults Mode) {
  // Set SP denorm mode to this value.
  unsigned SPDenormMode =
    Enable ? FP_DENORM_FLUSH_NONE : Mode.fpDenormModeSPValue();

  if (ST.hasDenormModeInst()) {
    // Preserve default FP64FP16 denorm mode while updating FP32 mode.
    uint32_t DPDenormModeDefault = Mode.fpDenormModeDPValue();

    uint32_t NewDenormModeValue = SPDenormMode | (DPDenormModeDefault << 2);
    B.buildInstr(AMDGPU::S_DENORM_MODE)
      .addImm(NewDenormModeValue);

  } else {
    B.buildInstr(AMDGPU::S_SETREG_IMM32_B32)
      .addImm(SPDenormMode)
      .addImm(SPDenormModeBitField);
  }
}

bool AMDGPULegalizerInfo::legalizeFDIV32(MachineInstr &MI,
                                         MachineRegisterInfo &MRI,
                                         MachineIRBuilder &B) const {
  if (legalizeFastUnsafeFDIV(MI, MRI, B))
    return true;

  Register Res = MI.getOperand(0).getReg();
  Register LHS = MI.getOperand(1).getReg();
  Register RHS = MI.getOperand(2).getReg();
  const SIMachineFunctionInfo *MFI = B.getMF().getInfo<SIMachineFunctionInfo>();
  SIModeRegisterDefaults Mode = MFI->getMode();

  uint16_t Flags = MI.getFlags();

  LLT S1 = LLT::scalar(1);

  auto One = B.buildFConstant(F32, 1.0f);

  auto DenominatorScaled =
      B.buildIntrinsic(Intrinsic::amdgcn_div_scale, {F32, S1})
          .addUse(LHS)
          .addUse(RHS)
          .addImm(0)
          .setMIFlags(Flags);
  auto NumeratorScaled =
      B.buildIntrinsic(Intrinsic::amdgcn_div_scale, {F32, S1})
          .addUse(LHS)
          .addUse(RHS)
          .addImm(1)
          .setMIFlags(Flags);

  auto ApproxRcp = B.buildIntrinsic(Intrinsic::amdgcn_rcp, {F32})
                       .addUse(DenominatorScaled.getReg(0))
                       .setMIFlags(Flags);
  auto NegDivScale0 = B.buildFNeg(F32, DenominatorScaled, Flags);

  const bool PreservesDenormals = Mode.FP32Denormals == DenormalMode::getIEEE();
  const bool HasDynamicDenormals =
      (Mode.FP32Denormals.Input == DenormalMode::Dynamic) ||
      (Mode.FP32Denormals.Output == DenormalMode::Dynamic);

  Register SavedSPDenormMode;
  if (!PreservesDenormals) {
    if (HasDynamicDenormals) {
      SavedSPDenormMode = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
      B.buildInstr(AMDGPU::S_GETREG_B32)
          .addDef(SavedSPDenormMode)
          .addImm(SPDenormModeBitField);
    }
    toggleSPDenormMode(true, B, ST, Mode);
  }

  auto Fma0 = B.buildFMA(F32, NegDivScale0, ApproxRcp, One, Flags);
  auto Fma1 = B.buildFMA(F32, Fma0, ApproxRcp, ApproxRcp, Flags);
  auto Mul = B.buildFMul(F32, NumeratorScaled, Fma1, Flags);
  auto Fma2 = B.buildFMA(F32, NegDivScale0, Mul, NumeratorScaled, Flags);
  auto Fma3 = B.buildFMA(F32, Fma2, Fma1, Mul, Flags);
  auto Fma4 = B.buildFMA(F32, NegDivScale0, Fma3, NumeratorScaled, Flags);

  if (!PreservesDenormals) {
    if (HasDynamicDenormals) {
      assert(SavedSPDenormMode);
      B.buildInstr(AMDGPU::S_SETREG_B32)
          .addReg(SavedSPDenormMode)
          .addImm(SPDenormModeBitField);
    } else
      toggleSPDenormMode(false, B, ST, Mode);
  }

  auto Fmas = B.buildIntrinsic(Intrinsic::amdgcn_div_fmas, {F32})
                  .addUse(Fma4.getReg(0))
                  .addUse(Fma1.getReg(0))
                  .addUse(Fma3.getReg(0))
                  .addUse(NumeratorScaled.getReg(1))
                  .setMIFlags(Flags);

  B.buildIntrinsic(Intrinsic::amdgcn_div_fixup, Res)
      .addUse(Fmas.getReg(0))
      .addUse(RHS)
      .addUse(LHS)
      .setMIFlags(Flags);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFDIV64(MachineInstr &MI,
                                         MachineRegisterInfo &MRI,
                                         MachineIRBuilder &B) const {
  if (legalizeFastUnsafeFDIV64(MI, MRI, B))
    return true;

  Register Res = MI.getOperand(0).getReg();
  Register LHS = MI.getOperand(1).getReg();
  Register RHS = MI.getOperand(2).getReg();

  uint16_t Flags = MI.getFlags();

  LLT S1 = LLT::scalar(1);

  auto One = B.buildFConstant(F64, 1.0);

  auto DivScale0 = B.buildIntrinsic(Intrinsic::amdgcn_div_scale, {F64, S1})
                       .addUse(LHS)
                       .addUse(RHS)
                       .addImm(0)
                       .setMIFlags(Flags);

  auto NegDivScale0 = B.buildFNeg(F64, DivScale0.getReg(0), Flags);

  auto Rcp = B.buildIntrinsic(Intrinsic::amdgcn_rcp, {F64})
                 .addUse(DivScale0.getReg(0))
                 .setMIFlags(Flags);

  auto Fma0 = B.buildFMA(F64, NegDivScale0, Rcp, One, Flags);
  auto Fma1 = B.buildFMA(F64, Rcp, Fma0, Rcp, Flags);
  auto Fma2 = B.buildFMA(F64, NegDivScale0, Fma1, One, Flags);

  auto DivScale1 = B.buildIntrinsic(Intrinsic::amdgcn_div_scale, {F64, S1})
                       .addUse(LHS)
                       .addUse(RHS)
                       .addImm(1)
                       .setMIFlags(Flags);

  auto Fma3 = B.buildFMA(F64, Fma1, Fma2, Fma1, Flags);
  auto Mul = B.buildFMul(F64, DivScale1.getReg(0), Fma3, Flags);
  auto Fma4 = B.buildFMA(F64, NegDivScale0, Mul, DivScale1.getReg(0), Flags);

  Register Scale;
  if (!ST.hasUsableDivScaleConditionOutput()) {
    // Workaround a hardware bug on SI where the condition output from div_scale
    // is not usable.

    LLT I32 = LLT::integer(32);
    LLT I64 = LLT::integer(64);

    auto NumUnmerge = B.buildUnmerge(I32, B.buildBitcast(I64, LHS));
    auto DenUnmerge = B.buildUnmerge(I32, B.buildBitcast(I64, RHS));
    auto Scale0Unmerge = B.buildUnmerge(I32, B.buildBitcast(I64, DivScale0));
    auto Scale1Unmerge = B.buildUnmerge(I32, B.buildBitcast(I64, DivScale1));

    auto CmpNum = B.buildICmp(ICmpInst::ICMP_EQ, S1, NumUnmerge.getReg(1),
                              Scale1Unmerge.getReg(1));
    auto CmpDen = B.buildICmp(ICmpInst::ICMP_EQ, S1, DenUnmerge.getReg(1),
                              Scale0Unmerge.getReg(1));
    Scale = B.buildXor(S1, CmpNum, CmpDen).getReg(0);
  } else {
    Scale = DivScale1.getReg(1);
  }

  auto Fmas = B.buildIntrinsic(Intrinsic::amdgcn_div_fmas, {F64})
                  .addUse(Fma4.getReg(0))
                  .addUse(Fma3.getReg(0))
                  .addUse(Mul.getReg(0))
                  .addUse(Scale)
                  .setMIFlags(Flags);

  B.buildIntrinsic(Intrinsic::amdgcn_div_fixup, ArrayRef(Res))
      .addUse(Fmas.getReg(0))
      .addUse(RHS)
      .addUse(LHS)
      .setMIFlags(Flags);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFFREXP(MachineInstr &MI,
                                         MachineRegisterInfo &MRI,
                                         MachineIRBuilder &B) const {
  Register Res0 = MI.getOperand(0).getReg();
  Register Res1 = MI.getOperand(1).getReg();
  Register Val = MI.getOperand(2).getReg();
  uint16_t Flags = MI.getFlags();

  LLT Ty = MRI.getType(Res0);
  LLT InstrExpTy = Ty == F16 ? LLT::integer(16) : LLT::integer(32);

  auto Mant = B.buildIntrinsic(Intrinsic::amdgcn_frexp_mant, {Ty})
                  .addUse(Val)
                  .setMIFlags(Flags);
  auto Exp = B.buildIntrinsic(Intrinsic::amdgcn_frexp_exp, {InstrExpTy})
                 .addUse(Val)
                 .setMIFlags(Flags);

  if (ST.hasFractBug()) {
    auto Fabs = B.buildFAbs(Ty, Val);
    auto Inf = B.buildFConstant(Ty, APFloat::getInf(getFltSemanticForLLT(Ty)));
    auto IsFinite =
        B.buildFCmp(CmpInst::FCMP_OLT, LLT::scalar(1), Fabs, Inf, Flags);
    auto Zero = B.buildConstant(InstrExpTy, 0);
    Exp = B.buildSelect(InstrExpTy, IsFinite, Exp, Zero);
    Mant = B.buildSelect(Ty, IsFinite, Mant, Val);
  }

  B.buildCopy(Res0, Mant);
  B.buildSExtOrTrunc(Res1, Exp);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFDIVFastIntrin(MachineInstr &MI,
                                                 MachineRegisterInfo &MRI,
                                                 MachineIRBuilder &B) const {
  Register Res = MI.getOperand(0).getReg();
  Register LHS = MI.getOperand(2).getReg();
  Register RHS = MI.getOperand(3).getReg();
  uint16_t Flags = MI.getFlags();

  LLT S1 = LLT::scalar(1);

  auto Abs = B.buildFAbs(F32, RHS, Flags);
  const APFloat C0Val(1.0f);

  auto C0 = B.buildFConstant(F32, 0x1p+96f);
  auto C1 = B.buildFConstant(F32, 0x1p-32f);
  auto C2 = B.buildFConstant(F32, 1.0f);

  auto CmpRes = B.buildFCmp(CmpInst::FCMP_OGT, S1, Abs, C0, Flags);
  auto Sel = B.buildSelect(F32, CmpRes, C1, C2, Flags);

  auto Mul0 = B.buildFMul(F32, RHS, Sel, Flags);

  auto RCP = B.buildIntrinsic(Intrinsic::amdgcn_rcp, {F32})
                 .addUse(Mul0.getReg(0))
                 .setMIFlags(Flags);

  auto Mul1 = B.buildFMul(F32, LHS, RCP, Flags);

  B.buildFMul(Res, Sel, Mul1, Flags);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFSQRTF16(MachineInstr &MI,
                                           MachineRegisterInfo &MRI,
                                           MachineIRBuilder &B) const {
  // Bypass the correct expansion a standard promotion through G_FSQRT would
  // get. The f32 op is accurate enough for the f16 cas.
  unsigned Flags = MI.getFlags();
  assert(!ST.has16BitInsts());
  auto Ext = B.buildFPExt(F32, MI.getOperand(1), Flags);
  auto Log2 = B.buildIntrinsic(Intrinsic::amdgcn_sqrt, {F32})
    .addUse(Ext.getReg(0))
    .setMIFlags(Flags);
  B.buildFPTrunc(MI.getOperand(0), Log2, Flags);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFSQRTF32(MachineInstr &MI,
                                           MachineRegisterInfo &MRI,
                                           MachineIRBuilder &B) const {
  MachineFunction &MF = B.getMF();
  Register Dst = MI.getOperand(0).getReg();
  Register X = MI.getOperand(1).getReg();
  const unsigned Flags = MI.getFlags();
  const LLT I1 = LLT::integer(1);
  const LLT I32 = LLT::integer(32);

  if (allowApproxFunc(MF, Flags)) {
    B.buildIntrinsic(Intrinsic::amdgcn_sqrt, ArrayRef<Register>({Dst}))
      .addUse(X)
      .setMIFlags(Flags);
    MI.eraseFromParent();
    return true;
  }

  auto ScaleThreshold = B.buildFConstant(F32, 0x1.0p-96f);
  auto NeedScale = B.buildFCmp(CmpInst::FCMP_OGT, I1, ScaleThreshold, X, Flags);
  auto ScaleUpFactor = B.buildFConstant(F32, 0x1.0p+32f);
  auto ScaledX = B.buildFMul(F32, X, ScaleUpFactor, Flags);
  auto SqrtX = B.buildSelect(F32, NeedScale, ScaledX, X, Flags);

  Register SqrtS = MRI.createGenericVirtualRegister(F32);
  if (needsDenormHandlingF32(MF, X, Flags)) {
    B.buildIntrinsic(Intrinsic::amdgcn_sqrt, ArrayRef<Register>({SqrtS}))
      .addUse(SqrtX.getReg(0))
      .setMIFlags(Flags);

    auto SqrtSInt = B.buildBitcast(I32, SqrtS);
    auto NegOne = B.buildConstant(I32, -1);
    auto SqrtSNextDown = B.buildBitcast(F32, B.buildAdd(I32, SqrtSInt, NegOne));

    auto NegSqrtSNextDown = B.buildFNeg(F32, SqrtSNextDown, Flags);
    auto SqrtVP = B.buildFMA(F32, NegSqrtSNextDown, SqrtS, SqrtX, Flags);

    auto PosOne = B.buildConstant(I32, 1);
    auto SqrtSNextUp = B.buildBitcast(F32, B.buildAdd(I32, SqrtSInt, PosOne));

    auto NegSqrtSNextUp = B.buildFNeg(F32, SqrtSNextUp, Flags);
    auto SqrtVS = B.buildFMA(F32, NegSqrtSNextUp, SqrtS, SqrtX, Flags);

    auto Zero = B.buildFConstant(F32, 0.0f);
    auto SqrtVPLE0 = B.buildFCmp(CmpInst::FCMP_OLE, I1, SqrtVP, Zero, Flags);

    SqrtS =
        B.buildSelect(F32, SqrtVPLE0, SqrtSNextDown, SqrtS, Flags).getReg(0);

    auto SqrtVPVSGT0 = B.buildFCmp(CmpInst::FCMP_OGT, I1, SqrtVS, Zero, Flags);
    SqrtS =
        B.buildSelect(F32, SqrtVPVSGT0, SqrtSNextUp, SqrtS, Flags).getReg(0);
  } else {
    auto SqrtR =
        B.buildIntrinsic(Intrinsic::amdgcn_rsq, {F32}).addReg(SqrtX.getReg(0));
    B.buildFMul(SqrtS, SqrtX, SqrtR, Flags);

    auto Half = B.buildFConstant(F32, 0.5f);
    auto SqrtH = B.buildFMul(F32, SqrtR, Half, Flags);
    auto NegSqrtH = B.buildFNeg(F32, SqrtH, Flags);
    auto SqrtE = B.buildFMA(F32, NegSqrtH, SqrtS, Half, Flags);
    SqrtH = B.buildFMA(F32, SqrtH, SqrtE, SqrtH, Flags);
    SqrtS = B.buildFMA(F32, SqrtS, SqrtE, SqrtS, Flags).getReg(0);
    auto NegSqrtS = B.buildFNeg(F32, SqrtS, Flags);
    auto SqrtD = B.buildFMA(F32, NegSqrtS, SqrtS, SqrtX, Flags);
    SqrtS = B.buildFMA(F32, SqrtD, SqrtH, SqrtS, Flags).getReg(0);
  }

  auto ScaleDownFactor = B.buildFConstant(F32, 0x1.0p-16f);

  auto ScaledDown = B.buildFMul(F32, SqrtS, ScaleDownFactor, Flags);

  SqrtS = B.buildSelect(F32, NeedScale, ScaledDown, SqrtS, Flags).getReg(0);

  auto IsZeroOrInf = B.buildIsFPClass(I1, SqrtX, fcZero | fcPosInf);
  B.buildSelect(Dst, IsZeroOrInf, SqrtX, SqrtS, Flags);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFSQRTF64(MachineInstr &MI,
                                           MachineRegisterInfo &MRI,
                                           MachineIRBuilder &B) const {
  // For double type, the SQRT and RSQ instructions don't have required
  // precision, we apply Goldschmidt's algorithm to improve the result:
  //
  //   y0 = rsq(x)
  //   g0 = x * y0
  //   h0 = 0.5 * y0
  //
  //   r0 = 0.5 - h0 * g0
  //   g1 = g0 * r0 + g0
  //   h1 = h0 * r0 + h0
  //
  //   r1 = 0.5 - h1 * g1 => d0 = x - g1 * g1
  //   g2 = g1 * r1 + g1     g2 = d0 * h1 + g1
  //   h2 = h1 * r1 + h1
  //
  //   r2 = 0.5 - h2 * g2 => d1 = x - g2 * g2
  //   g3 = g2 * r2 + g2     g3 = d1 * h1 + g2
  //
  //   sqrt(x) = g3

  const LLT I1 = LLT::integer(1);
  const LLT I32 = LLT::integer(32);

  Register Dst = MI.getOperand(0).getReg();
  assert(MRI.getType(Dst) == F64 && "only expect to lower f64 sqrt");

  Register X = MI.getOperand(1).getReg();
  unsigned Flags = MI.getFlags();

  Register SqrtX = X;
  Register Scaling, ZeroInt;
  if (!MI.getFlag(MachineInstr::FmAfn)) {
    auto ScaleConstant = B.buildFConstant(F64, 0x1.0p-767);

    ZeroInt = B.buildConstant(I32, 0).getReg(0);
    Scaling = B.buildFCmp(FCmpInst::FCMP_OLT, I1, X, ScaleConstant).getReg(0);

    // Scale up input if it is too small.
    auto ScaleUpFactor = B.buildConstant(I32, 256);
    auto ScaleUp = B.buildSelect(I32, Scaling, ScaleUpFactor, ZeroInt);
    SqrtX = B.buildFLdexp(F64, X, ScaleUp, Flags).getReg(0);
  }

  auto SqrtY = B.buildIntrinsic(Intrinsic::amdgcn_rsq, {F64}).addReg(SqrtX);

  auto Half = B.buildFConstant(F64, 0.5);
  auto SqrtH0 = B.buildFMul(F64, SqrtY, Half);
  auto SqrtS0 = B.buildFMul(F64, SqrtX, SqrtY);

  auto NegSqrtH0 = B.buildFNeg(F64, SqrtH0);
  auto SqrtR0 = B.buildFMA(F64, NegSqrtH0, SqrtS0, Half);

  auto SqrtS1 = B.buildFMA(F64, SqrtS0, SqrtR0, SqrtS0);
  auto SqrtH1 = B.buildFMA(F64, SqrtH0, SqrtR0, SqrtH0);

  auto NegSqrtS1 = B.buildFNeg(F64, SqrtS1);
  auto SqrtD0 = B.buildFMA(F64, NegSqrtS1, SqrtS1, SqrtX);

  auto SqrtS2 = B.buildFMA(F64, SqrtD0, SqrtH1, SqrtS1);

  Register SqrtRet = SqrtS2.getReg(0);
  if (!MI.getFlag(MachineInstr::FmAfn)) {
    auto NegSqrtS2 = B.buildFNeg(F64, SqrtS2);
    auto SqrtD1 = B.buildFMA(F64, NegSqrtS2, SqrtS2, SqrtX);
    auto SqrtD2 = B.buildFMA(F64, SqrtD1, SqrtH1, SqrtS2);

    // Scale down the result.
    auto ScaleDownFactor = B.buildConstant(I32, -128);
    auto ScaleDown = B.buildSelect(I32, Scaling, ScaleDownFactor, ZeroInt);
    SqrtRet = B.buildFLdexp(F64, SqrtD2, ScaleDown, Flags).getReg(0);
  }

  Register IsZeroOrInf;
  if (MI.getFlag(MachineInstr::FmNoInfs)) {
    auto ZeroFP = B.buildFConstant(F64, 0.0);
    IsZeroOrInf = B.buildFCmp(FCmpInst::FCMP_OEQ, I1, SqrtX, ZeroFP).getReg(0);
  } else {
    IsZeroOrInf = B.buildIsFPClass(I1, SqrtX, fcZero | fcPosInf).getReg(0);
  }

  // TODO: Check for DAZ and expand to subnormals

  // If x is +INF, +0, or -0, use its original value
  B.buildSelect(Dst, IsZeroOrInf, SqrtX, SqrtRet, Flags);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeFSQRT(MachineInstr &MI,
                                        MachineRegisterInfo &MRI,
                                        MachineIRBuilder &B) const {
  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
  if (Ty == F32)
    return legalizeFSQRTF32(MI, MRI, B);
  if (Ty == F64)
    return legalizeFSQRTF64(MI, MRI, B);
  if (Ty == F16)
    return legalizeFSQRTF16(MI, MRI, B);
  return false;
}

// Expand llvm.amdgcn.rsq.clamp on targets that don't support the instruction.
// FIXME: Why do we handle this one but not other removed instructions?
//
// Reciprocal square root.  The clamp prevents infinite results, clamping
// infinities to max_float.  D.f = 1.0 / sqrt(S0.f), result clamped to
// +-max_float.
bool AMDGPULegalizerInfo::legalizeRsqClampIntrinsic(MachineInstr &MI,
                                                    MachineRegisterInfo &MRI,
                                                    MachineIRBuilder &B) const {
  if (ST.getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS)
    return true;

  Register Dst = MI.getOperand(0).getReg();
  Register Src = MI.getOperand(2).getReg();
  auto Flags = MI.getFlags();

  LLT Ty = MRI.getType(Dst);

  const fltSemantics *FltSemantics;
  if (Ty == F32)
    FltSemantics = &APFloat::IEEEsingle();
  else if (Ty == F64)
    FltSemantics = &APFloat::IEEEdouble();
  else
    return false;

  auto Rsq = B.buildIntrinsic(Intrinsic::amdgcn_rsq, {Ty})
                 .addUse(Src)
                 .setMIFlags(Flags);

  // We don't need to concern ourselves with the snan handling difference, since
  // the rsq quieted (or not) so use the one which will directly select.
  const SIMachineFunctionInfo *MFI = B.getMF().getInfo<SIMachineFunctionInfo>();
  const bool UseIEEE = MFI->getMode().IEEE;

  auto MaxFlt = B.buildFConstant(Ty, APFloat::getLargest(*FltSemantics));
  auto ClampMax = UseIEEE && !ST.hasIEEEMinimumMaximumInsts()
                      ? B.buildFMinNumIEEE(Ty, Rsq, MaxFlt, Flags)
                      : B.buildFMinNum(Ty, Rsq, MaxFlt, Flags);

  auto MinFlt = B.buildFConstant(Ty, APFloat::getLargest(*FltSemantics, true));

  if (UseIEEE && !ST.hasIEEEMinimumMaximumInsts())
    B.buildFMaxNumIEEE(Dst, ClampMax, MinFlt, Flags);
  else
    B.buildFMaxNum(Dst, ClampMax, MinFlt, Flags);
  MI.eraseFromParent();
  return true;
}

// TODO: Fix pointer type handling
bool AMDGPULegalizerInfo::legalizeLaneOp(LegalizerHelper &Helper,
                                         MachineInstr &MI,
                                         Intrinsic::ID IID) const {

  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();

  bool IsPermLane16 = IID == Intrinsic::amdgcn_permlane16 ||
                      IID == Intrinsic::amdgcn_permlanex16;
  bool IsSetInactive = IID == Intrinsic::amdgcn_set_inactive ||
                       IID == Intrinsic::amdgcn_set_inactive_chain_arg;
  bool IsPermlaneShuffle = IID == Intrinsic::amdgcn_permlane_bcast ||
                           IID == Intrinsic::amdgcn_permlane_up ||
                           IID == Intrinsic::amdgcn_permlane_down ||
                           IID == Intrinsic::amdgcn_permlane_xor;

  auto createLaneOp = [&IID, &B, &MI](Register Src0, Register Src1,
                                      Register Src2, LLT VT) -> Register {
    auto LaneOp = B.buildIntrinsic(IID, {VT}).addUse(Src0);
    switch (IID) {
    case Intrinsic::amdgcn_readfirstlane:
    case Intrinsic::amdgcn_permlane64:
      return LaneOp.getReg(0);
    case Intrinsic::amdgcn_readlane:
    case Intrinsic::amdgcn_set_inactive:
    case Intrinsic::amdgcn_set_inactive_chain_arg:
      return LaneOp.addUse(Src1).getReg(0);
    case Intrinsic::amdgcn_writelane:
    case Intrinsic::amdgcn_permlane_bcast:
    case Intrinsic::amdgcn_permlane_up:
    case Intrinsic::amdgcn_permlane_down:
    case Intrinsic::amdgcn_permlane_xor:
      return LaneOp.addUse(Src1).addUse(Src2).getReg(0);
    case Intrinsic::amdgcn_permlane16:
    case Intrinsic::amdgcn_permlanex16: {
      Register Src3 = MI.getOperand(5).getReg();
      int64_t Src4 = MI.getOperand(6).getImm();
      int64_t Src5 = MI.getOperand(7).getImm();
      return LaneOp.addUse(Src1)
          .addUse(Src2)
          .addUse(Src3)
          .addImm(Src4)
          .addImm(Src5)
          .getReg(0);
    }
    case Intrinsic::amdgcn_mov_dpp8:
      return LaneOp.addImm(MI.getOperand(3).getImm()).getReg(0);
    case Intrinsic::amdgcn_update_dpp:
      return LaneOp.addUse(Src1)
          .addImm(MI.getOperand(4).getImm())
          .addImm(MI.getOperand(5).getImm())
          .addImm(MI.getOperand(6).getImm())
          .addImm(MI.getOperand(7).getImm())
          .getReg(0);
    default:
      llvm_unreachable("unhandled lane op");
    }
  };

  Register DstReg = MI.getOperand(0).getReg();
  Register Src0 = MI.getOperand(2).getReg();
  Register Src1, Src2;
  if (IID == Intrinsic::amdgcn_readlane || IID == Intrinsic::amdgcn_writelane ||
      IID == Intrinsic::amdgcn_update_dpp || IsSetInactive || IsPermLane16 ||
      IsPermlaneShuffle) {
    Src1 = MI.getOperand(3).getReg();
    if (IID == Intrinsic::amdgcn_writelane || IsPermLane16 ||
        IsPermlaneShuffle) {
      Src2 = MI.getOperand(4).getReg();
    }
  }

  LLT Ty = MRI.getType(DstReg);
  unsigned Size = Ty.getSizeInBits();

  unsigned SplitSize = 32;
  if (IID == Intrinsic::amdgcn_update_dpp && (Size % 64 == 0) &&
      ST.hasDPALU_DPP() &&
      AMDGPU::isLegalDPALU_DPPControl(ST, MI.getOperand(4).getImm()))
    SplitSize = 64;

  if (Size == SplitSize) {
    // Already legal
    return true;
  }

  const LLT I32 = LLT::integer(32);

  bool IsFloat = Ty.getScalarType().isFloat();

  LLT IntTy = IsFloat ? LLT::integer(Size) : Ty;
  if (IsFloat) {
    Src0 = B.buildBitcast(IntTy, Src0).getReg(0);
    if (Src1 && MRI.getType(Src1).getScalarType().isFloat())
      Src1 = B.buildBitcast(IntTy, Src1).getReg(0);
    if (Src2 && MRI.getType(Src2).getScalarType().isFloat())
      Src2 = B.buildBitcast(IntTy, Src2).getReg(0);
  }

  if (Size < 32) {
    Src0 = B.buildAnyExt(I32, Src0).getReg(0);

    if (IID == Intrinsic::amdgcn_update_dpp || IsSetInactive || IsPermLane16)
      Src1 = B.buildAnyExt(I32, Src1).getReg(0);

    if (IID == Intrinsic::amdgcn_writelane)
      Src2 = B.buildAnyExt(I32, Src2).getReg(0);

    Register LaneOpDst = createLaneOp(Src0, Src1, Src2, I32);
    if (IsFloat)
      B.buildBitcast(DstReg, B.buildTrunc(IntTy, LaneOpDst));
    else
      B.buildTrunc(DstReg, LaneOpDst);
    MI.eraseFromParent();
    return true;
  }

  if (Size % SplitSize != 0)
    return false;

  LLT PartialResTy = LLT::integer(SplitSize);
  bool NeedsBitcast = false;
  if (IntTy.isVector()) {
    LLT EltTy = IntTy.getElementType();
    unsigned EltSize = EltTy.getSizeInBits();
    if (EltSize == SplitSize) {
      PartialResTy = EltTy;
    } else if (EltSize == 16 || EltSize == 32) {
      unsigned NElem = SplitSize / EltSize;
      PartialResTy = IntTy.changeElementCount(ElementCount::getFixed(NElem));
    } else {
      NeedsBitcast = true;
    }
  }

  SmallVector<Register, 4> PartialRes;
  unsigned NumParts = Size / SplitSize;
  MachineInstrBuilder Src0Parts = B.buildUnmerge(PartialResTy, Src0);
  MachineInstrBuilder Src1Parts, Src2Parts;

  if (IID == Intrinsic::amdgcn_update_dpp || IsSetInactive || IsPermLane16)
    Src1Parts = B.buildUnmerge(PartialResTy, Src1);

  if (IID == Intrinsic::amdgcn_writelane)
    Src2Parts = B.buildUnmerge(PartialResTy, Src2);

  for (unsigned i = 0; i < NumParts; ++i) {
    Src0 = Src0Parts.getReg(i);

    if (IID == Intrinsic::amdgcn_update_dpp || IsSetInactive || IsPermLane16)
      Src1 = Src1Parts.getReg(i);

    if (IID == Intrinsic::amdgcn_writelane)
      Src2 = Src2Parts.getReg(i);

    PartialRes.push_back(createLaneOp(Src0, Src1, Src2, PartialResTy));
  }

  if (NeedsBitcast || IsFloat)
    B.buildBitcast(
        DstReg,
        B.buildMergeLikeInstr(LLT::integer(IntTy.getSizeInBits()), PartialRes));
  else
    B.buildMergeLikeInstr(DstReg, PartialRes);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::getImplicitArgPtr(Register DstReg,
                                            MachineRegisterInfo &MRI,
                                            MachineIRBuilder &B) const {
  uint64_t Offset =
    ST.getTargetLowering()->getImplicitParameterOffset(
      B.getMF(), AMDGPUTargetLowering::FIRST_IMPLICIT);
  LLT DstTy = MRI.getType(DstReg);
  LLT IdxTy = LLT::integer(DstTy.getSizeInBits());

  Register KernargPtrReg = MRI.createGenericVirtualRegister(DstTy);
  if (!loadInputValue(KernargPtrReg, B,
                      AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR))
    return false;

  B.buildObjectPtrOffset(DstReg, KernargPtrReg,
                         B.buildConstant(IdxTy, Offset).getReg(0));
  return true;
}

/// To create a buffer resource from a 64-bit pointer, mask off the upper 32
/// bits of the pointer and replace them with the stride argument, then
/// merge_values everything together. In the common case of a raw buffer (the
/// stride component is 0), we can just AND off the upper half.
bool AMDGPULegalizerInfo::legalizePointerAsRsrcIntrin(
    MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const {
  Register Result = MI.getOperand(0).getReg();
  Register Pointer = MI.getOperand(2).getReg();
  Register Stride = MI.getOperand(3).getReg();
  Register NumRecords = MI.getOperand(4).getReg();
  Register Flags = MI.getOperand(5).getReg();

  LLT I32 = LLT::integer(32);
  LLT I64 = LLT::integer(64);

  B.setInsertPt(B.getMBB(), ++B.getInsertPt());

  auto ExtStride = B.buildAnyExt(I32, Stride);

  if (ST.getBufferResourceNumRecordsWidth() == 45) {
    NumRecords = B.buildZExtOrTrunc(I64, NumRecords).getReg(0);
    NumRecords =
        B.buildAnd(I64, NumRecords, B.buildConstant(I64, (1ULL << 45) - 1))
            .getReg(0);
    Register Zero = B.buildConstant(I32, 0).getReg(0);
    // Build the lower 64-bit value, which has a 57-bit base and the lower 7-bit
    // num_records.
    LLT PtrIntTy = LLT::integer(MRI.getType(Pointer).getSizeInBits());
    auto PointerInt = B.buildPtrToInt(PtrIntTy, Pointer);
    auto ExtPointer = B.buildAnyExtOrTrunc(I64, PointerInt);
    auto NumRecordsLHS = B.buildShl(I64, NumRecords, B.buildConstant(I32, 57));
    Register LowHalf = B.buildOr(I64, ExtPointer, NumRecordsLHS).getReg(0);

    // Build the higher 64-bit value, which has the higher 38-bit num_records,
    // 6-bit zero (omit), 16-bit stride and scale and 4-bit flag.
    auto NumRecordsRHS = B.buildLShr(I64, NumRecords, B.buildConstant(I32, 7));
    auto ShiftedStride = B.buildShl(I32, ExtStride, B.buildConstant(I32, 12));
    auto ExtShiftedStride =
        B.buildMergeValues(I64, {Zero, ShiftedStride.getReg(0)});
    auto ShiftedFlags = B.buildShl(I32, Flags, B.buildConstant(I32, 28));
    auto ExtShiftedFlags =
        B.buildMergeValues(I64, {Zero, ShiftedFlags.getReg(0)});
    auto CombinedFields = B.buildOr(I64, NumRecordsRHS, ExtShiftedStride);
    Register HighHalf =
        B.buildOr(I64, CombinedFields, ExtShiftedFlags).getReg(0);
    B.buildMergeValues(Result, {LowHalf, HighHalf});
  } else {
    NumRecords = B.buildZExtOrTrunc(I32, NumRecords).getReg(0);
    auto Unmerge = B.buildUnmerge(I32, Pointer);
    auto LowHalf = Unmerge.getReg(0);
    auto HighHalf = Unmerge.getReg(1);

    auto AndMask = B.buildConstant(I32, 0x0000ffff);
    auto Masked = B.buildAnd(I32, HighHalf, AndMask);
    auto ShiftConst = B.buildConstant(I32, 16);
    auto ShiftedStride = B.buildShl(I32, ExtStride, ShiftConst);
    auto NewHighHalf = B.buildOr(I32, Masked, ShiftedStride);
    Register NewHighHalfReg = NewHighHalf.getReg(0);
    B.buildMergeValues(Result, {LowHalf, NewHighHalfReg, NumRecords, Flags});
  }

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeImplicitArgPtr(MachineInstr &MI,
                                                 MachineRegisterInfo &MRI,
                                                 MachineIRBuilder &B) const {
  const SIMachineFunctionInfo *MFI = B.getMF().getInfo<SIMachineFunctionInfo>();
  if (!MFI->isEntryFunction()) {
    return legalizePreloadedArgIntrin(MI, MRI, B,
                                      AMDGPUFunctionArgInfo::IMPLICIT_ARG_PTR);
  }

  Register DstReg = MI.getOperand(0).getReg();
  if (!getImplicitArgPtr(DstReg, MRI, B))
    return false;

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeIsAddrSpace(MachineInstr &MI,
                                              MachineRegisterInfo &MRI,
                                              MachineIRBuilder &B,
                                              unsigned AddrSpace) const {
  const LLT I32 = LLT::integer(32);
  auto Unmerge = B.buildUnmerge(I32, MI.getOperand(2).getReg());
  Register Hi32 = Unmerge.getReg(1);

  if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS &&
      ST.hasGloballyAddressableScratch()) {
    Register FlatScratchBaseHi =
        B.buildInstr(AMDGPU::S_MOV_B32, {I32},
                     {Register(AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)})
            .getReg(0);
    MRI.setRegClass(FlatScratchBaseHi, &AMDGPU::SReg_32RegClass);
    // Test bits 63..58 against the aperture address.
    Register XOR = B.buildXor(I32, Hi32, FlatScratchBaseHi).getReg(0);
    B.buildICmp(ICmpInst::ICMP_ULT, MI.getOperand(0), XOR,
                B.buildConstant(I32, 1u << 26));
  } else {
    Register ApertureReg = getSegmentAperture(AddrSpace, MRI, B);
    B.buildICmp(ICmpInst::ICMP_EQ, MI.getOperand(0), Hi32, ApertureReg);
  }
  MI.eraseFromParent();
  return true;
}

// The raw.(t)buffer and struct.(t)buffer intrinsics have two offset args:
// offset (the offset that is included in bounds checking and swizzling, to be
// split between the instruction's voffset and immoffset fields) and soffset
// (the offset that is excluded from bounds checking and swizzling, to go in
// the instruction's soffset field).  This function takes the first kind of
// offset and figures out how to split it between voffset and immoffset.
std::pair<Register, unsigned>
AMDGPULegalizerInfo::splitBufferOffsets(MachineIRBuilder &B,
                                        Register OrigOffset) const {
  const unsigned MaxImm = SIInstrInfo::getMaxMUBUFImmOffset(ST);
  Register BaseReg;
  unsigned ImmOffset;
  const LLT I32 = LLT::integer(32);
  MachineRegisterInfo &MRI = *B.getMRI();

  // On GFX1250+, voffset and immoffset are zero-extended from 32 bits before
  // being added, so we can only safely match a 32-bit addition with no unsigned
  // overflow.
  bool CheckNUW = ST.hasGFX1250Insts();
  std::tie(BaseReg, ImmOffset) = AMDGPU::getBaseWithConstantOffset(
      MRI, OrigOffset, /*KnownBits=*/nullptr, CheckNUW);

  // If BaseReg is a pointer, convert it to int.
  if (MRI.getType(BaseReg).isPointer())
    BaseReg = B.buildPtrToInt(MRI.getType(OrigOffset), BaseReg).getReg(0);

  // If the immediate value is too big for the immoffset field, put only bits
  // that would normally fit in the immoffset field. The remaining value that
  // is copied/added for the voffset field is a large power of 2, and it
  // stands more chance of being CSEd with the copy/add for another similar
  // load/store.
  // However, do not do that rounding down if that is a negative
  // number, as it appears to be illegal to have a negative offset in the
  // vgpr, even if adding the immediate offset makes it positive.
  unsigned Overflow = ImmOffset & ~MaxImm;
  ImmOffset -= Overflow;
  if ((int32_t)Overflow < 0) {
    Overflow += ImmOffset;
    ImmOffset = 0;
  }

  if (Overflow != 0) {
    if (!BaseReg) {
      BaseReg = B.buildConstant(I32, Overflow).getReg(0);
    } else {
      auto OverflowVal = B.buildConstant(I32, Overflow);
      BaseReg = B.buildAdd(I32, BaseReg, OverflowVal).getReg(0);
    }
  }

  if (!BaseReg)
    BaseReg = B.buildConstant(I32, 0).getReg(0);

  return std::pair(BaseReg, ImmOffset);
}

/// Handle register layout difference for f16 images for some subtargets.
Register AMDGPULegalizerInfo::handleD16VData(MachineIRBuilder &B,
                                             MachineRegisterInfo &MRI,
                                             Register Reg,
                                             bool ImageStore) const {
  const LLT I16 = LLT::integer(16);
  const LLT I32 = LLT::integer(32);
  LLT StoreVT = MRI.getType(Reg);
  assert(StoreVT.isVector() && StoreVT.getElementType().getSizeInBits() == 16);

  LLT I16Vec = StoreVT.changeElementType(I16);
  Register RegI16 =
      StoreVT == I16Vec ? Reg : B.buildBitcast(I16Vec, Reg).getReg(0);

  if (ST.hasUnpackedD16VMem()) {
    auto Unmerge = B.buildUnmerge(I16, RegI16);

    SmallVector<Register, 4> WideRegs;
    for (int I = 0, E = Unmerge->getNumOperands() - 1; I != E; ++I)
      WideRegs.push_back(B.buildAnyExt(I32, Unmerge.getReg(I)).getReg(0));

    int NumElts = StoreVT.getNumElements();

    return B.buildBuildVector(LLT::fixed_vector(NumElts, I32), WideRegs)
        .getReg(0);
  }

  if (ImageStore && ST.hasImageStoreD16Bug()) {
    if (StoreVT.getNumElements() == 2) {
      SmallVector<Register, 4> PackedRegs;
      Reg = B.buildBitcast(I32, RegI16).getReg(0);
      PackedRegs.push_back(Reg);
      PackedRegs.resize(2, B.buildUndef(I32).getReg(0));
      return B.buildBuildVector(LLT::fixed_vector(2, I32), PackedRegs)
          .getReg(0);
    }

    if (StoreVT.getNumElements() == 3) {
      SmallVector<Register, 4> PackedRegs;
      auto Unmerge = B.buildUnmerge(I16, RegI16);
      for (int I = 0, E = Unmerge->getNumOperands() - 1; I != E; ++I)
        PackedRegs.push_back(Unmerge.getReg(I));
      PackedRegs.resize(6, B.buildUndef(I16).getReg(0));
      Reg = B.buildBuildVector(LLT::fixed_vector(6, I16), PackedRegs).getReg(0);
      return B.buildBitcast(LLT::fixed_vector(3, I32), Reg).getReg(0);
    }

    if (StoreVT.getNumElements() == 4) {
      SmallVector<Register, 4> PackedRegs;
      Reg = B.buildBitcast(LLT::fixed_vector(2, I32), RegI16).getReg(0);
      auto Unmerge = B.buildUnmerge(I32, Reg);
      for (int I = 0, E = Unmerge->getNumOperands() - 1; I != E; ++I)
        PackedRegs.push_back(Unmerge.getReg(I));
      PackedRegs.resize(4, B.buildUndef(I32).getReg(0));
      return B.buildBuildVector(LLT::fixed_vector(4, I32), PackedRegs)
          .getReg(0);
    }

    llvm_unreachable("invalid data type");
  }

  if (StoreVT.isVector() && StoreVT.getNumElements() == 3 &&
      StoreVT.getElementType().getSizeInBits() == 16) {
    Reg = B.buildPadVectorWithUndefElements(
               LLT::fixed_vector(4, StoreVT.getElementType()), Reg)
              .getReg(0);
  }
  return Reg;
}

Register AMDGPULegalizerInfo::fixStoreSourceType(MachineIRBuilder &B,
                                                 Register VData, LLT MemTy,
                                                 bool IsFormat) const {
  MachineRegisterInfo *MRI = B.getMRI();
  LLT Ty = MRI->getType(VData);

  // Fixup buffer resources themselves needing to be v4i128.
  if (hasBufferRsrcWorkaround(Ty))
    return castBufferRsrcToV4I32(VData, B);

  if (shouldBitcastLoadStoreType(ST, Ty, MemTy)) {
    Ty = getBitcastRegisterType(Ty);
    VData = B.buildBitcast(Ty, VData).getReg(0);
  }
  if (Ty.isFloat(16)) {
    Ty = LLT::integer(16);
    VData = B.buildBitcast(Ty, VData).getReg(0);
  }

  // Fixup illegal register types for i8 stores.
  if (Ty == LLT::integer(8) || Ty == LLT::integer(16))
    return B.buildAnyExt(LLT::integer(32), VData).getReg(0);

  if (Ty.isVector()) {
    if (Ty.getElementType().getSizeInBits() == 16 && Ty.getNumElements() <= 4) {
      if (IsFormat)
        return handleD16VData(B, *MRI, VData);
    }
  }

  return VData;
}

bool AMDGPULegalizerInfo::legalizeBufferStore(MachineInstr &MI,
                                              LegalizerHelper &Helper,
                                              bool IsTyped,
                                              bool IsFormat) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();

  Register VData = MI.getOperand(1).getReg();
  LLT Ty = MRI.getType(VData);
  LLT EltTy = Ty.getScalarType();
  const bool IsD16 = IsFormat && (EltTy.getSizeInBits() == 16);
  const LLT I32 = LLT::integer(32);

  MachineMemOperand *MMO = *MI.memoperands_begin();
  const int MemSize = MMO->getSize().getValue();
  LLT MemTy = MMO->getMemoryType();

  if (IsFormat && !IsTyped && !IsD16 && MemTy.getSizeInBits() < 32) {
    const Function &Fn = B.getMF().getFunction();
    Fn.getContext().diagnose(DiagnosticInfoUnsupported(
        Fn, "unsupported sub-dword format buffer store", MI.getDebugLoc()));
    MI.eraseFromParent();
    return true;
  }

  VData = fixStoreSourceType(B, VData, MemTy, IsFormat);

  castBufferRsrcArgToV4I32(MI, B, 2);
  Register RSrc = MI.getOperand(2).getReg();

  unsigned ImmOffset;

  // The typed intrinsics add an immediate after the registers.
  const unsigned NumVIndexOps = IsTyped ? 8 : 7;

  // The struct intrinsic variants add one additional operand over raw.
  const bool HasVIndex = MI.getNumOperands() == NumVIndexOps;
  Register VIndex;
  int OpOffset = 0;
  if (HasVIndex) {
    VIndex = MI.getOperand(3).getReg();
    OpOffset = 1;
  } else {
    VIndex = B.buildConstant(I32, 0).getReg(0);
  }

  Register VOffset = MI.getOperand(3 + OpOffset).getReg();
  Register SOffset = MI.getOperand(4 + OpOffset).getReg();

  unsigned Format = 0;
  if (IsTyped) {
    Format = MI.getOperand(5 + OpOffset).getImm();
    ++OpOffset;
  }

  unsigned AuxiliaryData = MI.getOperand(5 + OpOffset).getImm();

  std::tie(VOffset, ImmOffset) = splitBufferOffsets(B, VOffset);

  unsigned Opc;
  if (IsTyped) {
    Opc = IsD16 ? AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT_D16 :
                  AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT;
  } else if (IsFormat) {
    Opc = IsD16 ? AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT_D16 :
                  AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT;
  } else {
    switch (MemSize) {
    case 1:
      Opc = AMDGPU::G_AMDGPU_BUFFER_STORE_BYTE;
      break;
    case 2:
      Opc = AMDGPU::G_AMDGPU_BUFFER_STORE_SHORT;
      break;
    default:
      Opc = AMDGPU::G_AMDGPU_BUFFER_STORE;
      break;
    }
  }

  auto MIB = B.buildInstr(Opc)
    .addUse(VData)              // vdata
    .addUse(RSrc)               // rsrc
    .addUse(VIndex)             // vindex
    .addUse(VOffset)            // voffset
    .addUse(SOffset)            // soffset
    .addImm(ImmOffset);         // offset(imm)

  if (IsTyped)
    MIB.addImm(Format);

  MIB.addImm(AuxiliaryData)      // cachepolicy, swizzled buffer(imm)
     .addImm(HasVIndex ? -1 : 0) // idxen(imm)
     .addMemOperand(MMO);

  MI.eraseFromParent();
  return true;
}

static void buildBufferLoad(unsigned Opc, Register LoadDstReg, Register RSrc,
                            Register VIndex, Register VOffset, Register SOffset,
                            unsigned ImmOffset, unsigned Format,
                            unsigned AuxiliaryData, MachineMemOperand *MMO,
                            bool IsTyped, bool HasVIndex, MachineIRBuilder &B) {
  auto MIB = B.buildInstr(Opc)
                 .addDef(LoadDstReg) // vdata
                 .addUse(RSrc)       // rsrc
                 .addUse(VIndex)     // vindex
                 .addUse(VOffset)    // voffset
                 .addUse(SOffset)    // soffset
                 .addImm(ImmOffset); // offset(imm)

  if (IsTyped)
    MIB.addImm(Format);

  MIB.addImm(AuxiliaryData)       // cachepolicy, swizzled buffer(imm)
      .addImm(HasVIndex ? -1 : 0) // idxen(imm)
      .addMemOperand(MMO);
}

static void buildTFEBufferLoad(unsigned Opc, ArrayRef<Register> ValueDsts,
                               Register StatusDst, Register RSrc,
                               Register VIndex, Register VOffset,
                               Register SOffset, unsigned ImmOffset,
                               unsigned Format, unsigned AuxiliaryData,
                               MachineMemOperand *MMO, bool IsTyped,
                               bool HasVIndex, MachineIRBuilder &B) {
  LLT LoadTy = LLT::fixed_vector(ValueDsts.size() + 1, LLT::integer(32));
  Register LoadDstReg = B.getMRI()->createGenericVirtualRegister(LoadTy);
  buildBufferLoad(Opc, LoadDstReg, RSrc, VIndex, VOffset, SOffset, ImmOffset,
                  Format, AuxiliaryData, MMO, IsTyped, HasVIndex, B);
  SmallVector<Register, 5> Unmerge(ValueDsts);
  Unmerge.push_back(StatusDst);
  B.buildUnmerge(Unmerge, LoadDstReg);
}

bool AMDGPULegalizerInfo::legalizeBufferLoad(MachineInstr &MI,
                                             LegalizerHelper &Helper,
                                             bool IsFormat,
                                             bool IsTyped) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();
  GISelChangeObserver &Observer = Helper.Observer;

  // FIXME: Verifier should enforce 1 MMO for these intrinsics.
  MachineMemOperand *MMO = *MI.memoperands_begin();
  const LLT MemTy = MMO->getMemoryType();
  const LLT I32 = LLT::integer(32);

  Register Dst = MI.getOperand(0).getReg();

  Register StatusDst;
  int OpOffset = 0;
  assert(MI.getNumExplicitDefs() == 1 || MI.getNumExplicitDefs() == 2);
  bool IsTFE = MI.getNumExplicitDefs() == 2;
  if (IsTFE) {
    StatusDst = MI.getOperand(1).getReg();
    ++OpOffset;
  }

  castBufferRsrcArgToV4I32(MI, B, 2 + OpOffset);
  Register RSrc = MI.getOperand(2 + OpOffset).getReg();

  // The typed intrinsics add an immediate after the registers.
  const unsigned NumVIndexOps = IsTyped ? 8 : 7;

  // The struct intrinsic variants add one additional operand over raw.
  const bool HasVIndex = MI.getNumOperands() == NumVIndexOps + OpOffset;
  Register VIndex;
  if (HasVIndex) {
    VIndex = MI.getOperand(3 + OpOffset).getReg();
    ++OpOffset;
  } else {
    VIndex = B.buildConstant(I32, 0).getReg(0);
  }

  Register VOffset = MI.getOperand(3 + OpOffset).getReg();
  Register SOffset = MI.getOperand(4 + OpOffset).getReg();

  unsigned Format = 0;
  if (IsTyped) {
    Format = MI.getOperand(5 + OpOffset).getImm();
    ++OpOffset;
  }

  unsigned AuxiliaryData = MI.getOperand(5 + OpOffset).getImm();
  unsigned ImmOffset;

  LLT Ty = MRI.getType(Dst);
  // Make addrspace 8 pointers loads into 4xi32 loads here, so the rest of the
  // logic doesn't have to handle that case.
  if (hasBufferRsrcWorkaround(Ty)) {
    Observer.changingInstr(MI);
    Ty = castBufferRsrcFromV4I32(MI, B, MRI, 0);
    Observer.changedInstr(MI);
    Dst = MI.getOperand(0).getReg();
    B.setInsertPt(B.getMBB(), MI);
  }
  if (shouldBitcastLoadStoreType(ST, Ty, MemTy)) {
    Ty = getBitcastRegisterType(Ty);
    Observer.changingInstr(MI);
    Helper.bitcastDst(MI, Ty, 0);
    Observer.changedInstr(MI);
    Dst = MI.getOperand(0).getReg();
    B.setInsertPt(B.getMBB(), MI);
  }

  LLT EltTy = Ty.getScalarType();
  const bool IsD16 = IsFormat && (EltTy.getSizeInBits() == 16);
  const bool Unpacked = ST.hasUnpackedD16VMem();

  if (IsFormat && !IsTyped && !IsD16 && MemTy.getSizeInBits() < 32) {
    const Function &Fn = B.getMF().getFunction();
    Fn.getContext().diagnose(DiagnosticInfoUnsupported(
        Fn, "unsupported sub-dword format buffer load", MI.getDebugLoc()));
    B.buildUndef(Dst);
    if (IsTFE)
      B.buildUndef(StatusDst);
    MI.eraseFromParent();
    return true;
  }

  if (!IsTyped && IsD16 && IsTFE && !ST.hasBufferTFEFormatD16()) {
    const Function &Fn = B.getMF().getFunction();
    Fn.getContext().diagnose(DiagnosticInfoUnsupported(
        Fn, "TFE D16 format buffer load is not supported on this GPU",
        MI.getDebugLoc()));
    B.buildUndef(Dst);
    B.buildUndef(StatusDst);
    MI.eraseFromParent();
    return true;
  }

  std::tie(VOffset, ImmOffset) = splitBufferOffsets(B, VOffset);

  unsigned Opc;

  // TODO: Support TFE for typed and narrow loads.
  if (IsTyped) {
    if (IsTFE)
      return false;
    Opc = IsD16 ? AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT_D16 :
                  AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT;
  } else if (IsFormat) {
    if (IsD16) {
      Opc = IsTFE ? AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT_D16_TFE
                  : AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT_D16;
    } else {
      Opc = IsTFE ? AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT_TFE
                  : AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT;
    }
  } else {
    switch (MemTy.getSizeInBits()) {
    case 8:
      Opc = IsTFE ? AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE_TFE
                  : AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE;
      break;
    case 16:
      Opc = IsTFE ? AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT_TFE
                  : AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT;
      break;
    default:
      Opc = IsTFE ? AMDGPU::G_AMDGPU_BUFFER_LOAD_TFE
                  : AMDGPU::G_AMDGPU_BUFFER_LOAD;
      break;
    }
  }

  if (IsTFE && IsD16 && Ty.isVector()) {
    // Value dwords need not cover Ty exactly: v3i16 needs 2 dwords for 48 bits.
    const unsigned NumElts = Ty.getNumElements();
    const unsigned NumValueDWords = Unpacked ? NumElts : divideCeil(NumElts, 2);

    SmallVector<Register, 4> ValueDWords;
    for (unsigned I = 0; I != NumValueDWords; ++I)
      ValueDWords.push_back(MRI.createGenericVirtualRegister(I32));
    buildTFEBufferLoad(Opc, ValueDWords, StatusDst, RSrc, VIndex, VOffset,
                       SOffset, ImmOffset, Format, AuxiliaryData, MMO, IsTyped,
                       HasVIndex, B);

    if (Unpacked) {
      for (Register &R : ValueDWords)
        R = B.buildTrunc(EltTy, R).getReg(0);
      B.buildMergeLikeInstr(Dst, ValueDWords);
    } else {
      Register Merged =
          NumValueDWords == 1
              ? ValueDWords[0]
              : B.buildMergeLikeInstr(LLT::fixed_vector(NumValueDWords, I32),
                                      ValueDWords)
                    .getReg(0);
      LLT PackedTy = LLT::fixed_vector(NumValueDWords * 2, EltTy);
      if (PackedTy == Ty) {
        B.buildBitcast(Dst, Merged);
      } else {
        Register Packed = B.buildBitcast(PackedTy, Merged).getReg(0);
        B.buildDeleteTrailingVectorElements(Dst, Packed);
      }
    }
  } else if (IsTFE) {
    const unsigned NumValueDWords = divideCeil(Ty.getSizeInBits(), 32);
    Register DstInt =
        EltTy.isFloat() ? MRI.createGenericVirtualRegister(Ty.changeElementType(
                              LLT::integer(EltTy.getSizeInBits())))
                        : Dst;
    if (MemTy.getSizeInBits() < 32) {
      Register ExtDst = MRI.createGenericVirtualRegister(I32);
      buildTFEBufferLoad(Opc, ExtDst, StatusDst, RSrc, VIndex, VOffset, SOffset,
                         ImmOffset, Format, AuxiliaryData, MMO, IsTyped,
                         HasVIndex, B);
      B.buildTrunc(DstInt, ExtDst);
    } else if (NumValueDWords == 1) {
      buildTFEBufferLoad(Opc, DstInt, StatusDst, RSrc, VIndex, VOffset, SOffset,
                         ImmOffset, Format, AuxiliaryData, MMO, IsTyped,
                         HasVIndex, B);
    } else {
      SmallVector<Register, 4> ValueDWords;
      for (unsigned I = 0; I != NumValueDWords; ++I)
        ValueDWords.push_back(MRI.createGenericVirtualRegister(I32));
      buildTFEBufferLoad(Opc, ValueDWords, StatusDst, RSrc, VIndex, VOffset,
                         SOffset, ImmOffset, Format, AuxiliaryData, MMO,
                         IsTyped, HasVIndex, B);
      B.buildMergeLikeInstr(DstInt, ValueDWords);
    }
    if (DstInt != Dst)
      B.buildBitcast(Dst, DstInt);
  } else if ((!IsD16 && MemTy.getSizeInBits() < 32) ||
             (IsD16 && !Ty.isVector())) {
    Register LoadDstReg = B.getMRI()->createGenericVirtualRegister(I32);
    buildBufferLoad(Opc, LoadDstReg, RSrc, VIndex, VOffset, SOffset, ImmOffset,
                    Format, AuxiliaryData, MMO, IsTyped, HasVIndex, B);
    B.setInsertPt(B.getMBB(), ++B.getInsertPt());
    B.buildTrunc(Dst, LoadDstReg);
  } else if (Unpacked && IsD16 && Ty.isVector()) {
    LLT UnpackedTy = LLT::fixed_vector(Ty.getNumElements(), LLT::integer(32));
    Register LoadDstReg = B.getMRI()->createGenericVirtualRegister(UnpackedTy);
    buildBufferLoad(Opc, LoadDstReg, RSrc, VIndex, VOffset, SOffset, ImmOffset,
                    Format, AuxiliaryData, MMO, IsTyped, HasVIndex, B);
    B.setInsertPt(B.getMBB(), ++B.getInsertPt());
    // FIXME: G_TRUNC should work, but legalization currently fails
    auto Unmerge = B.buildUnmerge(I32, LoadDstReg);
    SmallVector<Register, 4> Repack;
    for (unsigned I = 0, N = Unmerge->getNumOperands() - 1; I != N; ++I)
      Repack.push_back(B.buildTrunc(EltTy, Unmerge.getReg(I)).getReg(0));
    B.buildMergeLikeInstr(Dst, Repack);
  } else {
    buildBufferLoad(Opc, Dst, RSrc, VIndex, VOffset, SOffset, ImmOffset, Format,
                    AuxiliaryData, MMO, IsTyped, HasVIndex, B);
  }

  MI.eraseFromParent();
  return true;
}

static unsigned getBufferAtomicPseudo(Intrinsic::ID IntrID) {
  switch (IntrID) {
  case Intrinsic::amdgcn_raw_buffer_atomic_swap:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_swap:
  case Intrinsic::amdgcn_struct_buffer_atomic_swap:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_swap:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SWAP;
  case Intrinsic::amdgcn_raw_buffer_atomic_add:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_add:
  case Intrinsic::amdgcn_struct_buffer_atomic_add:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_add:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_ADD;
  case Intrinsic::amdgcn_raw_buffer_atomic_sub:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_sub:
  case Intrinsic::amdgcn_struct_buffer_atomic_sub:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_sub:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SUB;
  case Intrinsic::amdgcn_raw_buffer_atomic_smin:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_smin:
  case Intrinsic::amdgcn_struct_buffer_atomic_smin:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_smin:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMIN;
  case Intrinsic::amdgcn_raw_buffer_atomic_umin:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_umin:
  case Intrinsic::amdgcn_struct_buffer_atomic_umin:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_umin:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMIN;
  case Intrinsic::amdgcn_raw_buffer_atomic_smax:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_smax:
  case Intrinsic::amdgcn_struct_buffer_atomic_smax:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_smax:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMAX;
  case Intrinsic::amdgcn_raw_buffer_atomic_umax:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_umax:
  case Intrinsic::amdgcn_struct_buffer_atomic_umax:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_umax:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMAX;
  case Intrinsic::amdgcn_raw_buffer_atomic_and:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_and:
  case Intrinsic::amdgcn_struct_buffer_atomic_and:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_and:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_AND;
  case Intrinsic::amdgcn_raw_buffer_atomic_or:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_or:
  case Intrinsic::amdgcn_struct_buffer_atomic_or:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_or:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_OR;
  case Intrinsic::amdgcn_raw_buffer_atomic_xor:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_xor:
  case Intrinsic::amdgcn_struct_buffer_atomic_xor:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_xor:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_XOR;
  case Intrinsic::amdgcn_raw_buffer_atomic_inc:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_inc:
  case Intrinsic::amdgcn_struct_buffer_atomic_inc:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_inc:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_INC;
  case Intrinsic::amdgcn_raw_buffer_atomic_dec:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_dec:
  case Intrinsic::amdgcn_struct_buffer_atomic_dec:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_dec:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_DEC;
  case Intrinsic::amdgcn_raw_buffer_atomic_cmpswap:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_cmpswap:
  case Intrinsic::amdgcn_struct_buffer_atomic_cmpswap:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_cmpswap:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_CMPSWAP;
  case Intrinsic::amdgcn_raw_buffer_atomic_fadd:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_fadd:
  case Intrinsic::amdgcn_struct_buffer_atomic_fadd:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_fadd:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FADD;
  case Intrinsic::amdgcn_raw_buffer_atomic_fmin:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_fmin:
  case Intrinsic::amdgcn_struct_buffer_atomic_fmin:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_fmin:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FMIN;
  case Intrinsic::amdgcn_raw_buffer_atomic_fmax:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_fmax:
  case Intrinsic::amdgcn_struct_buffer_atomic_fmax:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_fmax:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FMAX;
  case Intrinsic::amdgcn_raw_buffer_atomic_sub_clamp_u32:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_sub_clamp_u32:
  case Intrinsic::amdgcn_struct_buffer_atomic_sub_clamp_u32:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_sub_clamp_u32:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SUB_CLAMP_U32;
  case Intrinsic::amdgcn_raw_buffer_atomic_cond_sub_u32:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_cond_sub_u32:
  case Intrinsic::amdgcn_struct_buffer_atomic_cond_sub_u32:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_cond_sub_u32:
    return AMDGPU::G_AMDGPU_BUFFER_ATOMIC_COND_SUB_U32;
  default:
    llvm_unreachable("unhandled atomic opcode");
  }
}

bool AMDGPULegalizerInfo::legalizeBufferAtomic(MachineInstr &MI,
                                               MachineIRBuilder &B,
                                               Intrinsic::ID IID) const {
  const bool IsCmpSwap =
      IID == Intrinsic::amdgcn_raw_buffer_atomic_cmpswap ||
      IID == Intrinsic::amdgcn_struct_buffer_atomic_cmpswap ||
      IID == Intrinsic::amdgcn_raw_ptr_buffer_atomic_cmpswap ||
      IID == Intrinsic::amdgcn_struct_ptr_buffer_atomic_cmpswap;

  Register Dst = MI.getOperand(0).getReg();
  // Since we don't have 128-bit atomics, we don't need to handle the case of
  // p8 argmunents to the atomic itself
  Register VData = MI.getOperand(2).getReg();

  Register CmpVal;
  int OpOffset = 0;

  if (IsCmpSwap) {
    CmpVal = MI.getOperand(3).getReg();
    ++OpOffset;
  }

  castBufferRsrcArgToV4I32(MI, B, 3 + OpOffset);
  Register RSrc = MI.getOperand(3 + OpOffset).getReg();
  const unsigned NumVIndexOps = IsCmpSwap ? 9 : 8;

  // The struct intrinsic variants add one additional operand over raw.
  const bool HasVIndex = MI.getNumOperands() == NumVIndexOps;
  Register VIndex;
  if (HasVIndex) {
    VIndex = MI.getOperand(4 + OpOffset).getReg();
    ++OpOffset;
  } else {
    VIndex = B.buildConstant(LLT::integer(32), 0).getReg(0);
  }

  Register VOffset = MI.getOperand(4 + OpOffset).getReg();
  Register SOffset = MI.getOperand(5 + OpOffset).getReg();
  unsigned AuxiliaryData = MI.getOperand(6 + OpOffset).getImm();

  MachineMemOperand *MMO = *MI.memoperands_begin();

  unsigned ImmOffset;
  std::tie(VOffset, ImmOffset) = splitBufferOffsets(B, VOffset);

  auto MIB = B.buildInstr(getBufferAtomicPseudo(IID))
      .addDef(Dst)
      .addUse(VData); // vdata

  if (IsCmpSwap)
    MIB.addReg(CmpVal);

  MIB.addUse(RSrc)               // rsrc
     .addUse(VIndex)             // vindex
     .addUse(VOffset)            // voffset
     .addUse(SOffset)            // soffset
     .addImm(ImmOffset)          // offset(imm)
     .addImm(AuxiliaryData)      // cachepolicy, swizzled buffer(imm)
     .addImm(HasVIndex ? -1 : 0) // idxen(imm)
     .addMemOperand(MMO);

  MI.eraseFromParent();
  return true;
}

/// Turn a set of f16 typed registers in \p AddrRegs into a dword sized
/// vector with f16 typed elements.
static void packImage16bitOpsToDwords(MachineIRBuilder &B, MachineInstr &MI,
                                      SmallVectorImpl<Register> &PackedAddrs,
                                      unsigned ArgOffset,
                                      const AMDGPU::ImageDimIntrinsicInfo *Intr,
                                      bool IsA16, bool IsG16) {
  auto EndIdx = Intr->VAddrEnd;

  for (unsigned I = Intr->VAddrStart; I < EndIdx; I++) {
    MachineOperand &SrcOp = MI.getOperand(ArgOffset + I);
    if (!SrcOp.isReg())
      continue; // _L to _LZ may have eliminated this.

    Register AddrReg = SrcOp.getReg();

    if ((I < Intr->GradientStart) ||
        (I >= Intr->GradientStart && I < Intr->CoordStart && !IsG16) ||
        (I >= Intr->CoordStart && !IsA16)) {
      if ((I < Intr->GradientStart) && IsA16 &&
          (B.getMRI()->getType(AddrReg) == F16)) {
        assert(I == Intr->BiasIndex && "Got unexpected 16-bit extra argument");
        // Special handling of bias when A16 is on. Bias is of type half but
        // occupies full 32-bit.
        PackedAddrs.push_back(
            B.buildBuildVector(V2F16, {AddrReg, B.buildUndef(F16).getReg(0)})
                .getReg(0));
      } else {
        assert((!IsA16 || Intr->NumBiasArgs == 0 || I != Intr->BiasIndex) &&
               "Bias needs to be converted to 16 bit in A16 mode");
        // Handle any gradient or coordinate operands that should not be packed
        AddrReg = B.buildBitcast(V2F16, AddrReg).getReg(0);
        PackedAddrs.push_back(AddrReg);
      }
    } else {
      const LLT EltTy = B.getMRI()->getType(AddrReg);
      const LLT V2EltTy = LLT::fixed_vector(2, EltTy);
      // Dz/dh, dz/dv and the last odd coord are packed with undef. Also, in 1D,
      // derivatives dx/dh and dx/dv are packed with undef.
      if (((I + 1) >= EndIdx) ||
          ((Intr->NumGradients / 2) % 2 == 1 &&
           (I == static_cast<unsigned>(Intr->GradientStart +
                                       (Intr->NumGradients / 2) - 1) ||
            I == static_cast<unsigned>(Intr->GradientStart +
                                       Intr->NumGradients - 1))) ||
          // Check for _L to _LZ optimization
          !MI.getOperand(ArgOffset + I + 1).isReg()) {
        PackedAddrs.push_back(
            B.buildBuildVector(V2EltTy,
                               {AddrReg, B.buildUndef(EltTy).getReg(0)})
                .getReg(0));
      } else {
        PackedAddrs.push_back(
            B.buildBuildVector(
                 V2EltTy, {AddrReg, MI.getOperand(ArgOffset + I + 1).getReg()})
                .getReg(0));
        ++I;
      }
    }
  }
}

/// Convert from separate vaddr components to a single vector address register,
/// and replace the remaining operands with $noreg.
static void convertImageAddrToPacked(MachineIRBuilder &B, MachineInstr &MI,
                                     int DimIdx, int NumVAddrs) {
  SmallVector<Register, 8> AddrRegs;
  for (int I = 0; I != NumVAddrs; ++I) {
    MachineOperand &SrcOp = MI.getOperand(DimIdx + I);
    if (SrcOp.isReg()) {
      Register Reg = SrcOp.getReg();
      LLT I32 = LLT::integer(32);
      assert(B.getMRI()->getType(Reg).getSizeInBits() == 32);
      if (B.getMRI()->getType(Reg) != I32)
        Reg = B.buildBitcast(I32, Reg).getReg(0);
      AddrRegs.push_back(Reg);
    }
  }

  int NumAddrRegs = AddrRegs.size();
  if (NumAddrRegs != 1) {
    LLT EltTy = B.getMRI()->getType(AddrRegs[0]);
    auto VAddr =
        B.buildBuildVector(LLT::fixed_vector(NumAddrRegs, EltTy), AddrRegs);
    MI.getOperand(DimIdx).setReg(VAddr.getReg(0));
  }

  for (int I = 1; I != NumVAddrs; ++I) {
    MachineOperand &SrcOp = MI.getOperand(DimIdx + I);
    if (SrcOp.isReg())
      MI.getOperand(DimIdx + I).setReg(AMDGPU::NoRegister);
  }
}

/// Rewrite image intrinsics to use register layouts expected by the subtarget.
///
/// Depending on the subtarget, load/store with 16-bit element data need to be
/// rewritten to use the low half of 32-bit registers, or directly use a packed
/// layout. 16-bit addresses should also sometimes be packed into 32-bit
/// registers.
///
/// We don't want to directly select image instructions just yet, but also want
/// to exposes all register repacking to the legalizer/combiners. We also don't
/// want a selected instruction entering RegBankSelect. In order to avoid
/// defining a multitude of intermediate image instructions, directly hack on
/// the intrinsic's arguments. In cases like a16 addresses, this requires
/// padding now unnecessary arguments with $noreg.
bool AMDGPULegalizerInfo::legalizeImageIntrinsic(
    MachineInstr &MI, MachineIRBuilder &B, GISelChangeObserver &Observer,
    const AMDGPU::ImageDimIntrinsicInfo *Intr) const {

  const MachineFunction &MF = *MI.getMF();
  const unsigned NumDefs = MI.getNumExplicitDefs();
  const unsigned ArgOffset = NumDefs + 1;
  bool IsTFE = NumDefs == 2;
  // We are only processing the operands of d16 image operations on subtargets
  // that use the unpacked register layout, or need to repack the TFE result.

  // TODO: Do we need to guard against already legalized intrinsics?
  const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
      AMDGPU::getMIMGBaseOpcodeInfo(Intr->BaseOpcode);

  MachineRegisterInfo *MRI = B.getMRI();
  const LLT I32 = LLT::integer(32);
  const LLT I16 = LLT::integer(16);
  const LLT V2I16 = LLT::fixed_vector(2, I16);

  unsigned DMask = 0;
  Register VData;
  LLT Ty;

  if (!BaseOpcode->NoReturn || BaseOpcode->Store) {
    VData = MI.getOperand(NumDefs == 0 ? 1 : 0).getReg();
    Ty = MRI->getType(VData);
  }

  const bool IsAtomicPacked16Bit =
      (BaseOpcode->BaseOpcode == AMDGPU::IMAGE_ATOMIC_PK_ADD_F16 ||
       BaseOpcode->BaseOpcode == AMDGPU::IMAGE_ATOMIC_PK_ADD_BF16);

  // Check for 16 bit addresses and pack if true.
  LLT GradTy =
      MRI->getType(MI.getOperand(ArgOffset + Intr->GradientStart).getReg());
  LLT AddrTy =
      MRI->getType(MI.getOperand(ArgOffset + Intr->CoordStart).getReg());
  const bool GradTyIs16 = GradTy == I16 || GradTy == F16;
  const bool AddrTyIs16 = AddrTy == I16 || AddrTy == F16;
  const bool DataTyIs16 =
      Ty.getScalarType() == I16 || Ty.getScalarType() == F16;
  const bool IsG16 =
      ST.hasG16() ? (BaseOpcode->Gradients && GradTyIs16) : GradTyIs16;
  const bool IsA16 = AddrTyIs16;
  const bool IsD16 = !IsAtomicPacked16Bit && DataTyIs16;

  int DMaskLanes = 0;
  if (!BaseOpcode->Atomic) {
    DMask = MI.getOperand(ArgOffset + Intr->DMaskIndex).getImm();
    if (BaseOpcode->Gather4) {
      DMaskLanes = 4;
    } else if (DMask != 0) {
      DMaskLanes = llvm::popcount(DMask);
    } else if (!IsTFE && !BaseOpcode->Store) {
      // If dmask is 0, this is a no-op load. This can be eliminated.
      B.buildUndef(MI.getOperand(0));
      MI.eraseFromParent();
      return true;
    }
  }

  Observer.changingInstr(MI);
  scope_exit ChangedInstr([&] { Observer.changedInstr(MI); });

  const unsigned StoreOpcode = IsD16 ? AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE_D16
                                     : AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE;
  const unsigned LoadOpcode = IsD16 ? AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD_D16
                                    : AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD;
  unsigned NewOpcode = LoadOpcode;
  if (BaseOpcode->Store)
    NewOpcode = StoreOpcode;
  else if (BaseOpcode->NoReturn)
    NewOpcode = AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD_NORET;

  // Track that we legalized this
  MI.setDesc(B.getTII().get(NewOpcode));

  // Expecting to get an error flag since TFC is on - and dmask is 0 Force
  // dmask to be at least 1 otherwise the instruction will fail
  if (IsTFE && DMask == 0) {
    DMask = 0x1;
    DMaskLanes = 1;
    MI.getOperand(ArgOffset + Intr->DMaskIndex).setImm(DMask);
  }

  if (BaseOpcode->Atomic) {
    Register VData0 = MI.getOperand(2).getReg();
    LLT Ty = MRI->getType(VData0);

    // TODO: Allow atomic swap and bit ops for v2f16/v4f16
    if (Ty.isVector() && !IsAtomicPacked16Bit)
      return false;

    if (BaseOpcode->AtomicX2) {
      Register VData1 = MI.getOperand(3).getReg();
      // The two values are packed in one register.
      LLT PackedTy = LLT::fixed_vector(2, Ty);
      auto Concat = B.buildBuildVector(PackedTy, {VData0, VData1});
      MI.getOperand(2).setReg(Concat.getReg(0));
      MI.getOperand(3).setReg(AMDGPU::NoRegister);
    }
  }

  unsigned CorrectedNumVAddrs = Intr->NumVAddrs;

  // Rewrite the addressing register layout before doing anything else.
  if (BaseOpcode->Gradients && !ST.hasG16() && (IsA16 != IsG16)) {
    // 16 bit gradients are supported, but are tied to the A16 control
    // so both gradients and addresses must be 16 bit
    return false;
  }

  if (IsA16 && !ST.hasA16()) {
    // A16 not supported
    return false;
  }

  const unsigned NSAMaxSize = ST.getNSAMaxSize(BaseOpcode->Sampler);
  const unsigned HasPartialNSA = ST.hasPartialNSAEncoding();

  if (IsA16 || IsG16) {
    // Even if NumVAddrs == 1 we should pack it into a 32-bit value, because the
    // instructions expect VGPR_32
    SmallVector<Register, 4> PackedRegs;

    packImage16bitOpsToDwords(B, MI, PackedRegs, ArgOffset, Intr, IsA16, IsG16);

    // See also below in the non-a16 branch
    const bool UseNSA = ST.hasNSAEncoding() &&
                        PackedRegs.size() >= ST.getNSAThreshold(MF) &&
                        (PackedRegs.size() <= NSAMaxSize || HasPartialNSA);
    const bool UsePartialNSA =
        UseNSA && HasPartialNSA && PackedRegs.size() > NSAMaxSize;

    if (UsePartialNSA) {
      // Pack registers that would go over NSAMaxSize into last VAddr register
      LLT PackedAddrTy =
          LLT::fixed_vector(2 * (PackedRegs.size() - NSAMaxSize + 1), F16);
      auto Concat = B.buildConcatVectors(
          PackedAddrTy, ArrayRef(PackedRegs).slice(NSAMaxSize - 1));
      PackedRegs[NSAMaxSize - 1] = Concat.getReg(0);
      PackedRegs.resize(NSAMaxSize);
    } else if (!UseNSA && PackedRegs.size() > 1) {
      LLT PackedAddrTy = LLT::fixed_vector(2 * PackedRegs.size(), F16);
      auto Concat = B.buildConcatVectors(PackedAddrTy, PackedRegs);
      PackedRegs[0] = Concat.getReg(0);
      PackedRegs.resize(1);
    }

    const unsigned NumPacked = PackedRegs.size();
    for (unsigned I = Intr->VAddrStart; I < Intr->VAddrEnd; I++) {
      MachineOperand &SrcOp = MI.getOperand(ArgOffset + I);
      if (!SrcOp.isReg()) {
        assert(SrcOp.isImm() && SrcOp.getImm() == 0);
        continue;
      }

      assert(SrcOp.getReg() != AMDGPU::NoRegister);

      if (I - Intr->VAddrStart < NumPacked)
        SrcOp.setReg(PackedRegs[I - Intr->VAddrStart]);
      else
        SrcOp.setReg(AMDGPU::NoRegister);
    }
  } else {
    // If the register allocator cannot place the address registers contiguously
    // without introducing moves, then using the non-sequential address encoding
    // is always preferable, since it saves VALU instructions and is usually a
    // wash in terms of code size or even better.
    //
    // However, we currently have no way of hinting to the register allocator
    // that MIMG addresses should be placed contiguously when it is possible to
    // do so, so force non-NSA for the common 2-address case as a heuristic.
    //
    // SIShrinkInstructions will convert NSA encodings to non-NSA after register
    // allocation when possible.
    //
    // Partial NSA is allowed on GFX11+ where the final register is a contiguous
    // set of the remaining addresses.
    const bool UseNSA = ST.hasNSAEncoding() &&
                        CorrectedNumVAddrs >= ST.getNSAThreshold(MF) &&
                        (CorrectedNumVAddrs <= NSAMaxSize || HasPartialNSA);
    const bool UsePartialNSA =
        UseNSA && HasPartialNSA && CorrectedNumVAddrs > NSAMaxSize;

    if (UsePartialNSA) {
      convertImageAddrToPacked(B, MI,
                               ArgOffset + Intr->VAddrStart + NSAMaxSize - 1,
                               Intr->NumVAddrs - NSAMaxSize + 1);
    } else if (!UseNSA && Intr->NumVAddrs > 1) {
      convertImageAddrToPacked(B, MI, ArgOffset + Intr->VAddrStart,
                               Intr->NumVAddrs);
    }
  }

  int Flags = 0;
  if (IsA16)
    Flags |= 1;
  if (IsG16)
    Flags |= 2;
  MI.addOperand(MachineOperand::CreateImm(Flags));

  if (BaseOpcode->NoReturn) { // No TFE for stores?
    // TODO: Handle dmask trim
    if (!Ty.isVector() || !IsD16)
      return true;

    Register RepackedReg = handleD16VData(B, *MRI, VData, true);
    if (RepackedReg != VData) {
      MI.getOperand(1).setReg(RepackedReg);
    }

    return true;
  }

  Register DstReg = MI.getOperand(0).getReg();
  const LLT EltTy = Ty.getScalarType();
  const int NumElts = Ty.isVector() ? Ty.getNumElements() : 1;

  // Confirm that the return type is large enough for the dmask specified
  if (NumElts < DMaskLanes)
    return false;

  if (NumElts > 4 || DMaskLanes > 4)
    return false;

  // Image atomic instructions are using DMask to specify how many bits
  // input/output data will have. 32-bits (i32, f32, v2f16) or 64-bits (i64,
  // f64, v4f16).
  // DMaskLanes for image atomic has default value '0'.
  // We must be sure that atomic variants (especially packed) will not be
  // truncated from v2f16 or v4f16 to f16 type.
  //
  // ChangeElementCount will be needed for image load where Ty is always scalar.
  const unsigned AdjustedNumElts = DMaskLanes == 0 ? 1 : DMaskLanes;
  const LLT AdjustedTy =
      DMaskLanes == 0
          ? Ty
          : Ty.changeElementCount(ElementCount::getFixed(AdjustedNumElts));

  // The raw dword aligned data component of the load. The only legal cases
  // where this matters should be when using the packed D16 format, for
  // f16 -> <2 x f16>, and <3 x f16> -> <4 x f16>,
  LLT RoundedTy;

  // I32 vector to cover all data, plus TFE result element.
  LLT TFETy;

  // Register type to use for each loaded component. Will be I32 or V2I16.
  LLT RegTy;

  if (IsD16 && ST.hasUnpackedD16VMem()) {
    RoundedTy =
        LLT::scalarOrVector(ElementCount::getFixed(AdjustedNumElts), I32);
    TFETy = LLT::fixed_vector(AdjustedNumElts + 1, I32);
    RegTy = I32;
  } else {
    unsigned EltSize = EltTy.getSizeInBits();
    unsigned RoundedElts = (AdjustedTy.getSizeInBits() + 31) / 32;
    unsigned RoundedSize = 32 * RoundedElts;
    RoundedTy = LLT::scalarOrVector(
        ElementCount::getFixed(RoundedSize / EltSize), EltTy);
    TFETy = LLT::fixed_vector(RoundedSize / 32 + 1, I32);
    RegTy = !IsTFE && EltSize == 16 ? V2I16 : I32;
  }

  // The return type does not need adjustment.
  // TODO: Should we change f16 case to i32 or <2 x f16>?
  if (!IsTFE && (RoundedTy == Ty || !Ty.isVector()))
    return true;

  Register Dst1Reg;

  // Insert after the instruction.
  B.setInsertPt(*MI.getParent(), ++MI.getIterator());

  // TODO: For TFE with d16, if we used a TFE type that was a multiple of <2 x
  // f16> instead of i32, we would only need 1 bitcast instead of multiple.
  const LLT LoadResultTy = IsTFE ? TFETy : RoundedTy;
  const int ResultNumRegs = LoadResultTy.getSizeInBits() / 32;

  Register NewResultReg = MRI->createGenericVirtualRegister(LoadResultTy);

  MI.getOperand(0).setReg(NewResultReg);

  // In the IR, TFE is supposed to be used with a 2 element struct return
  // type. The instruction really returns these two values in one contiguous
  // register, with one additional dword beyond the loaded data. Rewrite the
  // return type to use a single register result.

  if (IsTFE) {
    Dst1Reg = MI.getOperand(1).getReg();
    if (MRI->getType(Dst1Reg) != I32)
      return false;

    // TODO: Make sure the TFE operand bit is set.
    MI.removeOperand(1);

    // Handle the easy case that requires no repack instructions.
    if (!Ty.isVector() && Ty.getSizeInBits() == 32) {
      auto Unmerge = B.buildUnmerge({I32, I32}, NewResultReg);
      B.buildBitcast(DstReg, Unmerge.getReg(0));
      B.buildCopy(Dst1Reg, Unmerge.getReg(1));
      return true;
    }
  }

  // Now figure out how to copy the new result register back into the old
  // result.
  SmallVector<Register, 5> ResultRegs(ResultNumRegs, Dst1Reg);

  const int NumDataRegs = IsTFE ? ResultNumRegs - 1  : ResultNumRegs;

  if (ResultNumRegs == 1) {
    assert(!IsTFE);
    ResultRegs[0] = NewResultReg;
  } else {
    // We have to repack into a new vector of some kind.
    for (int I = 0; I != NumDataRegs; ++I)
      ResultRegs[I] = MRI->createGenericVirtualRegister(RegTy);
    B.buildUnmerge(ResultRegs, NewResultReg);

    // Drop the final TFE element to get the data part. The TFE result is
    // directly written to the right place already.
    if (IsTFE)
      ResultRegs.resize(NumDataRegs);
  }

  // For an f16 scalar result, we form an i32 result with a truncate regardless
  // of packed vs. unpacked.
  if (IsD16 && !Ty.isVector()) {
    B.buildTrunc(DstReg, ResultRegs[0]);
    return true;
  }

  // Avoid a build/concat_vector of 1 entry.
  if ((Ty == V2I16 || Ty == V2F16) && NumDataRegs == 1 &&
      !ST.hasUnpackedD16VMem()) {
    B.buildBitcast(DstReg, ResultRegs[0]);
    return true;
  }

  assert(Ty.isVector());

  if (IsD16) {
    // For packed D16 results with TFE enabled, all the data components are
    // I32. Cast back to the expected type.
    //
    // TODO: We don't really need to use load i32 elements. We would only need
    // one cast for the TFE result if a multiple of v2f16 was used.
    if (RegTy != V2I16 && !ST.hasUnpackedD16VMem()) {
      for (Register &Reg : ResultRegs)
        Reg = B.buildBitcast(V2I16, Reg).getReg(0);
    } else if (ST.hasUnpackedD16VMem()) {
      for (Register &Reg : ResultRegs)
        Reg = B.buildTrunc(I16, Reg).getReg(0);
    }
  }

  auto padWithUndef = [&](LLT Ty, int NumElts) {
    if (NumElts == 0)
      return;
    Register Undef = B.buildUndef(Ty).getReg(0);
    for (int I = 0; I != NumElts; ++I)
      ResultRegs.push_back(Undef);
  };

  // Pad out any elements eliminated due to the dmask.
  LLT ResTy = MRI->getType(ResultRegs[0]);
  if (!ResTy.isVector()) {
    padWithUndef(ResTy, NumElts - ResultRegs.size());
    B.buildBuildVector(DstReg, ResultRegs);
    return true;
  }

  assert(!ST.hasUnpackedD16VMem() && (ResTy == V2I16 || ResTy == V2F16));
  const int RegsToCover = (Ty.getSizeInBits() + 31) / 32;

  // Deal with the one annoying legal case.
  const LLT V3I16 = LLT::fixed_vector(3, I16);
  const LLT V3F16 = LLT::fixed_vector(3, F16);
  if (Ty == V3I16 || Ty == V3F16) {
    if (IsTFE) {
      if (ResultRegs.size() == 1) {
        NewResultReg = ResultRegs[0];
      } else if (ResultRegs.size() == 2) {
        LLT V4I16 = LLT::fixed_vector(4, I16);
        NewResultReg = B.buildConcatVectors(V4I16, ResultRegs).getReg(0);
      } else {
        return false;
      }
    }

    LLT DstTy = MRI->getType(DstReg);
    LLT NewResTy = MRI->getType(NewResultReg);
    LLT ResEltTy = NewResTy.getElementType();
    Register ResizeDst = DstTy.getElementType() == ResEltTy
                             ? DstReg
                             : MRI->createGenericVirtualRegister(
                                   DstTy.changeElementType(ResEltTy));

    if (DstTy.getNumElements() < NewResTy.getNumElements()) {
      B.buildDeleteTrailingVectorElements(ResizeDst, NewResultReg);
    } else {
      B.buildPadVectorWithUndefElements(ResizeDst, NewResultReg);
    }
    if (ResizeDst != DstReg)
      B.buildBitcast(DstReg, ResizeDst);
    return true;
  }

  padWithUndef(ResTy, RegsToCover - ResultRegs.size());
  B.buildConcatVectors(DstReg, ResultRegs);
  return true;
}

bool AMDGPULegalizerInfo::legalizeSBufferLoad(LegalizerHelper &Helper,
                                              MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  GISelChangeObserver &Observer = Helper.Observer;

  Register OrigDst = MI.getOperand(0).getReg();
  Register Dst;
  LLT Ty = B.getMRI()->getType(OrigDst);
  unsigned Size = Ty.getSizeInBits();
  MachineFunction &MF = B.getMF();
  bool HasMMO = !MI.memoperands_empty();

  // S_BUFFER_LOAD only produces values that fill whole SGPRs, apart from the
  // subword loads below. Those truncate from an s32 result, so they need a
  // scalar destination.
  bool IsSubwordLoad = Ty.isScalar() && Size < 32 && ST.hasScalarSubwordLoads();
  if (Size % 32 != 0 && !IsSubwordLoad) {
    const Function &Fn = MF.getFunction();
    Fn.getContext().diagnose(DiagnosticInfoUnsupported(
        Fn, "unsupported s_buffer_load result type", MI.getDebugLoc()));
    B.buildUndef(OrigDst);
    MI.eraseFromParent();
    return true;
  }

  unsigned Opc = 0;
  if (IsSubwordLoad) {
    assert(Size == 8 || Size == 16);
    Opc = Size == 8 ? AMDGPU::G_AMDGPU_S_BUFFER_LOAD_UBYTE
                    : AMDGPU::G_AMDGPU_S_BUFFER_LOAD_USHORT;
    // The 8-bit and 16-bit scalar buffer load instructions have 32-bit
    // destination register.
    Dst = B.getMRI()->createGenericVirtualRegister(LLT::integer(32));
  } else {
    Opc = AMDGPU::G_AMDGPU_S_BUFFER_LOAD;
    Dst = OrigDst;
  }

  Observer.changingInstr(MI);

  // Handle needing to s.buffer.load() a p8 value.
  if (hasBufferRsrcWorkaround(Ty)) {
    Ty = castBufferRsrcFromV4I32(MI, B, *B.getMRI(), 0);
    B.setInsertPt(B.getMBB(), MI);
  }
  if (shouldBitcastLoadStoreType(ST, Ty, LLT::integer(Size))) {
    Ty = getBitcastRegisterType(Ty);
    Helper.bitcastDst(MI, Ty, 0);
    B.setInsertPt(B.getMBB(), MI);
  }

  MI.setDesc(B.getTII().get(Opc));
  MI.removeOperand(1);
  castBufferRsrcArgToV4I32(MI, B, 1);

  if (!HasMMO) {
    // Legacy intrinsic that doesn't take a pointer and so can't already have an
    // MMO.
    const unsigned MemSize = (Size + 7) / 8;
    const Align MemAlign = B.getDataLayout().getABITypeAlign(
        getTypeForLLT(Ty, MF.getFunction().getContext()));
    MachineMemOperand *MMO = MF.getMachineMemOperand(
        MachinePointerInfo(),
        MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
            MachineMemOperand::MOInvariant,
        MemSize, MemAlign);
    MI.addMemOperand(MF, MMO);
  }
  if (Dst != OrigDst) {
    MI.getOperand(0).setReg(Dst);
    B.setInsertPt(B.getMBB(), ++B.getInsertPt());
    B.buildTrunc(OrigDst, Dst);
  }

  // If we don't have 96-bit result scalar loads, widening to 128-bit should
  // always be legal. We may need to restore this to a 96-bit result if it turns
  // out this needs to be converted to a vector load during RegBankSelect.
  if (!isPowerOf2_32(Size) && (Size != 96 || !ST.hasScalarDwordx3Loads())) {
    if (Ty.isVector())
      Helper.moreElementsVectorDst(MI, getPow2VectorType(Ty), 0);
    else
      Helper.widenScalarDst(MI, getPow2ScalarType(Ty), 0);
  }

  Observer.changedInstr(MI);
  return true;
}

bool AMDGPULegalizerInfo::legalizeSBufferPrefetch(LegalizerHelper &Helper,
                                                  MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  GISelChangeObserver &Observer = Helper.Observer;
  Observer.changingInstr(MI);
  MI.setDesc(B.getTII().get(AMDGPU::G_AMDGPU_S_BUFFER_PREFETCH));
  MI.removeOperand(0); // Remove intrinsic ID
  castBufferRsrcArgToV4I32(MI, B, 0);
  Observer.changedInstr(MI);
  return true;
}

// TODO: Move to selection
bool AMDGPULegalizerInfo::legalizeTrap(LegalizerHelper &Helper,
                                       MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();
  if (!ST.hasTrapHandler() ||
      ST.getTrapHandlerAbi() != GCNSubtarget::TrapHandlerAbi::AMDHSA)
    return legalizeTrapEndpgm(Helper, MI);

  return ST.supportsGetDoorbellID() ? legalizeTrapHsa(Helper, MI)
                                    : legalizeTrapHsaQueuePtr(MI, MRI, B);
}

bool AMDGPULegalizerInfo::legalizeTrapEndpgm(LegalizerHelper &Helper,
                                             MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  GISelChangeObserver &Observer = Helper.Observer;
  const DebugLoc &DL = MI.getDebugLoc();
  MachineBasicBlock &BB = B.getMBB();
  MachineFunction *MF = BB.getParent();

  if (BB.succ_empty() && std::next(MI.getIterator()) == BB.end()) {
    BuildMI(BB, BB.end(), DL, B.getTII().get(AMDGPU::S_ENDPGM))
      .addImm(0);
    MI.eraseFromParent();
    return true;
  }

  // We need a block split to make the real endpgm a terminator. We also don't
  // want to break phis in successor blocks, so we can't just delete to the
  // end of the block.
  // An instruction's parent block is part of its CSE profile, so notify
  // observers about the instructions moved by the split.
  SmallVector<MachineInstr *, 8> MovedInstrs;
  MachineBasicBlock::iterator SplitPoint(&MI);
  ++SplitPoint;
  for (auto I = SplitPoint, E = BB.end(); I != E; ++I) {
    Observer.changingInstr(*I);
    MovedInstrs.push_back(&*I);
  }
  BB.splitAt(MI, false /*UpdateLiveIns*/);
  for (MachineInstr *MovedMI : MovedInstrs)
    Observer.changedInstr(*MovedMI);
  MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
  MF->push_back(TrapBB);
  BuildMI(*TrapBB, TrapBB->end(), DL, B.getTII().get(AMDGPU::S_ENDPGM))
    .addImm(0);
  BuildMI(BB, &MI, DL, B.getTII().get(AMDGPU::S_CBRANCH_EXECNZ))
    .addMBB(TrapBB);

  BB.addSuccessor(TrapBB);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeTrapHsaQueuePtr(
    MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &B) const {
  MachineFunction &MF = B.getMF();
  const LLT I64 = LLT::integer(64);

  Register SGPR01(AMDGPU::SGPR0_SGPR1);
  // For code object version 5, queue_ptr is passed through implicit kernarg.
  if (AMDGPU::getAMDHSACodeObjectVersion(*MF.getFunction().getParent()) >=
      AMDGPU::AMDHSA_COV5) {
    AMDGPUTargetLowering::ImplicitParameter Param =
        AMDGPUTargetLowering::QUEUE_PTR;
    uint64_t Offset =
        ST.getTargetLowering()->getImplicitParameterOffset(B.getMF(), Param);

    Register KernargPtrReg = MRI.createGenericVirtualRegister(
        LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64));

    if (!loadInputValue(KernargPtrReg, B,
                        AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR))
      return false;

    // TODO: can we be smarter about machine pointer info?
    MachinePointerInfo PtrInfo = getKernargSegmentPtrInfo(MF);
    MachineMemOperand *MMO = MF.getMachineMemOperand(
        PtrInfo.getWithOffset(Offset),
        MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
            MachineMemOperand::MOInvariant,
        LLT::integer(64), commonAlignment(Align(64), Offset));

    // Pointer address
    Register LoadAddr = MRI.createGenericVirtualRegister(
        LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64));
    B.buildObjectPtrOffset(LoadAddr, KernargPtrReg,
                           B.buildConstant(LLT::integer(64), Offset).getReg(0));
    // Load address
    Register Temp = B.buildLoad(I64, LoadAddr, *MMO).getReg(0);
    B.buildCopy(SGPR01, Temp);
    B.buildInstr(AMDGPU::S_TRAP)
        .addImm(static_cast<unsigned>(GCNSubtarget::TrapID::LLVMAMDHSATrap))
        .addReg(SGPR01, RegState::Implicit);
    MI.eraseFromParent();
    return true;
  }

  // Pass queue pointer to trap handler as input, and insert trap instruction
  // Reference: https://llvm.org/docs/AMDGPUUsage.html#trap-handler-abi
  Register LiveIn =
    MRI.createGenericVirtualRegister(LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64));
  if (!loadInputValue(LiveIn, B, AMDGPUFunctionArgInfo::QUEUE_PTR))
    return false;

  B.buildCopy(SGPR01, LiveIn);
  B.buildInstr(AMDGPU::S_TRAP)
      .addImm(static_cast<unsigned>(GCNSubtarget::TrapID::LLVMAMDHSATrap))
      .addReg(SGPR01, RegState::Implicit);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeTrapHsa(LegalizerHelper &Helper,
                                          MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();

  // We need to simulate the 's_trap 2' instruction on targets that run in
  // PRIV=1 (where it is treated as a nop).
  if (ST.hasPrivEnabledTrap2NopBug()) {
    // insertSimulatedTrap may split the block after MI. An instruction's
    // parent block is part of its CSE profile, so notify observers about the
    // instructions that may be moved by the split.
    GISelChangeObserver &Observer = Helper.Observer;
    MachineBasicBlock &MBB = B.getMBB();
    SmallVector<MachineInstr *, 8> MovedInstrs;
    for (MachineInstr &I :
         make_range(std::next(MachineBasicBlock::iterator(MI)), MBB.end())) {
      Observer.changingInstr(I);
      MovedInstrs.push_back(&I);
    }
    ST.getInstrInfo()->insertSimulatedTrap(MRI, MBB, MI, MI.getDebugLoc());
    for (MachineInstr *MovedMI : MovedInstrs)
      Observer.changedInstr(*MovedMI);
    MI.eraseFromParent();
    return true;
  }

  B.buildInstr(AMDGPU::S_TRAP)
      .addImm(static_cast<unsigned>(GCNSubtarget::TrapID::LLVMAMDHSATrap));
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeDebugTrap(MachineInstr &MI,
                                            MachineRegisterInfo &MRI,
                                            MachineIRBuilder &B) const {
  // Is non-HSA path or trap-handler disabled? Then, report a warning
  // accordingly
  if (!ST.hasTrapHandler() ||
      ST.getTrapHandlerAbi() != GCNSubtarget::TrapHandlerAbi::AMDHSA) {
    Function &Fn = B.getMF().getFunction();
    Fn.getContext().diagnose(DiagnosticInfoUnsupported(
        Fn, "debugtrap handler not supported", MI.getDebugLoc(), DS_Warning));
  } else {
    // Insert debug-trap instruction
    B.buildInstr(AMDGPU::S_TRAP)
        .addImm(static_cast<unsigned>(GCNSubtarget::TrapID::LLVMAMDHSADebugTrap));
  }

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeBVHIntersectRayIntrinsic(
    MachineInstr &MI, MachineIRBuilder &B) const {
  MachineRegisterInfo &MRI = *B.getMRI();
  const LLT I16 = LLT::integer(16);
  const LLT I32 = LLT::integer(32);
  const LLT V2I16 = LLT::fixed_vector(2, I16);
  const LLT V3I32 = LLT::fixed_vector(3, I32);
  const LLT V3I16 = LLT::fixed_vector(3, I16);

  Register DstReg = MI.getOperand(0).getReg();
  Register NodePtr = MI.getOperand(2).getReg();
  Register RayExtent = MI.getOperand(3).getReg();
  Register RayOrigin = MI.getOperand(4).getReg();
  Register RayDir = MI.getOperand(5).getReg();
  Register RayInvDir = MI.getOperand(6).getReg();
  Register TDescr = MI.getOperand(7).getReg();

  RayExtent = B.buildBitcast(I32, RayExtent).getReg(0);

  const bool IsGFX11 = AMDGPU::isGFX11(ST);
  const bool IsGFX11Plus = AMDGPU::isGFX11Plus(ST);
  const bool IsGFX12Plus = AMDGPU::isGFX12Plus(ST);
  const bool IsA16 = MRI.getType(RayDir).getElementType().getSizeInBits() == 16;
  const bool Is64 = MRI.getType(NodePtr).getSizeInBits() == 64;
  const unsigned NumVDataDwords = 4;
  const unsigned NumVAddrDwords = IsA16 ? (Is64 ? 9 : 8) : (Is64 ? 12 : 11);
  const unsigned NumVAddrs = IsGFX11Plus ? (IsA16 ? 4 : 5) : NumVAddrDwords;
  const bool UseNSA =
      IsGFX12Plus || (ST.hasNSAEncoding() && NumVAddrs <= ST.getNSAMaxSize());

  const unsigned BaseOpcodes[2][2] = {
      {AMDGPU::IMAGE_BVH_INTERSECT_RAY, AMDGPU::IMAGE_BVH_INTERSECT_RAY_a16},
      {AMDGPU::IMAGE_BVH64_INTERSECT_RAY,
       AMDGPU::IMAGE_BVH64_INTERSECT_RAY_a16}};
  int Opcode;
  if (UseNSA) {
    Opcode = AMDGPU::getMIMGOpcode(BaseOpcodes[Is64][IsA16],
                                   IsGFX12Plus ? AMDGPU::MIMGEncGfx12
                                   : IsGFX11   ? AMDGPU::MIMGEncGfx11NSA
                                               : AMDGPU::MIMGEncGfx10NSA,
                                   NumVDataDwords, NumVAddrDwords);
  } else {
    assert(!IsGFX12Plus);
    Opcode = AMDGPU::getMIMGOpcode(BaseOpcodes[Is64][IsA16],
                                   IsGFX11 ? AMDGPU::MIMGEncGfx11Default
                                           : AMDGPU::MIMGEncGfx10Default,
                                   NumVDataDwords, NumVAddrDwords);
  }
  assert(Opcode != -1);

  SmallVector<Register, 12> Ops;
  if (UseNSA && IsGFX11Plus) {
    auto packLanes = [&Ops, &I32, &V3I32, &B](Register Src) {
      auto SrcInt = B.buildBitcast(V3I32, Src);
      auto Unmerge = B.buildUnmerge({I32, I32, I32}, SrcInt);
      auto Merged = B.buildMergeLikeInstr(
          V3I32, {Unmerge.getReg(0), Unmerge.getReg(1), Unmerge.getReg(2)});
      Ops.push_back(Merged.getReg(0));
    };

    Ops.push_back(NodePtr);
    Ops.push_back(RayExtent);
    packLanes(RayOrigin);

    if (IsA16) {
      auto UnmergeRayDir =
          B.buildUnmerge({I16, I16, I16}, B.buildBitcast(V3I16, RayDir));
      auto UnmergeRayInvDir =
          B.buildUnmerge({I16, I16, I16}, B.buildBitcast(V3I16, RayInvDir));
      auto MergedDir = B.buildMergeLikeInstr(
          V3I32,
          {B.buildBitcast(
                I32, B.buildMergeLikeInstr(V2I16, {UnmergeRayInvDir.getReg(0),
                                                   UnmergeRayDir.getReg(0)}))
               .getReg(0),
           B.buildBitcast(
                I32, B.buildMergeLikeInstr(V2I16, {UnmergeRayInvDir.getReg(1),
                                                   UnmergeRayDir.getReg(1)}))
               .getReg(0),
           B.buildBitcast(
                I32, B.buildMergeLikeInstr(V2I16, {UnmergeRayInvDir.getReg(2),
                                                   UnmergeRayDir.getReg(2)}))
               .getReg(0)});
      Ops.push_back(MergedDir.getReg(0));
    } else {
      packLanes(RayDir);
      packLanes(RayInvDir);
    }
  } else {
    if (Is64) {
      auto Unmerge = B.buildUnmerge({I32, I32}, NodePtr);
      Ops.push_back(Unmerge.getReg(0));
      Ops.push_back(Unmerge.getReg(1));
    } else {
      Ops.push_back(NodePtr);
    }
    Ops.push_back(RayExtent);

    auto packLanes = [&Ops, &I32, &V3I32, &B](Register Src) {
      auto SrcInt = B.buildBitcast(V3I32, Src);
      auto Unmerge = B.buildUnmerge({I32, I32, I32}, SrcInt);
      Ops.push_back(Unmerge.getReg(0));
      Ops.push_back(Unmerge.getReg(1));
      Ops.push_back(Unmerge.getReg(2));
    };

    packLanes(RayOrigin);
    if (IsA16) {
      auto UnmergeRayDir =
          B.buildUnmerge({I16, I16, I16}, B.buildBitcast(V3I16, RayDir));
      auto UnmergeRayInvDir =
          B.buildUnmerge({I16, I16, I16}, B.buildBitcast(V3I16, RayInvDir));
      Register R1 = MRI.createGenericVirtualRegister(I32);
      Register R2 = MRI.createGenericVirtualRegister(I32);
      Register R3 = MRI.createGenericVirtualRegister(I32);
      B.buildMergeLikeInstr(R1,
                            {UnmergeRayDir.getReg(0), UnmergeRayDir.getReg(1)});
      B.buildMergeLikeInstr(
          R2, {UnmergeRayDir.getReg(2), UnmergeRayInvDir.getReg(0)});
      B.buildMergeLikeInstr(
          R3, {UnmergeRayInvDir.getReg(1), UnmergeRayInvDir.getReg(2)});
      Ops.push_back(R1);
      Ops.push_back(R2);
      Ops.push_back(R3);
    } else {
      packLanes(RayDir);
      packLanes(RayInvDir);
    }
  }

  if (!UseNSA) {
    // Build a single vector containing all the operands so far prepared.
    LLT OpTy = LLT::fixed_vector(Ops.size(), I32);
    Register MergedOps = B.buildMergeLikeInstr(OpTy, Ops).getReg(0);
    Ops.clear();
    Ops.push_back(MergedOps);
  }

  auto MIB = B.buildInstr(AMDGPU::G_AMDGPU_BVH_INTERSECT_RAY)
                 .addDef(DstReg)
                 .addImm(Opcode);

  for (Register R : Ops) {
    MIB.addUse(R);
  }

  MIB.addUse(TDescr)
     .addImm(IsA16 ? 1 : 0)
     .cloneMemRefs(MI);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeBVHDualOrBVH8IntersectRayIntrinsic(
    MachineInstr &MI, MachineIRBuilder &B) const {
  const LLT I32 = LLT::integer(32);
  const LLT V2I32 = LLT::fixed_vector(2, I32);

  Register DstReg = MI.getOperand(0).getReg();
  Register DstOrigin = MI.getOperand(1).getReg();
  Register DstDir = MI.getOperand(2).getReg();
  Register NodePtr = MI.getOperand(4).getReg();
  Register RayExtent = MI.getOperand(5).getReg();
  Register InstanceMask = MI.getOperand(6).getReg();
  Register RayOrigin = MI.getOperand(7).getReg();
  Register RayDir = MI.getOperand(8).getReg();
  Register Offsets = MI.getOperand(9).getReg();
  Register TDescr = MI.getOperand(10).getReg();

  bool IsBVH8 = cast<GIntrinsic>(MI).getIntrinsicID() ==
                Intrinsic::amdgcn_image_bvh8_intersect_ray;
  const unsigned NumVDataDwords = 10;
  const unsigned NumVAddrDwords = IsBVH8 ? 11 : 12;
  int Opcode = AMDGPU::getMIMGOpcode(
      IsBVH8 ? AMDGPU::IMAGE_BVH8_INTERSECT_RAY
             : AMDGPU::IMAGE_BVH_DUAL_INTERSECT_RAY,
      AMDGPU::MIMGEncGfx12, NumVDataDwords, NumVAddrDwords);
  assert(Opcode != -1);

  auto RayExtentInstanceMaskVec =
      B.buildMergeLikeInstr(V2I32, {B.buildBitcast(I32, RayExtent),
                                    B.buildAnyExt(I32, InstanceMask)});

  B.buildInstr(IsBVH8 ? AMDGPU::G_AMDGPU_BVH8_INTERSECT_RAY
                      : AMDGPU::G_AMDGPU_BVH_DUAL_INTERSECT_RAY)
      .addDef(DstReg)
      .addDef(DstOrigin)
      .addDef(DstDir)
      .addImm(Opcode)
      .addUse(NodePtr)
      .addUse(RayExtentInstanceMaskVec.getReg(0))
      .addUse(RayOrigin)
      .addUse(RayDir)
      .addUse(Offsets)
      .addUse(TDescr)
      .cloneMemRefs(MI);

  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeStackSave(MachineInstr &MI,
                                            MachineIRBuilder &B) const {
  const SITargetLowering *TLI = ST.getTargetLowering();
  Register StackPtr = TLI->getStackPointerRegisterToSaveRestore();
  Register DstReg = MI.getOperand(0).getReg();
  B.buildInstr(AMDGPU::G_AMDGPU_WAVE_ADDRESS, {DstReg}, {StackPtr});
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeWaveID(MachineInstr &MI,
                                         MachineIRBuilder &B) const {
  // With architected SGPRs, waveIDinGroup is in TTMP8[29:25].
  if (!ST.hasArchitectedSGPRs())
    return false;
  LLT I32 = LLT::integer(32);
  Register DstReg = MI.getOperand(0).getReg();
  auto TTMP8 = B.buildCopy(I32, Register(AMDGPU::TTMP8));
  auto LSB = B.buildConstant(I32, 25);
  auto Width = B.buildConstant(I32, 5);
  B.buildUbfx(DstReg, TTMP8, LSB, Width);
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeConstHwRegRead(MachineInstr &MI,
                                                 MachineIRBuilder &B,
                                                 AMDGPU::Hwreg::Id HwReg,
                                                 unsigned LowBit,
                                                 unsigned Width) const {
  MachineRegisterInfo &MRI = *B.getMRI();
  Register DstReg = MI.getOperand(0).getReg();
  Register Result = MRI.createVirtualRegister(
      {&AMDGPU::SReg_32RegClass, MRI.getType(DstReg)});
  B.buildInstr(AMDGPU::S_GETREG_B32_const)
      .addDef(Result)
      .addImm(AMDGPU::Hwreg::HwregEncoding::encode(HwReg, LowBit, Width));
  B.buildCopy(DstReg, Result);
  MI.eraseFromParent();
  return true;
}

static constexpr unsigned FPEnvModeBitField =
    AMDGPU::Hwreg::HwregEncoding::encode(AMDGPU::Hwreg::ID_MODE, 0, 23);

static constexpr unsigned FPEnvTrapBitField =
    AMDGPU::Hwreg::HwregEncoding::encode(AMDGPU::Hwreg::ID_TRAPSTS, 0, 5);

bool AMDGPULegalizerInfo::legalizeGetFPEnv(MachineInstr &MI,
                                           MachineRegisterInfo &MRI,
                                           MachineIRBuilder &B) const {
  const LLT I32 = LLT::integer(32);
  const LLT I64 = LLT::integer(64);
  Register Src = MI.getOperand(0).getReg();
  if (MRI.getType(Src) != I64)
    return false;

  auto ModeReg =
      B.buildIntrinsic(Intrinsic::amdgcn_s_getreg, {I32},
                       /*HasSideEffects=*/true, /*isConvergent=*/false)
          .addImm(FPEnvModeBitField);
  auto TrapReg =
      B.buildIntrinsic(Intrinsic::amdgcn_s_getreg, {I32},
                       /*HasSideEffects=*/true, /*isConvergent=*/false)
          .addImm(FPEnvTrapBitField);
  B.buildMergeLikeInstr(Src, {ModeReg, TrapReg});
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeSetFPEnv(MachineInstr &MI,
                                           MachineRegisterInfo &MRI,
                                           MachineIRBuilder &B) const {
  const LLT I32 = LLT::integer(32);
  const LLT I64 = LLT::integer(64);
  Register Src = MI.getOperand(0).getReg();
  if (MRI.getType(Src) != I64)
    return false;

  auto Unmerge = B.buildUnmerge({I32, I32}, MI.getOperand(0));
  B.buildIntrinsic(Intrinsic::amdgcn_s_setreg, ArrayRef<DstOp>(),
                   /*HasSideEffects=*/true, /*isConvergent=*/false)
      .addImm(static_cast<int16_t>(FPEnvModeBitField))
      .addReg(Unmerge.getReg(0));
  B.buildIntrinsic(Intrinsic::amdgcn_s_setreg, ArrayRef<DstOp>(),
                   /*HasSideEffects=*/true, /*isConvergent=*/false)
      .addImm(static_cast<int16_t>(FPEnvTrapBitField))
      .addReg(Unmerge.getReg(1));
  MI.eraseFromParent();
  return true;
}

bool AMDGPULegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
                                            MachineInstr &MI) const {
  MachineIRBuilder &B = Helper.MIRBuilder;
  MachineRegisterInfo &MRI = *B.getMRI();

  // Replace the use G_BRCOND with the exec manipulate and branch pseudos.
  auto IntrID = cast<GIntrinsic>(MI).getIntrinsicID();
  switch (IntrID) {
  case Intrinsic::sponentry:
    if (B.getMF().getInfo<SIMachineFunctionInfo>()->isBottomOfStack()) {
      // FIXME: The imported pattern checks for i32 instead of p5; if we fix
      // that we can remove this cast.
      const LLT I32 = LLT::integer(32);
      Register TmpReg = MRI.createGenericVirtualRegister(I32);
      B.buildInstr(AMDGPU::G_AMDGPU_SPONENTRY).addDef(TmpReg);

      Register DstReg = MI.getOperand(0).getReg();
      B.buildIntToPtr(DstReg, TmpReg);
      MI.eraseFromParent();
    } else {
      int FI = B.getMF().getFrameInfo().CreateFixedObject(
          1, 0, /*IsImmutable=*/false);
      B.buildFrameIndex(MI.getOperand(0), FI);
      MI.eraseFromParent();
    }
    return true;
  case Intrinsic::amdgcn_if:
  case Intrinsic::amdgcn_else: {
    MachineInstr *Br = nullptr;
    MachineBasicBlock *UncondBrTarget = nullptr;
    bool Negated = false;
    if (MachineInstr *BrCond =
            verifyCFIntrinsic(MI, MRI, Br, UncondBrTarget, Negated)) {
      const SIRegisterInfo *TRI
        = static_cast<const SIRegisterInfo *>(MRI.getTargetRegisterInfo());

      Register Def = MI.getOperand(1).getReg();
      Register Use = MI.getOperand(3).getReg();
      const TargetRegisterClass *WaveMaskRC = TRI->getWaveMaskRegClass();
      Register NewDef =
          MRI.createVirtualRegister({WaveMaskRC, MRI.getType(Def)});
      Register NewUse =
          MRI.createVirtualRegister({WaveMaskRC, MRI.getType(Use)});

      MachineBasicBlock *CondBrTarget = BrCond->getOperand(1).getMBB();

      if (Negated)
        std::swap(CondBrTarget, UncondBrTarget);

      B.setInsertPt(B.getMBB(), BrCond->getIterator());
      B.buildCopy(NewUse, Use);
      if (IntrID == Intrinsic::amdgcn_if) {
        B.buildInstr(AMDGPU::SI_IF)
            .addDef(NewDef)
            .addUse(NewUse)
            .addMBB(UncondBrTarget)
            .setOperandDead(4); // implicit-def $scc
      } else {
        B.buildInstr(AMDGPU::SI_ELSE)
            .addDef(NewDef)
            .addUse(NewUse)
            .addMBB(UncondBrTarget)
            .setOperandDead(4); // implicit-def $scc
      }

      if (Br) {
        Br->getOperand(0).setMBB(CondBrTarget);
      } else {
        // The IRTranslator skips inserting the G_BR for fallthrough cases, but
        // since we're swapping branch targets it needs to be reinserted.
        // FIXME: IRTranslator should probably not do this
        B.buildBr(*CondBrTarget);
      }

      MI.eraseFromParent();
      BrCond->eraseFromParent();
      // SI_IF and SI_ELSE are terminators, so replace uses of Def rather than
      // defining Def with a following copy.
      Helper.Observer.changingAllUsesOfReg(MRI, Def);
      MRI.replaceRegWith(Def, NewDef);
      Helper.Observer.finishedChangingAllUsesOfReg();
      return true;
    }

    return false;
  }
  case Intrinsic::amdgcn_loop: {
    MachineInstr *Br = nullptr;
    MachineBasicBlock *UncondBrTarget = nullptr;
    bool Negated = false;
    if (MachineInstr *BrCond =
            verifyCFIntrinsic(MI, MRI, Br, UncondBrTarget, Negated)) {
      const SIRegisterInfo *TRI
        = static_cast<const SIRegisterInfo *>(MRI.getTargetRegisterInfo());

      MachineBasicBlock *CondBrTarget = BrCond->getOperand(1).getMBB();
      Register Reg = MI.getOperand(2).getReg();
      Register NewReg = MRI.createVirtualRegister(
          {TRI->getWaveMaskRegClass(), MRI.getType(Reg)});

      if (Negated)
        std::swap(CondBrTarget, UncondBrTarget);

      B.setInsertPt(B.getMBB(), BrCond->getIterator());
      B.buildCopy(NewReg, Reg);
      B.buildInstr(AMDGPU::SI_LOOP)
          .addUse(NewReg)
          .addMBB(UncondBrTarget)
          .setOperandDead(3); // implicit-def $scc

      if (Br)
        Br->getOperand(0).setMBB(CondBrTarget);
      else
        B.buildBr(*CondBrTarget);

      MI.eraseFromParent();
      BrCond->eraseFromParent();
      return true;
    }

    return false;
  }
  case Intrinsic::amdgcn_wave_reduce_min:
  case Intrinsic::amdgcn_wave_reduce_umin:
  case Intrinsic::amdgcn_wave_reduce_fmin:
  case Intrinsic::amdgcn_wave_reduce_max:
  case Intrinsic::amdgcn_wave_reduce_umax:
  case Intrinsic::amdgcn_wave_reduce_fmax:
  case Intrinsic::amdgcn_wave_reduce_add:
  case Intrinsic::amdgcn_wave_reduce_fadd:
  case Intrinsic::amdgcn_wave_reduce_sub:
  case Intrinsic::amdgcn_wave_reduce_fsub:
  case Intrinsic::amdgcn_wave_reduce_and:
  case Intrinsic::amdgcn_wave_reduce_or:
  case Intrinsic::amdgcn_wave_reduce_xor: {
    Register SrcReg = MI.getOperand(2).getReg();
    if (MRI.getType(SrcReg).getSizeInBits() != 16)
      return true;
    Register DstReg = MI.getOperand(0).getReg();
    bool IsFPOp = IntrID == Intrinsic::amdgcn_wave_reduce_fmin ||
                  IntrID == Intrinsic::amdgcn_wave_reduce_fmax ||
                  IntrID == Intrinsic::amdgcn_wave_reduce_fadd ||
                  IntrID == Intrinsic::amdgcn_wave_reduce_fsub;
    bool NeedsSignExt = IntrID == Intrinsic::amdgcn_wave_reduce_min ||
                        IntrID == Intrinsic::amdgcn_wave_reduce_max ||
                        IntrID == Intrinsic::amdgcn_wave_reduce_add ||
                        IntrID == Intrinsic::amdgcn_wave_reduce_sub;
    auto Ext = IsFPOp         ? B.buildFPExt(F32, SrcReg)
               : NeedsSignExt ? B.buildSExt(LLT::integer(32), SrcReg)
                              : B.buildZExt(LLT::integer(32), SrcReg);
    auto NewDst =
        MRI.createGenericVirtualRegister(IsFPOp ? F32 : LLT::integer(32));
    B.buildIntrinsic(IntrID, ArrayRef<Register>{NewDst},
                     /*hasSideEffects=*/false, /*isConvergent=*/true)
        .addUse(Ext.getReg(0))
        .addImm(MI.getOperand(3).getImm()); // strategy
    if (IsFPOp)
      B.buildFPTrunc(DstReg, NewDst);
    else
      B.buildTrunc(DstReg, NewDst);
    MI.eraseFromParent();
    return true;
  }
  case Intrinsic::amdgcn_make_buffer_rsrc:
    return legalizePointerAsRsrcIntrin(MI, MRI, B);
  case Intrinsic::amdgcn_kernarg_segment_ptr:
    if (!AMDGPU::isKernel(B.getMF().getFunction())) {
      // This only makes sense to call in a kernel, so just lower to null.
      B.buildConstant(MI.getOperand(0).getReg(), 0);
      MI.eraseFromParent();
      return true;
    }

    return legalizePreloadedArgIntrin(
      MI, MRI, B, AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR);
  case Intrinsic::amdgcn_implicitarg_ptr:
    return legalizeImplicitArgPtr(MI, MRI, B);
  case Intrinsic::amdgcn_workitem_id_x:
    return legalizeWorkitemIDIntrinsic(MI, MRI, B, 0,
                                       AMDGPUFunctionArgInfo::WORKITEM_ID_X);
  case Intrinsic::amdgcn_workitem_id_y:
    return legalizeWorkitemIDIntrinsic(MI, MRI, B, 1,
                                       AMDGPUFunctionArgInfo::WORKITEM_ID_Y);
  case Intrinsic::amdgcn_workitem_id_z:
    return legalizeWorkitemIDIntrinsic(MI, MRI, B, 2,
                                       AMDGPUFunctionArgInfo::WORKITEM_ID_Z);
  case Intrinsic::amdgcn_workgroup_id_x:
    return legalizeWorkGroupId(
        MI, B, AMDGPUFunctionArgInfo::WORKGROUP_ID_X,
        AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_ID_X,
        AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_ID_X);
  case Intrinsic::amdgcn_workgroup_id_y:
    return legalizeWorkGroupId(
        MI, B, AMDGPUFunctionArgInfo::WORKGROUP_ID_Y,
        AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_ID_Y,
        AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_ID_Y);
  case Intrinsic::amdgcn_workgroup_id_z:
    return legalizeWorkGroupId(
        MI, B, AMDGPUFunctionArgInfo::WORKGROUP_ID_Z,
        AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_ID_Z,
        AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_ID_Z);
  case Intrinsic::amdgcn_cluster_id_x:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(MI, MRI, B,
                                      AMDGPUFunctionArgInfo::WORKGROUP_ID_X);
  case Intrinsic::amdgcn_cluster_id_y:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(MI, MRI, B,
                                      AMDGPUFunctionArgInfo::WORKGROUP_ID_Y);
  case Intrinsic::amdgcn_cluster_id_z:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(MI, MRI, B,
                                      AMDGPUFunctionArgInfo::WORKGROUP_ID_Z);
  case Intrinsic::amdgcn_cluster_workgroup_id_x:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(
               MI, MRI, B, AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_ID_X);
  case Intrinsic::amdgcn_cluster_workgroup_id_y:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(
               MI, MRI, B, AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_ID_Y);
  case Intrinsic::amdgcn_cluster_workgroup_id_z:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(
               MI, MRI, B, AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_ID_Z);
  case Intrinsic::amdgcn_cluster_workgroup_flat_id:
    return ST.hasClusters() &&
           legalizeConstHwRegRead(MI, B, AMDGPU::Hwreg::ID_IB_STS2, 21, 4);
  case Intrinsic::amdgcn_cluster_workgroup_max_id_x:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(
               MI, MRI, B, AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_ID_X);
  case Intrinsic::amdgcn_cluster_workgroup_max_id_y:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(
               MI, MRI, B, AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_ID_Y);
  case Intrinsic::amdgcn_cluster_workgroup_max_id_z:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(
               MI, MRI, B, AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_ID_Z);
  case Intrinsic::amdgcn_cluster_workgroup_max_flat_id:
    return ST.hasClusters() &&
           legalizePreloadedArgIntrin(
               MI, MRI, B,
               AMDGPUFunctionArgInfo::CLUSTER_WORKGROUP_MAX_FLAT_ID);
  case Intrinsic::amdgcn_wave_id:
    return legalizeWaveID(MI, B);
  case Intrinsic::amdgcn_lds_kernel_id:
    return legalizePreloadedArgIntrin(MI, MRI, B,
                                      AMDGPUFunctionArgInfo::LDS_KERNEL_ID);
  case Intrinsic::amdgcn_dispatch_ptr:
    return legalizePreloadedArgIntrin(MI, MRI, B,
                                      AMDGPUFunctionArgInfo::DISPATCH_PTR);
  case Intrinsic::amdgcn_queue_ptr:
    return legalizePreloadedArgIntrin(MI, MRI, B,
                                      AMDGPUFunctionArgInfo::QUEUE_PTR);
  case Intrinsic::amdgcn_implicit_buffer_ptr: {
    const Function &Fn = B.getMF().getFunction();
    const SIMachineFunctionInfo *MFI =
        B.getMF().getInfo<SIMachineFunctionInfo>();
    if (!MFI->getUserSGPRInfo().hasImplicitBufferPtr()) {
      const char *Error =
          ST.hasArchitectedFlatScratch()
              ? "intrinsic not supported on subtarget"
          : !ST.isMesa3DOS() ? "intrinsic not supported for OS"
                             : "intrinsic not supported for calling convention";
      Fn.getContext().diagnose(
          DiagnosticInfoUnsupported(Fn, Error, MI.getDebugLoc()));
      B.buildUndef(MI.getOperand(0).getReg());
      MI.eraseFromParent();
      return true;
    }
    return legalizePreloadedArgIntrin(
      MI, MRI, B, AMDGPUFunctionArgInfo::IMPLICIT_BUFFER_PTR);
  }
  case Intrinsic::amdgcn_dispatch_id:
    return legalizePreloadedArgIntrin(MI, MRI, B,
                                      AMDGPUFunctionArgInfo::DISPATCH_ID);
  case Intrinsic::r600_read_ngroups_x:
    // TODO: Emit error for hsa
    return legalizeKernargMemParameter(MI, B,
                                       SI::KernelInputOffsets::NGROUPS_X);
  case Intrinsic::r600_read_ngroups_y:
    return legalizeKernargMemParameter(MI, B,
                                       SI::KernelInputOffsets::NGROUPS_Y);
  case Intrinsic::r600_read_ngroups_z:
    return legalizeKernargMemParameter(MI, B,
                                       SI::KernelInputOffsets::NGROUPS_Z);
  case Intrinsic::r600_read_local_size_x:
    // TODO: Could insert G_ASSERT_ZEXT from i16
    return legalizeKernargMemParameter(MI, B, SI::KernelInputOffsets::LOCAL_SIZE_X);
  case Intrinsic::r600_read_local_size_y:
    // TODO: Could insert G_ASSERT_ZEXT from i16
    return legalizeKernargMemParameter(MI, B,  SI::KernelInputOffsets::LOCAL_SIZE_Y);
    // TODO: Could insert G_ASSERT_ZEXT from i16
  case Intrinsic::r600_read_local_size_z:
    return legalizeKernargMemParameter(MI, B,
                                       SI::KernelInputOffsets::LOCAL_SIZE_Z);
  case Intrinsic::amdgcn_fdiv_fast:
    return legalizeFDIVFastIntrin(MI, MRI, B);
  case Intrinsic::amdgcn_is_shared:
    return legalizeIsAddrSpace(MI, MRI, B, AMDGPUAS::LOCAL_ADDRESS);
  case Intrinsic::amdgcn_is_private:
    return legalizeIsAddrSpace(MI, MRI, B, AMDGPUAS::PRIVATE_ADDRESS);
  case Intrinsic::amdgcn_wavefrontsize: {
    B.buildConstant(MI.getOperand(0), ST.getWavefrontSize());
    MI.eraseFromParent();
    return true;
  }
  case Intrinsic::amdgcn_s_buffer_load:
  case Intrinsic::amdgcn_ptr_s_buffer_load:
    return legalizeSBufferLoad(Helper, MI);
  case Intrinsic::amdgcn_raw_buffer_store:
  case Intrinsic::amdgcn_raw_ptr_buffer_store:
  case Intrinsic::amdgcn_struct_buffer_store:
  case Intrinsic::amdgcn_struct_ptr_buffer_store:
    return legalizeBufferStore(MI, Helper, false, false);
  case Intrinsic::amdgcn_raw_buffer_store_format:
  case Intrinsic::amdgcn_raw_ptr_buffer_store_format:
  case Intrinsic::amdgcn_struct_buffer_store_format:
  case Intrinsic::amdgcn_struct_ptr_buffer_store_format:
    return legalizeBufferStore(MI, Helper, false, true);
  case Intrinsic::amdgcn_raw_tbuffer_store:
  case Intrinsic::amdgcn_raw_ptr_tbuffer_store:
  case Intrinsic::amdgcn_struct_tbuffer_store:
  case Intrinsic::amdgcn_struct_ptr_tbuffer_store:
    return legalizeBufferStore(MI, Helper, true, true);
  case Intrinsic::amdgcn_raw_buffer_load:
  case Intrinsic::amdgcn_raw_ptr_buffer_load:
  case Intrinsic::amdgcn_raw_atomic_buffer_load:
  case Intrinsic::amdgcn_raw_ptr_atomic_buffer_load:
  case Intrinsic::amdgcn_struct_buffer_load:
  case Intrinsic::amdgcn_struct_ptr_buffer_load:
  case Intrinsic::amdgcn_struct_atomic_buffer_load:
  case Intrinsic::amdgcn_struct_ptr_atomic_buffer_load:
    return legalizeBufferLoad(MI, Helper, false, false);
  case Intrinsic::amdgcn_raw_buffer_load_format:
  case Intrinsic::amdgcn_raw_ptr_buffer_load_format:
  case Intrinsic::amdgcn_struct_buffer_load_format:
  case Intrinsic::amdgcn_struct_ptr_buffer_load_format:
    return legalizeBufferLoad(MI, Helper, true, false);
  case Intrinsic::amdgcn_raw_tbuffer_load:
  case Intrinsic::amdgcn_raw_ptr_tbuffer_load:
  case Intrinsic::amdgcn_struct_tbuffer_load:
  case Intrinsic::amdgcn_struct_ptr_tbuffer_load:
    return legalizeBufferLoad(MI, Helper, true, true);
  case Intrinsic::amdgcn_raw_buffer_atomic_swap:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_swap:
  case Intrinsic::amdgcn_struct_buffer_atomic_swap:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_swap:
  case Intrinsic::amdgcn_raw_buffer_atomic_add:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_add:
  case Intrinsic::amdgcn_struct_buffer_atomic_add:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_add:
  case Intrinsic::amdgcn_raw_buffer_atomic_sub:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_sub:
  case Intrinsic::amdgcn_struct_buffer_atomic_sub:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_sub:
  case Intrinsic::amdgcn_raw_buffer_atomic_smin:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_smin:
  case Intrinsic::amdgcn_struct_buffer_atomic_smin:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_smin:
  case Intrinsic::amdgcn_raw_buffer_atomic_umin:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_umin:
  case Intrinsic::amdgcn_struct_buffer_atomic_umin:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_umin:
  case Intrinsic::amdgcn_raw_buffer_atomic_smax:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_smax:
  case Intrinsic::amdgcn_struct_buffer_atomic_smax:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_smax:
  case Intrinsic::amdgcn_raw_buffer_atomic_umax:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_umax:
  case Intrinsic::amdgcn_struct_buffer_atomic_umax:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_umax:
  case Intrinsic::amdgcn_raw_buffer_atomic_and:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_and:
  case Intrinsic::amdgcn_struct_buffer_atomic_and:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_and:
  case Intrinsic::amdgcn_raw_buffer_atomic_or:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_or:
  case Intrinsic::amdgcn_struct_buffer_atomic_or:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_or:
  case Intrinsic::amdgcn_raw_buffer_atomic_xor:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_xor:
  case Intrinsic::amdgcn_struct_buffer_atomic_xor:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_xor:
  case Intrinsic::amdgcn_raw_buffer_atomic_inc:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_inc:
  case Intrinsic::amdgcn_struct_buffer_atomic_inc:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_inc:
  case Intrinsic::amdgcn_raw_buffer_atomic_dec:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_dec:
  case Intrinsic::amdgcn_struct_buffer_atomic_dec:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_dec:
  case Intrinsic::amdgcn_raw_buffer_atomic_cmpswap:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_cmpswap:
  case Intrinsic::amdgcn_struct_buffer_atomic_cmpswap:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_cmpswap:
  case Intrinsic::amdgcn_raw_buffer_atomic_fmin:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_fmin:
  case Intrinsic::amdgcn_struct_buffer_atomic_fmin:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_fmin:
  case Intrinsic::amdgcn_raw_buffer_atomic_fmax:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_fmax:
  case Intrinsic::amdgcn_struct_buffer_atomic_fmax:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_fmax:
  case Intrinsic::amdgcn_raw_buffer_atomic_sub_clamp_u32:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_sub_clamp_u32:
  case Intrinsic::amdgcn_struct_buffer_atomic_sub_clamp_u32:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_sub_clamp_u32:
  case Intrinsic::amdgcn_raw_buffer_atomic_cond_sub_u32:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_cond_sub_u32:
  case Intrinsic::amdgcn_struct_buffer_atomic_cond_sub_u32:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_cond_sub_u32:
  case Intrinsic::amdgcn_raw_buffer_atomic_fadd:
  case Intrinsic::amdgcn_raw_ptr_buffer_atomic_fadd:
  case Intrinsic::amdgcn_struct_buffer_atomic_fadd:
  case Intrinsic::amdgcn_struct_ptr_buffer_atomic_fadd:
    return legalizeBufferAtomic(MI, B, IntrID);
  case Intrinsic::amdgcn_rsq_clamp:
    return legalizeRsqClampIntrinsic(MI, MRI, B);
  case Intrinsic::amdgcn_image_bvh_intersect_ray:
    return legalizeBVHIntersectRayIntrinsic(MI, B);
  case Intrinsic::amdgcn_image_bvh_dual_intersect_ray:
  case Intrinsic::amdgcn_image_bvh8_intersect_ray:
    return legalizeBVHDualOrBVH8IntersectRayIntrinsic(MI, B);
  case Intrinsic::amdgcn_swmmac_f32_16x16x128_fp8_fp8:
  case Intrinsic::amdgcn_swmmac_f32_16x16x128_fp8_bf8:
  case Intrinsic::amdgcn_swmmac_f32_16x16x128_bf8_fp8:
  case Intrinsic::amdgcn_swmmac_f32_16x16x128_bf8_bf8:
  case Intrinsic::amdgcn_swmmac_f16_16x16x128_fp8_fp8:
  case Intrinsic::amdgcn_swmmac_f16_16x16x128_fp8_bf8:
  case Intrinsic::amdgcn_swmmac_f16_16x16x128_bf8_fp8:
  case Intrinsic::amdgcn_swmmac_f16_16x16x128_bf8_bf8: {
    Register Index = MI.getOperand(5).getReg();
    LLT I64 = LLT::integer(64);
    LLT IndexArgTy = MRI.getType(Index);
    if (IndexArgTy != I64) {
      auto NewIndex = IndexArgTy.isVector() ? B.buildBitcast(I64, Index)
                                            : B.buildAnyExt(I64, Index);
      MI.getOperand(5).setReg(NewIndex.getReg(0));
    }
    return true;
  }
  case Intrinsic::amdgcn_swmmac_f16_16x16x32_f16:
  case Intrinsic::amdgcn_swmmac_bf16_16x16x32_bf16:
  case Intrinsic::amdgcn_swmmac_f32_16x16x32_bf16:
  case Intrinsic::amdgcn_swmmac_f32_16x16x32_f16:
  case Intrinsic::amdgcn_swmmac_f32_16x16x32_fp8_fp8:
  case Intrinsic::amdgcn_swmmac_f32_16x16x32_fp8_bf8:
  case Intrinsic::amdgcn_swmmac_f32_16x16x32_bf8_fp8:
  case Intrinsic::amdgcn_swmmac_f32_16x16x32_bf8_bf8: {
    Register Index = MI.getOperand(5).getReg();
    LLT I32 = LLT::integer(32);
    if (MRI.getType(Index) != I32)
      MI.getOperand(5).setReg(B.buildAnyExt(I32, Index).getReg(0));
    return true;
  }
  case Intrinsic::amdgcn_swmmac_f16_16x16x64_f16:
  case Intrinsic::amdgcn_swmmac_bf16_16x16x64_bf16:
  case Intrinsic::amdgcn_swmmac_f32_16x16x64_bf16:
  case Intrinsic::amdgcn_swmmac_bf16f32_16x16x64_bf16:
  case Intrinsic::amdgcn_swmmac_f32_16x16x64_f16:
  case Intrinsic::amdgcn_swmmac_i32_16x16x128_iu8:
  case Intrinsic::amdgcn_swmmac_i32_16x16x32_iu4:
  case Intrinsic::amdgcn_swmmac_i32_16x16x32_iu8:
  case Intrinsic::amdgcn_swmmac_i32_16x16x64_iu4: {
    Register Index = MI.getOperand(7).getReg();
    LLT IdxTy = IntrID == Intrinsic::amdgcn_swmmac_i32_16x16x128_iu8
                    ? LLT::integer(64)
                    : LLT::integer(32);
    LLT IndexArgTy = MRI.getType(Index);
    if (IndexArgTy != IdxTy) {
      auto NewIndex = IndexArgTy.isVector() ? B.buildBitcast(IdxTy, Index)
                                            : B.buildAnyExt(IdxTy, Index);
      MI.getOperand(7).setReg(NewIndex.getReg(0));
    }
    return true;
  }

  case Intrinsic::amdgcn_fmed3: {
    GISelChangeObserver &Observer = Helper.Observer;

    // FIXME: This is to workaround the inability of tablegen match combiners to
    // match intrinsics in patterns.
    Observer.changingInstr(MI);
    MI.setDesc(B.getTII().get(AMDGPU::G_AMDGPU_FMED3));
    MI.removeOperand(1);
    Observer.changedInstr(MI);
    return true;
  }
  case Intrinsic::amdgcn_readlane:
  case Intrinsic::amdgcn_writelane:
  case Intrinsic::amdgcn_readfirstlane:
  case Intrinsic::amdgcn_permlane16:
  case Intrinsic::amdgcn_permlanex16:
  case Intrinsic::amdgcn_permlane64:
  case Intrinsic::amdgcn_set_inactive:
  case Intrinsic::amdgcn_set_inactive_chain_arg:
  case Intrinsic::amdgcn_mov_dpp8:
  case Intrinsic::amdgcn_update_dpp:
  case Intrinsic::amdgcn_permlane_bcast:
  case Intrinsic::amdgcn_permlane_up:
  case Intrinsic::amdgcn_permlane_down:
  case Intrinsic::amdgcn_permlane_xor:
    return legalizeLaneOp(Helper, MI, IntrID);
  case Intrinsic::amdgcn_s_buffer_prefetch_data:
    return legalizeSBufferPrefetch(Helper, MI);
  case Intrinsic::amdgcn_dead: {
    // TODO: Use poison instead of undef
    for (const MachineOperand &Def : MI.defs())
      B.buildUndef(Def);
    MI.eraseFromParent();
    return true;
  }
  case Intrinsic::amdgcn_cooperative_atomic_load_32x4B:
  case Intrinsic::amdgcn_cooperative_atomic_load_16x8B:
  case Intrinsic::amdgcn_cooperative_atomic_load_8x16B:
    assert(MI.hasOneMemOperand() && "Expected IRTranslator to set MemOp!");
    B.buildLoad(MI.getOperand(0), MI.getOperand(2), **MI.memoperands_begin());
    MI.eraseFromParent();
    return true;
  case Intrinsic::amdgcn_cooperative_atomic_store_32x4B:
  case Intrinsic::amdgcn_cooperative_atomic_store_16x8B:
  case Intrinsic::amdgcn_cooperative_atomic_store_8x16B:
    assert(MI.hasOneMemOperand() && "Expected IRTranslator to set MemOp!");
    B.buildStore(MI.getOperand(2), MI.getOperand(1), **MI.memoperands_begin());
    MI.eraseFromParent();
    return true;
  case Intrinsic::amdgcn_av_load_b128:
  case Intrinsic::amdgcn_av_store_b128: {
    assert(MI.hasOneMemOperand() && "Expected IRTranslator to set MemOp!");
    if (IntrID == Intrinsic::amdgcn_av_load_b128)
      B.buildLoad(MI.getOperand(0), MI.getOperand(2), **MI.memoperands_begin());
    else
      B.buildStore(MI.getOperand(2), MI.getOperand(1),
                   **MI.memoperands_begin());
    MI.eraseFromParent();
    return true;
  }
  case Intrinsic::amdgcn_flat_load_monitor_b32:
  case Intrinsic::amdgcn_flat_load_monitor_b64:
  case Intrinsic::amdgcn_flat_load_monitor_b128:
    assert(MI.hasOneMemOperand() && "Expected IRTranslator to set MemOp!");
    B.buildInstr(AMDGPU::G_AMDGPU_FLAT_LOAD_MONITOR)
        .add(MI.getOperand(0))
        .add(MI.getOperand(2))
        .addMemOperand(*MI.memoperands_begin());
    MI.eraseFromParent();
    return true;
  case Intrinsic::amdgcn_global_load_monitor_b32:
  case Intrinsic::amdgcn_global_load_monitor_b64:
  case Intrinsic::amdgcn_global_load_monitor_b128:
    assert(MI.hasOneMemOperand() && "Expected IRTranslator to set MemOp!");
    B.buildInstr(AMDGPU::G_AMDGPU_GLOBAL_LOAD_MONITOR)
        .add(MI.getOperand(0))
        .add(MI.getOperand(2))
        .addMemOperand(*MI.memoperands_begin());
    MI.eraseFromParent();
    return true;
  default: {
    if (const AMDGPU::ImageDimIntrinsicInfo *ImageDimIntr =
            AMDGPU::getImageDimIntrinsicInfo(IntrID))
      return legalizeImageIntrinsic(MI, B, Helper.Observer, ImageDimIntr);
    return true;
  }
  }

  return true;
}
