//===-- AMDGPUISelLowering.cpp - AMDGPU Common DAG lowering functions -----===//
//
// 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 is the parent TargetLowering class for hardware code gen
/// targets.
//
//===----------------------------------------------------------------------===//

#include "AMDGPUISelLowering.h"
#include "AMDGPU.h"
#include "AMDGPUInstrInfo.h"
#include "AMDGPUMachineFunctionInfo.h"
#include "AMDGPUMemoryUtils.h"
#include "AMDGPUSelectionDAGInfo.h"
#include "SIMachineFunctionInfo.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

#define GET_CALLING_CONV_IMPL
#include "AMDGPUGenCallingConv.inc"

static cl::opt<bool> AMDGPUBypassSlowDiv(
  "amdgpu-bypass-slow-div",
  cl::desc("Skip 64-bit divide for dynamic 32-bit values"),
  cl::init(true));

// Find a larger type to do a load / store of a vector with.
EVT AMDGPUTargetLowering::getEquivalentMemType(LLVMContext &Ctx, EVT VT) {
  unsigned StoreSize = VT.getStoreSizeInBits();
  if (StoreSize <= 32)
    return EVT::getIntegerVT(Ctx, StoreSize);

  if (StoreSize % 32 == 0)
    return EVT::getVectorVT(Ctx, MVT::i32, StoreSize / 32);

  return VT;
}

unsigned AMDGPUTargetLowering::numBitsUnsigned(SDValue Op, SelectionDAG &DAG) {
  return DAG.computeKnownBits(Op).countMaxActiveBits();
}

unsigned AMDGPUTargetLowering::numBitsSigned(SDValue Op, SelectionDAG &DAG) {
  // In order for this to be a signed 24-bit value, bit 23, must
  // be a sign bit.
  return DAG.ComputeMaxSignificantBits(Op);
}

AMDGPUTargetLowering::AMDGPUTargetLowering(const TargetMachine &TM,
                                           const TargetSubtargetInfo &STI,
                                           const AMDGPUSubtarget &AMDGPUSTI)
    : TargetLowering(TM, STI), Subtarget(&AMDGPUSTI) {
  // Always lower memset, memcpy, and memmove intrinsics to load/store
  // instructions, rather then generating calls to memset, mempcy or memmove.
  MaxStoresPerMemset = MaxStoresPerMemsetOptSize = ~0U;
  MaxStoresPerMemcpy = MaxStoresPerMemcpyOptSize = ~0U;
  MaxStoresPerMemmove = MaxStoresPerMemmoveOptSize = ~0U;

  // Enable ganging up loads and stores in the memcpy DAG lowering.
  MaxGluedStoresPerMemcpy = 16;

  // Lower floating point store/load to integer store/load to reduce the number
  // of patterns in tablegen.
  setOperationAction(ISD::LOAD, MVT::f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::f32, MVT::i32);

  setOperationAction(ISD::LOAD, MVT::v2f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v2f32, MVT::v2i32);

  setOperationAction(ISD::LOAD, MVT::v3f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v3f32, MVT::v3i32);

  setOperationAction(ISD::LOAD, MVT::v4f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v4f32, MVT::v4i32);

  setOperationAction(ISD::LOAD, MVT::v5f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v5f32, MVT::v5i32);

  setOperationAction(ISD::LOAD, MVT::v6f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v6f32, MVT::v6i32);

  setOperationAction(ISD::LOAD, MVT::v7f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v7f32, MVT::v7i32);

  setOperationAction(ISD::LOAD, MVT::v8f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v8f32, MVT::v8i32);

  setOperationAction(ISD::LOAD, MVT::v9f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v9f32, MVT::v9i32);

  setOperationAction(ISD::LOAD, MVT::v10f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v10f32, MVT::v10i32);

  setOperationAction(ISD::LOAD, MVT::v11f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v11f32, MVT::v11i32);

  setOperationAction(ISD::LOAD, MVT::v12f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v12f32, MVT::v12i32);

  setOperationAction(ISD::LOAD, MVT::v16f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v16f32, MVT::v16i32);

  setOperationAction(ISD::LOAD, MVT::v32f32, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v32f32, MVT::v32i32);

  setOperationAction(ISD::LOAD, MVT::i64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::i64, MVT::v2i32);

  setOperationAction(ISD::LOAD, MVT::v2i64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v2i64, MVT::v4i32);

  setOperationAction(ISD::LOAD, MVT::f64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::f64, MVT::v2i32);

  setOperationAction(ISD::LOAD, MVT::v2f64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v2f64, MVT::v4i32);

  setOperationAction(ISD::LOAD, MVT::v3i64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v3i64, MVT::v6i32);

  setOperationAction(ISD::LOAD, MVT::v4i64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v4i64, MVT::v8i32);

  setOperationAction(ISD::LOAD, MVT::v3f64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v3f64, MVT::v6i32);

  setOperationAction(ISD::LOAD, MVT::v4f64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v4f64, MVT::v8i32);

  setOperationAction(ISD::LOAD, MVT::v8i64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v8i64, MVT::v16i32);

  setOperationAction(ISD::LOAD, MVT::v8f64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v8f64, MVT::v16i32);

  setOperationAction(ISD::LOAD, MVT::v16i64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v16i64, MVT::v32i32);

  setOperationAction(ISD::LOAD, MVT::v16f64, Promote);
  AddPromotedToType(ISD::LOAD, MVT::v16f64, MVT::v32i32);

  setOperationAction(ISD::LOAD, MVT::i128, Promote);
  AddPromotedToType(ISD::LOAD, MVT::i128, MVT::v4i32);

  // TODO: Would be better to consume as directly legal
  setOperationAction(ISD::ATOMIC_LOAD, MVT::f32, Promote);
  AddPromotedToType(ISD::ATOMIC_LOAD, MVT::f32, MVT::i32);

  setOperationAction(ISD::ATOMIC_LOAD, MVT::f64, Promote);
  AddPromotedToType(ISD::ATOMIC_LOAD, MVT::f64, MVT::i64);

  setOperationAction(ISD::ATOMIC_LOAD, MVT::f16, Promote);
  AddPromotedToType(ISD::ATOMIC_LOAD, MVT::f16, MVT::i16);

  setOperationAction(ISD::ATOMIC_LOAD, MVT::bf16, Promote);
  AddPromotedToType(ISD::ATOMIC_LOAD, MVT::bf16, MVT::i16);

  setOperationAction(ISD::ATOMIC_LOAD, MVT::v2f32, Promote);
  AddPromotedToType(ISD::ATOMIC_LOAD, MVT::v2f32, MVT::i64);

  setOperationAction(ISD::ATOMIC_STORE, MVT::f32, Promote);
  AddPromotedToType(ISD::ATOMIC_STORE, MVT::f32, MVT::i32);

  setOperationAction(ISD::ATOMIC_STORE, MVT::f64, Promote);
  AddPromotedToType(ISD::ATOMIC_STORE, MVT::f64, MVT::i64);

  setOperationAction(ISD::ATOMIC_STORE, MVT::f16, Promote);
  AddPromotedToType(ISD::ATOMIC_STORE, MVT::f16, MVT::i16);

  setOperationAction(ISD::ATOMIC_STORE, MVT::bf16, Promote);
  AddPromotedToType(ISD::ATOMIC_STORE, MVT::bf16, MVT::i16);

  setOperationAction(ISD::ATOMIC_STORE, MVT::v2f32, Promote);
  AddPromotedToType(ISD::ATOMIC_STORE, MVT::v2f32, MVT::i64);

  // There are no 64-bit extloads. These should be done as a 32-bit extload and
  // an extension to 64-bit.
  for (MVT VT : MVT::integer_valuetypes())
    setLoadExtAction({ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}, MVT::i64, VT,
                     Expand);

  for (MVT VT : MVT::integer_valuetypes()) {
    if (VT == MVT::i64)
      continue;

    for (auto Op : {ISD::SEXTLOAD, ISD::ZEXTLOAD, ISD::EXTLOAD}) {
      setLoadExtAction(Op, VT, MVT::i1, Promote);
      setLoadExtAction(Op, VT, MVT::i8, Legal);
      setLoadExtAction(Op, VT, MVT::i16, Legal);
      setLoadExtAction(Op, VT, MVT::i32, Expand);
    }
  }

  for (MVT VT : MVT::integer_fixedlen_vector_valuetypes())
    for (auto MemVT :
         {MVT::v2i8, MVT::v4i8, MVT::v2i16, MVT::v3i16, MVT::v4i16})
      setLoadExtAction({ISD::SEXTLOAD, ISD::ZEXTLOAD, ISD::EXTLOAD}, VT, MemVT,
                       Expand);

  setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v2f32, MVT::v2f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v2f32, MVT::v2bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v3f32, MVT::v3f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v3f32, MVT::v3bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v4f32, MVT::v4f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v4f32, MVT::v4bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v8f32, MVT::v8f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v8f32, MVT::v8bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v16f32, MVT::v16f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v16f32, MVT::v16bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v32f32, MVT::v32f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v32f32, MVT::v32bf16, Expand);

  setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v2f64, MVT::v2f32, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v3f64, MVT::v3f32, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v4f64, MVT::v4f32, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v8f64, MVT::v8f32, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v16f64, MVT::v16f32, Expand);

  setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v2f64, MVT::v2f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v2f64, MVT::v2bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v3f64, MVT::v3f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v3f64, MVT::v3bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v4f64, MVT::v4f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v4f64, MVT::v4bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v8f64, MVT::v8f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v8f64, MVT::v8bf16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v16f64, MVT::v16f16, Expand);
  setLoadExtAction(ISD::EXTLOAD, MVT::v16f64, MVT::v16bf16, Expand);

  setOperationAction(ISD::STORE, MVT::f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::f32, MVT::i32);

  setOperationAction(ISD::STORE, MVT::v2f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v2f32, MVT::v2i32);

  setOperationAction(ISD::STORE, MVT::v3f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v3f32, MVT::v3i32);

  setOperationAction(ISD::STORE, MVT::v4f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v4f32, MVT::v4i32);

  setOperationAction(ISD::STORE, MVT::v5f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v5f32, MVT::v5i32);

  setOperationAction(ISD::STORE, MVT::v6f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v6f32, MVT::v6i32);

  setOperationAction(ISD::STORE, MVT::v7f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v7f32, MVT::v7i32);

  setOperationAction(ISD::STORE, MVT::v8f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v8f32, MVT::v8i32);

  setOperationAction(ISD::STORE, MVT::v9f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v9f32, MVT::v9i32);

  setOperationAction(ISD::STORE, MVT::v10f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v10f32, MVT::v10i32);

  setOperationAction(ISD::STORE, MVT::v11f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v11f32, MVT::v11i32);

  setOperationAction(ISD::STORE, MVT::v12f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v12f32, MVT::v12i32);

  setOperationAction(ISD::STORE, MVT::v16f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v16f32, MVT::v16i32);

  setOperationAction(ISD::STORE, MVT::v32f32, Promote);
  AddPromotedToType(ISD::STORE, MVT::v32f32, MVT::v32i32);

  setOperationAction(ISD::STORE, MVT::i64, Promote);
  AddPromotedToType(ISD::STORE, MVT::i64, MVT::v2i32);

  setOperationAction(ISD::STORE, MVT::v2i64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v2i64, MVT::v4i32);

  setOperationAction(ISD::STORE, MVT::f64, Promote);
  AddPromotedToType(ISD::STORE, MVT::f64, MVT::v2i32);

  setOperationAction(ISD::STORE, MVT::v2f64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v2f64, MVT::v4i32);

  setOperationAction(ISD::STORE, MVT::v3i64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v3i64, MVT::v6i32);

  setOperationAction(ISD::STORE, MVT::v3f64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v3f64, MVT::v6i32);

  setOperationAction(ISD::STORE, MVT::v4i64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v4i64, MVT::v8i32);

  setOperationAction(ISD::STORE, MVT::v4f64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v4f64, MVT::v8i32);

  setOperationAction(ISD::STORE, MVT::v8i64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v8i64, MVT::v16i32);

  setOperationAction(ISD::STORE, MVT::v8f64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v8f64, MVT::v16i32);

  setOperationAction(ISD::STORE, MVT::v16i64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v16i64, MVT::v32i32);

  setOperationAction(ISD::STORE, MVT::v16f64, Promote);
  AddPromotedToType(ISD::STORE, MVT::v16f64, MVT::v32i32);

  setOperationAction(ISD::STORE, MVT::i128, Promote);
  AddPromotedToType(ISD::STORE, MVT::i128, MVT::v4i32);

  setTruncStoreAction(MVT::i64, MVT::i1, Expand);
  setTruncStoreAction(MVT::i64, MVT::i8, Expand);
  setTruncStoreAction(MVT::i64, MVT::i16, Expand);
  setTruncStoreAction(MVT::i64, MVT::i32, Expand);

  setTruncStoreAction(MVT::v2i64, MVT::v2i1, Expand);
  setTruncStoreAction(MVT::v2i64, MVT::v2i8, Expand);
  setTruncStoreAction(MVT::v2i64, MVT::v2i16, Expand);
  setTruncStoreAction(MVT::v2i64, MVT::v2i32, Expand);

  setTruncStoreAction(MVT::f32, MVT::bf16, Expand);
  setTruncStoreAction(MVT::f32, MVT::f16, Expand);
  setTruncStoreAction(MVT::v2f32, MVT::v2bf16, Expand);
  setTruncStoreAction(MVT::v2f32, MVT::v2f16, Expand);
  setTruncStoreAction(MVT::v3f32, MVT::v3bf16, Expand);
  setTruncStoreAction(MVT::v3f32, MVT::v3f16, Expand);
  setTruncStoreAction(MVT::v4f32, MVT::v4bf16, Expand);
  setTruncStoreAction(MVT::v4f32, MVT::v4f16, Expand);
  setTruncStoreAction(MVT::v6f32, MVT::v6f16, Expand);
  setTruncStoreAction(MVT::v8f32, MVT::v8bf16, Expand);
  setTruncStoreAction(MVT::v8f32, MVT::v8f16, Expand);
  setTruncStoreAction(MVT::v16f32, MVT::v16bf16, Expand);
  setTruncStoreAction(MVT::v16f32, MVT::v16f16, Expand);
  setTruncStoreAction(MVT::v32f32, MVT::v32bf16, Expand);
  setTruncStoreAction(MVT::v32f32, MVT::v32f16, Expand);

  setTruncStoreAction(MVT::f64, MVT::bf16, Expand);
  setTruncStoreAction(MVT::f64, MVT::f16, Expand);
  setTruncStoreAction(MVT::f64, MVT::f32, Expand);

  setTruncStoreAction(MVT::v2f64, MVT::v2f32, Expand);
  setTruncStoreAction(MVT::v2f64, MVT::v2bf16, Expand);
  setTruncStoreAction(MVT::v2f64, MVT::v2f16, Expand);

  setTruncStoreAction(MVT::v3i32, MVT::v3i8, Expand);

  setTruncStoreAction(MVT::v3i64, MVT::v3i32, Expand);
  setTruncStoreAction(MVT::v3i64, MVT::v3i16, Expand);
  setTruncStoreAction(MVT::v3i64, MVT::v3i8, Expand);
  setTruncStoreAction(MVT::v3i64, MVT::v3i1, Expand);
  setTruncStoreAction(MVT::v3f64, MVT::v3f32, Expand);
  setTruncStoreAction(MVT::v3f64, MVT::v3bf16, Expand);
  setTruncStoreAction(MVT::v3f64, MVT::v3f16, Expand);

  setTruncStoreAction(MVT::v4i64, MVT::v4i32, Expand);
  setTruncStoreAction(MVT::v4i64, MVT::v4i16, Expand);
  setTruncStoreAction(MVT::v4f64, MVT::v4f32, Expand);
  setTruncStoreAction(MVT::v4f64, MVT::v4bf16, Expand);
  setTruncStoreAction(MVT::v4f64, MVT::v4f16, Expand);

  setTruncStoreAction(MVT::v5i32, MVT::v5i1, Expand);
  setTruncStoreAction(MVT::v5i32, MVT::v5i8, Expand);
  setTruncStoreAction(MVT::v5i32, MVT::v5i16, Expand);

  setTruncStoreAction(MVT::v6i32, MVT::v6i1, Expand);
  setTruncStoreAction(MVT::v6i32, MVT::v6i8, Expand);
  setTruncStoreAction(MVT::v6i32, MVT::v6i16, Expand);

  setTruncStoreAction(MVT::v7i32, MVT::v7i1, Expand);
  setTruncStoreAction(MVT::v7i32, MVT::v7i8, Expand);
  setTruncStoreAction(MVT::v7i32, MVT::v7i16, Expand);

  setTruncStoreAction(MVT::v8f64, MVT::v8f32, Expand);
  setTruncStoreAction(MVT::v8f64, MVT::v8bf16, Expand);
  setTruncStoreAction(MVT::v8f64, MVT::v8f16, Expand);

  setTruncStoreAction(MVT::v16f64, MVT::v16f32, Expand);
  setTruncStoreAction(MVT::v16f64, MVT::v16bf16, Expand);
  setTruncStoreAction(MVT::v16f64, MVT::v16f16, Expand);
  setTruncStoreAction(MVT::v16i64, MVT::v16i16, Expand);
  setTruncStoreAction(MVT::v16i64, MVT::v16i8, Expand);
  setTruncStoreAction(MVT::v16i64, MVT::v16i8, Expand);
  setTruncStoreAction(MVT::v16i64, MVT::v16i1, Expand);

  setOperationAction(ISD::Constant, {MVT::i32, MVT::i64}, Legal);
  setOperationAction(ISD::ConstantFP, {MVT::f32, MVT::f64}, Legal);

  setOperationAction({ISD::BR_JT, ISD::BRIND}, MVT::Other, Expand);

  // For R600, this is totally unsupported, just custom lower to produce an
  // error.
  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);

  // Library functions.  These default to Expand, but we have instructions
  // for them.
  setOperationAction({ISD::FCEIL, ISD::FPOW, ISD::FABS, ISD::FFLOOR,
                      ISD::FROUNDEVEN, ISD::FTRUNC},
                     {MVT::f16, MVT::f32}, Legal);
  setOperationAction({ISD::FMINNUM, ISD::FMAXNUM}, MVT::f32, Legal);

  setOperationAction(ISD::FLOG2, MVT::f32, Custom);
  setOperationAction(ISD::FROUND, {MVT::f32, MVT::f64}, Custom);
  setOperationAction({ISD::LROUND, ISD::LLROUND},
                     {MVT::f16, MVT::f32, MVT::f64}, Expand);

  setOperationAction(
      {ISD::FLOG, ISD::FLOG10, ISD::FEXP, ISD::FEXP2, ISD::FEXP10}, MVT::f32,
      Custom);
  setOperationAction({ISD::FEXP, ISD::FEXP2, ISD::FEXP10}, MVT::f64, Custom);

  setOperationAction(ISD::FNEARBYINT, {MVT::f16, MVT::f32, MVT::f64}, Custom);

  setOperationAction(ISD::FRINT, {MVT::f16, MVT::f32, MVT::f64}, Custom);

  setOperationAction({ISD::LRINT, ISD::LLRINT}, {MVT::f16, MVT::f32, MVT::f64},
                     Expand);

  setOperationAction(ISD::FREM, {MVT::f16, MVT::f32, MVT::f64}, Expand);
  setOperationAction(ISD::IS_FPCLASS, {MVT::f32, MVT::f64}, Legal);
  setOperationAction({ISD::FLOG2, ISD::FEXP2}, MVT::f16, Custom);

  setOperationAction({ISD::FLOG10, ISD::FLOG, ISD::FEXP, ISD::FEXP10}, MVT::f16,
                     Custom);

  setOperationAction(ISD::FCANONICALIZE, {MVT::f32, MVT::f64}, Legal);

  // FIXME: These IS_FPCLASS vector fp types are marked custom so it reaches
  // scalarization code. Can be removed when IS_FPCLASS expand isn't called by
  // default unless marked custom/legal.
  setOperationAction(ISD::IS_FPCLASS,
                     {MVT::v2f32, MVT::v3f32, MVT::v4f32, MVT::v5f32,
                      MVT::v6f32, MVT::v7f32, MVT::v8f32, MVT::v16f32,
                      MVT::v2f64, MVT::v3f64, MVT::v4f64, MVT::v8f64,
                      MVT::v16f64},
                     Custom);

  // Expand to fneg + fadd.
  setOperationAction(ISD::FSUB, MVT::f64, Expand);

  setOperationAction(ISD::CONCAT_VECTORS,
                     {MVT::v3i32,  MVT::v3f32,  MVT::v4i32,  MVT::v4f32,
                      MVT::v5i32,  MVT::v5f32,  MVT::v6i32,  MVT::v6f32,
                      MVT::v7i32,  MVT::v7f32,  MVT::v8i32,  MVT::v8f32,
                      MVT::v9i32,  MVT::v9f32,  MVT::v10i32, MVT::v10f32,
                      MVT::v11i32, MVT::v11f32, MVT::v12i32, MVT::v12f32},
                     Custom);

  setOperationAction(
      ISD::EXTRACT_SUBVECTOR,
      {MVT::v2f32,  MVT::v2i32,  MVT::v3f32,  MVT::v3i32,  MVT::v4f32,
       MVT::v4i32,  MVT::v5f32,  MVT::v5i32,  MVT::v6f32,  MVT::v6i32,
       MVT::v7f32,  MVT::v7i32,  MVT::v8f32,  MVT::v8i32,  MVT::v9f32,
       MVT::v9i32,  MVT::v10i32, MVT::v10f32, MVT::v11i32, MVT::v11f32,
       MVT::v12i32, MVT::v12f32, MVT::v16i32, MVT::v32f32, MVT::v32i32,
       MVT::v2f64,  MVT::v2i64,  MVT::v3f64,  MVT::v3i64,  MVT::v4f64,
       MVT::v4i64,  MVT::v8f64,  MVT::v8i64,  MVT::v16f64, MVT::v16i64},
      Custom);

  setOperationAction({ISD::FP16_TO_FP, ISD::STRICT_FP16_TO_FP}, MVT::f64,
                     Expand);
  setOperationAction(ISD::FP_TO_FP16, {MVT::f64, MVT::f32}, Custom);

  const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
  for (MVT VT : ScalarIntVTs) {
    // These should use [SU]DIVREM, so set them to expand
    setOperationAction({ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM}, VT,
                       Expand);

    // GPU does not have divrem function for signed or unsigned.
    setOperationAction({ISD::SDIVREM, ISD::UDIVREM}, VT, Custom);

    // GPU does not have [S|U]MUL_LOHI functions as a single instruction.
    setOperationAction({ISD::SMUL_LOHI, ISD::UMUL_LOHI}, VT, Expand);

    setOperationAction({ISD::BSWAP, ISD::CTTZ, ISD::CTLZ}, VT, Expand);

    setOperationAction({ISD::ADDC, ISD::SUBC, ISD::ADDE, ISD::SUBE}, VT,
                       Expand);
  }

  // The hardware supports 32-bit FSHR, but not FSHL.
  setOperationAction(ISD::FSHR, MVT::i32, Legal);

  setOperationAction({ISD::ROTL, ISD::ROTR}, {MVT::i32, MVT::i64}, Expand);

  setOperationAction({ISD::MULHU, ISD::MULHS}, MVT::i16, Expand);

  setOperationAction({ISD::MUL, ISD::MULHU, ISD::MULHS}, MVT::i64, Expand);
  setOperationAction({ISD::UINT_TO_FP, ISD::SINT_TO_FP, ISD::FP_TO_SINT,
                      ISD::FP_TO_UINT, ISD::FP_TO_SINT_SAT,
                      ISD::FP_TO_UINT_SAT},
                     MVT::i64, Custom);
  setOperationAction(ISD::SELECT_CC, MVT::i64, Expand);

  setOperationAction({ISD::SMIN, ISD::UMIN, ISD::SMAX, ISD::UMAX}, MVT::i32,
                     Legal);

  setOperationAction(
      {ISD::CTTZ, ISD::CTTZ_ZERO_POISON, ISD::CTLZ, ISD::CTLZ_ZERO_POISON},
      MVT::i64, Custom);

  for (auto VT : {MVT::i8, MVT::i16})
    setOperationAction({ISD::CTLZ, ISD::CTLZ_ZERO_POISON}, VT, Custom);

  static const MVT::SimpleValueType VectorIntTypes[] = {
      MVT::v2i32, MVT::v3i32, MVT::v4i32, MVT::v5i32, MVT::v6i32, MVT::v7i32,
      MVT::v9i32, MVT::v10i32, MVT::v11i32, MVT::v12i32};

  for (MVT VT : VectorIntTypes) {
    // Expand the following operations for the current type by default.
    // clang-format off
    setOperationAction({ISD::ADD,            ISD::AND,
                        ISD::FP_TO_SINT,     ISD::FP_TO_UINT,
                        ISD::FP_TO_SINT_SAT, ISD::FP_TO_UINT_SAT,
                        ISD::MUL,            ISD::MULHU,
                        ISD::MULHS,          ISD::OR,
                        ISD::SHL,            ISD::SRA,
                        ISD::SRL,            ISD::ROTL,
                        ISD::ROTR,           ISD::SUB,
                        ISD::SINT_TO_FP,     ISD::UINT_TO_FP,
                        ISD::SDIV,           ISD::UDIV,
                        ISD::SREM,           ISD::UREM,
                        ISD::SMUL_LOHI,      ISD::UMUL_LOHI,
                        ISD::SDIVREM,        ISD::UDIVREM,
                        ISD::SELECT,         ISD::VSELECT,
                        ISD::SELECT_CC,      ISD::XOR,
                        ISD::BSWAP,          ISD::CTPOP,
                        ISD::CTTZ,           ISD::CTLZ,
                        ISD::VECTOR_SHUFFLE, ISD::SETCC,
                        ISD::ADDRSPACECAST},
                       VT, Expand);
    // clang-format on
  }

  static const MVT::SimpleValueType FloatVectorTypes[] = {
      MVT::v2f32, MVT::v3f32,  MVT::v4f32, MVT::v5f32, MVT::v6f32, MVT::v7f32,
      MVT::v9f32, MVT::v10f32, MVT::v11f32, MVT::v12f32};

  for (MVT VT : FloatVectorTypes) {
    setOperationAction(
        {ISD::FABS,          ISD::FMINNUM,        ISD::FMAXNUM,
         ISD::FADD,          ISD::FCEIL,          ISD::FCOS,
         ISD::FDIV,          ISD::FEXP2,          ISD::FEXP,
         ISD::FEXP10,        ISD::FLOG2,          ISD::FREM,
         ISD::FLOG,          ISD::FLOG10,         ISD::FPOW,
         ISD::FFLOOR,        ISD::FTRUNC,         ISD::FMUL,
         ISD::FMA,           ISD::FRINT,          ISD::FNEARBYINT,
         ISD::FSQRT,         ISD::FSIN,           ISD::FSUB,
         ISD::FNEG,          ISD::VSELECT,        ISD::SELECT_CC,
         ISD::FCOPYSIGN,     ISD::VECTOR_SHUFFLE, ISD::SETCC,
         ISD::FCANONICALIZE, ISD::FROUNDEVEN},
        VT, Expand);
  }

  // This causes using an unrolled select operation rather than expansion with
  // bit operations. This is in general better, but the alternative using BFI
  // instructions may be better if the select sources are SGPRs.
  setOperationAction(ISD::SELECT, MVT::v2f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v2f32, MVT::v2i32);

  setOperationAction(ISD::SELECT, MVT::v3f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v3f32, MVT::v3i32);

  setOperationAction(ISD::SELECT, MVT::v4f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v4f32, MVT::v4i32);

  setOperationAction(ISD::SELECT, MVT::v5f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v5f32, MVT::v5i32);

  setOperationAction(ISD::SELECT, MVT::v6f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v6f32, MVT::v6i32);

  setOperationAction(ISD::SELECT, MVT::v7f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v7f32, MVT::v7i32);

  setOperationAction(ISD::SELECT, MVT::v9f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v9f32, MVT::v9i32);

  setOperationAction(ISD::SELECT, MVT::v10f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v10f32, MVT::v10i32);

  setOperationAction(ISD::SELECT, MVT::v11f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v11f32, MVT::v11i32);

  setOperationAction(ISD::SELECT, MVT::v12f32, Promote);
  AddPromotedToType(ISD::SELECT, MVT::v12f32, MVT::v12i32);

  setSchedulingPreference(Sched::RegPressure);
  setJumpIsExpensive(true);

  setMinCmpXchgSizeInBits(32);
  setSupportsUnalignedAtomics(false);

  PredictableSelectIsExpensive = false;

  // We want to find all load dependencies for long chains of stores to enable
  // merging into very wide vectors. The problem is with vectors with > 4
  // elements. MergeConsecutiveStores will attempt to merge these because x8/x16
  // vectors are a legal type, even though we have to split the loads
  // usually. When we can more precisely specify load legality per address
  // space, we should be able to make FindBetterChain/MergeConsecutiveStores
  // smarter so that they can figure out what to do in 2 iterations without all
  // N > 4 stores on the same chain.
  GatherAllAliasesMaxDepth = 16;

  // memcpy/memmove/memset are expanded in the IR, so we shouldn't need to worry
  // about these during lowering.
  MaxStoresPerMemcpy  = 0xffffffff;
  MaxStoresPerMemmove = 0xffffffff;
  MaxStoresPerMemset  = 0xffffffff;

  // The expansion for 64-bit division is enormous.
  if (AMDGPUBypassSlowDiv)
    addBypassSlowDiv(64, 32);

  setTargetDAGCombine({ISD::BITCAST,    ISD::SHL,
                       ISD::SRA,        ISD::SRL,
                       ISD::TRUNCATE,   ISD::MUL,
                       ISD::SMUL_LOHI,  ISD::UMUL_LOHI,
                       ISD::MULHU,      ISD::MULHS,
                       ISD::SELECT,     ISD::SELECT_CC,
                       ISD::STORE,      ISD::FADD,
                       ISD::FSUB,       ISD::FNEG,
                       ISD::FABS,       ISD::AssertZext,
                       ISD::AssertSext, ISD::INTRINSIC_WO_CHAIN});

  setMaxAtomicSizeInBitsSupported(64);
  setMaxDivRemBitWidthSupported(64);
  setMaxLargeFPConvertBitWidthSupported(64);
}

bool AMDGPUTargetLowering::mayIgnoreSignedZero(SDValue Op) const {
  const auto Flags = Op.getNode()->getFlags();
  if (Flags.hasNoSignedZeros())
    return true;

  return false;
}

//===----------------------------------------------------------------------===//
// Target Information
//===----------------------------------------------------------------------===//

LLVM_READNONE
static bool fnegFoldsIntoOpcode(unsigned Opc) {
  switch (Opc) {
  case ISD::FADD:
  case ISD::FSUB:
  case ISD::FMUL:
  case ISD::FMA:
  case ISD::FMAD:
  case ISD::FMINNUM:
  case ISD::FMAXNUM:
  case ISD::FMINNUM_IEEE:
  case ISD::FMAXNUM_IEEE:
  case ISD::FMINIMUM:
  case ISD::FMAXIMUM:
  case ISD::FMINIMUMNUM:
  case ISD::FMAXIMUMNUM:
  case ISD::SELECT:
  case ISD::FSIN:
  case ISD::FTRUNC:
  case ISD::FRINT:
  case ISD::FNEARBYINT:
  case ISD::FROUNDEVEN:
  case ISD::FCANONICALIZE:
  case AMDGPUISD::RCP:
  case AMDGPUISD::RCP_LEGACY:
  case AMDGPUISD::RCP_IFLAG:
  case AMDGPUISD::SIN_HW:
  case AMDGPUISD::FMUL_LEGACY:
  case AMDGPUISD::FMIN_LEGACY:
  case AMDGPUISD::FMAX_LEGACY:
  case AMDGPUISD::FMED3:
    // TODO: handle llvm.amdgcn.fma.legacy
    return true;
  case ISD::BITCAST:
    llvm_unreachable("bitcast is special cased");
  default:
    return false;
  }
}

static bool fnegFoldsIntoOp(const SDNode *N) {
  unsigned Opc = N->getOpcode();
  if (Opc == ISD::BITCAST) {
    // TODO: Is there a benefit to checking the conditions performFNegCombine
    // does? We don't for the other cases.
    SDValue BCSrc = N->getOperand(0);
    if (BCSrc.getOpcode() == ISD::BUILD_VECTOR) {
      return BCSrc.getNumOperands() == 2 &&
             BCSrc.getOperand(1).getValueSizeInBits() == 32;
    }

    return BCSrc.getOpcode() == ISD::SELECT && BCSrc.getValueType() == MVT::f32;
  }

  return fnegFoldsIntoOpcode(Opc);
}

/// \p returns true if the operation will definitely need to use a 64-bit
/// encoding, and thus will use a VOP3 encoding regardless of the source
/// modifiers.
LLVM_READONLY
static bool opMustUseVOP3Encoding(const SDNode *N, MVT VT) {
  return (N->getNumOperands() > 2 && N->getOpcode() != ISD::SELECT) ||
         VT == MVT::f64;
}

/// Return true if v_cndmask_b32 will support fabs/fneg source modifiers for the
/// type for ISD::SELECT.
LLVM_READONLY
static bool selectSupportsSourceMods(const SDNode *N) {
  // TODO: Only applies if select will be vector
  return N->getValueType(0) == MVT::f32;
}

// Most FP instructions support source modifiers, but this could be refined
// slightly.
LLVM_READONLY
static bool hasSourceMods(const SDNode *N) {
  if (isa<MemSDNode>(N))
    return false;

  switch (N->getOpcode()) {
  case ISD::CopyToReg:
  case ISD::FDIV:
  case ISD::FREM:
  case ISD::INLINEASM:
  case ISD::INLINEASM_BR:
  case AMDGPUISD::DIV_SCALE:
  case ISD::INTRINSIC_W_CHAIN:

  // TODO: Should really be looking at the users of the bitcast. These are
  // problematic because bitcasts are used to legalize all stores to integer
  // types.
  case ISD::BITCAST:
    return false;
  case ISD::INTRINSIC_WO_CHAIN: {
    switch (N->getConstantOperandVal(0)) {
    case Intrinsic::amdgcn_interp_p1:
    case Intrinsic::amdgcn_interp_p2:
    case Intrinsic::amdgcn_interp_mov:
    case Intrinsic::amdgcn_interp_p1_f16:
    case Intrinsic::amdgcn_interp_p2_f16:
      return false;
    default:
      return true;
    }
  }
  case ISD::SELECT:
    return selectSupportsSourceMods(N);
  default:
    return true;
  }
}

bool AMDGPUTargetLowering::allUsesHaveSourceMods(const SDNode *N,
                                                 unsigned CostThreshold) {
  // Some users (such as 3-operand FMA/MAD) must use a VOP3 encoding, and thus
  // it is truly free to use a source modifier in all cases. If there are
  // multiple users but for each one will necessitate using VOP3, there will be
  // a code size increase. Try to avoid increasing code size unless we know it
  // will save on the instruction count.
  unsigned NumMayIncreaseSize = 0;
  MVT VT = N->getValueType(0).getScalarType().getSimpleVT();

  assert(!N->use_empty());

  // XXX - Should this limit number of uses to check?
  for (const SDNode *U : N->users()) {
    if (!hasSourceMods(U))
      return false;

    if (!opMustUseVOP3Encoding(U, VT)) {
      if (++NumMayIncreaseSize > CostThreshold)
        return false;
    }
  }

  return true;
}

EVT AMDGPUTargetLowering::getTypeForExtReturn(LLVMContext &Context, EVT VT,
                                              ISD::NodeType ExtendKind) const {
  assert(!VT.isVector() && "only scalar expected");

  // Round to the next multiple of 32-bits.
  unsigned Size = VT.getSizeInBits();
  if (Size <= 32)
    return MVT::i32;
  return EVT::getIntegerVT(Context, 32 * ((Size + 31) / 32));
}

unsigned AMDGPUTargetLowering::getVectorIdxWidth(const DataLayout &) const {
  return 32;
}

bool AMDGPUTargetLowering::isSelectSupported(SelectSupportKind SelType) const {
  return true;
}

// The backend supports 32 and 64 bit floating point immediates.
// FIXME: Why are we reporting vectors of FP immediates as legal?
bool AMDGPUTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
                                        bool ForCodeSize) const {
  return isTypeLegal(VT.getScalarType());
}

// We don't want to shrink f64 / f32 constants.
bool AMDGPUTargetLowering::ShouldShrinkFPConstant(EVT VT) const {
  EVT ScalarVT = VT.getScalarType();
  return (ScalarVT != MVT::f32 && ScalarVT != MVT::f64);
}

bool AMDGPUTargetLowering::shouldReduceLoadWidth(
    SDNode *N, ISD::LoadExtType ExtTy, EVT NewVT,
    std::optional<unsigned> ByteOffset) const {
  // TODO: This may be worth removing. Check regression tests for diffs.
  if (!TargetLoweringBase::shouldReduceLoadWidth(N, ExtTy, NewVT, ByteOffset))
    return false;

  unsigned NewSize = NewVT.getStoreSizeInBits();

  // If we are reducing to a 32-bit load or a smaller multi-dword load,
  // this is always better.
  if (NewSize >= 32)
    return true;

  EVT OldVT = N->getValueType(0);
  unsigned OldSize = OldVT.getStoreSizeInBits();

  MemSDNode *MN = cast<MemSDNode>(N);
  unsigned AS = MN->getAddressSpace();
  // Do not shrink an aligned scalar load to sub-dword.
  // Scalar engine cannot do sub-dword loads.
  // TODO: Update this for GFX12 which does have scalar sub-dword loads.
  if (OldSize >= 32 && NewSize < 32 && MN->getAlign() >= Align(4) &&
      (AS == AMDGPUAS::CONSTANT_ADDRESS ||
       AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT ||
       (isa<LoadSDNode>(N) && AS == AMDGPUAS::GLOBAL_ADDRESS &&
        MN->isInvariant())) &&
      AMDGPU::isUniformMMO(MN->getMemOperand()))
    return false;

  // Don't produce extloads from sub 32-bit types. SI doesn't have scalar
  // extloads, so doing one requires using a buffer_load. In cases where we
  // still couldn't use a scalar load, using the wider load shouldn't really
  // hurt anything.

  // If the old size already had to be an extload, there's no harm in continuing
  // to reduce the width.
  return (OldSize < 32);
}

bool AMDGPUTargetLowering::isLoadBitCastBeneficial(EVT LoadTy, EVT CastTy,
                                                   const SelectionDAG &DAG,
                                                   const MachineMemOperand &MMO) const {

  assert(LoadTy.getSizeInBits() == CastTy.getSizeInBits());

  if (LoadTy.getScalarType() == MVT::i32)
    return false;

  unsigned LScalarSize = LoadTy.getScalarSizeInBits();
  unsigned CastScalarSize = CastTy.getScalarSizeInBits();

  if ((LScalarSize >= CastScalarSize) && (CastScalarSize < 32))
    return false;

  unsigned Fast = 0;
  return allowsMemoryAccessForAlignment(*DAG.getContext(), DAG.getDataLayout(),
                                        CastTy, MMO, &Fast) &&
         Fast;
}

// SI+ has instructions for cttz / ctlz for 32-bit values. This is probably also
// profitable with the expansion for 64-bit since it's generally good to
// speculate things.
bool AMDGPUTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
  return true;
}

bool AMDGPUTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {
  return true;
}

bool AMDGPUTargetLowering::isSDNodeAlwaysUniform(const SDNode *N) const {
  switch (N->getOpcode()) {
  case ISD::EntryToken:
  case ISD::TokenFactor:
    return true;
  case ISD::INTRINSIC_WO_CHAIN: {
    unsigned IntrID = N->getConstantOperandVal(0);
    return AMDGPU::isIntrinsicAlwaysUniform(IntrID);
  }
  case ISD::INTRINSIC_W_CHAIN: {
    unsigned IntrID = N->getConstantOperandVal(1);
    return AMDGPU::isIntrinsicAlwaysUniform(IntrID);
  }
  case ISD::LOAD:
    if (cast<LoadSDNode>(N)->getMemOperand()->getAddrSpace() ==
        AMDGPUAS::CONSTANT_ADDRESS_32BIT)
      return true;
    return false;
  case AMDGPUISD::SETCC: // ballot-style instruction
    return true;
  }
  return false;
}

SDValue AMDGPUTargetLowering::getNegatedExpression(
    SDValue Op, SelectionDAG &DAG, bool LegalOperations, bool ForCodeSize,
    NegatibleCost &Cost, unsigned Depth) const {

  switch (Op.getOpcode()) {
  case ISD::FMA:
  case ISD::FMAD: {
    // Negating a fma is not free if it has users without source mods.
    if (!allUsesHaveSourceMods(Op.getNode()))
      return SDValue();
    break;
  }
  case AMDGPUISD::RCP: {
    SDValue Src = Op.getOperand(0);
    EVT VT = Op.getValueType();
    SDLoc SL(Op);

    SDValue NegSrc = getNegatedExpression(Src, DAG, LegalOperations,
                                          ForCodeSize, Cost, Depth + 1);
    if (NegSrc)
      return DAG.getNode(AMDGPUISD::RCP, SL, VT, NegSrc, Op->getFlags());
    return SDValue();
  }
  default:
    break;
  }

  return TargetLowering::getNegatedExpression(Op, DAG, LegalOperations,
                                              ForCodeSize, Cost, Depth);
}

//===---------------------------------------------------------------------===//
// Target Properties
//===---------------------------------------------------------------------===//

bool AMDGPUTargetLowering::isFAbsFree(EVT VT) const {
  assert(VT.isFloatingPoint());

  // Packed operations do not have a fabs modifier.
  // Report this based on the end legalized type.
  return VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f16 || VT == MVT::bf16;
}

bool AMDGPUTargetLowering::isFNegFree(EVT VT) const {
  assert(VT.isFloatingPoint());
  // Report this based on the end legalized type.
  VT = VT.getScalarType();
  return VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f16 || VT == MVT::bf16;
}

bool AMDGPUTargetLowering:: storeOfVectorConstantIsCheap(bool IsZero, EVT MemVT,
                                                         unsigned NumElem,
                                                         unsigned AS) const {
  return true;
}

bool AMDGPUTargetLowering::aggressivelyPreferBuildVectorSources(EVT VecVT) const {
  // There are few operations which truly have vector input operands. Any vector
  // operation is going to involve operations on each component, and a
  // build_vector will be a copy per element, so it always makes sense to use a
  // build_vector input in place of the extracted element to avoid a copy into a
  // super register.
  //
  // We should probably only do this if all users are extracts only, but this
  // should be the common case.
  return true;
}

bool AMDGPUTargetLowering::isTruncateFree(EVT Source, EVT Dest) const {
  // Truncate is just accessing a subregister.

  unsigned SrcSize = Source.getSizeInBits();
  unsigned DestSize = Dest.getSizeInBits();

  return DestSize < SrcSize && DestSize % 32 == 0 ;
}

bool AMDGPUTargetLowering::isTruncateFree(Type *Source, Type *Dest) const {
  // Truncate is just accessing a subregister.

  unsigned SrcSize = Source->getScalarSizeInBits();
  unsigned DestSize = Dest->getScalarSizeInBits();

  if (DestSize== 16 && Subtarget->has16BitInsts())
    return SrcSize >= 32;

  return DestSize < SrcSize && DestSize % 32 == 0;
}

bool AMDGPUTargetLowering::isZExtFree(Type *Src, Type *Dest) const {
  unsigned SrcSize = Src->getScalarSizeInBits();
  unsigned DestSize = Dest->getScalarSizeInBits();

  if (SrcSize == 16 && Subtarget->has16BitInsts())
    return DestSize >= 32;

  return SrcSize == 32 && DestSize == 64;
}

bool AMDGPUTargetLowering::isZExtFree(EVT Src, EVT Dest) const {
  // Any register load of a 64-bit value really requires 2 32-bit moves. For all
  // practical purposes, the extra mov 0 to load a 64-bit is free.  As used,
  // this will enable reducing 64-bit operations the 32-bit, which is always
  // good.

  if (Src == MVT::i16)
    return Dest == MVT::i32 ||Dest == MVT::i64 ;

  return Src == MVT::i32 && Dest == MVT::i64;
}

bool AMDGPUTargetLowering::isNarrowingProfitable(SDNode *N, EVT SrcVT,
                                                 EVT DestVT) const {
  switch (N->getOpcode()) {
  case ISD::ABS:
  case ISD::ADD:
  case ISD::SUB:
  case ISD::SHL:
  case ISD::SRL:
  case ISD::SRA:
  case ISD::AND:
  case ISD::OR:
  case ISD::XOR:
  case ISD::MUL:
  case ISD::SETCC:
  case ISD::SELECT:
  case ISD::SMIN:
  case ISD::SMAX:
  case ISD::UMIN:
  case ISD::UMAX:
  case ISD::USUBSAT:
    if (isTypeLegal(MVT::i16) &&
        (!DestVT.isVector() ||
         !isOperationLegal(ISD::ADD, MVT::v2i16))) { // Check if VOP3P
      // Don't narrow back down to i16 if promoted to i32 already.
      if (!N->isDivergent() && DestVT.isInteger() &&
          DestVT.getScalarSizeInBits() > 1 &&
          DestVT.getScalarSizeInBits() <= 16 &&
          SrcVT.getScalarSizeInBits() > 16) {
        return false;
      }
    }
    return true;
  default:
    break;
  }

  // There aren't really 64-bit registers, but pairs of 32-bit ones and only a
  // limited number of native 64-bit operations. Shrinking an operation to fit
  // in a single 32-bit register should always be helpful. As currently used,
  // this is much less general than the name suggests, and is only used in
  // places trying to reduce the sizes of loads. Shrinking loads to < 32-bits is
  // not profitable, and may actually be harmful.
  if (isa<LoadSDNode>(N))
    return SrcVT.getSizeInBits() > 32 && DestVT.getSizeInBits() == 32;

  return true;
}

bool AMDGPUTargetLowering::isDesirableToCommuteWithShift(
    const SDNode* N, CombineLevel Level) const {
  assert((N->getOpcode() == ISD::SHL || N->getOpcode() == ISD::SRA ||
          N->getOpcode() == ISD::SRL) &&
         "Expected shift op");

  SDValue ShiftLHS = N->getOperand(0);
  if (!ShiftLHS->hasOneUse())
    return false;

  if (ShiftLHS.getOpcode() == ISD::SIGN_EXTEND &&
      !ShiftLHS.getOperand(0)->hasOneUse())
    return false;

  // Always commute pre-type legalization and right shifts.
  // We're looking for shl(or(x,y),z) patterns.
  if (Level < CombineLevel::AfterLegalizeTypes ||
      N->getOpcode() != ISD::SHL || N->getOperand(0).getOpcode() != ISD::OR)
    return true;

  // If only user is a i32 right-shift, then don't destroy a BFE pattern.
  if (N->getValueType(0) == MVT::i32 && N->hasOneUse() &&
      (N->user_begin()->getOpcode() == ISD::SRA ||
       N->user_begin()->getOpcode() == ISD::SRL))
    return false;

  // Don't destroy or(shl(load_zext(),c), load_zext()) patterns.
  auto IsShiftAndLoad = [](SDValue LHS, SDValue RHS) {
    if (LHS.getOpcode() != ISD::SHL)
      return false;
    auto *RHSLd = dyn_cast<LoadSDNode>(RHS);
    auto *LHS0 = dyn_cast<LoadSDNode>(LHS.getOperand(0));
    auto *LHS1 = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
    return LHS0 && LHS1 && RHSLd && LHS0->getExtensionType() == ISD::ZEXTLOAD &&
           LHS1->getAPIntValue() == LHS0->getMemoryVT().getScalarSizeInBits() &&
           RHSLd->getExtensionType() == ISD::ZEXTLOAD;
  };
  SDValue LHS = N->getOperand(0).getOperand(0);
  SDValue RHS = N->getOperand(0).getOperand(1);
  return !(IsShiftAndLoad(LHS, RHS) || IsShiftAndLoad(RHS, LHS));
}

//===---------------------------------------------------------------------===//
// TargetLowering Callbacks
//===---------------------------------------------------------------------===//

CCAssignFn *AMDGPUCallLowering::CCAssignFnForCall(CallingConv::ID CC,
                                                  bool IsVarArg) {
  switch (CC) {
  case CallingConv::AMDGPU_VS:
  case CallingConv::AMDGPU_GS:
  case CallingConv::AMDGPU_PS:
  case CallingConv::AMDGPU_CS:
  case CallingConv::AMDGPU_HS:
  case CallingConv::AMDGPU_ES:
  case CallingConv::AMDGPU_LS:
    return CC_AMDGPU;
  case CallingConv::AMDGPU_CS_Chain:
  case CallingConv::AMDGPU_CS_ChainPreserve:
    return CC_AMDGPU_CS_CHAIN;
  case CallingConv::C:
  case CallingConv::Fast:
  case CallingConv::Cold:
    return CC_AMDGPU_Func;
  case CallingConv::AMDGPU_Gfx:
  case CallingConv::AMDGPU_Gfx_WholeWave:
    return CC_SI_Gfx;
  case CallingConv::AMDGPU_KERNEL:
  case CallingConv::SPIR_KERNEL:
  default:
    reportFatalUsageError("unsupported calling convention for call");
  }
}

CCAssignFn *AMDGPUCallLowering::CCAssignFnForReturn(CallingConv::ID CC,
                                                    bool IsVarArg) {
  switch (CC) {
  case CallingConv::AMDGPU_KERNEL:
  case CallingConv::SPIR_KERNEL:
    llvm_unreachable("kernels should not be handled here");
  case CallingConv::AMDGPU_VS:
  case CallingConv::AMDGPU_GS:
  case CallingConv::AMDGPU_PS:
  case CallingConv::AMDGPU_CS:
  case CallingConv::AMDGPU_CS_Chain:
  case CallingConv::AMDGPU_CS_ChainPreserve:
  case CallingConv::AMDGPU_HS:
  case CallingConv::AMDGPU_ES:
  case CallingConv::AMDGPU_LS:
    return RetCC_SI_Shader;
  case CallingConv::AMDGPU_Gfx:
  case CallingConv::AMDGPU_Gfx_WholeWave:
    return RetCC_SI_Gfx;
  case CallingConv::C:
  case CallingConv::Fast:
  case CallingConv::Cold:
    return RetCC_AMDGPU_Func;
  default:
    reportFatalUsageError("unsupported calling convention");
  }
}

/// The SelectionDAGBuilder will automatically promote function arguments
/// with illegal types.  However, this does not work for the AMDGPU targets
/// since the function arguments are stored in memory as these illegal types.
/// In order to handle this properly we need to get the original types sizes
/// from the LLVM IR Function and fixup the ISD:InputArg values before
/// passing them to AnalyzeFormalArguments()

/// When the SelectionDAGBuilder computes the Ins, it takes care of splitting
/// input values across multiple registers.  Each item in the Ins array
/// represents a single value that will be stored in registers.  Ins[x].VT is
/// the value type of the value that will be stored in the register, so
/// whatever SDNode we lower the argument to needs to be this type.
///
/// In order to correctly lower the arguments we need to know the size of each
/// argument.  Since Ins[x].VT gives us the size of the register that will
/// hold the value, we need to look at Ins[x].ArgVT to see the 'real' type
/// for the original function argument so that we can deduce the correct memory
/// type to use for Ins[x].  In most cases the correct memory type will be
/// Ins[x].ArgVT.  However, this will not always be the case.  If, for example,
/// we have a kernel argument of type v8i8, this argument will be split into
/// 8 parts and each part will be represented by its own item in the Ins array.
/// For each part the Ins[x].ArgVT will be the v8i8, which is the full type of
/// the argument before it was split.  From this, we deduce that the memory type
/// for each individual part is i8.  We pass the memory type as LocVT to the
/// calling convention analysis function and the register type (Ins[x].VT) as
/// the ValVT.
void AMDGPUTargetLowering::analyzeFormalArgumentsCompute(
  CCState &State,
  const SmallVectorImpl<ISD::InputArg> &Ins) const {
  const MachineFunction &MF = State.getMachineFunction();
  const Function &Fn = MF.getFunction();
  LLVMContext &Ctx = Fn.getContext();
  const unsigned ExplicitOffset = Subtarget->getExplicitKernelArgOffset();
  CallingConv::ID CC = Fn.getCallingConv();

  Align MaxAlign = Align(1);
  uint64_t ExplicitArgOffset = 0;
  const DataLayout &DL = Fn.getDataLayout();

  unsigned InIndex = 0;

  for (const Argument &Arg : Fn.args()) {
    const bool IsByRef = Arg.hasByRefAttr();
    Type *BaseArgTy = Arg.getType();
    Type *MemArgTy = IsByRef ? Arg.getParamByRefType() : BaseArgTy;
    Align Alignment = DL.getValueOrABITypeAlignment(
        IsByRef ? Arg.getParamAlign() : std::nullopt, MemArgTy);
    MaxAlign = std::max(Alignment, MaxAlign);
    uint64_t AllocSize = DL.getTypeAllocSize(MemArgTy);

    uint64_t ArgOffset = alignTo(ExplicitArgOffset, Alignment) + ExplicitOffset;
    ExplicitArgOffset = alignTo(ExplicitArgOffset, Alignment) + AllocSize;

    // We're basically throwing away everything passed into us and starting over
    // to get accurate in-memory offsets. The "PartOffset" is completely useless
    // to us as computed in Ins.
    //
    // We also need to figure out what type legalization is trying to do to get
    // the correct memory offsets.

    SmallVector<EVT, 16> ValueVTs;
    SmallVector<uint64_t, 16> Offsets;
    ComputeValueVTs(*this, DL, BaseArgTy, ValueVTs, /*MemVTs=*/nullptr,
                    &Offsets, ArgOffset);

    for (unsigned Value = 0, NumValues = ValueVTs.size();
         Value != NumValues; ++Value) {
      uint64_t BasePartOffset = Offsets[Value];

      EVT ArgVT = ValueVTs[Value];
      EVT MemVT = ArgVT;
      MVT RegisterVT = getRegisterTypeForCallingConv(Ctx, CC, ArgVT);
      unsigned NumRegs = getNumRegistersForCallingConv(Ctx, CC, ArgVT);

      if (NumRegs == 1) {
        // This argument is not split, so the IR type is the memory type.
        if (ArgVT.isExtended()) {
          // We have an extended type, like i24, so we should just use the
          // register type.
          MemVT = RegisterVT;
        } else {
          MemVT = ArgVT;
        }
      } else if (ArgVT.isVector() && RegisterVT.isVector() &&
                 ArgVT.getScalarType() == RegisterVT.getScalarType()) {
        assert(ArgVT.getVectorNumElements() > RegisterVT.getVectorNumElements());
        // We have a vector value which has been split into a vector with
        // the same scalar type, but fewer elements.  This should handle
        // all the floating-point vector types.
        MemVT = RegisterVT;
      } else if (ArgVT.isVector() &&
                 ArgVT.getVectorNumElements() == NumRegs) {
        // This arg has been split so that each element is stored in a separate
        // register.
        MemVT = ArgVT.getScalarType();
      } else if (ArgVT.isExtended()) {
        // We have an extended type, like i65.
        MemVT = RegisterVT;
      } else {
        unsigned MemoryBits = ArgVT.getStoreSizeInBits() / NumRegs;
        assert(ArgVT.getStoreSizeInBits() % NumRegs == 0);
        if (RegisterVT.isInteger()) {
          MemVT = EVT::getIntegerVT(State.getContext(), MemoryBits);
        } else if (RegisterVT.isVector()) {
          assert(!RegisterVT.getScalarType().isFloatingPoint());
          unsigned NumElements = RegisterVT.getVectorNumElements();
          assert(MemoryBits % NumElements == 0);
          // This vector type has been split into another vector type with
          // a different elements size.
          EVT ScalarVT = EVT::getIntegerVT(State.getContext(),
                                           MemoryBits / NumElements);
          MemVT = EVT::getVectorVT(State.getContext(), ScalarVT, NumElements);
        } else {
          llvm_unreachable("cannot deduce memory type.");
        }
      }

      // Convert one element vectors to scalar.
      if (MemVT.isVector() && MemVT.getVectorNumElements() == 1)
        MemVT = MemVT.getScalarType();

      // Round up vec3/vec5 argument.
      if (MemVT.isVector() && !MemVT.isPow2VectorType()) {
        MemVT = MemVT.getPow2VectorType(State.getContext());
      } else if (!MemVT.isSimple() && !MemVT.isVector()) {
        MemVT = MemVT.getRoundIntegerType(State.getContext());
      }

      unsigned PartOffset = 0;
      for (unsigned i = 0; i != NumRegs; ++i) {
        State.addLoc(CCValAssign::getCustomMem(InIndex++, RegisterVT,
                                               BasePartOffset + PartOffset,
                                               MemVT.getSimpleVT(),
                                               CCValAssign::Full));
        PartOffset += MemVT.getStoreSize();
      }
    }
  }
}

SDValue AMDGPUTargetLowering::LowerReturn(
  SDValue Chain, CallingConv::ID CallConv,
  bool isVarArg,
  const SmallVectorImpl<ISD::OutputArg> &Outs,
  const SmallVectorImpl<SDValue> &OutVals,
  const SDLoc &DL, SelectionDAG &DAG) const {
  // FIXME: Fails for r600 tests
  //assert(!isVarArg && Outs.empty() && OutVals.empty() &&
  // "wave terminate should not have return values");
  return DAG.getNode(AMDGPUISD::ENDPGM, DL, MVT::Other, Chain);
}

//===---------------------------------------------------------------------===//
// Target specific lowering
//===---------------------------------------------------------------------===//

/// Selects the correct CCAssignFn for a given CallingConvention value.
CCAssignFn *AMDGPUTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
                                                    bool IsVarArg) {
  return AMDGPUCallLowering::CCAssignFnForCall(CC, IsVarArg);
}

CCAssignFn *AMDGPUTargetLowering::CCAssignFnForReturn(CallingConv::ID CC,
                                                      bool IsVarArg) {
  return AMDGPUCallLowering::CCAssignFnForReturn(CC, IsVarArg);
}

SDValue AMDGPUTargetLowering::addTokenForArgument(SDValue Chain,
                                                  SelectionDAG &DAG,
                                                  MachineFrameInfo &MFI,
                                                  int ClobberedFI) const {
  SmallVector<SDValue, 8> ArgChains;
  int64_t FirstByte = MFI.getObjectOffset(ClobberedFI);
  int64_t LastByte = FirstByte + MFI.getObjectSize(ClobberedFI) - 1;

  // Include the original chain at the beginning of the list. When this is
  // used by target LowerCall hooks, this helps legalize find the
  // CALLSEQ_BEGIN node.
  ArgChains.push_back(Chain);

  // Add a chain value for each stack argument corresponding
  for (SDNode *U : DAG.getEntryNode().getNode()->users()) {
    if (LoadSDNode *L = dyn_cast<LoadSDNode>(U)) {
      if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(L->getBasePtr())) {
        if (FI->getIndex() < 0) {
          int64_t InFirstByte = MFI.getObjectOffset(FI->getIndex());
          int64_t InLastByte = InFirstByte;
          InLastByte += MFI.getObjectSize(FI->getIndex()) - 1;

          if ((InFirstByte <= FirstByte && FirstByte <= InLastByte) ||
              (FirstByte <= InFirstByte && InFirstByte <= LastByte))
            ArgChains.push_back(SDValue(L, 1));
        }
      }
    }
  }

  // Build a tokenfactor for all the chains.
  return DAG.getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, ArgChains);
}

SDValue AMDGPUTargetLowering::lowerUnhandledCall(CallLoweringInfo &CLI,
                                                 SmallVectorImpl<SDValue> &InVals,
                                                 StringRef Reason) const {
  SDValue Callee = CLI.Callee;
  SelectionDAG &DAG = CLI.DAG;

  const Function &Fn = DAG.getMachineFunction().getFunction();

  StringRef FuncName("<unknown>");

  if (const ExternalSymbolSDNode *G = dyn_cast<ExternalSymbolSDNode>(Callee))
    FuncName = G->getSymbol();
  else if (const GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
    FuncName = G->getGlobal()->getName();

  DAG.getContext()->diagnose(
      DiagnosticInfoUnsupported(Fn, Reason + FuncName, CLI.DL.getDebugLoc()));

  if (!CLI.IsTailCall) {
    for (ISD::InputArg &Arg : CLI.Ins)
      InVals.push_back(DAG.getPOISON(Arg.VT));
  }

  // FIXME: Hack because R600 doesn't handle callseq pseudos yet.
  if (getTargetMachine().getTargetTriple().getArch() == Triple::r600)
    return CLI.Chain;

  SDValue Chain = DAG.getCALLSEQ_START(CLI.Chain, 0, 0, CLI.DL);
  return DAG.getCALLSEQ_END(Chain, 0, 0, /*InGlue=*/SDValue(), CLI.DL);
}

SDValue AMDGPUTargetLowering::LowerCall(CallLoweringInfo &CLI,
                                        SmallVectorImpl<SDValue> &InVals) const {
  return lowerUnhandledCall(CLI, InVals, "unsupported call to function ");
}

SDValue AMDGPUTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
                                                      SelectionDAG &DAG) const {
  const Function &Fn = DAG.getMachineFunction().getFunction();

  DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
      Fn, "unsupported dynamic alloca", SDLoc(Op).getDebugLoc()));
  auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
  return DAG.getMergeValues(Ops, SDLoc());
}

SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op,
                                             SelectionDAG &DAG) const {
  switch (Op.getOpcode()) {
  default:
    Op->print(errs(), &DAG);
    llvm_unreachable("Custom lowering code for this "
                     "instruction is not implemented yet!");
    break;
  case ISD::SIGN_EXTEND_INREG: return LowerSIGN_EXTEND_INREG(Op, DAG);
  case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
  case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG);
  case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
  case ISD::SDIVREM:
    return LowerSDIVREM(Op, DAG);
  case ISD::FCEIL: return LowerFCEIL(Op, DAG);
  case ISD::FTRUNC: return LowerFTRUNC(Op, DAG);
  case ISD::FRINT: return LowerFRINT(Op, DAG);
  case ISD::FNEARBYINT: return LowerFNEARBYINT(Op, DAG);
  case ISD::FROUNDEVEN:
    return LowerFROUNDEVEN(Op, DAG);
  case ISD::FROUND: return LowerFROUND(Op, DAG);
  case ISD::FFLOOR: return LowerFFLOOR(Op, DAG);
  case ISD::FLOG2:
    return LowerFLOG2(Op, DAG);
  case ISD::FLOG:
  case ISD::FLOG10:
    return LowerFLOGCommon(Op, DAG);
  case ISD::FEXP:
  case ISD::FEXP10:
    return lowerFEXP(Op, DAG);
  case ISD::FEXP2:
    return lowerFEXP2(Op, DAG);
  case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
  case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG);
  case ISD::FP_TO_FP16: return LowerFP_TO_FP16(Op, DAG);
  case ISD::FP_TO_SINT:
  case ISD::FP_TO_UINT:
    return LowerFP_TO_INT(Op, DAG);
  case ISD::FP_TO_SINT_SAT:
  case ISD::FP_TO_UINT_SAT:
    return LowerFP_TO_INT_SAT(Op, DAG);
  case ISD::CTTZ:
  case ISD::CTTZ_ZERO_POISON:
  case ISD::CTLZ:
  case ISD::CTLZ_ZERO_POISON:
    return LowerCTLZ_CTTZ(Op, DAG);
  case ISD::CTLS:
    return LowerCTLS(Op, DAG);
  case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
  }
  return Op;
}

void AMDGPUTargetLowering::ReplaceNodeResults(SDNode *N,
                                              SmallVectorImpl<SDValue> &Results,
                                              SelectionDAG &DAG) const {
  switch (N->getOpcode()) {
  case ISD::SIGN_EXTEND_INREG:
    // Different parts of legalization seem to interpret which type of
    // sign_extend_inreg is the one to check for custom lowering. The extended
    // from type is what really matters, but some places check for custom
    // lowering of the result type. This results in trying to use
    // ReplaceNodeResults to sext_in_reg to an illegal type, so we'll just do
    // nothing here and let the illegal result integer be handled normally.
    return;
  case ISD::FLOG2:
    if (SDValue Lowered = LowerFLOG2(SDValue(N, 0), DAG))
      Results.push_back(Lowered);
    return;
  case ISD::FLOG:
  case ISD::FLOG10:
    if (SDValue Lowered = LowerFLOGCommon(SDValue(N, 0), DAG))
      Results.push_back(Lowered);
    return;
  case ISD::FEXP2:
    if (SDValue Lowered = lowerFEXP2(SDValue(N, 0), DAG))
      Results.push_back(Lowered);
    return;
  case ISD::FEXP:
  case ISD::FEXP10:
    if (SDValue Lowered = lowerFEXP(SDValue(N, 0), DAG))
      Results.push_back(Lowered);
    return;
  case ISD::CTLZ:
  case ISD::CTLZ_ZERO_POISON:
    if (auto Lowered = lowerCTLZResults(SDValue(N, 0u), DAG))
      Results.push_back(Lowered);
    return;
  default:
    return;
  }
}

SDValue AMDGPUTargetLowering::LowerBlockAddress(SDValue Op,
                                                SelectionDAG &DAG) const {
  BlockAddressSDNode *BA = cast<BlockAddressSDNode>(Op);
  SDLoc SL(Op);
  EVT VT = Op.getValueType();
  return DAG.getTargetBlockAddress(BA->getBlockAddress(), VT, BA->getOffset(),
                                   BA->getTargetFlags());
}

SDValue AMDGPUTargetLowering::LowerGlobalAddress(AMDGPUMachineFunctionInfo *MFI,
                                                 SDValue Op,
                                                 SelectionDAG &DAG) const {

  const DataLayout &DL = DAG.getDataLayout();
  GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
  const GlobalValue *GV = G->getGlobal();

  if (!MFI->isModuleEntryFunction()) {
    bool IsNamedBarrier = AMDGPU::isNamedBarrier(*cast<GlobalVariable>(GV));
    std::optional<uint32_t> Address =
        AMDGPUMachineFunctionInfo::getLDSAbsoluteAddress(*GV);
    if (!Address && IsNamedBarrier)
      llvm_unreachable("named barrier should have an assigned address");
    if (Address) {
      if (IsNamedBarrier) {
        unsigned BarCnt = cast<GlobalVariable>(GV)->getGlobalSize(DL) / 16;
        MFI->recordNumNamedBarriers(Address.value(), BarCnt);
      }
      // A constant byte offset (e.g. from a GEP into an array of named
      // barriers) folds directly into the fixed LDS address.
      return DAG.getConstant(*Address + G->getOffset(), SDLoc(Op),
                             Op.getValueType());
    }
  }

  if (G->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS ||
      G->getAddressSpace() == AMDGPUAS::REGION_ADDRESS) {
    if (!MFI->isModuleEntryFunction() &&
        GV->getName() != "llvm.amdgcn.module.lds" &&
        !AMDGPU::isNamedBarrier(*cast<GlobalVariable>(GV))) {
      SDLoc DL(Op);
      const Function &Fn = DAG.getMachineFunction().getFunction();
      DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
          Fn, "local memory global used by non-kernel function",
          DL.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.
      SDValue Trap = DAG.getNode(ISD::TRAP, DL, MVT::Other, DAG.getEntryNode());
      SDValue OutputChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
                                        Trap, DAG.getRoot());
      DAG.setRoot(OutputChain);
      return DAG.getPOISON(Op.getValueType());
    }

    // 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.
    unsigned Offset = MFI->allocateLDSGlobal(DL, *cast<GlobalVariable>(GV));
    // A constant byte offset (e.g. from a GEP into an array of named barriers)
    // folds directly into the allocated LDS address.
    return DAG.getConstant(Offset + G->getOffset(), SDLoc(Op),
                           Op.getValueType());
  }
  return SDValue();
}

SDValue AMDGPUTargetLowering::LowerCONCAT_VECTORS(SDValue Op,
                                                  SelectionDAG &DAG) const {
  SmallVector<SDValue, 8> Args;
  SDLoc SL(Op);

  EVT VT = Op.getValueType();
  if (VT.getVectorElementType().getSizeInBits() < 32) {
    unsigned OpBitSize = Op.getOperand(0).getValueType().getSizeInBits();
    if (OpBitSize >= 32 && OpBitSize % 32 == 0) {
      unsigned NewNumElt = OpBitSize / 32;
      EVT NewEltVT = (NewNumElt == 1) ? MVT::i32
                                      : EVT::getVectorVT(*DAG.getContext(),
                                                         MVT::i32, NewNumElt);
      for (const SDUse &U : Op->ops()) {
        SDValue In = U.get();
        SDValue NewIn = DAG.getNode(ISD::BITCAST, SL, NewEltVT, In);
        if (NewNumElt > 1)
          DAG.ExtractVectorElements(NewIn, Args);
        else
          Args.push_back(NewIn);
      }

      EVT NewVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32,
                                   NewNumElt * Op.getNumOperands());
      SDValue BV = DAG.getBuildVector(NewVT, SL, Args);
      return DAG.getNode(ISD::BITCAST, SL, VT, BV);
    }
  }

  for (const SDUse &U : Op->ops())
    DAG.ExtractVectorElements(U.get(), Args);

  return DAG.getBuildVector(Op.getValueType(), SL, Args);
}

SDValue AMDGPUTargetLowering::LowerEXTRACT_SUBVECTOR(SDValue Op,
                                                     SelectionDAG &DAG) const {
  SDLoc SL(Op);
  SmallVector<SDValue, 8> Args;
  unsigned Start = Op.getConstantOperandVal(1);
  EVT VT = Op.getValueType();
  EVT SrcVT = Op.getOperand(0).getValueType();

  if (VT.getScalarSizeInBits() == 16 && Start % 2 == 0) {
    unsigned NumElt = VT.getVectorNumElements();
    unsigned NumSrcElt = SrcVT.getVectorNumElements();
    assert(NumElt % 2 == 0 && NumSrcElt % 2 == 0 && "expect legal types");

    // Extract 32-bit registers at a time.
    EVT NewSrcVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumSrcElt / 2);
    EVT NewVT = NumElt == 2
                    ? MVT::i32
                    : EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElt / 2);
    SDValue Tmp = DAG.getNode(ISD::BITCAST, SL, NewSrcVT, Op.getOperand(0));

    DAG.ExtractVectorElements(Tmp, Args, Start / 2, NumElt / 2);
    if (NumElt == 2)
      Tmp = Args[0];
    else
      Tmp = DAG.getBuildVector(NewVT, SL, Args);

    return DAG.getNode(ISD::BITCAST, SL, VT, Tmp);
  }

  DAG.ExtractVectorElements(Op.getOperand(0), Args, Start,
                            VT.getVectorNumElements());

  return DAG.getBuildVector(Op.getValueType(), SL, Args);
}

// TODO: Handle fabs too
static SDValue peekFNeg(SDValue Val) {
  if (Val.getOpcode() == ISD::FNEG)
    return Val.getOperand(0);

  return Val;
}

static SDValue peekFPSignOps(SDValue Val) {
  if (Val.getOpcode() == ISD::FNEG)
    Val = Val.getOperand(0);
  if (Val.getOpcode() == ISD::FABS)
    Val = Val.getOperand(0);
  if (Val.getOpcode() == ISD::FCOPYSIGN)
    Val = Val.getOperand(0);
  return Val;
}

SDValue AMDGPUTargetLowering::combineFMinMaxLegacyImpl(
    const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True,
    SDValue False, SDValue CC, DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
  switch (CCOpcode) {
  case ISD::SETOEQ:
  case ISD::SETONE:
  case ISD::SETUNE:
  case ISD::SETNE:
  case ISD::SETUEQ:
  case ISD::SETEQ:
  case ISD::SETFALSE:
  case ISD::SETFALSE2:
  case ISD::SETTRUE:
  case ISD::SETTRUE2:
  case ISD::SETUO:
  case ISD::SETO:
    break;
  case ISD::SETULE:
  case ISD::SETULT: {
    if (LHS == True)
      return DAG.getNode(AMDGPUISD::FMIN_LEGACY, DL, VT, RHS, LHS);
    return DAG.getNode(AMDGPUISD::FMAX_LEGACY, DL, VT, LHS, RHS);
  }
  case ISD::SETOLE:
  case ISD::SETOLT:
  case ISD::SETLE:
  case ISD::SETLT: {
    // Ordered. Assume ordered for undefined.

    // Only do this after legalization to avoid interfering with other combines
    // which might occur.
    if (DCI.getDAGCombineLevel() < AfterLegalizeDAG &&
        !DCI.isCalledByLegalizer())
      return SDValue();

    // We need to permute the operands to get the correct NaN behavior. The
    // selected operand is the second one based on the failing compare with NaN,
    // so permute it based on the compare type the hardware uses.
    if (LHS == True)
      return DAG.getNode(AMDGPUISD::FMIN_LEGACY, DL, VT, LHS, RHS);
    return DAG.getNode(AMDGPUISD::FMAX_LEGACY, DL, VT, RHS, LHS);
  }
  case ISD::SETUGE:
  case ISD::SETUGT: {
    if (LHS == True)
      return DAG.getNode(AMDGPUISD::FMAX_LEGACY, DL, VT, RHS, LHS);
    return DAG.getNode(AMDGPUISD::FMIN_LEGACY, DL, VT, LHS, RHS);
  }
  case ISD::SETGT:
  case ISD::SETGE:
  case ISD::SETOGE:
  case ISD::SETOGT: {
    if (DCI.getDAGCombineLevel() < AfterLegalizeDAG &&
        !DCI.isCalledByLegalizer())
      return SDValue();

    if (LHS == True)
      return DAG.getNode(AMDGPUISD::FMAX_LEGACY, DL, VT, LHS, RHS);
    return DAG.getNode(AMDGPUISD::FMIN_LEGACY, DL, VT, RHS, LHS);
  }
  case ISD::SETCC_INVALID:
    llvm_unreachable("Invalid setcc condcode!");
  }
  return SDValue();
}

/// Generate Min/Max node
SDValue AMDGPUTargetLowering::combineFMinMaxLegacy(const SDLoc &DL, EVT VT,
                                                   SDValue LHS, SDValue RHS,
                                                   SDValue True, SDValue False,
                                                   SDValue CC,
                                                   DAGCombinerInfo &DCI) const {
  if ((LHS == True && RHS == False) || (LHS == False && RHS == True))
    return combineFMinMaxLegacyImpl(DL, VT, LHS, RHS, True, False, CC, DCI);

  SelectionDAG &DAG = DCI.DAG;

  // If we can't directly match this, try to see if we can fold an fneg to
  // match.

  ConstantFPSDNode *CRHS = dyn_cast<ConstantFPSDNode>(RHS);
  ConstantFPSDNode *CFalse = dyn_cast<ConstantFPSDNode>(False);
  SDValue NegTrue = peekFNeg(True);

  // Undo the combine foldFreeOpFromSelect does if it helps us match the
  // fmin/fmax.
  //
  // select (fcmp olt (lhs, K)), (fneg lhs), -K
  // -> fneg (fmin_legacy lhs, K)
  //
  // TODO: Use getNegatedExpression
  if (LHS == NegTrue && CFalse && CRHS) {
    APFloat NegRHS = neg(CRHS->getValueAPF());
    if (NegRHS == CFalse->getValueAPF()) {
      SDValue Combined =
          combineFMinMaxLegacyImpl(DL, VT, LHS, RHS, NegTrue, False, CC, DCI);
      if (Combined)
        return DAG.getNode(ISD::FNEG, DL, VT, Combined);
      return SDValue();
    }
  }

  return SDValue();
}

std::pair<SDValue, SDValue>
AMDGPUTargetLowering::split64BitValue(SDValue Op, SelectionDAG &DAG) const {
  SDLoc SL(Op);

  SDValue Vec = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op);

  const SDValue Zero = DAG.getConstant(0, SL, MVT::i32);
  const SDValue One = DAG.getConstant(1, SL, MVT::i32);

  SDValue Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, Zero);
  SDValue Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, One);

  return std::pair(Lo, Hi);
}

SDValue AMDGPUTargetLowering::getLoHalf64(SDValue Op, SelectionDAG &DAG) const {
  SDLoc SL(Op);

  SDValue Vec = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op);
  const SDValue Zero = DAG.getConstant(0, SL, MVT::i32);
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, Zero);
}

SDValue AMDGPUTargetLowering::getHiHalf64(SDValue Op, SelectionDAG &DAG) const {
  SDLoc SL(Op);

  SDValue Vec = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Op);
  const SDValue One = DAG.getConstant(1, SL, MVT::i32);
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Vec, One);
}

// Split a vector type into two parts. The first part is a power of two vector.
// The second part is whatever is left over, and is a scalar if it would
// otherwise be a 1-vector.
std::pair<EVT, EVT>
AMDGPUTargetLowering::getSplitDestVTs(const EVT &VT, SelectionDAG &DAG) const {
  EVT LoVT, HiVT;
  EVT EltVT = VT.getVectorElementType();
  unsigned NumElts = VT.getVectorNumElements();
  unsigned LoNumElts = PowerOf2Ceil((NumElts + 1) / 2);
  LoVT = EVT::getVectorVT(*DAG.getContext(), EltVT, LoNumElts);
  HiVT = NumElts - LoNumElts == 1
             ? EltVT
             : EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts - LoNumElts);
  return std::pair(LoVT, HiVT);
}

// Split a vector value into two parts of types LoVT and HiVT. HiVT could be
// scalar.
std::pair<SDValue, SDValue>
AMDGPUTargetLowering::splitVector(const SDValue &N, const SDLoc &DL,
                                  const EVT &LoVT, const EVT &HiVT,
                                  SelectionDAG &DAG) const {
  EVT VT = N.getValueType();
  assert(LoVT.getVectorNumElements() +
                 (HiVT.isVector() ? HiVT.getVectorNumElements() : 1) <=
             VT.getVectorNumElements() &&
         "More vector elements requested than available!");
  SDValue Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LoVT, N,
                           DAG.getVectorIdxConstant(0, DL));

  unsigned LoNumElts = LoVT.getVectorNumElements();

  if (HiVT.isVector()) {
    unsigned HiNumElts = HiVT.getVectorNumElements();
    if ((VT.getVectorNumElements() % HiNumElts) == 0) {
      // Avoid creating an extract_subvector with an index that isn't a multiple
      // of the result type.
      SDValue Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HiVT, N,
                               DAG.getConstant(LoNumElts, DL, MVT::i32));
      return {Lo, Hi};
    }

    SmallVector<SDValue, 8> Elts;
    DAG.ExtractVectorElements(N, Elts, /*Start=*/LoNumElts,
                              /*Count=*/HiNumElts);
    SDValue Hi = DAG.getBuildVector(HiVT, DL, Elts);
    return {Lo, Hi};
  }

  SDValue Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, HiVT, N,
                           DAG.getVectorIdxConstant(LoNumElts, DL));
  return {Lo, Hi};
}

SDValue AMDGPUTargetLowering::SplitVectorLoad(const SDValue Op,
                                              SelectionDAG &DAG) const {
  LoadSDNode *Load = cast<LoadSDNode>(Op);
  EVT VT = Op.getValueType();
  SDLoc SL(Op);


  // If this is a 2 element vector, we really want to scalarize and not create
  // weird 1 element vectors.
  if (VT.getVectorNumElements() == 2) {
    SDValue Ops[2];
    std::tie(Ops[0], Ops[1]) = scalarizeVectorLoad(Load, DAG);
    return DAG.getMergeValues(Ops, SL);
  }

  SDValue BasePtr = Load->getBasePtr();
  EVT MemVT = Load->getMemoryVT();

  const MachinePointerInfo &SrcValue = Load->getMemOperand()->getPointerInfo();

  EVT LoVT, HiVT;
  EVT LoMemVT, HiMemVT;
  SDValue Lo, Hi;

  std::tie(LoVT, HiVT) = getSplitDestVTs(VT, DAG);
  std::tie(LoMemVT, HiMemVT) = getSplitDestVTs(MemVT, DAG);
  std::tie(Lo, Hi) = splitVector(Op, SL, LoVT, HiVT, DAG);

  unsigned Size = LoMemVT.getStoreSize();
  Align BaseAlign = Load->getAlign();
  Align HiAlign = commonAlignment(BaseAlign, Size);

  SDValue LoLoad = DAG.getExtLoad(
      Load->getExtensionType(), SL, LoVT, Load->getChain(), BasePtr, SrcValue,
      LoMemVT, BaseAlign, Load->getMemOperand()->getFlags(), Load->getAAInfo());
  SDValue HiPtr = DAG.getObjectPtrOffset(SL, BasePtr, TypeSize::getFixed(Size));
  SDValue HiLoad = DAG.getExtLoad(
      Load->getExtensionType(), SL, HiVT, Load->getChain(), HiPtr,
      SrcValue.getWithOffset(LoMemVT.getStoreSize()), HiMemVT, HiAlign,
      Load->getMemOperand()->getFlags(), Load->getAAInfo());

  SDValue Join;
  if (LoVT == HiVT) {
    // This is the case that the vector is power of two so was evenly split.
    Join = DAG.getNode(ISD::CONCAT_VECTORS, SL, VT, LoLoad, HiLoad);
  } else {
    Join = DAG.getNode(ISD::INSERT_SUBVECTOR, SL, VT, DAG.getPOISON(VT), LoLoad,
                       DAG.getVectorIdxConstant(0, SL));
    Join = DAG.getNode(
        HiVT.isVector() ? ISD::INSERT_SUBVECTOR : ISD::INSERT_VECTOR_ELT, SL,
        VT, Join, HiLoad,
        DAG.getVectorIdxConstant(LoVT.getVectorNumElements(), SL));
  }

  SDValue Ops[] = {Join, DAG.getNode(ISD::TokenFactor, SL, MVT::Other,
                                     LoLoad.getValue(1), HiLoad.getValue(1))};

  return DAG.getMergeValues(Ops, SL);
}

SDValue AMDGPUTargetLowering::WidenOrSplitVectorLoad(SDValue Op,
                                                     SelectionDAG &DAG) const {
  LoadSDNode *Load = cast<LoadSDNode>(Op);
  EVT VT = Op.getValueType();
  SDValue BasePtr = Load->getBasePtr();
  EVT MemVT = Load->getMemoryVT();
  SDLoc SL(Op);
  const MachinePointerInfo &SrcValue = Load->getMemOperand()->getPointerInfo();
  Align BaseAlign = Load->getAlign();
  unsigned NumElements = MemVT.getVectorNumElements();

  // Widen from vec3 to vec4 when the load is at least 8-byte aligned
  // or 16-byte fully dereferenceable. Otherwise, split the vector load.
  if (NumElements != 3 ||
      (BaseAlign < Align(8) &&
       !SrcValue.isDereferenceable(16, *DAG.getContext(), DAG.getDataLayout())))
    return SplitVectorLoad(Op, DAG);

  assert(NumElements == 3);

  EVT WideVT =
      EVT::getVectorVT(*DAG.getContext(), VT.getVectorElementType(), 4);
  EVT WideMemVT =
      EVT::getVectorVT(*DAG.getContext(), MemVT.getVectorElementType(), 4);
  SDValue WideLoad = DAG.getExtLoad(
      Load->getExtensionType(), SL, WideVT, Load->getChain(), BasePtr, SrcValue,
      WideMemVT, BaseAlign, Load->getMemOperand()->getFlags());
  return DAG.getMergeValues(
      {DAG.getNode(ISD::EXTRACT_SUBVECTOR, SL, VT, WideLoad,
                   DAG.getVectorIdxConstant(0, SL)),
       WideLoad.getValue(1)},
      SL);
}

SDValue AMDGPUTargetLowering::SplitVectorStore(SDValue Op,
                                               SelectionDAG &DAG) const {
  StoreSDNode *Store = cast<StoreSDNode>(Op);
  SDValue Val = Store->getValue();
  EVT VT = Val.getValueType();

  // If this is a 2 element vector, we really want to scalarize and not create
  // weird 1 element vectors.
  if (VT.getVectorNumElements() == 2)
    return scalarizeVectorStore(Store, DAG);

  EVT MemVT = Store->getMemoryVT();
  SDValue Chain = Store->getChain();
  SDValue BasePtr = Store->getBasePtr();
  SDLoc SL(Op);

  EVT LoVT, HiVT;
  EVT LoMemVT, HiMemVT;
  SDValue Lo, Hi;

  std::tie(LoVT, HiVT) = getSplitDestVTs(VT, DAG);
  std::tie(LoMemVT, HiMemVT) = getSplitDestVTs(MemVT, DAG);
  std::tie(Lo, Hi) = splitVector(Val, SL, LoVT, HiVT, DAG);

  SDValue HiPtr = DAG.getObjectPtrOffset(SL, BasePtr, LoMemVT.getStoreSize());

  const MachinePointerInfo &SrcValue = Store->getMemOperand()->getPointerInfo();
  Align BaseAlign = Store->getAlign();
  unsigned Size = LoMemVT.getStoreSize();
  Align HiAlign = commonAlignment(BaseAlign, Size);

  SDValue LoStore =
      DAG.getTruncStore(Chain, SL, Lo, BasePtr, SrcValue, LoMemVT, BaseAlign,
                        Store->getMemOperand()->getFlags(), Store->getAAInfo());
  SDValue HiStore = DAG.getTruncStore(
      Chain, SL, Hi, HiPtr, SrcValue.getWithOffset(Size), HiMemVT, HiAlign,
      Store->getMemOperand()->getFlags(), Store->getAAInfo());

  return DAG.getNode(ISD::TokenFactor, SL, MVT::Other, LoStore, HiStore);
}

// This is a shortcut for integer division because we have fast i32<->f32
// conversions, and fast f32 reciprocal instructions. The fractional part of a
// float is enough to accurately represent up to a 24-bit integer.
SDValue AMDGPUTargetLowering::LowerDIVREM24(SDValue Op, SelectionDAG &DAG,
                                            bool Sign) const {
  SDLoc DL(Op);
  EVT VT = Op.getValueType();
  assert(VT == MVT::i32 && "LowerDIVREM24 expects an i32");

  SDValue LHS = Op.getOperand(0);
  SDValue RHS = Op.getOperand(1);
  MVT IntVT = MVT::i32;
  MVT FltVT = MVT::f32;

  unsigned LHSSignBits;
  unsigned RHSSignBits;
  if (Sign) {
    LHSSignBits = DAG.ComputeNumSignBits(LHS);
    RHSSignBits = DAG.ComputeNumSignBits(RHS);
    if (LHSSignBits < 9 || RHSSignBits < 9)
      return SDValue();
  } else {
    KnownBits LHSKnown = DAG.computeKnownBits(LHS);
    KnownBits RHSKnown = DAG.computeKnownBits(RHS);
    APInt U24Max = APInt::getLowBitsSet(32, 24);
    if (LHSKnown.getMaxValue().ugt(U24Max) ||
        RHSKnown.getMaxValue().ugt(U24Max))
      return SDValue();
    LHSSignBits = LHSKnown.countMinLeadingZeros();
    RHSSignBits = RHSKnown.countMinLeadingZeros();
  }

  unsigned BitSize = VT.getSizeInBits();
  unsigned SignBits = std::min(LHSSignBits, RHSSignBits);
  unsigned DivBits = BitSize - SignBits;
  if (Sign)
    ++DivBits;

  ISD::NodeType ToFp = Sign ? ISD::SINT_TO_FP : ISD::UINT_TO_FP;
  ISD::NodeType ToInt = Sign ? ISD::FP_TO_SINT : ISD::FP_TO_UINT;

  SDValue jq = DAG.getConstant(1, DL, IntVT);

  if (Sign) {
    // char|short jq = ia ^ ib;
    jq = DAG.getNode(ISD::XOR, DL, VT, LHS, RHS);

    // jq = jq >> (bitsize - 2)
    jq = DAG.getNode(ISD::SRA, DL, VT, jq,
                     DAG.getConstant(BitSize - 2, DL, VT));

    // jq = jq | 0x1
    jq = DAG.getNode(ISD::OR, DL, VT, jq, DAG.getConstant(1, DL, VT));
  }

  // int ia = (int)LHS;
  SDValue ia = LHS;

  // int ib, (int)RHS;
  SDValue ib = RHS;

  // float fa = (float)ia;
  SDValue fa = DAG.getNode(ToFp, DL, FltVT, ia);

  // float fb = (float)ib;
  SDValue fb = DAG.getNode(ToFp, DL, FltVT, ib);

  SDValue fq = DAG.getNode(ISD::FMUL, DL, FltVT,
                           fa, DAG.getNode(AMDGPUISD::RCP, DL, FltVT, fb));

  // fq = trunc(fq);
  fq = DAG.getNode(ISD::FTRUNC, DL, FltVT, fq);

  // float fqneg = -fq;
  SDValue fqneg = DAG.getNode(ISD::FNEG, DL, FltVT, fq);

  MachineFunction &MF = DAG.getMachineFunction();

  bool UseFmadFtz = false;
  if (Subtarget->isGCN()) {
    const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
    UseFmadFtz =
        MFI->getMode().FP32Denormals != DenormalMode::getPreserveSign();
  }

  // float fr = mad(fqneg, fb, fa);
  unsigned OpCode = !Subtarget->hasMadMacF32Insts() ? (unsigned)ISD::FMA
                    : UseFmadFtz ? (unsigned)AMDGPUISD::FMAD_FTZ
                                 : (unsigned)ISD::FMAD;
  SDValue fr = DAG.getNode(OpCode, DL, FltVT, fqneg, fb, fa);

  // int iq = (int)fq;
  SDValue iq = DAG.getNode(ToInt, DL, IntVT, fq);

  // fr = fabs(fr);
  fr = DAG.getNode(ISD::FABS, DL, FltVT, fr);

  // fb = fabs(fb);
  fb = DAG.getNode(ISD::FABS, DL, FltVT, fb);

  EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);

  // int cv = fr >= fb;
  SDValue cv = DAG.getSetCC(DL, SetCCVT, fr, fb, ISD::SETOGE);

  // jq = (cv ? jq : 0);
  jq = DAG.getNode(ISD::SELECT, DL, VT, cv, jq, DAG.getConstant(0, DL, VT));

  // dst = iq + jq;
  SDValue Div = DAG.getNode(ISD::ADD, DL, VT, iq, jq);

  // Rem needs compensation, it's easier to recompute it
  SDValue Rem = DAG.getNode(ISD::MUL, DL, VT, Div, RHS);
  Rem = DAG.getNode(ISD::SUB, DL, VT, LHS, Rem);

  // Truncate to number of bits this divide really is.
  if (Sign) {
    SDValue InRegSize
      = DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(), DivBits));
    Div = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Div, InRegSize);
    Rem = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Rem, InRegSize);
  } else {
    SDValue TruncMask = DAG.getConstant((UINT64_C(1) << DivBits) - 1, DL, VT);
    Div = DAG.getNode(ISD::AND, DL, VT, Div, TruncMask);
    Rem = DAG.getNode(ISD::AND, DL, VT, Rem, TruncMask);
  }

  return DAG.getMergeValues({ Div, Rem }, DL);
}

void AMDGPUTargetLowering::LowerUDIVREM64(SDValue Op,
                                      SelectionDAG &DAG,
                                      SmallVectorImpl<SDValue> &Results) const {
  SDLoc DL(Op);
  EVT VT = Op.getValueType();

  assert(VT == MVT::i64 && "LowerUDIVREM64 expects an i64");

  EVT HalfVT = VT.getHalfSizedIntegerVT(*DAG.getContext());

  SDValue One = DAG.getConstant(1, DL, HalfVT);
  SDValue Zero = DAG.getConstant(0, DL, HalfVT);

  //HiLo split
  SDValue LHS_Lo, LHS_Hi;
  SDValue LHS = Op.getOperand(0);
  std::tie(LHS_Lo, LHS_Hi) = DAG.SplitScalar(LHS, DL, HalfVT, HalfVT);

  SDValue RHS_Lo, RHS_Hi;
  SDValue RHS = Op.getOperand(1);
  std::tie(RHS_Lo, RHS_Hi) = DAG.SplitScalar(RHS, DL, HalfVT, HalfVT);

  if (DAG.MaskedValueIsZero(RHS, APInt::getHighBitsSet(64, 32)) &&
      DAG.MaskedValueIsZero(LHS, APInt::getHighBitsSet(64, 32))) {

    SDValue Res = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(HalfVT, HalfVT),
                              LHS_Lo, RHS_Lo);

    SDValue DIV = DAG.getBuildVector(MVT::v2i32, DL, {Res.getValue(0), Zero});
    SDValue REM = DAG.getBuildVector(MVT::v2i32, DL, {Res.getValue(1), Zero});

    Results.push_back(DAG.getNode(ISD::BITCAST, DL, MVT::i64, DIV));
    Results.push_back(DAG.getNode(ISD::BITCAST, DL, MVT::i64, REM));
    return;
  }

  if (isTypeLegal(MVT::i64)) {
    // The algorithm here is based on ideas from "Software Integer Division",
    // Tom Rodeheffer, August 2008.

    MachineFunction &MF = DAG.getMachineFunction();
    const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();

    // Compute denominator reciprocal.
    unsigned FMAD =
        !Subtarget->hasMadMacF32Insts() ? (unsigned)ISD::FMA
        : MFI->getMode().FP32Denormals == DenormalMode::getPreserveSign()
            ? (unsigned)ISD::FMAD
            : (unsigned)AMDGPUISD::FMAD_FTZ;

    SDValue Cvt_Lo = DAG.getNode(ISD::UINT_TO_FP, DL, MVT::f32, RHS_Lo);
    SDValue Cvt_Hi = DAG.getNode(ISD::UINT_TO_FP, DL, MVT::f32, RHS_Hi);
    SDValue Mad1 = DAG.getNode(FMAD, DL, MVT::f32, Cvt_Hi,
      DAG.getConstantFP(APInt(32, 0x4f800000).bitsToFloat(), DL, MVT::f32),
      Cvt_Lo);
    SDValue Rcp = DAG.getNode(AMDGPUISD::RCP, DL, MVT::f32, Mad1);
    SDValue Mul1 = DAG.getNode(ISD::FMUL, DL, MVT::f32, Rcp,
      DAG.getConstantFP(APInt(32, 0x5f7ffffc).bitsToFloat(), DL, MVT::f32));
    SDValue Mul2 = DAG.getNode(ISD::FMUL, DL, MVT::f32, Mul1,
      DAG.getConstantFP(APInt(32, 0x2f800000).bitsToFloat(), DL, MVT::f32));
    SDValue Trunc = DAG.getNode(ISD::FTRUNC, DL, MVT::f32, Mul2);
    SDValue Mad2 = DAG.getNode(FMAD, DL, MVT::f32, Trunc,
      DAG.getConstantFP(APInt(32, 0xcf800000).bitsToFloat(), DL, MVT::f32),
      Mul1);
    SDValue Rcp_Lo = DAG.getNode(ISD::FP_TO_UINT, DL, HalfVT, Mad2);
    SDValue Rcp_Hi = DAG.getNode(ISD::FP_TO_UINT, DL, HalfVT, Trunc);
    SDValue Rcp64 = DAG.getBitcast(VT,
                        DAG.getBuildVector(MVT::v2i32, DL, {Rcp_Lo, Rcp_Hi}));

    SDValue Zero64 = DAG.getConstant(0, DL, VT);
    SDValue One64  = DAG.getConstant(1, DL, VT);
    SDValue Zero1 = DAG.getConstant(0, DL, MVT::i1);
    SDVTList HalfCarryVT = DAG.getVTList(HalfVT, MVT::i1);

    // First round of UNR (Unsigned integer Newton-Raphson).
    SDValue Neg_RHS = DAG.getNode(ISD::SUB, DL, VT, Zero64, RHS);
    SDValue Mullo1 = DAG.getNode(ISD::MUL, DL, VT, Neg_RHS, Rcp64);
    SDValue Mulhi1 = DAG.getNode(ISD::MULHU, DL, VT, Rcp64, Mullo1);
    SDValue Mulhi1_Lo, Mulhi1_Hi;
    std::tie(Mulhi1_Lo, Mulhi1_Hi) =
        DAG.SplitScalar(Mulhi1, DL, HalfVT, HalfVT);
    SDValue Add1_Lo = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Rcp_Lo,
                                  Mulhi1_Lo, Zero1);
    SDValue Add1_Hi = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Rcp_Hi,
                                  Mulhi1_Hi, Add1_Lo.getValue(1));
    SDValue Add1 = DAG.getBitcast(VT,
                        DAG.getBuildVector(MVT::v2i32, DL, {Add1_Lo, Add1_Hi}));

    // Second round of UNR.
    SDValue Mullo2 = DAG.getNode(ISD::MUL, DL, VT, Neg_RHS, Add1);
    SDValue Mulhi2 = DAG.getNode(ISD::MULHU, DL, VT, Add1, Mullo2);
    SDValue Mulhi2_Lo, Mulhi2_Hi;
    std::tie(Mulhi2_Lo, Mulhi2_Hi) =
        DAG.SplitScalar(Mulhi2, DL, HalfVT, HalfVT);
    SDValue Add2_Lo = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Add1_Lo,
                                  Mulhi2_Lo, Zero1);
    SDValue Add2_Hi = DAG.getNode(ISD::UADDO_CARRY, DL, HalfCarryVT, Add1_Hi,
                                  Mulhi2_Hi, Add2_Lo.getValue(1));
    SDValue Add2 = DAG.getBitcast(VT,
                        DAG.getBuildVector(MVT::v2i32, DL, {Add2_Lo, Add2_Hi}));

    SDValue Mulhi3 = DAG.getNode(ISD::MULHU, DL, VT, LHS, Add2);

    SDValue Mul3 = DAG.getNode(ISD::MUL, DL, VT, RHS, Mulhi3);

    SDValue Mul3_Lo, Mul3_Hi;
    std::tie(Mul3_Lo, Mul3_Hi) = DAG.SplitScalar(Mul3, DL, HalfVT, HalfVT);
    SDValue Sub1_Lo = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, LHS_Lo,
                                  Mul3_Lo, Zero1);
    SDValue Sub1_Hi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, LHS_Hi,
                                  Mul3_Hi, Sub1_Lo.getValue(1));
    SDValue Sub1_Mi = DAG.getNode(ISD::SUB, DL, HalfVT, LHS_Hi, Mul3_Hi);
    SDValue Sub1 = DAG.getBitcast(VT,
                        DAG.getBuildVector(MVT::v2i32, DL, {Sub1_Lo, Sub1_Hi}));

    SDValue MinusOne = DAG.getConstant(0xffffffffu, DL, HalfVT);
    SDValue C1 = DAG.getSelectCC(DL, Sub1_Hi, RHS_Hi, MinusOne, Zero,
                                 ISD::SETUGE);
    SDValue C2 = DAG.getSelectCC(DL, Sub1_Lo, RHS_Lo, MinusOne, Zero,
                                 ISD::SETUGE);
    SDValue C3 = DAG.getSelectCC(DL, Sub1_Hi, RHS_Hi, C2, C1, ISD::SETEQ);

    // 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 ...
    SDValue Sub2_Lo = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub1_Lo,
                                  RHS_Lo, Zero1);
    SDValue Sub2_Mi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub1_Mi,
                                  RHS_Hi, Sub1_Lo.getValue(1));
    SDValue Sub2_Hi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub2_Mi,
                                  Zero, Sub2_Lo.getValue(1));
    SDValue Sub2 = DAG.getBitcast(VT,
                        DAG.getBuildVector(MVT::v2i32, DL, {Sub2_Lo, Sub2_Hi}));

    SDValue Add3 = DAG.getNode(ISD::ADD, DL, VT, Mulhi3, One64);

    SDValue C4 = DAG.getSelectCC(DL, Sub2_Hi, RHS_Hi, MinusOne, Zero,
                                 ISD::SETUGE);
    SDValue C5 = DAG.getSelectCC(DL, Sub2_Lo, RHS_Lo, MinusOne, Zero,
                                 ISD::SETUGE);
    SDValue C6 = DAG.getSelectCC(DL, Sub2_Hi, RHS_Hi, C5, C4, ISD::SETEQ);

    // if (C6 != 0)
    SDValue Add4 = DAG.getNode(ISD::ADD, DL, VT, Add3, One64);

    SDValue Sub3_Lo = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub2_Lo,
                                  RHS_Lo, Zero1);
    SDValue Sub3_Mi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub2_Mi,
                                  RHS_Hi, Sub2_Lo.getValue(1));
    SDValue Sub3_Hi = DAG.getNode(ISD::USUBO_CARRY, DL, HalfCarryVT, Sub3_Mi,
                                  Zero, Sub3_Lo.getValue(1));
    SDValue Sub3 = DAG.getBitcast(VT,
                        DAG.getBuildVector(MVT::v2i32, DL, {Sub3_Lo, Sub3_Hi}));

    // endif C6
    // endif C3

    SDValue Sel1 = DAG.getSelectCC(DL, C6, Zero, Add4, Add3, ISD::SETNE);
    SDValue Div  = DAG.getSelectCC(DL, C3, Zero, Sel1, Mulhi3, ISD::SETNE);

    SDValue Sel2 = DAG.getSelectCC(DL, C6, Zero, Sub3, Sub2, ISD::SETNE);
    SDValue Rem  = DAG.getSelectCC(DL, C3, Zero, Sel2, Sub1, ISD::SETNE);

    Results.push_back(Div);
    Results.push_back(Rem);

    return;
  }

  // r600 expandion.
  // Get Speculative values
  SDValue DIV_Part = DAG.getNode(ISD::UDIV, DL, HalfVT, LHS_Hi, RHS_Lo);
  SDValue REM_Part = DAG.getNode(ISD::UREM, DL, HalfVT, LHS_Hi, RHS_Lo);

  SDValue REM_Lo = DAG.getSelectCC(DL, RHS_Hi, Zero, REM_Part, LHS_Hi, ISD::SETEQ);
  SDValue REM = DAG.getBuildVector(MVT::v2i32, DL, {REM_Lo, Zero});
  REM = DAG.getNode(ISD::BITCAST, DL, MVT::i64, REM);

  SDValue DIV_Hi = DAG.getSelectCC(DL, RHS_Hi, Zero, DIV_Part, Zero, ISD::SETEQ);
  SDValue DIV_Lo = Zero;

  const unsigned halfBitWidth = HalfVT.getSizeInBits();

  for (unsigned i = 0; i < halfBitWidth; ++i) {
    const unsigned bitPos = halfBitWidth - i - 1;
    SDValue POS = DAG.getConstant(bitPos, DL, HalfVT);
    // Get value of high bit
    SDValue HBit = DAG.getNode(ISD::SRL, DL, HalfVT, LHS_Lo, POS);
    HBit = DAG.getNode(ISD::AND, DL, HalfVT, HBit, One);
    HBit = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, HBit);

    // Shift
    REM = DAG.getNode(ISD::SHL, DL, VT, REM, DAG.getConstant(1, DL, VT));
    // Add LHS high bit
    REM = DAG.getNode(ISD::OR, DL, VT, REM, HBit);

    SDValue BIT = DAG.getConstant(1ULL << bitPos, DL, HalfVT);
    SDValue realBIT = DAG.getSelectCC(DL, REM, RHS, BIT, Zero, ISD::SETUGE);

    DIV_Lo = DAG.getNode(ISD::OR, DL, HalfVT, DIV_Lo, realBIT);

    // Update REM
    SDValue REM_sub = DAG.getNode(ISD::SUB, DL, VT, REM, RHS);
    REM = DAG.getSelectCC(DL, REM, RHS, REM_sub, REM, ISD::SETUGE);
  }

  SDValue DIV = DAG.getBuildVector(MVT::v2i32, DL, {DIV_Lo, DIV_Hi});
  DIV = DAG.getNode(ISD::BITCAST, DL, MVT::i64, DIV);
  Results.push_back(DIV);
  Results.push_back(REM);
}

SDValue AMDGPUTargetLowering::LowerUDIVREM(SDValue Op,
                                           SelectionDAG &DAG) const {
  SDLoc DL(Op);
  EVT VT = Op.getValueType();

  if (VT == MVT::i64) {
    SmallVector<SDValue, 2> Results;
    LowerUDIVREM64(Op, DAG, Results);
    return DAG.getMergeValues(Results, DL);
  }

  if (VT == MVT::i32) {
    if (SDValue Res = LowerDIVREM24(Op, DAG, false))
      return Res;
  }

  SDValue X = Op.getOperand(0);
  SDValue Y = Op.getOperand(1);

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

  // Initial estimate of inv(y).
  SDValue Z = DAG.getNode(AMDGPUISD::URECIP, DL, VT, Y);

  // One round of UNR.
  SDValue NegY = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Y);
  SDValue NegYZ = DAG.getNode(ISD::MUL, DL, VT, NegY, Z);
  Z = DAG.getNode(ISD::ADD, DL, VT, Z,
                  DAG.getNode(ISD::MULHU, DL, VT, Z, NegYZ));

  // Quotient/remainder estimate.
  SDValue Q = DAG.getNode(ISD::MULHU, DL, VT, X, Z);
  SDValue R =
      DAG.getNode(ISD::SUB, DL, VT, X, DAG.getNode(ISD::MUL, DL, VT, Q, Y));

  // First quotient/remainder refinement.
  EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
  SDValue One = DAG.getConstant(1, DL, VT);
  SDValue Cond = DAG.getSetCC(DL, CCVT, R, Y, ISD::SETUGE);
  Q = DAG.getNode(ISD::SELECT, DL, VT, Cond,
                  DAG.getNode(ISD::ADD, DL, VT, Q, One), Q);
  R = DAG.getNode(ISD::SELECT, DL, VT, Cond,
                  DAG.getNode(ISD::SUB, DL, VT, R, Y), R);

  // Second quotient/remainder refinement.
  Cond = DAG.getSetCC(DL, CCVT, R, Y, ISD::SETUGE);
  Q = DAG.getNode(ISD::SELECT, DL, VT, Cond,
                  DAG.getNode(ISD::ADD, DL, VT, Q, One), Q);
  R = DAG.getNode(ISD::SELECT, DL, VT, Cond,
                  DAG.getNode(ISD::SUB, DL, VT, R, Y), R);

  return DAG.getMergeValues({Q, R}, DL);
}

SDValue AMDGPUTargetLowering::LowerSDIVREM(SDValue Op,
                                           SelectionDAG &DAG) const {
  SDLoc DL(Op);
  EVT VT = Op.getValueType();

  SDValue LHS = Op.getOperand(0);
  SDValue RHS = Op.getOperand(1);

  SDValue Zero = DAG.getConstant(0, DL, VT);
  SDValue NegOne = DAG.getAllOnesConstant(DL, VT);

  if (VT == MVT::i32) {
    if (SDValue Res = LowerDIVREM24(Op, DAG, true))
      return Res;
  }

  // LHS must have > 33 sign-bits to ensure that LHS != -2147483648
  // Otherwise 32-bit division cannot be used safely.
  // -2147483648/1 and -2147483648/-1 are not equal,
  // but they produce the same lower 32-bit result.
  if (VT == MVT::i64 && DAG.ComputeNumSignBits(LHS) > 33 &&
      DAG.ComputeNumSignBits(RHS) > 32) {
    EVT HalfVT = VT.getHalfSizedIntegerVT(*DAG.getContext());

    //HiLo split
    SDValue LHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, LHS, Zero);
    SDValue RHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, RHS, Zero);
    SDValue DIVREM = DAG.getNode(ISD::SDIVREM, DL, DAG.getVTList(HalfVT, HalfVT),
                                 LHS_Lo, RHS_Lo);
    SDValue Res[2] = {
      DAG.getNode(ISD::SIGN_EXTEND, DL, VT, DIVREM.getValue(0)),
      DAG.getNode(ISD::SIGN_EXTEND, DL, VT, DIVREM.getValue(1))
    };
    return DAG.getMergeValues(Res, DL);
  }

  SDValue LHSign = DAG.getSelectCC(DL, LHS, Zero, NegOne, Zero, ISD::SETLT);
  SDValue RHSign = DAG.getSelectCC(DL, RHS, Zero, NegOne, Zero, ISD::SETLT);
  SDValue DSign = DAG.getNode(ISD::XOR, DL, VT, LHSign, RHSign);
  SDValue RSign = LHSign; // Remainder sign is the same as LHS

  LHS = DAG.getNode(ISD::ADD, DL, VT, LHS, LHSign);
  RHS = DAG.getNode(ISD::ADD, DL, VT, RHS, RHSign);

  LHS = DAG.getNode(ISD::XOR, DL, VT, LHS, LHSign);
  RHS = DAG.getNode(ISD::XOR, DL, VT, RHS, RHSign);

  SDValue Div = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(VT, VT), LHS, RHS);
  SDValue Rem = Div.getValue(1);

  Div = DAG.getNode(ISD::XOR, DL, VT, Div, DSign);
  Rem = DAG.getNode(ISD::XOR, DL, VT, Rem, RSign);

  Div = DAG.getNode(ISD::SUB, DL, VT, Div, DSign);
  Rem = DAG.getNode(ISD::SUB, DL, VT, Rem, RSign);

  SDValue Res[2] = {
    Div,
    Rem
  };
  return DAG.getMergeValues(Res, DL);
}

SDValue AMDGPUTargetLowering::LowerFCEIL(SDValue Op, SelectionDAG &DAG) const {
  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);

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

  SDValue Trunc = DAG.getNode(ISD::FTRUNC, SL, MVT::f64, Src);

  const SDValue Zero = DAG.getConstantFP(0.0, SL, MVT::f64);
  const SDValue One = DAG.getConstantFP(1.0, SL, MVT::f64);

  EVT SetCCVT =
      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::f64);

  SDValue Lt0 = DAG.getSetCC(SL, SetCCVT, Src, Zero, ISD::SETOGT);
  SDValue NeTrunc = DAG.getSetCC(SL, SetCCVT, Src, Trunc, ISD::SETONE);
  SDValue And = DAG.getNode(ISD::AND, SL, SetCCVT, Lt0, NeTrunc);

  SDValue Add = DAG.getNode(ISD::SELECT, SL, MVT::f64, And, One, Zero);
  // TODO: Should this propagate fast-math-flags?
  return DAG.getNode(ISD::FADD, SL, MVT::f64, Trunc, Add);
}

static SDValue extractF64Exponent(SDValue Hi, const SDLoc &SL,
                                  SelectionDAG &DAG) {
  const unsigned FractBits = 52;
  const unsigned ExpBits = 11;

  SDValue ExpPart = DAG.getNode(AMDGPUISD::BFE_U32, SL, MVT::i32,
                                Hi,
                                DAG.getConstant(FractBits - 32, SL, MVT::i32),
                                DAG.getConstant(ExpBits, SL, MVT::i32));
  SDValue Exp = DAG.getNode(ISD::SUB, SL, MVT::i32, ExpPart,
                            DAG.getConstant(1023, SL, MVT::i32));

  return Exp;
}

SDValue AMDGPUTargetLowering::LowerFTRUNC(SDValue Op, SelectionDAG &DAG) const {
  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);

  assert(Op.getValueType() == MVT::f64);

  const SDValue Zero = DAG.getConstant(0, SL, MVT::i32);

  // Extract the upper half, since this is where we will find the sign and
  // exponent.
  SDValue Hi = getHiHalf64(Src, DAG);

  SDValue Exp = extractF64Exponent(Hi, SL, DAG);

  const unsigned FractBits = 52;

  // Extract the sign bit.
  const SDValue SignBitMask = DAG.getConstant(UINT32_C(1) << 31, SL, MVT::i32);
  SDValue SignBit = DAG.getNode(ISD::AND, SL, MVT::i32, Hi, SignBitMask);

  // Extend back to 64-bits.
  SDValue SignBit64 = DAG.getBuildVector(MVT::v2i32, SL, {Zero, SignBit});
  SignBit64 = DAG.getNode(ISD::BITCAST, SL, MVT::i64, SignBit64);

  SDValue BcInt = DAG.getNode(ISD::BITCAST, SL, MVT::i64, Src);
  const SDValue FractMask
    = DAG.getConstant((UINT64_C(1) << FractBits) - 1, SL, MVT::i64);

  SDValue Shr = DAG.getNode(ISD::SRA, SL, MVT::i64, FractMask, Exp);
  SDValue Not = DAG.getNOT(SL, Shr, MVT::i64);
  SDValue Tmp0 = DAG.getNode(ISD::AND, SL, MVT::i64, BcInt, Not);

  EVT SetCCVT =
      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::i32);

  const SDValue FiftyOne = DAG.getConstant(FractBits - 1, SL, MVT::i32);

  SDValue ExpLt0 = DAG.getSetCC(SL, SetCCVT, Exp, Zero, ISD::SETLT);
  SDValue ExpGt51 = DAG.getSetCC(SL, SetCCVT, Exp, FiftyOne, ISD::SETGT);

  SDValue Tmp1 = DAG.getNode(ISD::SELECT, SL, MVT::i64, ExpLt0, SignBit64, Tmp0);
  SDValue Tmp2 = DAG.getNode(ISD::SELECT, SL, MVT::i64, ExpGt51, BcInt, Tmp1);

  return DAG.getNode(ISD::BITCAST, SL, MVT::f64, Tmp2);
}

SDValue AMDGPUTargetLowering::LowerFROUNDEVEN(SDValue Op,
                                              SelectionDAG &DAG) const {
  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);

  assert(Op.getValueType() == MVT::f64);

  APFloat C1Val(APFloat::IEEEdouble(), "0x1.0p+52");
  SDValue C1 = DAG.getConstantFP(C1Val, SL, MVT::f64);
  SDValue CopySign = DAG.getNode(ISD::FCOPYSIGN, SL, MVT::f64, C1, Src);

  // TODO: Should this propagate fast-math-flags?

  SDValue Tmp1 = DAG.getNode(ISD::FADD, SL, MVT::f64, Src, CopySign);
  SDValue Tmp2 = DAG.getNode(ISD::FSUB, SL, MVT::f64, Tmp1, CopySign);

  SDValue Fabs = DAG.getNode(ISD::FABS, SL, MVT::f64, Src);

  APFloat C2Val(APFloat::IEEEdouble(), "0x1.fffffffffffffp+51");
  SDValue C2 = DAG.getConstantFP(C2Val, SL, MVT::f64);

  EVT SetCCVT =
      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::f64);
  SDValue Cond = DAG.getSetCC(SL, SetCCVT, Fabs, C2, ISD::SETOGT);

  return DAG.getSelect(SL, MVT::f64, Cond, Src, Tmp2);
}

SDValue AMDGPUTargetLowering::LowerFNEARBYINT(SDValue Op,
                                              SelectionDAG &DAG) const {
  // FNEARBYINT and FRINT are the same, except in their handling of FP
  // exceptions. Those aren't really meaningful for us, and OpenCL only has
  // rint, so just treat them as equivalent.
  return DAG.getNode(ISD::FROUNDEVEN, SDLoc(Op), Op.getValueType(),
                     Op.getOperand(0));
}

SDValue AMDGPUTargetLowering::LowerFRINT(SDValue Op, SelectionDAG &DAG) const {
  auto VT = Op.getValueType();
  auto Arg = Op.getOperand(0u);
  return DAG.getNode(ISD::FROUNDEVEN, SDLoc(Op), VT, Arg);
}

// XXX - May require not supporting f32 denormals?

// Don't handle v2f16. The extra instructions to scalarize and repack around the
// compare and vselect end up producing worse code than scalarizing the whole
// operation.
SDValue AMDGPUTargetLowering::LowerFROUND(SDValue Op, SelectionDAG &DAG) const {
  SDLoc SL(Op);
  SDValue X = Op.getOperand(0);
  EVT VT = Op.getValueType();

  SDValue T = DAG.getNode(ISD::FTRUNC, SL, VT, X);

  // TODO: Should this propagate fast-math-flags?

  SDValue Diff = DAG.getNode(ISD::FSUB, SL, VT, X, T);

  SDValue AbsDiff = DAG.getNode(ISD::FABS, SL, VT, Diff);

  const SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
  const SDValue One = DAG.getConstantFP(1.0, SL, VT);

  EVT SetCCVT =
      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);

  const SDValue Half = DAG.getConstantFP(0.5, SL, VT);
  SDValue Cmp = DAG.getSetCC(SL, SetCCVT, AbsDiff, Half, ISD::SETOGE);
  SDValue OneOrZeroFP = DAG.getNode(ISD::SELECT, SL, VT, Cmp, One, Zero);

  SDValue SignedOffset = DAG.getNode(ISD::FCOPYSIGN, SL, VT, OneOrZeroFP, X);
  return DAG.getNode(ISD::FADD, SL, VT, T, SignedOffset);
}

SDValue AMDGPUTargetLowering::LowerFFLOOR(SDValue Op, SelectionDAG &DAG) const {
  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);

  // result = trunc(src);
  // if (src < 0.0 && src != result)
  //   result += -1.0.

  SDValue Trunc = DAG.getNode(ISD::FTRUNC, SL, MVT::f64, Src);

  const SDValue Zero = DAG.getConstantFP(0.0, SL, MVT::f64);
  const SDValue NegOne = DAG.getConstantFP(-1.0, SL, MVT::f64);

  EVT SetCCVT =
      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), MVT::f64);

  SDValue Lt0 = DAG.getSetCC(SL, SetCCVT, Src, Zero, ISD::SETOLT);
  SDValue NeTrunc = DAG.getSetCC(SL, SetCCVT, Src, Trunc, ISD::SETONE);
  SDValue And = DAG.getNode(ISD::AND, SL, SetCCVT, Lt0, NeTrunc);

  SDValue Add = DAG.getNode(ISD::SELECT, SL, MVT::f64, And, NegOne, Zero);
  // TODO: Should this propagate fast-math-flags?
  return DAG.getNode(ISD::FADD, SL, MVT::f64, Trunc, Add);
}

/// Return true if it's known that \p Src can never be an f32 denormal value.
static bool valueIsKnownNeverF32Denorm(SDValue Src) {
  switch (Src.getOpcode()) {
  case ISD::FP_EXTEND:
    return Src.getOperand(0).getValueType() == MVT::f16;
  case ISD::FP16_TO_FP:
  case ISD::FFREXP:
  case ISD::FSQRT:
  case AMDGPUISD::LOG:
  case AMDGPUISD::EXP:
    return true;
  case ISD::INTRINSIC_WO_CHAIN: {
    unsigned IntrinsicID = Src.getConstantOperandVal(0);
    switch (IntrinsicID) {
    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:
      return false;
    }
  }
  default:
    return false;
  }

  llvm_unreachable("covered opcode switch");
}

bool AMDGPUTargetLowering::allowApproxFunc(const SelectionDAG &DAG,
                                           SDNodeFlags Flags) {
  return Flags.hasApproximateFuncs();
}

bool AMDGPUTargetLowering::needsDenormHandlingF32(const SelectionDAG &DAG,
                                                  SDValue Src,
                                                  SDNodeFlags Flags) {
  return !valueIsKnownNeverF32Denorm(Src) &&
         DAG.getMachineFunction()
                 .getDenormalMode(APFloat::IEEEsingle())
                 .Input != DenormalMode::PreserveSign;
}

SDValue AMDGPUTargetLowering::getIsLtSmallestNormal(SelectionDAG &DAG,
                                                    SDValue Src,
                                                    SDNodeFlags Flags) const {
  SDLoc SL(Src);
  EVT VT = Src.getValueType();
  const fltSemantics &Semantics = VT.getFltSemantics();
  SDValue SmallestNormal =
      DAG.getConstantFP(APFloat::getSmallestNormalized(Semantics), SL, VT);

  // Want to scale denormals up, but negatives and 0 work just as well on the
  // scaled path.
  SDValue IsLtSmallestNormal = DAG.getSetCC(
      SL, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT), Src,
      SmallestNormal, ISD::SETOLT);

  return IsLtSmallestNormal;
}

SDValue AMDGPUTargetLowering::getIsFinite(SelectionDAG &DAG, SDValue Src,
                                          SDNodeFlags Flags) const {
  SDLoc SL(Src);
  EVT VT = Src.getValueType();
  const fltSemantics &Semantics = VT.getFltSemantics();
  SDValue Inf = DAG.getConstantFP(APFloat::getInf(Semantics), SL, VT);

  SDValue Fabs = DAG.getNode(ISD::FABS, SL, VT, Src, Flags);
  SDValue IsFinite = DAG.getSetCC(
      SL, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT), Fabs,
      Inf, ISD::SETOLT);
  return IsFinite;
}

/// If denormal handling is required return the scaled input to FLOG2, and the
/// check for denormal range. Otherwise, return null values.
std::pair<SDValue, SDValue>
AMDGPUTargetLowering::getScaledLogInput(SelectionDAG &DAG, const SDLoc SL,
                                        SDValue Src, SDNodeFlags Flags) const {
  if (!needsDenormHandlingF32(DAG, Src, Flags))
    return {};

  MVT VT = MVT::f32;
  const fltSemantics &Semantics = APFloat::IEEEsingle();
  SDValue SmallestNormal =
      DAG.getConstantFP(APFloat::getSmallestNormalized(Semantics), SL, VT);

  SDValue IsLtSmallestNormal = DAG.getSetCC(
      SL, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT), Src,
      SmallestNormal, ISD::SETOLT);

  SDValue Scale32 = DAG.getConstantFP(0x1.0p+32, SL, VT);
  SDValue One = DAG.getConstantFP(1.0, SL, VT);
  SDValue ScaleFactor =
      DAG.getNode(ISD::SELECT, SL, VT, IsLtSmallestNormal, Scale32, One, Flags);

  SDValue ScaledInput = DAG.getNode(ISD::FMUL, SL, VT, Src, ScaleFactor, Flags);
  return {ScaledInput, IsLtSmallestNormal};
}

SDValue AMDGPUTargetLowering::LowerFLOG2(SDValue Op, SelectionDAG &DAG) 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)

  SDLoc SL(Op);
  EVT VT = Op.getValueType();
  SDValue Src = Op.getOperand(0);
  SDNodeFlags Flags = Op->getFlags();

  if (VT == MVT::f16) {
    // Nothing in half is a denormal when promoted to f32.
    assert(!isTypeLegal(VT));
    SDValue Ext = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, Src, Flags);
    SDValue Log = DAG.getNode(AMDGPUISD::LOG, SL, MVT::f32, Ext, Flags);
    return DAG.getNode(ISD::FP_ROUND, SL, VT, Log,
                       DAG.getTargetConstant(0, SL, MVT::i32), Flags);
  }

  auto [ScaledInput, IsLtSmallestNormal] =
      getScaledLogInput(DAG, SL, Src, Flags);
  if (!ScaledInput)
    return DAG.getNode(AMDGPUISD::LOG, SL, VT, Src, Flags);

  SDValue Log2 = DAG.getNode(AMDGPUISD::LOG, SL, VT, ScaledInput, Flags);

  SDValue ThirtyTwo = DAG.getConstantFP(32.0, SL, VT);
  SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
  SDValue ResultOffset =
      DAG.getNode(ISD::SELECT, SL, VT, IsLtSmallestNormal, ThirtyTwo, Zero);
  return DAG.getNode(ISD::FSUB, SL, VT, Log2, ResultOffset, Flags);
}

static SDValue getMad(SelectionDAG &DAG, const SDLoc &SL, EVT VT, SDValue X,
                      SDValue Y, SDValue C, SDNodeFlags Flags = SDNodeFlags()) {
  SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, X, Y, Flags);
  return DAG.getNode(ISD::FADD, SL, VT, Mul, C, Flags);
}

SDValue AMDGPUTargetLowering::LowerFLOGCommon(SDValue Op,
                                              SelectionDAG &DAG) const {
  SDValue X = Op.getOperand(0);
  EVT VT = Op.getValueType();
  SDNodeFlags Flags = Op->getFlags();
  SDLoc DL(Op);
  const bool IsLog10 = Op.getOpcode() == ISD::FLOG10;
  assert(IsLog10 || Op.getOpcode() == ISD::FLOG);

  if (VT == MVT::f16 || Flags.hasApproximateFuncs()) {
    // TODO: The direct f16 path is 1.79 ulp for f16. This should be used
    // depending on !fpmath metadata.

    bool PromoteToF32 = VT == MVT::f16 && (!Flags.hasApproximateFuncs() ||
                                           !isTypeLegal(MVT::f16));

    if (PromoteToF32) {
      // Log and multiply in f32 is always good enough for f16.
      X = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, X, Flags);
    }

    SDValue Lowered = LowerFLOGUnsafe(X, DL, DAG, IsLog10, Flags);
    if (PromoteToF32) {
      return DAG.getNode(ISD::FP_ROUND, DL, VT, Lowered,
                         DAG.getTargetConstant(0, DL, MVT::i32), Flags);
    }

    return Lowered;
  }

  SDValue ScaledInput, IsScaled;
  if (VT == MVT::f16)
    X = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, X, Flags);
  else {
    std::tie(ScaledInput, IsScaled) = getScaledLogInput(DAG, DL, X, Flags);
    if (ScaledInput)
      X = ScaledInput;
  }

  SDValue Y = DAG.getNode(AMDGPUISD::LOG, DL, VT, X, Flags);

  SDValue R;
  if (Subtarget->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;

    SDValue C = DAG.getConstantFP(IsLog10 ? c_log10 : c_log, DL, VT);
    SDValue CC = DAG.getConstantFP(IsLog10 ? cc_log10 : cc_log, DL, VT);
    // This adds correction terms for which contraction may lead to an increase
    // in the error of the approximation, so disable it.
    Flags.setAllowContract(false);
    R = DAG.getNode(ISD::FMUL, DL, VT, Y, C, Flags);
    SDValue NegR = DAG.getNode(ISD::FNEG, DL, VT, R, Flags);
    SDValue FMA0 = DAG.getNode(ISD::FMA, DL, VT, Y, C, NegR, Flags);
    SDValue FMA1 = DAG.getNode(ISD::FMA, DL, VT, Y, CC, FMA0, Flags);
    R = DAG.getNode(ISD::FADD, DL, VT, R, FMA1, Flags);
  } 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;

    SDValue CH = DAG.getConstantFP(IsLog10 ? ch_log10 : ch_log, DL, VT);
    SDValue CT = DAG.getConstantFP(IsLog10 ? ct_log10 : ct_log, DL, VT);

    SDValue YAsInt = DAG.getNode(ISD::BITCAST, DL, MVT::i32, Y);
    SDValue MaskConst = DAG.getConstant(0xfffff000, DL, MVT::i32);
    SDValue YHInt = DAG.getNode(ISD::AND, DL, MVT::i32, YAsInt, MaskConst);
    SDValue YH = DAG.getNode(ISD::BITCAST, DL, MVT::f32, YHInt);
    SDValue YT = DAG.getNode(ISD::FSUB, DL, VT, Y, YH, Flags);
    // This adds correction terms for which contraction may lead to an increase
    // in the error of the approximation, so disable it.
    Flags.setAllowContract(false);
    SDValue YTCT = DAG.getNode(ISD::FMUL, DL, VT, YT, CT, Flags);
    SDValue Mad0 = getMad(DAG, DL, VT, YH, CT, YTCT, Flags);
    SDValue Mad1 = getMad(DAG, DL, VT, YT, CH, Mad0, Flags);
    R = getMad(DAG, DL, VT, YH, CH, Mad1);
  }

  const bool IsFiniteOnly = Flags.hasNoNaNs() && Flags.hasNoInfs();

  // TODO: Check if known finite from source value.
  if (!IsFiniteOnly) {
    SDValue IsFinite = getIsFinite(DAG, Y, Flags);
    R = DAG.getNode(ISD::SELECT, DL, VT, IsFinite, R, Y, Flags);
  }

  if (IsScaled) {
    SDValue Zero = DAG.getConstantFP(0.0f, DL, VT);
    SDValue ShiftK =
        DAG.getConstantFP(IsLog10 ? 0x1.344136p+3f : 0x1.62e430p+4f, DL, VT);
    SDValue Shift =
        DAG.getNode(ISD::SELECT, DL, VT, IsScaled, ShiftK, Zero, Flags);
    R = DAG.getNode(ISD::FSUB, DL, VT, R, Shift, Flags);
  }

  return R;
}

SDValue AMDGPUTargetLowering::LowerFLOG10(SDValue Op, SelectionDAG &DAG) const {
  return LowerFLOGCommon(Op, DAG);
}

// Do f32 fast math expansion for flog2 or flog10. This is accurate enough for a
// promote f16 operation.
SDValue AMDGPUTargetLowering::LowerFLOGUnsafe(SDValue Src, const SDLoc &SL,
                                              SelectionDAG &DAG, bool IsLog10,
                                              SDNodeFlags Flags) const {
  EVT VT = Src.getValueType();
  unsigned LogOp =
      VT == MVT::f32 ? (unsigned)AMDGPUISD::LOG : (unsigned)ISD::FLOG2;

  double Log2BaseInverted =
      IsLog10 ? numbers::ln2 / numbers::ln10 : numbers::ln2;

  if (VT == MVT::f32) {
    auto [ScaledInput, IsScaled] = getScaledLogInput(DAG, SL, Src, Flags);
    if (ScaledInput) {
      SDValue LogSrc = DAG.getNode(AMDGPUISD::LOG, SL, VT, ScaledInput, Flags);
      SDValue ScaledResultOffset =
          DAG.getConstantFP(-32.0 * Log2BaseInverted, SL, VT);

      SDValue Zero = DAG.getConstantFP(0.0f, SL, VT);

      SDValue ResultOffset = DAG.getNode(ISD::SELECT, SL, VT, IsScaled,
                                         ScaledResultOffset, Zero, Flags);

      SDValue Log2Inv = DAG.getConstantFP(Log2BaseInverted, SL, VT);

      if (Subtarget->hasFastFMAF32())
        return DAG.getNode(ISD::FMA, SL, VT, LogSrc, Log2Inv, ResultOffset,
                           Flags);
      SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, LogSrc, Log2Inv, Flags);
      return DAG.getNode(ISD::FADD, SL, VT, Mul, ResultOffset);
    }
  }

  SDValue Log2Operand = DAG.getNode(LogOp, SL, VT, Src, Flags);
  SDValue Log2BaseInvertedOperand = DAG.getConstantFP(Log2BaseInverted, SL, VT);

  return DAG.getNode(ISD::FMUL, SL, VT, Log2Operand, Log2BaseInvertedOperand,
                     Flags);
}

// This expansion gives a result slightly better than 1ulp.
SDValue AMDGPUTargetLowering::lowerFEXPF64(SDValue Op,
                                           SelectionDAG &DAG) const {
  SDLoc DL(Op);
  SDValue X = Op.getOperand(0);

  // TODO: Check if reassoc is safe. There is an output change in exp2 and
  // exp10, which slightly increases ulp.
  SDNodeFlags Flags = Op->getFlags() & ~SDNodeFlags::AllowReassociation;

  SDValue DN, F, T;

  if (Op.getOpcode() == ISD::FEXP2) {
    // dn = rint(x)
    DN = DAG.getNode(ISD::FRINT, DL, MVT::f64, X, Flags);
    // f = x - dn
    F = DAG.getNode(ISD::FSUB, DL, MVT::f64, X, DN, Flags);
    // t = f*C1 + f*C2
    SDValue C1 = DAG.getConstantFP(0x1.62e42fefa39efp-1, DL, MVT::f64);
    SDValue C2 = DAG.getConstantFP(0x1.abc9e3b39803fp-56, DL, MVT::f64);
    SDValue Mul2 = DAG.getNode(ISD::FMUL, DL, MVT::f64, F, C2, Flags);
    T = DAG.getNode(ISD::FMA, DL, MVT::f64, F, C1, Mul2, Flags);
  } else if (Op.getOpcode() == ISD::FEXP10) {
    // dn = rint(x * C1)
    SDValue C1 = DAG.getConstantFP(0x1.a934f0979a371p+1, DL, MVT::f64);
    SDValue Mul = DAG.getNode(ISD::FMUL, DL, MVT::f64, X, C1, Flags);
    DN = DAG.getNode(ISD::FRINT, DL, MVT::f64, Mul, Flags);

    // f = FMA(-dn, C2, FMA(-dn, C3, x))
    SDValue NegDN = DAG.getNode(ISD::FNEG, DL, MVT::f64, DN, Flags);
    SDValue C2 = DAG.getConstantFP(-0x1.9dc1da994fd21p-59, DL, MVT::f64);
    SDValue C3 = DAG.getConstantFP(0x1.34413509f79ffp-2, DL, MVT::f64);
    SDValue Inner = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C3, X, Flags);
    F = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C2, Inner, Flags);

    // t = FMA(f, C4, f*C5)
    SDValue C4 = DAG.getConstantFP(0x1.26bb1bbb55516p+1, DL, MVT::f64);
    SDValue C5 = DAG.getConstantFP(-0x1.f48ad494ea3e9p-53, DL, MVT::f64);
    SDValue MulF = DAG.getNode(ISD::FMUL, DL, MVT::f64, F, C5, Flags);
    T = DAG.getNode(ISD::FMA, DL, MVT::f64, F, C4, MulF, Flags);
  } else { // ISD::FEXP
    // dn = rint(x * C1)
    SDValue C1 = DAG.getConstantFP(0x1.71547652b82fep+0, DL, MVT::f64);
    SDValue Mul = DAG.getNode(ISD::FMUL, DL, MVT::f64, X, C1, Flags);
    DN = DAG.getNode(ISD::FRINT, DL, MVT::f64, Mul, Flags);

    // t = FMA(-dn, C2, FMA(-dn, C3, x))
    SDValue NegDN = DAG.getNode(ISD::FNEG, DL, MVT::f64, DN, Flags);
    SDValue C2 = DAG.getConstantFP(0x1.abc9e3b39803fp-56, DL, MVT::f64);
    SDValue C3 = DAG.getConstantFP(0x1.62e42fefa39efp-1, DL, MVT::f64);
    SDValue Inner = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C3, X, Flags);
    T = DAG.getNode(ISD::FMA, DL, MVT::f64, NegDN, C2, Inner, Flags);
  }

  // Polynomial expansion for p
  SDValue P = DAG.getConstantFP(0x1.ade156a5dcb37p-26, DL, MVT::f64);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
                  DAG.getConstantFP(0x1.28af3fca7ab0cp-22, DL, MVT::f64),
                  Flags);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
                  DAG.getConstantFP(0x1.71dee623fde64p-19, DL, MVT::f64),
                  Flags);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
                  DAG.getConstantFP(0x1.a01997c89e6b0p-16, DL, MVT::f64),
                  Flags);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
                  DAG.getConstantFP(0x1.a01a014761f6ep-13, DL, MVT::f64),
                  Flags);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
                  DAG.getConstantFP(0x1.6c16c1852b7b0p-10, DL, MVT::f64),
                  Flags);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
                  DAG.getConstantFP(0x1.1111111122322p-7, DL, MVT::f64), Flags);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
                  DAG.getConstantFP(0x1.55555555502a1p-5, DL, MVT::f64), Flags);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
                  DAG.getConstantFP(0x1.5555555555511p-3, DL, MVT::f64), Flags);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P,
                  DAG.getConstantFP(0x1.000000000000bp-1, DL, MVT::f64), Flags);

  SDValue One = DAG.getConstantFP(1.0, DL, MVT::f64);

  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P, One, Flags);
  P = DAG.getNode(ISD::FMA, DL, MVT::f64, T, P, One, Flags);

  // z = ldexp(p, (int)dn)
  SDValue DNInt = DAG.getNode(ISD::FP_TO_SINT, DL, MVT::i32, DN);
  SDValue Z = DAG.getNode(ISD::FLDEXP, DL, MVT::f64, P, DNInt, Flags);

  // Overflow/underflow guards
  SDValue CondHi = DAG.getSetCC(
      DL, MVT::i1, X, DAG.getConstantFP(1024.0, DL, MVT::f64), ISD::SETULE);

  if (!Flags.hasNoInfs()) {
    SDValue PInf = DAG.getConstantFP(std::numeric_limits<double>::infinity(),
                                     DL, MVT::f64);
    Z = DAG.getSelect(DL, MVT::f64, CondHi, Z, PInf, Flags);
  }

  SDValue CondLo = DAG.getSetCC(
      DL, MVT::i1, X, DAG.getConstantFP(-1075.0, DL, MVT::f64), ISD::SETUGE);
  SDValue Zero = DAG.getConstantFP(0.0, DL, MVT::f64);
  Z = DAG.getSelect(DL, MVT::f64, CondLo, Z, Zero, Flags);

  return Z;
}

SDValue AMDGPUTargetLowering::lowerFEXP2(SDValue Op, SelectionDAG &DAG) 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.

  EVT VT = Op.getValueType();
  if (VT == MVT::f64)
    return lowerFEXPF64(Op, DAG);

  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);
  SDNodeFlags Flags = Op->getFlags();

  if (VT == MVT::f16) {
    // Nothing in half is a denormal when promoted to f32.
    assert(!isTypeLegal(MVT::f16));
    SDValue Ext = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, Src, Flags);
    SDValue Log = DAG.getNode(AMDGPUISD::EXP, SL, MVT::f32, Ext, Flags);
    return DAG.getNode(ISD::FP_ROUND, SL, VT, Log,
                       DAG.getTargetConstant(0, SL, MVT::i32), Flags);
  }

  assert(VT == MVT::f32);

  if (!needsDenormHandlingF32(DAG, Src, Flags))
    return DAG.getNode(AMDGPUISD::EXP, SL, MVT::f32, Src, Flags);

  // 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)
  SDValue RangeCheckConst = DAG.getConstantFP(-0x1.f80000p+6f, SL, VT);

  EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);

  SDValue NeedsScaling =
      DAG.getSetCC(SL, SetCCVT, Src, RangeCheckConst, ISD::SETOLT);

  SDValue SixtyFour = DAG.getConstantFP(0x1.0p+6f, SL, VT);
  SDValue Zero = DAG.getConstantFP(0.0, SL, VT);

  SDValue AddOffset =
      DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, SixtyFour, Zero);

  SDValue AddInput = DAG.getNode(ISD::FADD, SL, VT, Src, AddOffset, Flags);
  SDValue Exp2 = DAG.getNode(AMDGPUISD::EXP, SL, VT, AddInput, Flags);

  SDValue TwoExpNeg64 = DAG.getConstantFP(0x1.0p-64f, SL, VT);
  SDValue One = DAG.getConstantFP(1.0, SL, VT);
  SDValue ResultScale =
      DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, TwoExpNeg64, One);

  return DAG.getNode(ISD::FMUL, SL, VT, Exp2, ResultScale, Flags);
}

SDValue AMDGPUTargetLowering::lowerFEXPUnsafeImpl(SDValue X, const SDLoc &SL,
                                                  SelectionDAG &DAG,
                                                  SDNodeFlags Flags,
                                                  bool IsExp10) const {
  // exp(x) -> exp2(M_LOG2E_F * x);
  // exp10(x) -> exp2(log2(10) * x);
  EVT VT = X.getValueType();
  SDValue Const =
      DAG.getConstantFP(IsExp10 ? 0x1.a934f0p+1f : numbers::log2e, SL, VT);

  SDValue Mul = DAG.getNode(ISD::FMUL, SL, VT, X, Const, Flags);
  return DAG.getNode(VT == MVT::f32 ? (unsigned)AMDGPUISD::EXP
                                    : (unsigned)ISD::FEXP2,
                     SL, VT, Mul, Flags);
}

SDValue AMDGPUTargetLowering::lowerFEXPUnsafe(SDValue X, const SDLoc &SL,
                                              SelectionDAG &DAG,
                                              SDNodeFlags Flags) const {
  EVT VT = X.getValueType();
  if (VT != MVT::f32 || !needsDenormHandlingF32(DAG, X, Flags))
    return lowerFEXPUnsafeImpl(X, SL, DAG, Flags, /*IsExp10=*/false);

  EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);

  SDValue Threshold = DAG.getConstantFP(-0x1.5d58a0p+6f, SL, VT);
  SDValue NeedsScaling = DAG.getSetCC(SL, SetCCVT, X, Threshold, ISD::SETOLT);

  SDValue ScaleOffset = DAG.getConstantFP(0x1.0p+6f, SL, VT);

  SDValue ScaledX = DAG.getNode(ISD::FADD, SL, VT, X, ScaleOffset, Flags);

  SDValue AdjustedX =
      DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, ScaledX, X);

  const SDValue Log2E = DAG.getConstantFP(numbers::log2e, SL, VT);
  SDValue ExpInput = DAG.getNode(ISD::FMUL, SL, VT, AdjustedX, Log2E, Flags);

  SDValue Exp2 = DAG.getNode(AMDGPUISD::EXP, SL, VT, ExpInput, Flags);

  SDValue ResultScaleFactor = DAG.getConstantFP(0x1.969d48p-93f, SL, VT);
  SDValue AdjustedResult =
      DAG.getNode(ISD::FMUL, SL, VT, Exp2, ResultScaleFactor, Flags);

  return DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, AdjustedResult, Exp2,
                     Flags);
}

/// Emit approx-funcs appropriate lowering for exp10. inf/nan should still be
/// handled correctly.
SDValue AMDGPUTargetLowering::lowerFEXP10Unsafe(SDValue X, const SDLoc &SL,
                                                SelectionDAG &DAG,
                                                SDNodeFlags Flags) const {
  const EVT VT = X.getValueType();

  const unsigned Exp2Op = VT == MVT::f32 ? static_cast<unsigned>(AMDGPUISD::EXP)
                                         : static_cast<unsigned>(ISD::FEXP2);

  if (VT != MVT::f32 || !needsDenormHandlingF32(DAG, X, Flags)) {
    // exp2(x * 0x1.a92000p+1f) * exp2(x * 0x1.4f0978p-11f);
    SDValue K0 = DAG.getConstantFP(0x1.a92000p+1f, SL, VT);
    SDValue K1 = DAG.getConstantFP(0x1.4f0978p-11f, SL, VT);

    SDValue Mul0 = DAG.getNode(ISD::FMUL, SL, VT, X, K0, Flags);
    SDValue Exp2_0 = DAG.getNode(Exp2Op, SL, VT, Mul0, Flags);
    SDValue Mul1 = DAG.getNode(ISD::FMUL, SL, VT, X, K1, Flags);
    SDValue Exp2_1 = DAG.getNode(Exp2Op, SL, VT, Mul1, Flags);
    return DAG.getNode(ISD::FMUL, SL, VT, Exp2_0, Exp2_1);
  }

  // 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);

  EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);

  SDValue Threshold = DAG.getConstantFP(-0x1.2f7030p+5f, SL, VT);
  SDValue NeedsScaling = DAG.getSetCC(SL, SetCCVT, X, Threshold, ISD::SETOLT);

  SDValue ScaleOffset = DAG.getConstantFP(0x1.0p+5f, SL, VT);
  SDValue ScaledX = DAG.getNode(ISD::FADD, SL, VT, X, ScaleOffset, Flags);
  SDValue AdjustedX =
      DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, ScaledX, X);

  SDValue K0 = DAG.getConstantFP(0x1.a92000p+1f, SL, VT);
  SDValue K1 = DAG.getConstantFP(0x1.4f0978p-11f, SL, VT);

  SDValue Mul0 = DAG.getNode(ISD::FMUL, SL, VT, AdjustedX, K0, Flags);
  SDValue Exp2_0 = DAG.getNode(Exp2Op, SL, VT, Mul0, Flags);
  SDValue Mul1 = DAG.getNode(ISD::FMUL, SL, VT, AdjustedX, K1, Flags);
  SDValue Exp2_1 = DAG.getNode(Exp2Op, SL, VT, Mul1, Flags);

  SDValue MulExps = DAG.getNode(ISD::FMUL, SL, VT, Exp2_0, Exp2_1, Flags);

  SDValue ResultScaleFactor = DAG.getConstantFP(0x1.9f623ep-107f, SL, VT);
  SDValue AdjustedResult =
      DAG.getNode(ISD::FMUL, SL, VT, MulExps, ResultScaleFactor, Flags);

  return DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, AdjustedResult, MulExps,
                     Flags);
}

SDValue AMDGPUTargetLowering::lowerFEXP(SDValue Op, SelectionDAG &DAG) const {
  EVT VT = Op.getValueType();

  if (VT == MVT::f64)
    return lowerFEXPF64(Op, DAG);

  SDLoc SL(Op);
  SDValue X = Op.getOperand(0);
  SDNodeFlags Flags = Op->getFlags();
  const bool IsExp10 = Op.getOpcode() == ISD::FEXP10;

  // TODO: Interpret allowApproxFunc as ignoring DAZ. This is currently copying
  // library behavior. Also, is known-not-daz source sufficient?
  if (allowApproxFunc(DAG, Flags)) { // TODO: Does this really require fast?
    return IsExp10 ? lowerFEXP10Unsafe(X, SL, DAG, Flags)
                   : lowerFEXPUnsafe(X, SL, DAG, Flags);
  }

  if (VT.getScalarType() == MVT::f16) {
    if (VT.isVector())
      return SDValue();

    // 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)))
    SDValue Ext = DAG.getNode(ISD::FP_EXTEND, SL, MVT::f32, X, Flags);
    SDValue Lowered = lowerFEXPUnsafeImpl(Ext, SL, DAG, Flags, IsExp10);
    return DAG.getNode(ISD::FP_ROUND, SL, VT, Lowered,
                       DAG.getTargetConstant(0, SL, MVT::i32), Flags);
  }

  assert(VT == MVT::f32);

  //    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)) )
  SDNodeFlags FlagsNoContract = Flags;
  FlagsNoContract.setAllowContract(false);

  SDValue PH, PL;
  if (Subtarget->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;

    SDValue C = DAG.getConstantFP(IsExp10 ? c_exp10 : c_exp, SL, VT);
    SDValue CC = DAG.getConstantFP(IsExp10 ? cc_exp10 : cc_exp, SL, VT);

    PH = DAG.getNode(ISD::FMUL, SL, VT, X, C, Flags);
    SDValue NegPH = DAG.getNode(ISD::FNEG, SL, VT, PH, Flags);
    SDValue FMA0 = DAG.getNode(ISD::FMA, SL, VT, X, C, NegPH, Flags);
    PL = DAG.getNode(ISD::FMA, SL, VT, X, CC, FMA0, Flags);
  } 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;

    SDValue CH = DAG.getConstantFP(IsExp10 ? ch_exp10 : ch_exp, SL, VT);
    SDValue CL = DAG.getConstantFP(IsExp10 ? cl_exp10 : cl_exp, SL, VT);

    SDValue XAsInt = DAG.getNode(ISD::BITCAST, SL, MVT::i32, X);
    SDValue MaskConst = DAG.getConstant(0xfffff000, SL, MVT::i32);
    SDValue XHAsInt = DAG.getNode(ISD::AND, SL, MVT::i32, XAsInt, MaskConst);
    SDValue XH = DAG.getNode(ISD::BITCAST, SL, VT, XHAsInt);
    SDValue XL = DAG.getNode(ISD::FSUB, SL, VT, X, XH, Flags);

    PH = DAG.getNode(ISD::FMUL, SL, VT, XH, CH, Flags);

    SDValue XLCL = DAG.getNode(ISD::FMUL, SL, VT, XL, CL, Flags);
    SDValue Mad0 = getMad(DAG, SL, VT, XL, CH, XLCL, Flags);
    PL = getMad(DAG, SL, VT, XH, CL, Mad0, Flags);
  }

  SDValue E = DAG.getNode(ISD::FROUNDEVEN, SL, VT, PH, Flags);

  // It is unsafe to contract this fsub into the PH multiply.
  SDValue PHSubE = DAG.getNode(ISD::FSUB, SL, VT, PH, E, FlagsNoContract);

  SDValue A = DAG.getNode(ISD::FADD, SL, VT, PHSubE, PL, Flags);
  SDValue IntE = DAG.getNode(ISD::FP_TO_SINT, SL, MVT::i32, E);
  SDValue Exp2 = DAG.getNode(AMDGPUISD::EXP, SL, VT, A, Flags);

  SDValue R = DAG.getNode(ISD::FLDEXP, SL, VT, Exp2, IntE, Flags);

  SDValue UnderflowCheckConst =
      DAG.getConstantFP(IsExp10 ? -0x1.66d3e8p+5f : -0x1.9d1da0p+6f, SL, VT);

  EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
  SDValue Zero = DAG.getConstantFP(0.0, SL, VT);
  SDValue Underflow =
      DAG.getSetCC(SL, SetCCVT, X, UnderflowCheckConst, ISD::SETOLT);

  R = DAG.getNode(ISD::SELECT, SL, VT, Underflow, Zero, R);

  if (!Flags.hasNoInfs()) {
    SDValue OverflowCheckConst =
        DAG.getConstantFP(IsExp10 ? 0x1.344136p+5f : 0x1.62e430p+6f, SL, VT);
    SDValue Overflow =
        DAG.getSetCC(SL, SetCCVT, X, OverflowCheckConst, ISD::SETOGT);
    SDValue Inf =
        DAG.getConstantFP(APFloat::getInf(APFloat::IEEEsingle()), SL, VT);
    R = DAG.getNode(ISD::SELECT, SL, VT, Overflow, Inf, R);
  }

  return R;
}

static bool isCtlzOpc(unsigned Opc) {
  return Opc == ISD::CTLZ || Opc == ISD::CTLZ_ZERO_POISON;
}

static bool isCttzOpc(unsigned Opc) {
  return Opc == ISD::CTTZ || Opc == ISD::CTTZ_ZERO_POISON;
}

SDValue AMDGPUTargetLowering::lowerCTLZResults(SDValue Op,
                                               SelectionDAG &DAG) const {
  auto SL = SDLoc(Op);
  auto Opc = Op.getOpcode();
  auto Arg = Op.getOperand(0u);
  auto ResultVT = Op.getValueType();

  if (ResultVT != MVT::i8 && ResultVT != MVT::i16)
    return {};

  assert(isCtlzOpc(Opc));
  assert(ResultVT == Arg.getValueType());

  const uint64_t NumBits = ResultVT.getFixedSizeInBits();
  SDValue NumExtBits = DAG.getConstant(32u - NumBits, SL, MVT::i32);
  SDValue NewOp;

  if (Opc == ISD::CTLZ_ZERO_POISON) {
    NewOp = DAG.getNode(ISD::ANY_EXTEND, SL, MVT::i32, Arg);
    NewOp = DAG.getNode(ISD::SHL, SL, MVT::i32, NewOp, NumExtBits);
    NewOp = DAG.getNode(Opc, SL, MVT::i32, NewOp);
  } else {
    NewOp = DAG.getNode(ISD::ZERO_EXTEND, SL, MVT::i32, Arg);
    NewOp = DAG.getNode(Opc, SL, MVT::i32, NewOp);
    NewOp = DAG.getNode(ISD::SUB, SL, MVT::i32, NewOp, NumExtBits);
  }

  return DAG.getNode(ISD::TRUNCATE, SL, ResultVT, NewOp);
}

SDValue AMDGPUTargetLowering::LowerCTLZ_CTTZ(SDValue Op, SelectionDAG &DAG) const {
  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);

  assert(isCtlzOpc(Op.getOpcode()) || isCttzOpc(Op.getOpcode()));
  bool Ctlz = isCtlzOpc(Op.getOpcode());
  unsigned NewOpc = Ctlz ? AMDGPUISD::FFBH_U32 : AMDGPUISD::FFBL_B32;

  bool ZeroUndef = Op.getOpcode() == ISD::CTLZ_ZERO_POISON ||
                   Op.getOpcode() == ISD::CTTZ_ZERO_POISON;
  bool Is64BitScalar = !Src->isDivergent() && Src.getValueType() == MVT::i64;

  if (Src.getValueType() == MVT::i32 || Is64BitScalar) {
    // (ctlz hi:lo) -> (umin (ffbh src), 32)
    // (cttz hi:lo) -> (umin (ffbl src), 32)
    // (ctlz_zero_poison src) -> (ffbh src)
    // (cttz_zero_poison src) -> (ffbl src)

    //  64-bit scalar version produce 32-bit result
    // (ctlz hi:lo) -> (umin (S_FLBIT_I32_B64 src), 64)
    // (cttz hi:lo) -> (umin (S_FF1_I32_B64 src), 64)
    // (ctlz_zero_poison src) -> (S_FLBIT_I32_B64 src)
    // (cttz_zero_poison src) -> (S_FF1_I32_B64 src)
    SDValue NewOpr = DAG.getNode(NewOpc, SL, MVT::i32, Src);
    if (!ZeroUndef) {
      const SDValue ConstVal = DAG.getConstant(
          Op.getValueType().getScalarSizeInBits(), SL, MVT::i32);
      NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, NewOpr, ConstVal);
    }
    return DAG.getNode(ISD::ZERO_EXTEND, SL, Src.getValueType(), NewOpr);
  }

  SDValue Lo, Hi;
  std::tie(Lo, Hi) = split64BitValue(Src, DAG);

  SDValue OprLo = DAG.getNode(NewOpc, SL, MVT::i32, Lo);
  SDValue OprHi = DAG.getNode(NewOpc, SL, MVT::i32, Hi);

  // (ctlz hi:lo) -> (umin3 (ffbh hi), (uaddsat (ffbh lo), 32), 64)
  // (cttz hi:lo) -> (umin3 (uaddsat (ffbl hi), 32), (ffbl lo), 64)
  // (ctlz_zero_poison hi:lo) -> (umin (ffbh hi), (add (ffbh lo), 32))
  // (cttz_zero_poison hi:lo) -> (umin (add (ffbl hi), 32), (ffbl lo))

  unsigned AddOpc = ZeroUndef ? ISD::ADD : ISD::UADDSAT;
  const SDValue Const32 = DAG.getConstant(32, SL, MVT::i32);
  if (Ctlz)
    OprLo = DAG.getNode(AddOpc, SL, MVT::i32, OprLo, Const32);
  else
    OprHi = DAG.getNode(AddOpc, SL, MVT::i32, OprHi, Const32);

  SDValue NewOpr;
  NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, OprLo, OprHi);
  if (!ZeroUndef) {
    const SDValue Const64 = DAG.getConstant(64, SL, MVT::i32);
    NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, NewOpr, Const64);
  }

  return DAG.getNode(ISD::ZERO_EXTEND, SL, MVT::i64, NewOpr);
}

SDValue AMDGPUTargetLowering::LowerCTLS(SDValue Op, SelectionDAG &DAG) const {
  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);
  assert(Src.getValueType() == MVT::i32 && "LowerCTLS only supports i32");
  SDValue Ffbh = DAG.getNode(
      ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
      DAG.getTargetConstant(Intrinsic::amdgcn_sffbh, SL, MVT::i32), Src);
  SDValue Clamped = DAG.getNode(ISD::UMIN, SL, MVT::i32, Ffbh,
                                DAG.getConstant(32, SL, MVT::i32));
  return DAG.getNode(ISD::ADD, SL, MVT::i32, Clamped,
                     DAG.getAllOnesConstant(SL, MVT::i32));
}

SDValue AMDGPUTargetLowering::LowerINT_TO_FP16(SDValue Op, SelectionDAG &DAG,
                                               EVT FP16Ty) const {
  assert(FP16Ty == MVT::f16 || FP16Ty == MVT::bf16);
  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);
  SDValue ToF32 = DAG.getNode(Op.getOpcode(), SL, MVT::f32, Src);
  SDValue FPRoundFlag = DAG.getIntPtrConstant(0, SL, /*isTarget=*/true);
  return DAG.getNode(ISD::FP_ROUND, SL, FP16Ty, ToF32, FPRoundFlag);
}

SDValue AMDGPUTargetLowering::LowerINT_TO_FP32(SDValue Op, SelectionDAG &DAG,
                                               bool Signed) const {
  // The regular method converting a 64-bit integer to float roughly consists of
  // 2 steps: normalization and rounding. In fact, after normalization, the
  // conversion from a 64-bit integer to a float is essentially the same as the
  // one from a 32-bit integer. The only difference is that it has more
  // trailing bits to be rounded. To leverage the native 32-bit conversion, a
  // 64-bit integer could be preprocessed and fit into a 32-bit integer then
  // converted into the correct float number. The basic steps for the unsigned
  // conversion are illustrated in the following pseudo code:
  //
  // f32 uitofp(i64 u) {
  //   i32 hi, lo = split(u);
  //   // Only count the leading zeros in hi as we have native support of the
  //   // conversion from i32 to f32. If hi is all 0s, the conversion is
  //   // reduced to a 32-bit one automatically.
  //   i32 shamt = clz(hi); // Return 32 if hi is all 0s.
  //   u <<= shamt;
  //   hi, lo = split(u);
  //   hi |= (lo != 0) ? 1 : 0; // Adjust rounding bit in hi based on lo.
  //   // convert it as a 32-bit integer and scale the result back.
  //   return uitofp(hi) * 2^(32 - shamt);
  // }
  //
  // The signed one follows the same principle but uses 'ffbh_i32' to count its
  // sign bits instead. If 'ffbh_i32' is not available, its absolute value is
  // converted instead followed by negation based its sign bit.

  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);

  SDValue Lo, Hi;
  std::tie(Lo, Hi) = split64BitValue(Src, DAG);
  SDValue Sign;
  SDValue ShAmt;
  if (Signed && Subtarget->isGCN()) {
    // We also need to consider the sign bit in Lo if Hi has just sign bits,
    // i.e. Hi is 0 or -1. However, that only needs to take the MSB into
    // account. That is, the maximal shift is
    // - 32 if Lo and Hi have opposite signs;
    // - 33 if Lo and Hi have the same sign.
    //
    // Or, MaxShAmt = 33 + OppositeSign, where
    //
    // OppositeSign is defined as ((Lo ^ Hi) >> 31), which is
    // - -1 if Lo and Hi have opposite signs; and
    // -  0 otherwise.
    //
    // All in all, ShAmt is calculated as
    //
    //  umin(sffbh(Hi), 33 + (Lo^Hi)>>31) - 1.
    //
    // or
    //
    //  umin(sffbh(Hi) - 1, 32 + (Lo^Hi)>>31).
    //
    // to reduce the critical path.
    SDValue OppositeSign = DAG.getNode(
        ISD::SRA, SL, MVT::i32, DAG.getNode(ISD::XOR, SL, MVT::i32, Lo, Hi),
        DAG.getConstant(31, SL, MVT::i32));
    SDValue MaxShAmt =
        DAG.getNode(ISD::ADD, SL, MVT::i32, DAG.getConstant(32, SL, MVT::i32),
                    OppositeSign);
    // Count the leading sign bits.
    ShAmt = DAG.getNode(
        ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32,
        DAG.getTargetConstant(Intrinsic::amdgcn_sffbh, SL, MVT::i32), Hi);
    // Different from unsigned conversion, the shift should be one bit less to
    // preserve the sign bit.
    ShAmt = DAG.getNode(ISD::SUB, SL, MVT::i32, ShAmt,
                        DAG.getConstant(1, SL, MVT::i32));
    ShAmt = DAG.getNode(ISD::UMIN, SL, MVT::i32, ShAmt, MaxShAmt);
  } else {
    if (Signed) {
      // Without 'ffbh_i32', only leading zeros could be counted. Take the
      // absolute value first.
      Sign = DAG.getNode(ISD::SRA, SL, MVT::i64, Src,
                         DAG.getConstant(63, SL, MVT::i64));
      SDValue Abs =
          DAG.getNode(ISD::XOR, SL, MVT::i64,
                      DAG.getNode(ISD::ADD, SL, MVT::i64, Src, Sign), Sign);
      std::tie(Lo, Hi) = split64BitValue(Abs, DAG);
    }
    // Count the leading zeros.
    ShAmt = DAG.getNode(ISD::CTLZ, SL, MVT::i32, Hi);
    // The shift amount for signed integers is [0, 32].
  }
  // Normalize the given 64-bit integer.
  SDValue Norm = DAG.getNode(ISD::SHL, SL, MVT::i64, Src, ShAmt);
  // Split it again.
  std::tie(Lo, Hi) = split64BitValue(Norm, DAG);
  // Calculate the adjust bit for rounding.
  // (lo != 0) ? 1 : 0 => (lo >= 1) ? 1 : 0 => umin(1, lo)
  SDValue Adjust = DAG.getNode(ISD::UMIN, SL, MVT::i32,
                               DAG.getConstant(1, SL, MVT::i32), Lo);
  // Get the 32-bit normalized integer.
  Norm = DAG.getNode(ISD::OR, SL, MVT::i32, Hi, Adjust);
  // Convert the normalized 32-bit integer into f32.

  bool UseLDEXP = isOperationLegal(ISD::FLDEXP, MVT::f32);
  unsigned Opc = Signed && UseLDEXP ? ISD::SINT_TO_FP : ISD::UINT_TO_FP;
  SDValue FVal = DAG.getNode(Opc, SL, MVT::f32, Norm);

  // Finally, need to scale back the converted floating number as the original
  // 64-bit integer is converted as a 32-bit one.
  ShAmt = DAG.getNode(ISD::SUB, SL, MVT::i32, DAG.getConstant(32, SL, MVT::i32),
                      ShAmt);
  // On GCN, use LDEXP directly.
  if (UseLDEXP)
    return DAG.getNode(ISD::FLDEXP, SL, MVT::f32, FVal, ShAmt);

  // Otherwise, align 'ShAmt' to the exponent part and add it into the exponent
  // part directly to emulate the multiplication of 2^ShAmt. That 8-bit
  // exponent is enough to avoid overflowing into the sign bit.
  SDValue Exp = DAG.getNode(ISD::SHL, SL, MVT::i32, ShAmt,
                            DAG.getConstant(23, SL, MVT::i32));
  SDValue IVal =
      DAG.getNode(ISD::ADD, SL, MVT::i32,
                  DAG.getNode(ISD::BITCAST, SL, MVT::i32, FVal), Exp);
  if (Signed) {
    // Set the sign bit.
    Sign = DAG.getNode(ISD::SHL, SL, MVT::i32,
                       DAG.getNode(ISD::TRUNCATE, SL, MVT::i32, Sign),
                       DAG.getConstant(31, SL, MVT::i32));
    IVal = DAG.getNode(ISD::OR, SL, MVT::i32, IVal, Sign);
  }
  return DAG.getNode(ISD::BITCAST, SL, MVT::f32, IVal);
}

SDValue AMDGPUTargetLowering::LowerINT_TO_FP64(SDValue Op, SelectionDAG &DAG,
                                               bool Signed) const {
  SDLoc SL(Op);
  SDValue Src = Op.getOperand(0);

  SDValue Lo, Hi;
  std::tie(Lo, Hi) = split64BitValue(Src, DAG);

  SDValue CvtHi = DAG.getNode(Signed ? ISD::SINT_TO_FP : ISD::UINT_TO_FP,
                              SL, MVT::f64, Hi);

  SDValue CvtLo = DAG.getNode(ISD::UINT_TO_FP, SL, MVT::f64, Lo);

  SDValue LdExp = DAG.getNode(ISD::FLDEXP, SL, MVT::f64, CvtHi,
                              DAG.getConstant(32, SL, MVT::i32));
  // TODO: Should this propagate fast-math-flags?
  return DAG.getNode(ISD::FADD, SL, MVT::f64, LdExp, CvtLo);
}

SDValue AMDGPUTargetLowering::LowerUINT_TO_FP(SDValue Op,
                                               SelectionDAG &DAG) const {
  // TODO: Factor out code common with LowerSINT_TO_FP.
  EVT DestVT = Op.getValueType();
  SDValue Src = Op.getOperand(0);
  EVT SrcVT = Src.getValueType();

  if (SrcVT == MVT::i16) {
    if (DestVT == MVT::f16)
      return Op;
    SDLoc DL(Op);

    // Promote src to i32
    SDValue Ext = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Src);
    return DAG.getNode(ISD::UINT_TO_FP, DL, DestVT, Ext);
  }

  if (DestVT == MVT::bf16 || DestVT == MVT::f16)
    return LowerINT_TO_FP16(Op, DAG, DestVT);

  if (SrcVT != MVT::i64)
    return Op;

  if (DestVT == MVT::f32)
    return LowerINT_TO_FP32(Op, DAG, false);

  assert(DestVT == MVT::f64);
  return LowerINT_TO_FP64(Op, DAG, false);
}

SDValue AMDGPUTargetLowering::LowerSINT_TO_FP(SDValue Op,
                                              SelectionDAG &DAG) const {
  EVT DestVT = Op.getValueType();

  SDValue Src = Op.getOperand(0);
  EVT SrcVT = Src.getValueType();

  if (SrcVT == MVT::i16) {
    if (DestVT == MVT::f16)
      return Op;

    SDLoc DL(Op);
    // Promote src to i32
    SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i32, Src);
    return DAG.getNode(ISD::SINT_TO_FP, DL, DestVT, Ext);
  }

  if (DestVT == MVT::bf16 || DestVT == MVT::f16)
    return LowerINT_TO_FP16(Op, DAG, DestVT);

  if (SrcVT != MVT::i64)
    return Op;

  // TODO: Factor out code common with LowerUINT_TO_FP.

  if (DestVT == MVT::f32)
    return LowerINT_TO_FP32(Op, DAG, true);

  assert(DestVT == MVT::f64);
  return LowerINT_TO_FP64(Op, DAG, true);
}

SDValue AMDGPUTargetLowering::LowerFP_TO_INT64(SDValue Op, SelectionDAG &DAG,
                                               bool Signed) const {
  SDLoc SL(Op);

  SDValue Src = Op.getOperand(0);
  EVT SrcVT = Src.getValueType();

  assert(SrcVT == MVT::f32 || SrcVT == MVT::f64);

  // 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);
  //
  SDValue Trunc = DAG.getNode(ISD::FTRUNC, SL, SrcVT, Src);
  SDValue Sign;
  if (Signed && SrcVT == MVT::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.
    Sign = DAG.getNode(ISD::SRA, SL, MVT::i32,
                       DAG.getNode(ISD::BITCAST, SL, MVT::i32, Trunc),
                       DAG.getConstant(31, SL, MVT::i32));
    Trunc = DAG.getNode(ISD::FABS, SL, SrcVT, Trunc);
  }

  SDValue K0, K1;
  if (SrcVT == MVT::f64) {
    K0 = DAG.getConstantFP(
        llvm::bit_cast<double>(UINT64_C(/*2^-32*/ 0x3df0000000000000)), SL,
        SrcVT);
    K1 = DAG.getConstantFP(
        llvm::bit_cast<double>(UINT64_C(/*-2^32*/ 0xc1f0000000000000)), SL,
        SrcVT);
  } else {
    K0 = DAG.getConstantFP(
        llvm::bit_cast<float>(UINT32_C(/*2^-32*/ 0x2f800000)), SL, SrcVT);
    K1 = DAG.getConstantFP(
        llvm::bit_cast<float>(UINT32_C(/*-2^32*/ 0xcf800000)), SL, SrcVT);
  }
  // TODO: Should this propagate fast-math-flags?
  SDValue Mul = DAG.getNode(ISD::FMUL, SL, SrcVT, Trunc, K0);

  SDValue FloorMul = DAG.getNode(ISD::FFLOOR, SL, SrcVT, Mul);

  SDValue Fma = DAG.getNode(ISD::FMA, SL, SrcVT, FloorMul, K1, Trunc);

  SDValue Hi = DAG.getNode((Signed && SrcVT == MVT::f64) ? ISD::FP_TO_SINT
                                                         : ISD::FP_TO_UINT,
                           SL, MVT::i32, FloorMul);
  SDValue Lo = DAG.getNode(ISD::FP_TO_UINT, SL, MVT::i32, Fma);

  SDValue Result = DAG.getNode(ISD::BITCAST, SL, MVT::i64,
                               DAG.getBuildVector(MVT::v2i32, SL, {Lo, Hi}));

  if (Signed && SrcVT == MVT::f32) {
    assert(Sign);
    // Flip the result based on the signedness, which is either all 0s or 1s.
    Sign = DAG.getNode(ISD::BITCAST, SL, MVT::i64,
                       DAG.getBuildVector(MVT::v2i32, SL, {Sign, Sign}));
    // r := xor(r, sign) - sign;
    Result =
        DAG.getNode(ISD::SUB, SL, MVT::i64,
                    DAG.getNode(ISD::XOR, SL, MVT::i64, Result, Sign), Sign);
  }

  return Result;
}

SDValue AMDGPUTargetLowering::LowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) const {
  SDLoc DL(Op);
  SDValue N0 = Op.getOperand(0);

  // Convert to target node to get known bits
  if (N0.getValueType() == MVT::f32)
    return DAG.getNode(AMDGPUISD::FP_TO_FP16, DL, Op.getValueType(), N0);

  if (Op->getFlags().hasApproximateFuncs()) {
    // There is a generic expand for FP_TO_FP16 with unsafe fast math.
    return SDValue();
  }

  return LowerF64ToF16Safe(N0, DL, DAG);
}

// return node in i32
SDValue AMDGPUTargetLowering::LowerF64ToF16Safe(SDValue Src, const SDLoc &DL,
                                                SelectionDAG &DAG) const {
  assert(Src.getSimpleValueType() == MVT::f64);

  // f64 -> f16 conversion using round-to-nearest-even rounding mode.
  // TODO: We can generate better code for True16.
  const unsigned ExpMask = 0x7ff;
  const unsigned ExpBiasf64 = 1023;
  const unsigned ExpBiasf16 = 15;
  SDValue Zero = DAG.getConstant(0, DL, MVT::i32);
  SDValue One = DAG.getConstant(1, DL, MVT::i32);
  SDValue U = DAG.getNode(ISD::BITCAST, DL, MVT::i64, Src);
  SDValue UH = DAG.getNode(ISD::SRL, DL, MVT::i64, U,
                           DAG.getConstant(32, DL, MVT::i64));
  UH = DAG.getZExtOrTrunc(UH, DL, MVT::i32);
  U = DAG.getZExtOrTrunc(U, DL, MVT::i32);
  SDValue E = DAG.getNode(ISD::SRL, DL, MVT::i32, UH,
                          DAG.getConstant(20, DL, MVT::i64));
  E = DAG.getNode(ISD::AND, DL, MVT::i32, E,
                  DAG.getConstant(ExpMask, DL, MVT::i32));
  // Subtract the fp64 exponent bias (1023) to get the real exponent and
  // add the f16 bias (15) to get the biased exponent for the f16 format.
  E = DAG.getNode(ISD::ADD, DL, MVT::i32, E,
                  DAG.getConstant(-ExpBiasf64 + ExpBiasf16, DL, MVT::i32));

  SDValue M = DAG.getNode(ISD::SRL, DL, MVT::i32, UH,
                          DAG.getConstant(8, DL, MVT::i32));
  M = DAG.getNode(ISD::AND, DL, MVT::i32, M,
                  DAG.getConstant(0xffe, DL, MVT::i32));

  SDValue MaskedSig = DAG.getNode(ISD::AND, DL, MVT::i32, UH,
                                  DAG.getConstant(0x1ff, DL, MVT::i32));
  MaskedSig = DAG.getNode(ISD::OR, DL, MVT::i32, MaskedSig, U);

  SDValue Lo40Set = DAG.getSelectCC(DL, MaskedSig, Zero, Zero, One, ISD::SETEQ);
  M = DAG.getNode(ISD::OR, DL, MVT::i32, M, Lo40Set);

  // (M != 0 ? 0x0200 : 0) | 0x7c00;
  SDValue I = DAG.getNode(ISD::OR, DL, MVT::i32,
      DAG.getSelectCC(DL, M, Zero, DAG.getConstant(0x0200, DL, MVT::i32),
                      Zero, ISD::SETNE), DAG.getConstant(0x7c00, DL, MVT::i32));

  // N = M | (E << 12);
  SDValue N = DAG.getNode(ISD::OR, DL, MVT::i32, M,
      DAG.getNode(ISD::SHL, DL, MVT::i32, E,
                  DAG.getConstant(12, DL, MVT::i32)));

  // B = clamp(1-E, 0, 13);
  SDValue OneSubExp = DAG.getNode(ISD::SUB, DL, MVT::i32,
                                  One, E);
  SDValue B = DAG.getNode(ISD::SMAX, DL, MVT::i32, OneSubExp, Zero);
  B = DAG.getNode(ISD::SMIN, DL, MVT::i32, B,
                  DAG.getConstant(13, DL, MVT::i32));

  SDValue SigSetHigh = DAG.getNode(ISD::OR, DL, MVT::i32, M,
                                   DAG.getConstant(0x1000, DL, MVT::i32));

  SDValue D = DAG.getNode(ISD::SRL, DL, MVT::i32, SigSetHigh, B);
  SDValue D0 = DAG.getNode(ISD::SHL, DL, MVT::i32, D, B);
  SDValue D1 = DAG.getSelectCC(DL, D0, SigSetHigh, One, Zero, ISD::SETNE);
  D = DAG.getNode(ISD::OR, DL, MVT::i32, D, D1);

  SDValue V = DAG.getSelectCC(DL, E, One, D, N, ISD::SETLT);
  SDValue VLow3 = DAG.getNode(ISD::AND, DL, MVT::i32, V,
                              DAG.getConstant(0x7, DL, MVT::i32));
  V = DAG.getNode(ISD::SRL, DL, MVT::i32, V,
                  DAG.getConstant(2, DL, MVT::i32));
  SDValue V0 = DAG.getSelectCC(DL, VLow3, DAG.getConstant(3, DL, MVT::i32),
                               One, Zero, ISD::SETEQ);
  SDValue V1 = DAG.getSelectCC(DL, VLow3, DAG.getConstant(5, DL, MVT::i32),
                               One, Zero, ISD::SETGT);
  V1 = DAG.getNode(ISD::OR, DL, MVT::i32, V0, V1);
  V = DAG.getNode(ISD::ADD, DL, MVT::i32, V, V1);

  V = DAG.getSelectCC(DL, E, DAG.getConstant(30, DL, MVT::i32),
                      DAG.getConstant(0x7c00, DL, MVT::i32), V, ISD::SETGT);
  V = DAG.getSelectCC(DL, E, DAG.getConstant(1039, DL, MVT::i32),
                      I, V, ISD::SETEQ);

  // Extract the sign bit.
  SDValue Sign = DAG.getNode(ISD::SRL, DL, MVT::i32, UH,
                            DAG.getConstant(16, DL, MVT::i32));
  Sign = DAG.getNode(ISD::AND, DL, MVT::i32, Sign,
                     DAG.getConstant(0x8000, DL, MVT::i32));

  return DAG.getNode(ISD::OR, DL, MVT::i32, Sign, V);
}

SDValue AMDGPUTargetLowering::LowerFP_TO_INT(const SDValue Op,
                                             SelectionDAG &DAG) const {
  SDValue Src = Op.getOperand(0);
  unsigned OpOpcode = Op.getOpcode();
  EVT SrcVT = Src.getValueType();
  EVT DestVT = Op.getValueType();

  // Will be selected natively
  if (SrcVT == MVT::f16 && DestVT == MVT::i16)
    return Op;

  if (SrcVT == MVT::bf16 || (SrcVT == MVT::f16 && DestVT == MVT::i32)) {
    SDLoc DL(Op);
    SDValue PromotedSrc = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Src);
    return DAG.getNode(Op.getOpcode(), DL, DestVT, PromotedSrc);
  }

  // Promote i16 to i32
  if (DestVT == MVT::i16 && (SrcVT == MVT::f32 || SrcVT == MVT::f64)) {
    SDLoc DL(Op);

    SDValue FpToInt32 = DAG.getNode(OpOpcode, DL, MVT::i32, Src);
    return DAG.getNode(ISD::TRUNCATE, DL, MVT::i16, FpToInt32);
  }

  if (DestVT != MVT::i64)
    return Op;

  if (SrcVT == MVT::f16 ||
      (SrcVT == MVT::f32 && Src.getOpcode() == ISD::FP16_TO_FP)) {
    SDLoc DL(Op);

    SDValue FpToInt32 = DAG.getNode(OpOpcode, DL, MVT::i32, Src);
    unsigned Ext =
        OpOpcode == ISD::FP_TO_SINT ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
    return DAG.getNode(Ext, DL, MVT::i64, FpToInt32);
  }

  if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
    return LowerFP_TO_INT64(Op, DAG, OpOpcode == ISD::FP_TO_SINT);

  return SDValue();
}

SDValue AMDGPUTargetLowering::LowerFP_TO_INT_SAT(const SDValue Op,
                                                 SelectionDAG &DAG) const {
  SDValue Src = Op.getOperand(0);
  unsigned OpOpcode = Op.getOpcode();
  EVT SrcVT = Src.getValueType();
  EVT DstVT = Op.getValueType();
  SDValue SatVTOp = Op.getNode()->getOperand(1);
  EVT SatVT = cast<VTSDNode>(SatVTOp)->getVT();
  SDLoc DL(Op);

  uint64_t DstWidth = DstVT.getScalarSizeInBits();
  uint64_t SatWidth = SatVT.getScalarSizeInBits();
  assert(SatWidth <= DstWidth && "Saturation width cannot exceed result width");

  // Scalar cases will be selected natively to v_cvt_/s_cvt_ instructions.
  // v2f32 -> v2i16 will be selected natively to v_cvt_pk_[iu]16_f32.
  if (SatWidth == DstWidth) {
    if ((DstVT == MVT::i32 && (SrcVT == MVT::f32 || SrcVT == MVT::f64)) ||
        (DstVT == MVT::i16 && (SrcVT == MVT::f16 || SrcVT == MVT::f32)) ||
        (DstVT == MVT::v2i16 && SrcVT == MVT::v2f32))
      return Op;
  }

  // Vectors can only be selected natively.
  if (DstVT.isVector())
    return SDValue();

  // Perform all saturation at selected width (i16 or i32) and truncate
  if (SatWidth < DstWidth && SatWidth <= 32) {
    // For f16 conversion with sub-i16 saturation perform saturation
    // at i16, if available in the target. This removes the need for extra f16
    // to f32 conversion. For all the others use i32.
    MVT ResultVT =
        Subtarget->has16BitInsts() && SrcVT == MVT::f16 && SatWidth < 16
            ? MVT::i16
            : MVT::i32;

    const SDValue ResultVTOp = DAG.getValueType(ResultVT);
    const uint64_t ResultWidth = ResultVT.getScalarSizeInBits();

    // First, convert input float into selected integer (i16 or i32)
    SDValue FpToInt = DAG.getNode(OpOpcode, DL, ResultVT, Src, ResultVTOp);
    SDValue IntSatVal;

    // Then, clamp at the saturation width using either i16 or i32 instructions
    if (OpOpcode == ISD::FP_TO_SINT_SAT) {
      SDValue MinConst = DAG.getConstant(
          APInt::getSignedMaxValue(SatWidth).sext(ResultWidth), DL, ResultVT);
      SDValue MaxConst = DAG.getConstant(
          APInt::getSignedMinValue(SatWidth).sext(ResultWidth), DL, ResultVT);
      SDValue MinVal = DAG.getNode(ISD::SMIN, DL, ResultVT, FpToInt, MinConst);
      IntSatVal = DAG.getNode(ISD::SMAX, DL, ResultVT, MinVal, MaxConst);
    } else {
      SDValue MinConst = DAG.getConstant(
          APInt::getMaxValue(SatWidth).zext(ResultWidth), DL, ResultVT);
      IntSatVal = DAG.getNode(ISD::UMIN, DL, ResultVT, FpToInt, MinConst);
    }

    // Finally, after saturating at i16 or i32 fit into the destination type
    return DAG.getExtOrTrunc(OpOpcode == ISD::FP_TO_SINT_SAT, IntSatVal, DL,
                             DstVT);
  }

  // SatWidth == DstWidth or SatWidth > 32

  // Saturate at i32 for i64 dst and f16/bf16 src (will invoke f16 promotion
  // below)
  if (DstVT == MVT::i64 &&
      (SrcVT == MVT::f16 || SrcVT == MVT::bf16 ||
       (SrcVT == MVT::f32 && Src.getOpcode() == ISD::FP16_TO_FP))) {
    const SDValue Int32VTOp = DAG.getValueType(MVT::i32);
    return DAG.getNode(OpOpcode, DL, DstVT, Src, Int32VTOp);
  }

  // Promote f16/bf16 src to f32 for i32 conversion
  if (DstVT == MVT::i32 && (SrcVT == MVT::f16 || SrcVT == MVT::bf16)) {
    SDValue PromotedSrc = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Src);
    return DAG.getNode(Op.getOpcode(), DL, DstVT, PromotedSrc, SatVTOp);
  }

  // For DstWidth < 16, promote i1 and i8 dst to i16 (if legal) with sub-i16
  // saturation. For DstWidth == 16, promote i16 dst to i32 with sub-i32
  // saturation; this covers i16.f32 and i16.f64
  if (DstWidth < 32) {
    // Note: this triggers SatWidth < DstWidth above to generate saturated
    // truncate by requesting MVT::i16/i32 destination with SatWidth < 16/32.
    MVT PromoteVT =
        (DstWidth < 16 && Subtarget->has16BitInsts()) ? MVT::i16 : MVT::i32;
    SDValue FpToInt = DAG.getNode(OpOpcode, DL, PromoteVT, Src, SatVTOp);
    return DAG.getNode(ISD::TRUNCATE, DL, DstVT, FpToInt);
  }

  // TODO: can we implement i64 dst for f32/f64?

  return SDValue();
}

SDValue AMDGPUTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
                                                     SelectionDAG &DAG) const {
  EVT ExtraVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
  MVT VT = Op.getSimpleValueType();
  MVT ScalarVT = VT.getScalarType();

  assert(VT.isVector());

  SDValue Src = Op.getOperand(0);
  SDLoc DL(Op);

  // TODO: Don't scalarize on Evergreen?
  unsigned NElts = VT.getVectorNumElements();
  SmallVector<SDValue, 8> Args;
  DAG.ExtractVectorElements(Src, Args, 0, NElts);

  SDValue VTOp = DAG.getValueType(ExtraVT.getScalarType());
  for (unsigned I = 0; I < NElts; ++I)
    Args[I] = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, ScalarVT, Args[I], VTOp);

  return DAG.getBuildVector(VT, DL, Args);
}

//===----------------------------------------------------------------------===//
// Custom DAG optimizations
//===----------------------------------------------------------------------===//

static bool isU24(SDValue Op, SelectionDAG &DAG) {
  return AMDGPUTargetLowering::numBitsUnsigned(Op, DAG) <= 24;
}

static bool isI24(SDValue Op, SelectionDAG &DAG) {
  EVT VT = Op.getValueType();
  return VT.getSizeInBits() >= 24 && // Types less than 24-bit should be treated
                                     // as unsigned 24-bit values.
         AMDGPUTargetLowering::numBitsSigned(Op, DAG) <= 24;
}

static SDValue simplifyMul24(SDNode *Node24,
                             TargetLowering::DAGCombinerInfo &DCI) {
  SelectionDAG &DAG = DCI.DAG;
  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
  bool IsIntrin = Node24->getOpcode() == ISD::INTRINSIC_WO_CHAIN;

  SDValue LHS = IsIntrin ? Node24->getOperand(1) : Node24->getOperand(0);
  SDValue RHS = IsIntrin ? Node24->getOperand(2) : Node24->getOperand(1);
  unsigned NewOpcode = Node24->getOpcode();
  if (IsIntrin) {
    unsigned IID = Node24->getConstantOperandVal(0);
    switch (IID) {
    case Intrinsic::amdgcn_mul_i24:
      NewOpcode = AMDGPUISD::MUL_I24;
      break;
    case Intrinsic::amdgcn_mul_u24:
      NewOpcode = AMDGPUISD::MUL_U24;
      break;
    case Intrinsic::amdgcn_mulhi_i24:
      NewOpcode = AMDGPUISD::MULHI_I24;
      break;
    case Intrinsic::amdgcn_mulhi_u24:
      NewOpcode = AMDGPUISD::MULHI_U24;
      break;
    default:
      llvm_unreachable("Expected 24-bit mul intrinsic");
    }
  }

  APInt Demanded = APInt::getLowBitsSet(LHS.getValueSizeInBits(), 24);

  // First try to simplify using SimplifyMultipleUseDemandedBits which allows
  // the operands to have other uses, but will only perform simplifications that
  // involve bypassing some nodes for this user.
  SDValue DemandedLHS = TLI.SimplifyMultipleUseDemandedBits(LHS, Demanded, DAG);
  SDValue DemandedRHS = TLI.SimplifyMultipleUseDemandedBits(RHS, Demanded, DAG);
  if (DemandedLHS || DemandedRHS)
    return DAG.getNode(NewOpcode, SDLoc(Node24), Node24->getVTList(),
                       DemandedLHS ? DemandedLHS : LHS,
                       DemandedRHS ? DemandedRHS : RHS);

  // Now try SimplifyDemandedBits which can simplify the nodes used by our
  // operands if this node is the only user.
  if (TLI.SimplifyDemandedBits(LHS, Demanded, DCI))
    return SDValue(Node24, 0);
  if (TLI.SimplifyDemandedBits(RHS, Demanded, DCI))
    return SDValue(Node24, 0);

  return SDValue();
}

template <typename IntTy>
static SDValue constantFoldBFE(SelectionDAG &DAG, IntTy Src0, uint32_t Offset,
                               uint32_t Width, const SDLoc &DL) {
  if (Width + Offset < 32) {
    uint32_t Shl = static_cast<uint32_t>(Src0) << (32 - Offset - Width);
    IntTy Result = static_cast<IntTy>(Shl) >> (32 - Width);
    if constexpr (std::is_signed_v<IntTy>) {
      return DAG.getSignedConstant(Result, DL, MVT::i32);
    } else {
      return DAG.getConstant(Result, DL, MVT::i32);
    }
  }

  return DAG.getConstant(Src0 >> Offset, DL, MVT::i32);
}

static bool hasVolatileUser(SDNode *Val) {
  for (SDNode *U : Val->users()) {
    if (MemSDNode *M = dyn_cast<MemSDNode>(U)) {
      if (M->isVolatile())
        return true;
    }
  }

  return false;
}

bool AMDGPUTargetLowering::shouldCombineMemoryType(EVT VT) const {
  // i32 vectors are the canonical memory type.
  if (VT.getScalarType() == MVT::i32 || isTypeLegal(VT))
    return false;

  if (!VT.isByteSized())
    return false;

  unsigned Size = VT.getStoreSize();

  if ((Size == 1 || Size == 2 || Size == 4) && !VT.isVector())
    return false;

  if (Size == 3 || (Size > 4 && (Size % 4 != 0)))
    return false;

  return true;
}

// Replace load of an illegal type with a bitcast from a load of a friendlier
// type.
SDValue AMDGPUTargetLowering::performLoadCombine(SDNode *N,
                                                 DAGCombinerInfo &DCI) const {
  if (!DCI.isBeforeLegalize())
    return SDValue();

  LoadSDNode *LN = cast<LoadSDNode>(N);
  if (!LN->isSimple() || !ISD::isNormalLoad(LN) || hasVolatileUser(LN))
    return SDValue();

  SDLoc SL(N);
  SelectionDAG &DAG = DCI.DAG;
  EVT VT = LN->getMemoryVT();

  unsigned Size = VT.getStoreSize();
  Align Alignment = LN->getAlign();
  if (Alignment < Size && isTypeLegal(VT)) {
    unsigned IsFast;
    unsigned AS = LN->getAddressSpace();

    // Expand unaligned loads earlier than legalization. Due to visitation order
    // problems during legalization, the emitted instructions to pack and unpack
    // the bytes again are not eliminated in the case of an unaligned copy.
    if (!allowsMisalignedMemoryAccesses(
            VT, AS, Alignment, LN->getMemOperand()->getFlags(), &IsFast)) {
      if (VT.isVector())
        return SplitVectorLoad(SDValue(LN, 0), DAG);

      SDValue Ops[2];
      std::tie(Ops[0], Ops[1]) = expandUnalignedLoad(LN, DAG);

      return DAG.getMergeValues(Ops, SDLoc(N));
    }

    if (!IsFast)
      return SDValue();
  }

  if (!shouldCombineMemoryType(VT))
    return SDValue();

  EVT NewVT = getEquivalentMemType(*DAG.getContext(), VT);

  SDValue NewLoad
    = DAG.getLoad(NewVT, SL, LN->getChain(),
                  LN->getBasePtr(), LN->getMemOperand());

  SDValue BC = DAG.getNode(ISD::BITCAST, SL, VT, NewLoad);
  DCI.CombineTo(N, BC, NewLoad.getValue(1));
  return SDValue(N, 0);
}

// Replace store of an illegal type with a store of a bitcast to a friendlier
// type.
SDValue AMDGPUTargetLowering::performStoreCombine(SDNode *N,
                                                  DAGCombinerInfo &DCI) const {
  if (!DCI.isBeforeLegalize())
    return SDValue();

  StoreSDNode *SN = cast<StoreSDNode>(N);
  if (!SN->isSimple() || !ISD::isNormalStore(SN))
    return SDValue();

  EVT VT = SN->getMemoryVT();
  unsigned Size = VT.getStoreSize();

  SDLoc SL(N);
  SelectionDAG &DAG = DCI.DAG;
  Align Alignment = SN->getAlign();
  if (Alignment < Size && isTypeLegal(VT)) {
    unsigned IsFast;
    unsigned AS = SN->getAddressSpace();

    // Expand unaligned stores earlier than legalization. Due to visitation
    // order problems during legalization, the emitted instructions to pack and
    // unpack the bytes again are not eliminated in the case of an unaligned
    // copy.
    if (!allowsMisalignedMemoryAccesses(
            VT, AS, Alignment, SN->getMemOperand()->getFlags(), &IsFast)) {
      if (VT.isVector())
        return SplitVectorStore(SDValue(SN, 0), DAG);

      return expandUnalignedStore(SN, DAG);
    }

    if (!IsFast)
      return SDValue();
  }

  if (!shouldCombineMemoryType(VT))
    return SDValue();

  EVT NewVT = getEquivalentMemType(*DAG.getContext(), VT);
  SDValue Val = SN->getValue();

  // DCI.AddToWorklist(Val.getNode());

  bool OtherUses = !Val.hasOneUse();
  SDValue CastVal = DAG.getBitcast(NewVT, Val);
  if (OtherUses) {
    SDValue CastBack = DAG.getBitcast(VT, CastVal);
    DAG.ReplaceAllUsesOfValueWith(Val, CastBack);
  }

  return DAG.getStore(SN->getChain(), SL, CastVal,
                      SN->getBasePtr(), SN->getMemOperand());
}

// FIXME: This should go in generic DAG combiner with an isTruncateFree check,
// but isTruncateFree is inaccurate for i16 now because of SALU vs. VALU
// issues.
SDValue AMDGPUTargetLowering::performAssertSZExtCombine(SDNode *N,
                                                        DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  SDValue N0 = N->getOperand(0);

  // (vt2 (assertzext (truncate vt0:x), vt1)) ->
  //     (vt2 (truncate (assertzext vt0:x, vt1)))
  if (N0.getOpcode() == ISD::TRUNCATE) {
    SDValue N1 = N->getOperand(1);
    EVT ExtVT = cast<VTSDNode>(N1)->getVT();
    SDLoc SL(N);

    SDValue Src = N0.getOperand(0);
    EVT SrcVT = Src.getValueType();
    if (SrcVT.bitsGE(ExtVT)) {
      SDValue NewInReg = DAG.getNode(N->getOpcode(), SL, SrcVT, Src, N1);
      return DAG.getNode(ISD::TRUNCATE, SL, N->getValueType(0), NewInReg);
    }
  }

  return SDValue();
}

SDValue AMDGPUTargetLowering::performIntrinsicWOChainCombine(
  SDNode *N, DAGCombinerInfo &DCI) const {
  unsigned IID = N->getConstantOperandVal(0);
  switch (IID) {
  case Intrinsic::amdgcn_mul_i24:
  case Intrinsic::amdgcn_mul_u24:
  case Intrinsic::amdgcn_mulhi_i24:
  case Intrinsic::amdgcn_mulhi_u24:
    return simplifyMul24(N, DCI);
  case Intrinsic::amdgcn_fract:
  case Intrinsic::amdgcn_rsq:
  case Intrinsic::amdgcn_rcp_legacy:
  case Intrinsic::amdgcn_rsq_legacy:
  case Intrinsic::amdgcn_rsq_clamp:
  case Intrinsic::amdgcn_tanh:
  case Intrinsic::amdgcn_prng_b32: {
    // FIXME: This is probably wrong. If src is an sNaN, it won't be quieted
    SDValue Src = N->getOperand(1);
    return Src.isUndef() ? Src : SDValue();
  }
  case Intrinsic::amdgcn_frexp_exp: {
    // frexp_exp (fneg x) -> frexp_exp x
    // frexp_exp (fabs x) -> frexp_exp x
    // frexp_exp (fneg (fabs x)) -> frexp_exp x
    SDValue Src = N->getOperand(1);
    SDValue PeekSign = peekFPSignOps(Src);
    if (PeekSign == Src)
      return SDValue();
    return SDValue(DCI.DAG.UpdateNodeOperands(N, N->getOperand(0), PeekSign),
                   0);
  }
  default:
    return SDValue();
  }
}

/// Split the 64-bit value \p LHS into two 32-bit components, and perform the
/// binary operation \p Opc to it with the corresponding constant operands.
SDValue AMDGPUTargetLowering::splitBinaryBitConstantOpImpl(
  DAGCombinerInfo &DCI, const SDLoc &SL,
  unsigned Opc, SDValue LHS,
  uint32_t ValLo, uint32_t ValHi) const {
  SelectionDAG &DAG = DCI.DAG;
  SDValue Lo, Hi;
  std::tie(Lo, Hi) = split64BitValue(LHS, DAG);

  SDValue LoRHS = DAG.getConstant(ValLo, SL, MVT::i32);
  SDValue HiRHS = DAG.getConstant(ValHi, SL, MVT::i32);

  SDValue LoAnd = DAG.getNode(Opc, SL, MVT::i32, Lo, LoRHS);
  SDValue HiAnd = DAG.getNode(Opc, SL, MVT::i32, Hi, HiRHS);

  // Re-visit the ands. It's possible we eliminated one of them and it could
  // simplify the vector.
  DCI.AddToWorklist(Lo.getNode());
  DCI.AddToWorklist(Hi.getNode());

  SDValue Vec = DAG.getBuildVector(MVT::v2i32, SL, {LoAnd, HiAnd});
  return DAG.getNode(ISD::BITCAST, SL, MVT::i64, Vec);
}

SDValue AMDGPUTargetLowering::performShlCombine(SDNode *N,
                                                DAGCombinerInfo &DCI) const {
  EVT VT = N->getValueType(0);
  SDValue LHS = N->getOperand(0);
  SDValue RHS = N->getOperand(1);
  ConstantSDNode *CRHS = dyn_cast<ConstantSDNode>(RHS);
  SDLoc SL(N);
  SelectionDAG &DAG = DCI.DAG;

  unsigned RHSVal;
  if (CRHS) {
    RHSVal = CRHS->getZExtValue();
    if (!RHSVal)
      return LHS;

    switch (LHS->getOpcode()) {
    default:
      break;
    case ISD::ZERO_EXTEND:
    case ISD::SIGN_EXTEND:
    case ISD::ANY_EXTEND: {
      SDValue X = LHS->getOperand(0);

      if (VT == MVT::i32 && RHSVal == 16 && X.getValueType() == MVT::i16 &&
          isOperationLegal(ISD::BUILD_VECTOR, MVT::v2i16)) {
        // Prefer build_vector as the canonical form if packed types are legal.
        // (shl ([asz]ext i16:x), 16 -> build_vector 0, x
        SDValue Vec = DAG.getBuildVector(
            MVT::v2i16, SL,
            {DAG.getConstant(0, SL, MVT::i16), LHS->getOperand(0)});
        return DAG.getNode(ISD::BITCAST, SL, MVT::i32, Vec);
      }

      // shl (ext x) => zext (shl x), if shift does not overflow int
      if (VT != MVT::i64)
        break;
      KnownBits Known = DAG.computeKnownBits(X);
      unsigned LZ = Known.countMinLeadingZeros();
      if (LZ < RHSVal)
        break;
      EVT XVT = X.getValueType();
      SDValue Shl = DAG.getNode(ISD::SHL, SL, XVT, X, SDValue(CRHS, 0));
      return DAG.getZExtOrTrunc(Shl, SL, VT);
    }
    }
  }

  if (VT.getScalarType() != MVT::i64)
    return SDValue();

  // On some subtargets, 64-bit shift is a quarter rate instruction. In the
  // common case, splitting this into a move and a 32-bit shift is faster and
  // the same code size.
  KnownBits Known = DAG.computeKnownBits(RHS);

  EVT ElementType = VT.getScalarType();
  EVT TargetScalarType = ElementType.getHalfSizedIntegerVT(*DAG.getContext());
  EVT TargetType = VT.changeElementType(*DAG.getContext(), TargetScalarType);

  if (Known.getMinValue().getZExtValue() < TargetScalarType.getSizeInBits())
    return SDValue();
  SDValue ShiftAmt;

  if (CRHS) {
    ShiftAmt = DAG.getConstant(RHSVal - TargetScalarType.getSizeInBits(), SL,
                               TargetType);
  } else {
    SDValue TruncShiftAmt = DAG.getNode(ISD::TRUNCATE, SL, TargetType, RHS);
    const SDValue ShiftMask =
        DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
    // This AND instruction will clamp out of bounds shift values.
    // It will also be removed during later instruction selection.
    ShiftAmt = DAG.getNode(ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
  }

  SDValue Lo = DAG.getNode(ISD::TRUNCATE, SL, TargetType, LHS);
  SDValue NewShift =
      DAG.getNode(ISD::SHL, SL, TargetType, Lo, ShiftAmt, N->getFlags());

  const SDValue Zero = DAG.getConstant(0, SL, TargetScalarType);
  SDValue Vec;

  if (VT.isVector()) {
    EVT ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.getContext());
    unsigned NElts = TargetType.getVectorNumElements();
    SmallVector<SDValue, 8> HiOps;
    SmallVector<SDValue, 16> HiAndLoOps(NElts * 2, Zero);

    DAG.ExtractVectorElements(NewShift, HiOps, 0, NElts);
    for (unsigned I = 0; I != NElts; ++I)
      HiAndLoOps[2 * I + 1] = HiOps[I];
    Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, ConcatType, HiAndLoOps);
  } else {
    EVT ConcatType = EVT::getVectorVT(*DAG.getContext(), TargetType, 2);
    Vec = DAG.getBuildVector(ConcatType, SL, {Zero, NewShift});
  }
  return DAG.getNode(ISD::BITCAST, SL, VT, Vec);
}

SDValue AMDGPUTargetLowering::performSraCombine(SDNode *N,
                                                DAGCombinerInfo &DCI) const {
  SDValue RHS = N->getOperand(1);
  ConstantSDNode *CRHS = dyn_cast<ConstantSDNode>(RHS);
  EVT VT = N->getValueType(0);
  SDValue LHS = N->getOperand(0);
  SelectionDAG &DAG = DCI.DAG;
  SDLoc SL(N);

  if (VT.getScalarType() != MVT::i64)
    return SDValue();

  // For C >= 32
  // i64 (sra x, C) -> (build_pair (sra hi_32(x), C - 32), sra hi_32(x), 31))

  // On some subtargets, 64-bit shift is a quarter rate instruction. In the
  // common case, splitting this into a move and a 32-bit shift is faster and
  // the same code size.
  KnownBits Known = DAG.computeKnownBits(RHS);

  EVT ElementType = VT.getScalarType();
  EVT TargetScalarType = ElementType.getHalfSizedIntegerVT(*DAG.getContext());
  EVT TargetType = VT.changeElementType(*DAG.getContext(), TargetScalarType);

  if (Known.getMinValue().getZExtValue() < TargetScalarType.getSizeInBits())
    return SDValue();

  SDValue ShiftFullAmt =
      DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
  SDValue ShiftAmt;
  if (CRHS) {
    unsigned RHSVal = CRHS->getZExtValue();
    ShiftAmt = DAG.getConstant(RHSVal - TargetScalarType.getSizeInBits(), SL,
                               TargetType);
  } else if (Known.getMinValue().getZExtValue() ==
             (ElementType.getSizeInBits() - 1)) {
    ShiftAmt = ShiftFullAmt;
  } else {
    SDValue TruncShiftAmt = DAG.getNode(ISD::TRUNCATE, SL, TargetType, RHS);
    const SDValue ShiftMask =
        DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
    // This AND instruction will clamp out of bounds shift values.
    // It will also be removed during later instruction selection.
    ShiftAmt = DAG.getNode(ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
  }

  EVT ConcatType;
  SDValue Hi;
  SDLoc LHSSL(LHS);
  // Bitcast LHS into ConcatType so hi-half of source can be extracted into Hi
  if (VT.isVector()) {
    unsigned NElts = TargetType.getVectorNumElements();
    ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.getContext());
    SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
    SmallVector<SDValue, 8> HiOps(NElts);
    SmallVector<SDValue, 16> HiAndLoOps;

    DAG.ExtractVectorElements(SplitLHS, HiAndLoOps, 0, NElts * 2);
    for (unsigned I = 0; I != NElts; ++I) {
      HiOps[I] = HiAndLoOps[2 * I + 1];
    }
    Hi = DAG.getNode(ISD::BUILD_VECTOR, LHSSL, TargetType, HiOps);
  } else {
    const SDValue One = DAG.getConstant(1, LHSSL, TargetScalarType);
    ConcatType = EVT::getVectorVT(*DAG.getContext(), TargetType, 2);
    SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
    Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, LHSSL, TargetType, SplitLHS, One);
  }

  KnownBits KnownLHS = DAG.computeKnownBits(LHS);
  SDValue NewShift, HiShift;
  if (KnownLHS.isNegative()) {
    HiShift = DAG.getAllOnesConstant(SL, TargetType);
    NewShift =
        DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftAmt, N->getFlags());
  } else if (CRHS &&
             CRHS->getZExtValue() == (ElementType.getSizeInBits() - 1)) {
    NewShift = HiShift =
        DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftAmt, N->getFlags());
  } else {
    Hi = DAG.getFreeze(Hi);
    HiShift = DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftFullAmt);
    NewShift =
        DAG.getNode(ISD::SRA, SL, TargetType, Hi, ShiftAmt, N->getFlags());
  }

  SDValue Vec;
  if (VT.isVector()) {
    unsigned NElts = TargetType.getVectorNumElements();
    SmallVector<SDValue, 8> HiOps;
    SmallVector<SDValue, 8> LoOps;
    SmallVector<SDValue, 16> HiAndLoOps(NElts * 2);

    DAG.ExtractVectorElements(HiShift, HiOps, 0, NElts);
    DAG.ExtractVectorElements(NewShift, LoOps, 0, NElts);
    for (unsigned I = 0; I != NElts; ++I) {
      HiAndLoOps[2 * I + 1] = HiOps[I];
      HiAndLoOps[2 * I] = LoOps[I];
    }
    Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, ConcatType, HiAndLoOps);
  } else {
    Vec = DAG.getBuildVector(ConcatType, SL, {NewShift, HiShift});
  }
  return DAG.getNode(ISD::BITCAST, SL, VT, Vec);
}

SDValue AMDGPUTargetLowering::performSrlCombine(SDNode *N,
                                                DAGCombinerInfo &DCI) const {
  SDValue RHS = N->getOperand(1);
  ConstantSDNode *CRHS = dyn_cast<ConstantSDNode>(RHS);
  EVT VT = N->getValueType(0);
  SDValue LHS = N->getOperand(0);
  SelectionDAG &DAG = DCI.DAG;
  SDLoc SL(N);
  unsigned RHSVal;

  if (CRHS) {
    RHSVal = CRHS->getZExtValue();

    // fold (srl (and x, c1 << c2), c2) -> (and (srl(x, c2), c1)
    // this improves the ability to match BFE patterns in isel.
    if (LHS.getOpcode() == ISD::AND) {
      if (auto *Mask = dyn_cast<ConstantSDNode>(LHS.getOperand(1))) {
        unsigned MaskIdx, MaskLen;
        if (Mask->getAPIntValue().isShiftedMask(MaskIdx, MaskLen) &&
            MaskIdx == RHSVal) {
          return DAG.getNode(ISD::AND, SL, VT,
                             DAG.getNode(ISD::SRL, SL, VT, LHS.getOperand(0),
                                         N->getOperand(1)),
                             DAG.getNode(ISD::SRL, SL, VT, LHS.getOperand(1),
                                         N->getOperand(1)));
        }
      }
    }
  }

  if (VT.getScalarType() != MVT::i64)
    return SDValue();

  // for C >= 32
  // i64 (srl x, C) -> (build_pair (srl hi_32(x), C - 32), 0)

  // On some subtargets, 64-bit shift is a quarter rate instruction. In the
  // common case, splitting this into a move and a 32-bit shift is faster and
  // the same code size.
  KnownBits Known = DAG.computeKnownBits(RHS);

  EVT ElementType = VT.getScalarType();
  EVT TargetScalarType = ElementType.getHalfSizedIntegerVT(*DAG.getContext());
  EVT TargetType = VT.changeElementType(*DAG.getContext(), TargetScalarType);

  if (Known.getMinValue().getZExtValue() < TargetScalarType.getSizeInBits())
    return SDValue();

  SDValue ShiftAmt;
  if (CRHS) {
    ShiftAmt = DAG.getConstant(RHSVal - TargetScalarType.getSizeInBits(), SL,
                               TargetType);
  } else {
    SDValue TruncShiftAmt = DAG.getNode(ISD::TRUNCATE, SL, TargetType, RHS);
    const SDValue ShiftMask =
        DAG.getConstant(TargetScalarType.getSizeInBits() - 1, SL, TargetType);
    // This AND instruction will clamp out of bounds shift values.
    // It will also be removed during later instruction selection.
    ShiftAmt = DAG.getNode(ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
  }

  const SDValue Zero = DAG.getConstant(0, SL, TargetScalarType);
  EVT ConcatType;
  SDValue Hi;
  SDLoc LHSSL(LHS);
  // Bitcast LHS into ConcatType so hi-half of source can be extracted into Hi
  if (VT.isVector()) {
    unsigned NElts = TargetType.getVectorNumElements();
    ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.getContext());
    SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
    SmallVector<SDValue, 8> HiOps(NElts);
    SmallVector<SDValue, 16> HiAndLoOps;

    DAG.ExtractVectorElements(SplitLHS, HiAndLoOps, /*Start=*/0, NElts * 2);
    for (unsigned I = 0; I != NElts; ++I)
      HiOps[I] = HiAndLoOps[2 * I + 1];
    Hi = DAG.getNode(ISD::BUILD_VECTOR, LHSSL, TargetType, HiOps);
  } else {
    const SDValue One = DAG.getConstant(1, LHSSL, TargetScalarType);
    ConcatType = EVT::getVectorVT(*DAG.getContext(), TargetType, 2);
    SDValue SplitLHS = DAG.getNode(ISD::BITCAST, LHSSL, ConcatType, LHS);
    Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, LHSSL, TargetType, SplitLHS, One);
  }

  SDValue NewShift =
      DAG.getNode(ISD::SRL, SL, TargetType, Hi, ShiftAmt, N->getFlags());

  SDValue Vec;
  if (VT.isVector()) {
    unsigned NElts = TargetType.getVectorNumElements();
    SmallVector<SDValue, 8> LoOps;
    SmallVector<SDValue, 16> HiAndLoOps(NElts * 2, Zero);

    DAG.ExtractVectorElements(NewShift, LoOps, 0, NElts);
    for (unsigned I = 0; I != NElts; ++I)
      HiAndLoOps[2 * I] = LoOps[I];
    Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, ConcatType, HiAndLoOps);
  } else {
    Vec = DAG.getBuildVector(ConcatType, SL, {NewShift, Zero});
  }
  return DAG.getNode(ISD::BITCAST, SL, VT, Vec);
}

SDValue AMDGPUTargetLowering::performTruncateCombine(
  SDNode *N, DAGCombinerInfo &DCI) const {
  SDLoc SL(N);
  SelectionDAG &DAG = DCI.DAG;
  EVT VT = N->getValueType(0);
  SDValue Src = N->getOperand(0);

  // vt1 (truncate (bitcast (build_vector vt0:x, ...))) -> vt1 (bitcast vt0:x)
  if (Src.getOpcode() == ISD::BITCAST && !VT.isVector()) {
    SDValue Vec = Src.getOperand(0);
    if (Vec.getOpcode() == ISD::BUILD_VECTOR) {
      SDValue Elt0 = Vec.getOperand(0);
      EVT EltVT = Elt0.getValueType();
      if (VT.getFixedSizeInBits() <= EltVT.getFixedSizeInBits()) {
        if (EltVT.isFloatingPoint()) {
          Elt0 = DAG.getNode(ISD::BITCAST, SL,
                             EltVT.changeTypeToInteger(), Elt0);
        }

        return DAG.getNode(ISD::TRUNCATE, SL, VT, Elt0);
      }
    }
  }

  // Equivalent of above for accessing the high element of a vector as an
  // integer operation.
  // trunc (srl (bitcast (build_vector x, y))), 16 -> trunc (bitcast y)
  if (Src.getOpcode() == ISD::SRL && !VT.isVector()) {
    if (auto *K = isConstOrConstSplat(Src.getOperand(1))) {
      SDValue BV = stripBitcast(Src.getOperand(0));
      if (BV.getOpcode() == ISD::BUILD_VECTOR) {
        EVT SrcEltVT = BV.getOperand(0).getValueType();
        unsigned SrcEltSize = SrcEltVT.getSizeInBits();
        unsigned BitIndex = K->getZExtValue();
        unsigned PartIndex = BitIndex / SrcEltSize;

        if (PartIndex * SrcEltSize == BitIndex &&
            PartIndex < BV.getNumOperands()) {
          if (SrcEltVT.getSizeInBits() == VT.getSizeInBits()) {
            SDValue SrcElt =
                DAG.getNode(ISD::BITCAST, SL, SrcEltVT.changeTypeToInteger(),
                            BV.getOperand(PartIndex));
            return DAG.getNode(ISD::TRUNCATE, SL, VT, SrcElt);
          }
        }
      }
    }
  }

  // Partially shrink 64-bit shifts to 32-bit if reduced to 16-bit.
  //
  // i16 (trunc (srl i64:x, K)), K <= 16 ->
  //     i16 (trunc (srl (i32 (trunc x), K)))
  if (VT.getScalarSizeInBits() < 32) {
    EVT SrcVT = Src.getValueType();
    if (SrcVT.getScalarSizeInBits() > 32 &&
        (Src.getOpcode() == ISD::SRL ||
         Src.getOpcode() == ISD::SRA ||
         Src.getOpcode() == ISD::SHL)) {
      SDValue Amt = Src.getOperand(1);
      KnownBits Known = DAG.computeKnownBits(Amt);

      // - For left shifts, do the transform as long as the shift
      //   amount is still legal for i32, so when ShiftAmt < 32 (<= 31)
      // - For right shift, do it if ShiftAmt <= (32 - Size) to avoid
      //   losing information stored in the high bits when truncating.
      const unsigned MaxCstSize =
          (Src.getOpcode() == ISD::SHL) ? 31 : (32 - VT.getScalarSizeInBits());
      if (Known.getMaxValue().ule(MaxCstSize)) {
        EVT MidVT = VT.isVector() ?
          EVT::getVectorVT(*DAG.getContext(), MVT::i32,
                           VT.getVectorNumElements()) : MVT::i32;

        EVT NewShiftVT = getShiftAmountTy(MidVT, DAG.getDataLayout());
        SDValue Trunc = DAG.getNode(ISD::TRUNCATE, SL, MidVT,
                                    Src.getOperand(0));
        DCI.AddToWorklist(Trunc.getNode());

        if (Amt.getValueType() != NewShiftVT) {
          Amt = DAG.getZExtOrTrunc(Amt, SL, NewShiftVT);
          DCI.AddToWorklist(Amt.getNode());
        }

        SDValue ShrunkShift = DAG.getNode(Src.getOpcode(), SL, MidVT,
                                          Trunc, Amt);
        return DAG.getNode(ISD::TRUNCATE, SL, VT, ShrunkShift);
      }
    }
  }

  return SDValue();
}

// We need to specifically handle i64 mul here to avoid unnecessary conversion
// instructions. If we only match on the legalized i64 mul expansion,
// SimplifyDemandedBits will be unable to remove them because there will be
// multiple uses due to the separate mul + mulh[su].
static SDValue getMul24(SelectionDAG &DAG, const SDLoc &SL,
                        SDValue N0, SDValue N1, unsigned Size, bool Signed) {
  if (Size <= 32) {
    unsigned MulOpc = Signed ? AMDGPUISD::MUL_I24 : AMDGPUISD::MUL_U24;
    return DAG.getNode(MulOpc, SL, MVT::i32, N0, N1);
  }

  unsigned MulLoOpc = Signed ? AMDGPUISD::MUL_I24 : AMDGPUISD::MUL_U24;
  unsigned MulHiOpc = Signed ? AMDGPUISD::MULHI_I24 : AMDGPUISD::MULHI_U24;

  SDValue MulLo = DAG.getNode(MulLoOpc, SL, MVT::i32, N0, N1);
  SDValue MulHi = DAG.getNode(MulHiOpc, SL, MVT::i32, N0, N1);

  return DAG.getNode(ISD::BUILD_PAIR, SL, MVT::i64, MulLo, MulHi);
}

/// If \p V is an add of a constant 1, returns the other operand. Otherwise
/// return SDValue().
static SDValue getAddOneOp(const SDNode *V) {
  if (V->getOpcode() != ISD::ADD)
    return SDValue();

  return isOneConstant(V->getOperand(1)) ? V->getOperand(0) : SDValue();
}

SDValue AMDGPUTargetLowering::performMulCombine(SDNode *N,
                                                DAGCombinerInfo &DCI) const {
  assert(N->getOpcode() == ISD::MUL);
  EVT VT = N->getValueType(0);

  // Don't generate 24-bit multiplies on values that are in SGPRs, since
  // we only have a 32-bit scalar multiply (avoid values being moved to VGPRs
  // unnecessarily). isDivergent() is used as an approximation of whether the
  // value is in an SGPR.
  if (!N->isDivergent())
    return SDValue();

  unsigned Size = VT.getSizeInBits();
  if (VT.isVector() || Size > 64)
    return SDValue();

  SelectionDAG &DAG = DCI.DAG;
  SDLoc DL(N);

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // Undo InstCombine canonicalize X * (Y + 1) -> X * Y + X to enable mad
  // matching.

  // mul x, (add y, 1) -> add (mul x, y), x
  auto IsFoldableAdd = [](SDValue V) -> SDValue {
    SDValue AddOp = getAddOneOp(V.getNode());
    if (!AddOp)
      return SDValue();

    if (V.hasOneUse() || all_of(V->users(), [](const SDNode *U) -> bool {
          return U->getOpcode() == ISD::MUL;
        }))
      return AddOp;

    return SDValue();
  };

  // FIXME: The selection pattern is not properly checking for commuted
  // operands, so we have to place the mul in the LHS
  if (SDValue MulOper = IsFoldableAdd(N0)) {
    SDValue MulVal = DAG.getNode(N->getOpcode(), DL, VT, N1, MulOper);
    return DAG.getNode(ISD::ADD, DL, VT, MulVal, N1);
  }

  if (SDValue MulOper = IsFoldableAdd(N1)) {
    SDValue MulVal = DAG.getNode(N->getOpcode(), DL, VT, N0, MulOper);
    return DAG.getNode(ISD::ADD, DL, VT, MulVal, N0);
  }

  // There are i16 integer mul/mad.
  if (isTypeLegal(MVT::i16) && VT.getScalarType().bitsLE(MVT::i16))
    return SDValue();

  // SimplifyDemandedBits has the annoying habit of turning useful zero_extends
  // in the source into any_extends if the result of the mul is truncated. Since
  // we can assume the high bits are whatever we want, use the underlying value
  // to avoid the unknown high bits from interfering.
  if (N0.getOpcode() == ISD::ANY_EXTEND)
    N0 = N0.getOperand(0);

  if (N1.getOpcode() == ISD::ANY_EXTEND)
    N1 = N1.getOperand(0);

  SDValue Mul;

  if (Subtarget->hasMulU24() && isU24(N0, DAG) && isU24(N1, DAG)) {
    N0 = DAG.getZExtOrTrunc(N0, DL, MVT::i32);
    N1 = DAG.getZExtOrTrunc(N1, DL, MVT::i32);
    Mul = getMul24(DAG, DL, N0, N1, Size, false);
  } else if (Subtarget->hasMulI24() && isI24(N0, DAG) && isI24(N1, DAG)) {
    N0 = DAG.getSExtOrTrunc(N0, DL, MVT::i32);
    N1 = DAG.getSExtOrTrunc(N1, DL, MVT::i32);
    Mul = getMul24(DAG, DL, N0, N1, Size, true);
  } else {
    return SDValue();
  }

  // We need to use sext even for MUL_U24, because MUL_U24 is used
  // for signed multiply of 8 and 16-bit types.
  return DAG.getSExtOrTrunc(Mul, DL, VT);
}

SDValue
AMDGPUTargetLowering::performMulLoHiCombine(SDNode *N,
                                            DAGCombinerInfo &DCI) const {
  if (N->getValueType(0) != MVT::i32)
    return SDValue();

  SelectionDAG &DAG = DCI.DAG;
  SDLoc DL(N);

  bool Signed = N->getOpcode() == ISD::SMUL_LOHI;
  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  // SimplifyDemandedBits has the annoying habit of turning useful zero_extends
  // in the source into any_extends if the result of the mul is truncated. Since
  // we can assume the high bits are whatever we want, use the underlying value
  // to avoid the unknown high bits from interfering.
  if (N0.getOpcode() == ISD::ANY_EXTEND)
    N0 = N0.getOperand(0);
  if (N1.getOpcode() == ISD::ANY_EXTEND)
    N1 = N1.getOperand(0);

  // Try to use two fast 24-bit multiplies (one for each half of the result)
  // instead of one slow extending multiply.
  unsigned LoOpcode = 0;
  unsigned HiOpcode = 0;
  if (Signed) {
    if (Subtarget->hasMulI24() && isI24(N0, DAG) && isI24(N1, DAG)) {
      N0 = DAG.getSExtOrTrunc(N0, DL, MVT::i32);
      N1 = DAG.getSExtOrTrunc(N1, DL, MVT::i32);
      LoOpcode = AMDGPUISD::MUL_I24;
      HiOpcode = AMDGPUISD::MULHI_I24;
    }
  } else {
    if (Subtarget->hasMulU24() && isU24(N0, DAG) && isU24(N1, DAG)) {
      N0 = DAG.getZExtOrTrunc(N0, DL, MVT::i32);
      N1 = DAG.getZExtOrTrunc(N1, DL, MVT::i32);
      LoOpcode = AMDGPUISD::MUL_U24;
      HiOpcode = AMDGPUISD::MULHI_U24;
    }
  }
  if (!LoOpcode)
    return SDValue();

  SDValue Lo = DAG.getNode(LoOpcode, DL, MVT::i32, N0, N1);
  SDValue Hi = DAG.getNode(HiOpcode, DL, MVT::i32, N0, N1);
  DCI.CombineTo(N, Lo, Hi);
  return SDValue(N, 0);
}

SDValue AMDGPUTargetLowering::performMulhsCombine(SDNode *N,
                                                  DAGCombinerInfo &DCI) const {
  EVT VT = N->getValueType(0);

  if (!Subtarget->hasMulI24() || VT.isVector())
    return SDValue();

  // Don't generate 24-bit multiplies on values that are in SGPRs, since
  // we only have a 32-bit scalar multiply (avoid values being moved to VGPRs
  // unnecessarily). isDivergent() is used as an approximation of whether the
  // value is in an SGPR.
  // This doesn't apply if no s_mul_hi is available (since we'll end up with a
  // valu op anyway)
  if (Subtarget->hasSMulHi() && !N->isDivergent())
    return SDValue();

  SelectionDAG &DAG = DCI.DAG;
  SDLoc DL(N);

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  if (!isI24(N0, DAG) || !isI24(N1, DAG))
    return SDValue();

  N0 = DAG.getSExtOrTrunc(N0, DL, MVT::i32);
  N1 = DAG.getSExtOrTrunc(N1, DL, MVT::i32);

  SDValue Mulhi = DAG.getNode(AMDGPUISD::MULHI_I24, DL, MVT::i32, N0, N1);
  DCI.AddToWorklist(Mulhi.getNode());
  return DAG.getSExtOrTrunc(Mulhi, DL, VT);
}

SDValue AMDGPUTargetLowering::performMulhuCombine(SDNode *N,
                                                  DAGCombinerInfo &DCI) const {
  EVT VT = N->getValueType(0);

  if (VT.isVector() || VT.getSizeInBits() > 32 || !Subtarget->hasMulU24())
    return SDValue();

  // Don't generate 24-bit multiplies on values that are in SGPRs, since
  // we only have a 32-bit scalar multiply (avoid values being moved to VGPRs
  // unnecessarily). isDivergent() is used as an approximation of whether the
  // value is in an SGPR.
  // This doesn't apply if no s_mul_hi is available (since we'll end up with a
  // valu op anyway)
  if (!N->isDivergent() && Subtarget->hasSMulHi())
    return SDValue();

  SelectionDAG &DAG = DCI.DAG;
  SDLoc DL(N);

  SDValue N0 = N->getOperand(0);
  SDValue N1 = N->getOperand(1);

  if (!isU24(N0, DAG) || !isU24(N1, DAG))
    return SDValue();

  N0 = DAG.getZExtOrTrunc(N0, DL, MVT::i32);
  N1 = DAG.getZExtOrTrunc(N1, DL, MVT::i32);

  SDValue Mulhi = DAG.getNode(AMDGPUISD::MULHI_U24, DL, MVT::i32, N0, N1);
  DCI.AddToWorklist(Mulhi.getNode());
  return DAG.getZExtOrTrunc(Mulhi, DL, VT);
}

SDValue AMDGPUTargetLowering::getFFBX_U32(SelectionDAG &DAG,
                                          SDValue Op,
                                          const SDLoc &DL,
                                          unsigned Opc) const {
  EVT VT = Op.getValueType();
  if (VT.bitsGT(MVT::i32))
    return SDValue();

  if (VT != MVT::i32)
    Op = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Op);

  SDValue FFBX = DAG.getNode(Opc, DL, MVT::i32, Op);
  if (VT != MVT::i32)
    FFBX = DAG.getNode(ISD::TRUNCATE, DL, VT, FFBX);

  return FFBX;
}

// The native instructions return -1 on 0 input. Optimize out a select that
// produces -1 on 0.
//
// TODO: If zero is not undef, we could also do this if the output is compared
// against the bitwidth.
//
// TODO: Should probably combine against FFBH_U32 instead of ctlz directly.
SDValue AMDGPUTargetLowering::performCtlz_CttzCombine(const SDLoc &SL, SDValue Cond,
                                                 SDValue LHS, SDValue RHS,
                                                 DAGCombinerInfo &DCI) const {
  if (!isNullConstant(Cond.getOperand(1)))
    return SDValue();

  SelectionDAG &DAG = DCI.DAG;
  ISD::CondCode CCOpcode = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
  SDValue CmpLHS = Cond.getOperand(0);

  // select (setcc x, 0, eq), -1, (ctlz_zero_poison x) -> ffbh_u32 x
  // select (setcc x, 0, eq), -1, (cttz_zero_poison x) -> ffbl_u32 x
  if (CCOpcode == ISD::SETEQ &&
      (isCtlzOpc(RHS.getOpcode()) || isCttzOpc(RHS.getOpcode())) &&
      RHS.getOperand(0) == CmpLHS && isAllOnesConstant(LHS)) {
    unsigned Opc =
        isCttzOpc(RHS.getOpcode()) ? AMDGPUISD::FFBL_B32 : AMDGPUISD::FFBH_U32;
    return getFFBX_U32(DAG, CmpLHS, SL, Opc);
  }

  // select (setcc x, 0, ne), (ctlz_zero_poison x), -1 -> ffbh_u32 x
  // select (setcc x, 0, ne), (cttz_zero_poison x), -1 -> ffbl_u32 x
  if (CCOpcode == ISD::SETNE &&
      (isCtlzOpc(LHS.getOpcode()) || isCttzOpc(LHS.getOpcode())) &&
      LHS.getOperand(0) == CmpLHS && isAllOnesConstant(RHS)) {
    unsigned Opc =
        isCttzOpc(LHS.getOpcode()) ? AMDGPUISD::FFBL_B32 : AMDGPUISD::FFBH_U32;

    return getFFBX_U32(DAG, CmpLHS, SL, Opc);
  }

  return SDValue();
}

static SDValue distributeOpThroughSelect(TargetLowering::DAGCombinerInfo &DCI,
                                         unsigned Op,
                                         const SDLoc &SL,
                                         SDValue Cond,
                                         SDValue N1,
                                         SDValue N2) {
  SelectionDAG &DAG = DCI.DAG;
  EVT VT = N1.getValueType();

  SDValue NewSelect = DAG.getNode(ISD::SELECT, SL, VT, Cond,
                                  N1.getOperand(0), N2.getOperand(0));
  DCI.AddToWorklist(NewSelect.getNode());
  return DAG.getNode(Op, SL, VT, NewSelect);
}

// Pull a free FP operation out of a select so it may fold into uses.
//
// select c, (fneg x), (fneg y) -> fneg (select c, x, y)
// select c, (fneg x), k -> fneg (select c, x, (fneg k))
//
// select c, (fabs x), (fabs y) -> fabs (select c, x, y)
// select c, (fabs x), +k -> fabs (select c, x, k)
SDValue
AMDGPUTargetLowering::foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI,
                                           SDValue N) const {
  SelectionDAG &DAG = DCI.DAG;
  SDValue Cond = N.getOperand(0);
  SDValue LHS = N.getOperand(1);
  SDValue RHS = N.getOperand(2);

  EVT VT = N.getValueType();
  if ((LHS.getOpcode() == ISD::FABS && RHS.getOpcode() == ISD::FABS) ||
      (LHS.getOpcode() == ISD::FNEG && RHS.getOpcode() == ISD::FNEG)) {
    if (!AMDGPUTargetLowering::allUsesHaveSourceMods(N.getNode()))
      return SDValue();

    return distributeOpThroughSelect(DCI, LHS.getOpcode(),
                                     SDLoc(N), Cond, LHS, RHS);
  }

  bool Inv = false;
  if (RHS.getOpcode() == ISD::FABS || RHS.getOpcode() == ISD::FNEG) {
    std::swap(LHS, RHS);
    Inv = true;
  }

  // TODO: Support vector constants.
  ConstantFPSDNode *CRHS = dyn_cast<ConstantFPSDNode>(RHS);
  if ((LHS.getOpcode() == ISD::FNEG || LHS.getOpcode() == ISD::FABS) && CRHS &&
      !selectSupportsSourceMods(N.getNode())) {
    SDLoc SL(N);
    // If one side is an fneg/fabs and the other is a constant, we can push the
    // fneg/fabs down. If it's an fabs, the constant needs to be non-negative.
    SDValue NewLHS = LHS.getOperand(0);
    SDValue NewRHS = RHS;

    // Careful: if the neg can be folded up, don't try to pull it back down.
    bool ShouldFoldNeg = true;

    if (NewLHS.hasOneUse()) {
      unsigned Opc = NewLHS.getOpcode();
      if (LHS.getOpcode() == ISD::FNEG && fnegFoldsIntoOp(NewLHS.getNode()))
        ShouldFoldNeg = false;
      if (LHS.getOpcode() == ISD::FABS && Opc == ISD::FMUL)
        ShouldFoldNeg = false;
    }

    if (ShouldFoldNeg) {
      if (LHS.getOpcode() == ISD::FABS && CRHS->isNegative())
        return SDValue();

      // We're going to be forced to use a source modifier anyway, there's no
      // point to pulling the negate out unless we can get a size reduction by
      // negating the constant.
      //
      // TODO: Generalize to use getCheaperNegatedExpression which doesn't know
      // about cheaper constants.
      if (NewLHS.getOpcode() == ISD::FABS &&
          getConstantNegateCost(CRHS) != NegatibleCost::Cheaper)
        return SDValue();

      if (!AMDGPUTargetLowering::allUsesHaveSourceMods(N.getNode()))
        return SDValue();

      if (LHS.getOpcode() == ISD::FNEG)
        NewRHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);

      if (Inv)
        std::swap(NewLHS, NewRHS);

      SDValue NewSelect = DAG.getNode(ISD::SELECT, SL, VT,
                                      Cond, NewLHS, NewRHS);
      DCI.AddToWorklist(NewSelect.getNode());
      return DAG.getNode(LHS.getOpcode(), SL, VT, NewSelect);
    }
  }

  return SDValue();
}

SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
                                                   DAGCombinerInfo &DCI) const {
  if (SDValue Folded = foldFreeOpFromSelect(DCI, SDValue(N, 0)))
    return Folded;

  SDValue Cond = N->getOperand(0);
  if (Cond.getOpcode() != ISD::SETCC)
    return SDValue();

  EVT VT = N->getValueType(0);
  SDValue LHS = Cond.getOperand(0);
  SDValue RHS = Cond.getOperand(1);
  SDValue CC = Cond.getOperand(2);

  SDValue True = N->getOperand(1);
  SDValue False = N->getOperand(2);

  if (Cond.hasOneUse()) { // TODO: Look for multiple select uses.
    SelectionDAG &DAG = DCI.DAG;
    if (DAG.isConstantValueOfAnyType(True) &&
        !DAG.isConstantValueOfAnyType(False)) {
      // Swap cmp + select pair to move constant to false input.
      // This will allow using VOPC cndmasks more often.
      // select (setcc x, y), k, x -> select (setccinv x, y), x, k

      SDLoc SL(N);
      ISD::CondCode NewCC =
          getSetCCInverse(cast<CondCodeSDNode>(CC)->get(), LHS.getValueType());

      SDValue NewCond = DAG.getSetCC(SL, Cond.getValueType(), LHS, RHS, NewCC);
      return DAG.getNode(ISD::SELECT, SL, VT, NewCond, False, True);
    }

    if (VT == MVT::f32 && Subtarget->hasFminFmaxLegacy()) {
      SDValue MinMax
        = combineFMinMaxLegacy(SDLoc(N), VT, LHS, RHS, True, False, CC, DCI);
      // Revisit this node so we can catch min3/max3/med3 patterns.
      //DCI.AddToWorklist(MinMax.getNode());
      return MinMax;
    }
  }

  // There's no reason to not do this if the condition has other uses.
  return performCtlz_CttzCombine(SDLoc(N), Cond, True, False, DCI);
}

static bool isInv2Pi(const APFloat &APF) {
  static const APFloat KF16(APFloat::IEEEhalf(), APInt(16, 0x3118));
  static const APFloat KF32(APFloat::IEEEsingle(), APInt(32, 0x3e22f983));
  static const APFloat KF64(APFloat::IEEEdouble(), APInt(64, 0x3fc45f306dc9c882));

  return APF.bitwiseIsEqual(KF16) ||
         APF.bitwiseIsEqual(KF32) ||
         APF.bitwiseIsEqual(KF64);
}

// 0 and 1.0 / (0.5 * pi) do not have inline immmediates, so there is an
// additional cost to negate them.
TargetLowering::NegatibleCost
AMDGPUTargetLowering::getConstantNegateCost(const ConstantFPSDNode *C) const {
  if (C->isZero())
    return C->isNegative() ? NegatibleCost::Cheaper : NegatibleCost::Expensive;

  if (Subtarget->hasInv2PiInlineImm() && isInv2Pi(C->getValueAPF()))
    return C->isNegative() ? NegatibleCost::Cheaper : NegatibleCost::Expensive;

  return NegatibleCost::Neutral;
}

bool AMDGPUTargetLowering::isConstantCostlierToNegate(SDValue N) const {
  if (const ConstantFPSDNode *C = isConstOrConstSplatFP(N))
    return getConstantNegateCost(C) == NegatibleCost::Expensive;
  return false;
}

bool AMDGPUTargetLowering::isConstantCheaperToNegate(SDValue N) const {
  if (const ConstantFPSDNode *C = isConstOrConstSplatFP(N))
    return getConstantNegateCost(C) == NegatibleCost::Cheaper;
  return false;
}

static unsigned inverseMinMax(unsigned Opc) {
  switch (Opc) {
  case ISD::FMAXNUM:
    return ISD::FMINNUM;
  case ISD::FMINNUM:
    return ISD::FMAXNUM;
  case ISD::FMAXNUM_IEEE:
    return ISD::FMINNUM_IEEE;
  case ISD::FMINNUM_IEEE:
    return ISD::FMAXNUM_IEEE;
  case ISD::FMAXIMUM:
    return ISD::FMINIMUM;
  case ISD::FMINIMUM:
    return ISD::FMAXIMUM;
  case ISD::FMAXIMUMNUM:
    return ISD::FMINIMUMNUM;
  case ISD::FMINIMUMNUM:
    return ISD::FMAXIMUMNUM;
  case AMDGPUISD::FMAX_LEGACY:
    return AMDGPUISD::FMIN_LEGACY;
  case AMDGPUISD::FMIN_LEGACY:
    return AMDGPUISD::FMAX_LEGACY;
  default:
    llvm_unreachable("invalid min/max opcode");
  }
}

/// \return true if it's profitable to try to push an fneg into its source
/// instruction.
bool AMDGPUTargetLowering::shouldFoldFNegIntoSrc(SDNode *N, SDValue N0) {
  // If the input has multiple uses and we can either fold the negate down, or
  // the other uses cannot, give up. This both prevents unprofitable
  // transformations and infinite loops: we won't repeatedly try to fold around
  // a negate that has no 'good' form.
  if (N0.hasOneUse()) {
    // This may be able to fold into the source, but at a code size cost. Don't
    // fold if the fold into the user is free.
    if (allUsesHaveSourceMods(N, 0))
      return false;
  } else {
    if (fnegFoldsIntoOp(N0.getNode()) &&
        (allUsesHaveSourceMods(N) || !allUsesHaveSourceMods(N0.getNode())))
      return false;
  }

  return true;
}

SDValue AMDGPUTargetLowering::performFNegCombine(SDNode *N,
                                                 DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  SDValue N0 = N->getOperand(0);
  EVT VT = N->getValueType(0);

  unsigned Opc = N0.getOpcode();

  if (!shouldFoldFNegIntoSrc(N, N0))
    return SDValue();

  SDLoc SL(N);
  switch (Opc) {
  case ISD::FADD: {
    if (!mayIgnoreSignedZero(N0) && !N->getFlags().hasNoSignedZeros())
      return SDValue();

    // (fneg (fadd x, y)) -> (fadd (fneg x), (fneg y))
    SDValue LHS = N0.getOperand(0);
    SDValue RHS = N0.getOperand(1);

    if (LHS.getOpcode() != ISD::FNEG)
      LHS = DAG.getNode(ISD::FNEG, SL, VT, LHS);
    else
      LHS = LHS.getOperand(0);

    if (RHS.getOpcode() != ISD::FNEG)
      RHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
    else
      RHS = RHS.getOperand(0);

    SDValue Res = DAG.getNode(ISD::FADD, SL, VT, LHS, RHS, N0->getFlags());
    if (Res.getOpcode() != ISD::FADD)
      return SDValue(); // Op got folded away.
    if (!N0.hasOneUse())
      DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
    return Res;
  }
  case ISD::FMUL:
  case AMDGPUISD::FMUL_LEGACY: {
    // (fneg (fmul x, y)) -> (fmul x, (fneg y))
    // (fneg (fmul_legacy x, y)) -> (fmul_legacy x, (fneg y))
    SDValue LHS = N0.getOperand(0);
    SDValue RHS = N0.getOperand(1);

    if (LHS.getOpcode() == ISD::FNEG)
      LHS = LHS.getOperand(0);
    else if (RHS.getOpcode() == ISD::FNEG)
      RHS = RHS.getOperand(0);
    else
      RHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);

    SDValue Res = DAG.getNode(Opc, SL, VT, LHS, RHS, N0->getFlags());
    if (Res.getOpcode() != Opc)
      return SDValue(); // Op got folded away.
    if (!N0.hasOneUse())
      DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
    return Res;
  }
  case ISD::FMA:
  case ISD::FMAD: {
    // TODO: handle llvm.amdgcn.fma.legacy
    if (!mayIgnoreSignedZero(N0) && !N->getFlags().hasNoSignedZeros())
      return SDValue();

    // (fneg (fma x, y, z)) -> (fma x, (fneg y), (fneg z))
    SDValue LHS = N0.getOperand(0);
    SDValue MHS = N0.getOperand(1);
    SDValue RHS = N0.getOperand(2);

    if (LHS.getOpcode() == ISD::FNEG)
      LHS = LHS.getOperand(0);
    else if (MHS.getOpcode() == ISD::FNEG)
      MHS = MHS.getOperand(0);
    else
      MHS = DAG.getNode(ISD::FNEG, SL, VT, MHS);

    if (RHS.getOpcode() != ISD::FNEG)
      RHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
    else
      RHS = RHS.getOperand(0);

    SDValue Res = DAG.getNode(Opc, SL, VT, LHS, MHS, RHS);
    if (Res.getOpcode() != Opc)
      return SDValue(); // Op got folded away.
    if (!N0.hasOneUse())
      DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
    return Res;
  }
  case ISD::FMAXNUM:
  case ISD::FMINNUM:
  case ISD::FMAXNUM_IEEE:
  case ISD::FMINNUM_IEEE:
  case ISD::FMINIMUM:
  case ISD::FMAXIMUM:
  case ISD::FMINIMUMNUM:
  case ISD::FMAXIMUMNUM:
  case AMDGPUISD::FMAX_LEGACY:
  case AMDGPUISD::FMIN_LEGACY: {
    // fneg (fmaxnum x, y) -> fminnum (fneg x), (fneg y)
    // fneg (fminnum x, y) -> fmaxnum (fneg x), (fneg y)
    // fneg (fmax_legacy x, y) -> fmin_legacy (fneg x), (fneg y)
    // fneg (fmin_legacy x, y) -> fmax_legacy (fneg x), (fneg y)

    SDValue LHS = N0.getOperand(0);
    SDValue RHS = N0.getOperand(1);

    // 0 doesn't have a negated inline immediate.
    // TODO: This constant check should be generalized to other operations.
    if (isConstantCostlierToNegate(RHS))
      return SDValue();

    SDValue NegLHS = DAG.getNode(ISD::FNEG, SL, VT, LHS);
    SDValue NegRHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
    unsigned Opposite = inverseMinMax(Opc);

    SDValue Res = DAG.getNode(Opposite, SL, VT, NegLHS, NegRHS, N0->getFlags());
    if (Res.getOpcode() != Opposite)
      return SDValue(); // Op got folded away.
    if (!N0.hasOneUse())
      DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Res));
    return Res;
  }
  case AMDGPUISD::FMED3: {
    // med3 sorts a NaN input as smaller than everything regardless of its sign,
    // so negating all operands does not sign-flip the median when an input may
    // be NaN.
    if (!N0->getFlags().hasNoNaNs())
      return SDValue();

    SDValue Ops[3];
    for (unsigned I = 0; I < 3; ++I)
      Ops[I] = DAG.getNode(ISD::FNEG, SL, VT, N0->getOperand(I), N0->getFlags());

    SDValue Res = DAG.getNode(AMDGPUISD::FMED3, SL, VT, Ops, N0->getFlags());
    if (Res.getOpcode() != AMDGPUISD::FMED3)
      return SDValue(); // Op got folded away.

    if (!N0.hasOneUse()) {
      SDValue Neg = DAG.getNode(ISD::FNEG, SL, VT, Res);
      DAG.ReplaceAllUsesWith(N0, Neg);

      for (SDNode *U : Neg->users())
        DCI.AddToWorklist(U);
    }

    return Res;
  }
  case ISD::FP_EXTEND:
  case ISD::FTRUNC:
  case ISD::FRINT:
  case ISD::FNEARBYINT: // XXX - Should fround be handled?
  case ISD::FROUNDEVEN:
  case ISD::FSIN:
  case ISD::FCANONICALIZE:
  case AMDGPUISD::RCP:
  case AMDGPUISD::RCP_LEGACY:
  case AMDGPUISD::RCP_IFLAG:
  case AMDGPUISD::SIN_HW: {
    SDValue CvtSrc = N0.getOperand(0);
    if (CvtSrc.getOpcode() == ISD::FNEG) {
      // (fneg (fp_extend (fneg x))) -> (fp_extend x)
      // (fneg (rcp (fneg x))) -> (rcp x)
      return DAG.getNode(Opc, SL, VT, CvtSrc.getOperand(0));
    }

    if (!N0.hasOneUse())
      return SDValue();

    // (fneg (fp_extend x)) -> (fp_extend (fneg x))
    // (fneg (rcp x)) -> (rcp (fneg x))
    SDValue Neg = DAG.getNode(ISD::FNEG, SL, CvtSrc.getValueType(), CvtSrc);
    return DAG.getNode(Opc, SL, VT, Neg, N0->getFlags());
  }
  case ISD::FP_ROUND: {
    SDValue CvtSrc = N0.getOperand(0);

    if (CvtSrc.getOpcode() == ISD::FNEG) {
      // (fneg (fp_round (fneg x))) -> (fp_round x)
      return DAG.getNode(ISD::FP_ROUND, SL, VT,
                         CvtSrc.getOperand(0), N0.getOperand(1));
    }

    if (!N0.hasOneUse())
      return SDValue();

    // (fneg (fp_round x)) -> (fp_round (fneg x))
    SDValue Neg = DAG.getNode(ISD::FNEG, SL, CvtSrc.getValueType(), CvtSrc);
    return DAG.getNode(ISD::FP_ROUND, SL, VT, Neg, N0.getOperand(1));
  }
  case ISD::FP16_TO_FP: {
    // v_cvt_f32_f16 supports source modifiers on pre-VI targets without legal
    // f16, but legalization of f16 fneg ends up pulling it out of the source.
    // Put the fneg back as a legal source operation that can be matched later.
    SDLoc SL(N);

    SDValue Src = N0.getOperand(0);
    EVT SrcVT = Src.getValueType();

    // fneg (fp16_to_fp x) -> fp16_to_fp (xor x, 0x8000)
    SDValue IntFNeg = DAG.getNode(ISD::XOR, SL, SrcVT, Src,
                                  DAG.getConstant(0x8000, SL, SrcVT));
    return DAG.getNode(ISD::FP16_TO_FP, SL, N->getValueType(0), IntFNeg);
  }
  case ISD::SELECT: {
    // fneg (select c, a, b) -> select c, (fneg a), (fneg b)
    // TODO: Invert conditions of foldFreeOpFromSelect
    return SDValue();
  }
  case ISD::BITCAST: {
    SDLoc SL(N);
    SDValue BCSrc = N0.getOperand(0);
    if (BCSrc.getOpcode() == ISD::BUILD_VECTOR) {
      SDValue HighBits = BCSrc.getOperand(BCSrc.getNumOperands() - 1);
      if (VT != MVT::f64 || HighBits.getValueType().getSizeInBits() != 32 ||
          !fnegFoldsIntoOp(HighBits.getNode()))
        return SDValue();

      // f64 fneg only really needs to operate on the high half of of the
      // register, so try to force it to an f32 operation to help make use of
      // source modifiers.
      //
      //
      // fneg (f64 (bitcast (build_vector x, y))) ->
      // f64 (bitcast (build_vector (bitcast i32:x to f32),
      //                            (fneg (bitcast i32:y to f32)))

      SDValue CastHi = DAG.getNode(ISD::BITCAST, SL, MVT::f32, HighBits);
      SDValue NegHi = DAG.getNode(ISD::FNEG, SL, MVT::f32, CastHi);
      SDValue CastBack =
          DAG.getNode(ISD::BITCAST, SL, HighBits.getValueType(), NegHi);

      SmallVector<SDValue, 8> Ops(BCSrc->ops());
      Ops.back() = CastBack;
      DCI.AddToWorklist(NegHi.getNode());
      SDValue Build =
          DAG.getNode(ISD::BUILD_VECTOR, SL, BCSrc.getValueType(), Ops);
      SDValue Result = DAG.getNode(ISD::BITCAST, SL, VT, Build);

      if (!N0.hasOneUse())
        DAG.ReplaceAllUsesWith(N0, DAG.getNode(ISD::FNEG, SL, VT, Result));
      return Result;
    }

    if (BCSrc.getOpcode() == ISD::SELECT && VT == MVT::f32 &&
        BCSrc.hasOneUse()) {
      // fneg (bitcast (f32 (select cond, i32:lhs, i32:rhs))) ->
      //   select cond, (bitcast i32:lhs to f32), (bitcast i32:rhs to f32)

      // TODO: Cast back result for multiple uses is beneficial in some cases.

      SDValue LHS =
          DAG.getNode(ISD::BITCAST, SL, MVT::f32, BCSrc.getOperand(1));
      SDValue RHS =
          DAG.getNode(ISD::BITCAST, SL, MVT::f32, BCSrc.getOperand(2));

      SDValue NegLHS = DAG.getNode(ISD::FNEG, SL, MVT::f32, LHS);
      SDValue NegRHS = DAG.getNode(ISD::FNEG, SL, MVT::f32, RHS);

      return DAG.getNode(ISD::SELECT, SL, MVT::f32, BCSrc.getOperand(0), NegLHS,
                         NegRHS);
    }

    return SDValue();
  }
  default:
    return SDValue();
  }
}

SDValue AMDGPUTargetLowering::performFAbsCombine(SDNode *N,
                                                 DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  SDValue N0 = N->getOperand(0);

  if (!N0.hasOneUse())
    return SDValue();

  switch (N0.getOpcode()) {
  case ISD::FP16_TO_FP: {
    assert(!isTypeLegal(MVT::f16) && "should only see if f16 is illegal");
    SDLoc SL(N);
    SDValue Src = N0.getOperand(0);
    EVT SrcVT = Src.getValueType();

    // fabs (fp16_to_fp x) -> fp16_to_fp (and x, 0x7fff)
    SDValue IntFAbs = DAG.getNode(ISD::AND, SL, SrcVT, Src,
                                  DAG.getConstant(0x7fff, SL, SrcVT));
    return DAG.getNode(ISD::FP16_TO_FP, SL, N->getValueType(0), IntFAbs);
  }
  case ISD::FP_ROUND: {
    SDLoc SL(N);
    SDValue CvtSrc = N0.getOperand(0);

    // fabs (fp_round x) -> fp_round (fabs x)
    SDValue Abs = DAG.getNode(ISD::FABS, SL, CvtSrc.getValueType(), CvtSrc,
                              N->getFlags());
    return DAG.getNode(ISD::FP_ROUND, SL, N->getValueType(0), Abs,
                       N0.getOperand(1), N0->getFlags());
  }
  default:
    return SDValue();
  }
}

SDValue AMDGPUTargetLowering::performRcpCombine(SDNode *N,
                                                DAGCombinerInfo &DCI) const {
  const auto *CFP = dyn_cast<ConstantFPSDNode>(N->getOperand(0));
  if (!CFP)
    return SDValue();

  // XXX - Should this flush denormals?
  const APFloat &Val = CFP->getValueAPF();
  APFloat One = APFloat::getOne(Val.getSemantics());
  return DCI.DAG.getConstantFP(One / Val, SDLoc(N), N->getValueType(0));
}

bool AMDGPUTargetLowering::isInt64ImmLegal(SDNode *N, SelectionDAG &DAG) const {
  if (!Subtarget->isGCN())
    return false;

  ConstantSDNode *SDConstant = dyn_cast<ConstantSDNode>(N);
  ConstantFPSDNode *SDFPConstant = dyn_cast<ConstantFPSDNode>(N);
  auto &ST = DAG.getSubtarget<GCNSubtarget>();
  const auto *TII = ST.getInstrInfo();

  if (!ST.hasVMovB64Inst() || (!SDConstant && !SDFPConstant))
    return false;

  if (ST.has64BitLiterals())
    return true;

  if (SDConstant) {
    const APInt &APVal = SDConstant->getAPIntValue();
    return isUInt<32>(APVal.getZExtValue()) || TII->isInlineConstant(APVal);
  }

  APInt Val = SDFPConstant->getValueAPF().bitcastToAPInt();
  return isUInt<32>(Val.getZExtValue()) || TII->isInlineConstant(Val);
}

SDValue AMDGPUTargetLowering::PerformDAGCombine(SDNode *N,
                                                DAGCombinerInfo &DCI) const {
  SelectionDAG &DAG = DCI.DAG;
  SDLoc DL(N);

  switch(N->getOpcode()) {
  default:
    break;
  case ISD::BITCAST: {
    EVT DestVT = N->getValueType(0);

    // Push casts through vector builds. This helps avoid emitting a large
    // number of copies when materializing floating point vector constants.
    //
    // vNt1 bitcast (vNt0 (build_vector t0:x, t0:y)) =>
    //   vnt1 = build_vector (t1 (bitcast t0:x)), (t1 (bitcast t0:y))
    if (DestVT.isVector()) {
      SDValue Src = N->getOperand(0);
      if (Src.getOpcode() == ISD::BUILD_VECTOR &&
          (DCI.getDAGCombineLevel() < AfterLegalizeDAG ||
           isOperationLegal(ISD::BUILD_VECTOR, DestVT))) {
        EVT SrcVT = Src.getValueType();
        unsigned NElts = DestVT.getVectorNumElements();

        if (SrcVT.getVectorNumElements() == NElts) {
          EVT DestEltVT = DestVT.getVectorElementType();

          SmallVector<SDValue, 8> CastedElts;
          SDLoc SL(N);
          for (unsigned I = 0, E = SrcVT.getVectorNumElements(); I != E; ++I) {
            SDValue Elt = Src.getOperand(I);
            CastedElts.push_back(DAG.getNode(ISD::BITCAST, DL, DestEltVT, Elt));
          }

          return DAG.getBuildVector(DestVT, SL, CastedElts);
        }
      }
    }

    if (DestVT.getSizeInBits() != 64 || !DestVT.isVector())
      break;

    // Fold bitcasts of constants.
    //
    // v2i32 (bitcast i64:k) -> build_vector lo_32(k), hi_32(k)
    // TODO: Generalize and move to DAGCombiner
    SDValue Src = N->getOperand(0);
    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Src)) {
      SDLoc SL(N);
      if (isInt64ImmLegal(C, DAG))
        break;
      uint64_t CVal = C->getZExtValue();
      SDValue BV = DAG.getNode(ISD::BUILD_VECTOR, SL, MVT::v2i32,
                               DAG.getConstant(Lo_32(CVal), SL, MVT::i32),
                               DAG.getConstant(Hi_32(CVal), SL, MVT::i32));
      return DAG.getNode(ISD::BITCAST, SL, DestVT, BV);
    }

    if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Src)) {
      const APInt &Val = C->getValueAPF().bitcastToAPInt();
      SDLoc SL(N);
      if (isInt64ImmLegal(C, DAG))
        break;
      uint64_t CVal = Val.getZExtValue();
      SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, SL, MVT::v2i32,
                                DAG.getConstant(Lo_32(CVal), SL, MVT::i32),
                                DAG.getConstant(Hi_32(CVal), SL, MVT::i32));

      return DAG.getNode(ISD::BITCAST, SL, DestVT, Vec);
    }

    break;
  }
  case ISD::SHL:
  case ISD::SRA:
  case ISD::SRL: {
    // Range metadata can be invalidated when loads are converted to legal types
    // (e.g. v2i64 -> v4i32).
    // Try to convert vector shl/sra/srl before type legalization so that range
    // metadata can be utilized.
    if (!(N->getValueType(0).isVector() &&
          DCI.getDAGCombineLevel() == BeforeLegalizeTypes) &&
        DCI.getDAGCombineLevel() < AfterLegalizeDAG)
      break;
    if (N->getOpcode() == ISD::SHL)
      return performShlCombine(N, DCI);
    if (N->getOpcode() == ISD::SRA)
      return performSraCombine(N, DCI);
    return performSrlCombine(N, DCI);
  }
  case ISD::TRUNCATE:
    return performTruncateCombine(N, DCI);
  case ISD::MUL:
    return performMulCombine(N, DCI);
  case AMDGPUISD::MUL_U24:
  case AMDGPUISD::MUL_I24: {
    if (SDValue Simplified = simplifyMul24(N, DCI))
      return Simplified;
    break;
  }
  case AMDGPUISD::MULHI_I24:
  case AMDGPUISD::MULHI_U24:
    return simplifyMul24(N, DCI);
  case ISD::SMUL_LOHI:
  case ISD::UMUL_LOHI:
    return performMulLoHiCombine(N, DCI);
  case ISD::MULHS:
    return performMulhsCombine(N, DCI);
  case ISD::MULHU:
    return performMulhuCombine(N, DCI);
  case ISD::SELECT:
    return performSelectCombine(N, DCI);
  case ISD::FNEG:
    return performFNegCombine(N, DCI);
  case ISD::FABS:
    return performFAbsCombine(N, DCI);
  case AMDGPUISD::BFE_I32:
  case AMDGPUISD::BFE_U32: {
    assert(!N->getValueType(0).isVector() &&
           "Vector handling of BFE not implemented");
    ConstantSDNode *Width = dyn_cast<ConstantSDNode>(N->getOperand(2));
    if (!Width)
      break;

    uint32_t WidthVal = Width->getZExtValue() & 0x1f;
    if (WidthVal == 0)
      return DAG.getConstant(0, DL, MVT::i32);

    ConstantSDNode *Offset = dyn_cast<ConstantSDNode>(N->getOperand(1));
    if (!Offset)
      break;

    SDValue BitsFrom = N->getOperand(0);
    uint32_t OffsetVal = Offset->getZExtValue() & 0x1f;

    bool Signed = N->getOpcode() == AMDGPUISD::BFE_I32;

    if (OffsetVal == 0) {
      // This is already sign / zero extended, so try to fold away extra BFEs.
      unsigned SignBits =  Signed ? (32 - WidthVal + 1) : (32 - WidthVal);

      unsigned OpSignBits = DAG.ComputeNumSignBits(BitsFrom);
      if (OpSignBits >= SignBits)
        return BitsFrom;

      EVT SmallVT = EVT::getIntegerVT(*DAG.getContext(), WidthVal);
      if (Signed) {
        // This is a sign_extend_inreg. Replace it to take advantage of existing
        // DAG Combines. If not eliminated, we will match back to BFE during
        // selection.

        // TODO: The sext_inreg of extended types ends, although we can could
        // handle them in a single BFE.
        return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i32, BitsFrom,
                           DAG.getValueType(SmallVT));
      }

      return DAG.getZeroExtendInReg(BitsFrom, DL, SmallVT);
    }

    if (ConstantSDNode *CVal = dyn_cast<ConstantSDNode>(BitsFrom)) {
      if (Signed) {
        return constantFoldBFE<int32_t>(DAG,
                                        CVal->getSExtValue(),
                                        OffsetVal,
                                        WidthVal,
                                        DL);
      }

      return constantFoldBFE<uint32_t>(DAG,
                                       CVal->getZExtValue(),
                                       OffsetVal,
                                       WidthVal,
                                       DL);
    }

    if ((OffsetVal + WidthVal) >= 32 &&
        !(OffsetVal == 16 && WidthVal == 16 && Subtarget->hasSDWA())) {
      SDValue ShiftVal = DAG.getConstant(OffsetVal, DL, MVT::i32);
      return DAG.getNode(Signed ? ISD::SRA : ISD::SRL, DL, MVT::i32,
                         BitsFrom, ShiftVal);
    }

    if (BitsFrom.hasOneUse()) {
      APInt Demanded = APInt::getBitsSet(32,
                                         OffsetVal,
                                         OffsetVal + WidthVal);

      KnownBits Known;
      TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
                                            !DCI.isBeforeLegalizeOps());
      const TargetLowering &TLI = DAG.getTargetLoweringInfo();
      if (TLI.ShrinkDemandedConstant(BitsFrom, Demanded, TLO) ||
          TLI.SimplifyDemandedBits(BitsFrom, Demanded, Known, TLO)) {
        DCI.CommitTargetLoweringOpt(TLO);
      }
    }

    break;
  }
  case ISD::LOAD:
    return performLoadCombine(N, DCI);
  case ISD::STORE:
    return performStoreCombine(N, DCI);
  case AMDGPUISD::RCP:
  case AMDGPUISD::RCP_IFLAG:
    return performRcpCombine(N, DCI);
  case ISD::AssertZext:
  case ISD::AssertSext:
    return performAssertSZExtCombine(N, DCI);
  case ISD::INTRINSIC_WO_CHAIN:
    return performIntrinsicWOChainCombine(N, DCI);
  case AMDGPUISD::FMAD_FTZ: {
    SDValue N0 = N->getOperand(0);
    SDValue N1 = N->getOperand(1);
    SDValue N2 = N->getOperand(2);
    EVT VT = N->getValueType(0);

    // FMAD_FTZ is a FMAD + flush denormals to zero.
    // We flush the inputs, the intermediate step, and the output.
    ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0);
    ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
    ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2);
    if (N0CFP && N1CFP && N2CFP) {
      const auto FTZ = [](const APFloat &V) {
        if (V.isDenormal()) {
          APFloat Zero(V.getSemantics(), 0);
          return V.isNegative() ? -Zero : Zero;
        }
        return V;
      };

      APFloat V0 = FTZ(N0CFP->getValueAPF());
      APFloat V1 = FTZ(N1CFP->getValueAPF());
      APFloat V2 = FTZ(N2CFP->getValueAPF());
      V0.multiply(V1, APFloat::rmNearestTiesToEven);
      V0 = FTZ(V0);
      V0.add(V2, APFloat::rmNearestTiesToEven);
      return DAG.getConstantFP(FTZ(V0), DL, VT);
    }
    break;
  }
  }
  return SDValue();
}

bool AMDGPUTargetLowering::SimplifyDemandedBitsForTargetNode(
    SDValue Op, const APInt &OriginalDemandedBits,
    const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO,
    unsigned Depth) const {
  switch (Op.getOpcode()) {
  case ISD::INTRINSIC_WO_CHAIN: {
    switch (Op.getConstantOperandVal(0)) {
    case Intrinsic::amdgcn_readfirstlane:
    case Intrinsic::amdgcn_readlane:
    case Intrinsic::amdgcn_set_inactive:
    case Intrinsic::amdgcn_wwm: {
      if (SimplifyDemandedBits(Op.getOperand(1), OriginalDemandedBits,
                               OriginalDemandedElts, Known, TLO, Depth + 1))
        return true;
      break;
    }
    default:
      break;
    }
    break;
  }
  default:
    break;
  }

  return false;
}

//===----------------------------------------------------------------------===//
// Helper functions
//===----------------------------------------------------------------------===//

SDValue AMDGPUTargetLowering::CreateLiveInRegister(SelectionDAG &DAG,
                                                   const TargetRegisterClass *RC,
                                                   Register Reg, EVT VT,
                                                   const SDLoc &SL,
                                                   bool RawReg) const {
  MachineFunction &MF = DAG.getMachineFunction();
  MachineRegisterInfo &MRI = MF.getRegInfo();
  Register VReg;

  if (!MRI.isLiveIn(Reg)) {
    VReg = MRI.createVirtualRegister(RC);
    MRI.addLiveIn(Reg, VReg);
  } else {
    VReg = MRI.getLiveInVirtReg(Reg);
  }

  if (RawReg)
    return DAG.getRegister(VReg, VT);

  return DAG.getCopyFromReg(DAG.getEntryNode(), SL, VReg, VT);
}

// This may be called multiple times, and nothing prevents creating multiple
// objects at the same offset. See if we already defined this object.
static int getOrCreateFixedStackObject(MachineFrameInfo &MFI, unsigned Size,
                                       int64_t Offset) {
  for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
    if (MFI.getObjectOffset(I) == Offset) {
      assert(MFI.getObjectSize(I) == Size);
      return I;
    }
  }

  return MFI.CreateFixedObject(Size, Offset, true);
}

SDValue AMDGPUTargetLowering::loadStackInputValue(SelectionDAG &DAG,
                                                  EVT VT,
                                                  const SDLoc &SL,
                                                  int64_t Offset) const {
  MachineFunction &MF = DAG.getMachineFunction();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  int FI = getOrCreateFixedStackObject(MFI, VT.getStoreSize(), Offset);

  auto SrcPtrInfo = MachinePointerInfo::getStack(MF, Offset);
  SDValue Ptr = DAG.getFrameIndex(FI, MVT::i32);

  return DAG.getLoad(VT, SL, DAG.getEntryNode(), Ptr, SrcPtrInfo, Align(4),
                     MachineMemOperand::MODereferenceable |
                         MachineMemOperand::MOInvariant);
}

SDValue AMDGPUTargetLowering::storeStackInputValue(SelectionDAG &DAG,
                                                   const SDLoc &SL,
                                                   SDValue Chain,
                                                   SDValue ArgVal,
                                                   int64_t Offset) const {
  MachineFunction &MF = DAG.getMachineFunction();
  MachinePointerInfo DstInfo = MachinePointerInfo::getStack(MF, Offset);
  const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();

  SDValue Ptr = DAG.getConstant(Offset, SL, MVT::i32);
  // Stores to the argument stack area are relative to the stack pointer.
  SDValue SP =
      DAG.getCopyFromReg(Chain, SL, Info->getStackPtrOffsetReg(), MVT::i32);
  Ptr = DAG.getNode(ISD::ADD, SL, MVT::i32, SP, Ptr);
  SDValue Store = DAG.getStore(Chain, SL, ArgVal, Ptr, DstInfo, Align(4),
                               MachineMemOperand::MODereferenceable);
  return Store;
}

SDValue AMDGPUTargetLowering::loadInputValue(SelectionDAG &DAG,
                                             const TargetRegisterClass *RC,
                                             EVT VT, const SDLoc &SL,
                                             const ArgDescriptor &Arg) const {
  assert(Arg && "Attempting to load missing argument");

  SDValue V = Arg.isRegister() ?
    CreateLiveInRegister(DAG, RC, Arg.getRegister(), VT, SL) :
    loadStackInputValue(DAG, VT, SL, Arg.getStackOffset());

  if (!Arg.isMasked())
    return V;

  unsigned Mask = Arg.getMask();
  unsigned Shift = llvm::countr_zero<unsigned>(Mask);
  V = DAG.getNode(ISD::SRL, SL, VT, V,
                  DAG.getShiftAmountConstant(Shift, VT, SL));
  return DAG.getNode(ISD::AND, SL, VT, V,
                     DAG.getConstant(Mask >> Shift, SL, VT));
}

uint32_t AMDGPUTargetLowering::getImplicitParameterOffset(
    uint64_t ExplicitKernArgSize, const ImplicitParameter Param) const {
  unsigned ExplicitArgOffset = Subtarget->getExplicitKernelArgOffset();
  const Align Alignment = Subtarget->getAlignmentForImplicitArgPtr();
  uint64_t ArgOffset =
      alignTo(ExplicitKernArgSize, Alignment) + ExplicitArgOffset;
  switch (Param) {
  case FIRST_IMPLICIT:
    return ArgOffset;
  case PRIVATE_BASE:
    return ArgOffset + AMDGPU::ImplicitArg::PRIVATE_BASE_OFFSET;
  case SHARED_BASE:
    return ArgOffset + AMDGPU::ImplicitArg::SHARED_BASE_OFFSET;
  case QUEUE_PTR:
    return ArgOffset + AMDGPU::ImplicitArg::QUEUE_PTR_OFFSET;
  }
  llvm_unreachable("unexpected implicit parameter type");
}

uint32_t AMDGPUTargetLowering::getImplicitParameterOffset(
    const MachineFunction &MF, const ImplicitParameter Param) const {
  const AMDGPUMachineFunctionInfo *MFI =
      MF.getInfo<AMDGPUMachineFunctionInfo>();
  return getImplicitParameterOffset(MFI->getExplicitKernArgSize(), Param);
}

SDValue AMDGPUTargetLowering::getSqrtEstimate(SDValue Operand,
                                              SelectionDAG &DAG, int Enabled,
                                              int &RefinementSteps,
                                              bool &UseOneConstNR,
                                              bool Reciprocal) const {
  EVT VT = Operand.getValueType();

  if (VT == MVT::f32) {
    RefinementSteps = 0;
    return DAG.getNode(AMDGPUISD::RSQ, SDLoc(Operand), VT, Operand);
  }

  // TODO: There is also f64 rsq instruction, but the documentation is less
  // clear on its precision.

  return SDValue();
}

SDValue AMDGPUTargetLowering::getRecipEstimate(SDValue Operand,
                                               SelectionDAG &DAG, int Enabled,
                                               int &RefinementSteps) const {
  EVT VT = Operand.getValueType();

  if (VT == MVT::f32) {
    // Reciprocal, < 1 ulp error.
    //
    // This reciprocal approximation converges to < 0.5 ulp error with one
    // newton rhapson performed with two fused multiple adds (FMAs).

    RefinementSteps = 0;
    return DAG.getNode(AMDGPUISD::RCP, SDLoc(Operand), VT, Operand);
  }

  // TODO: There is also f64 rcp instruction, but the documentation is less
  // clear on its precision.

  return SDValue();
}

static unsigned workitemIntrinsicDim(unsigned ID) {
  switch (ID) {
  case Intrinsic::amdgcn_workitem_id_x:
    return 0;
  case Intrinsic::amdgcn_workitem_id_y:
    return 1;
  case Intrinsic::amdgcn_workitem_id_z:
    return 2;
  default:
    llvm_unreachable("not a workitem intrinsic");
  }
}

void AMDGPUTargetLowering::computeKnownBitsForTargetNode(
    const SDValue Op, KnownBits &Known,
    const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const {

  Known.resetAll(); // Don't know anything.

  unsigned Opc = Op.getOpcode();

  switch (Opc) {
  default:
    break;
  case AMDGPUISD::CARRY:
  case AMDGPUISD::BORROW: {
    Known.Zero = APInt::getHighBitsSet(32, 31);
    break;
  }

  case AMDGPUISD::BFE_I32:
  case AMDGPUISD::BFE_U32: {
    ConstantSDNode *CWidth = dyn_cast<ConstantSDNode>(Op.getOperand(2));
    if (!CWidth)
      return;

    uint32_t Width = CWidth->getZExtValue() & 0x1f;

    if (Opc == AMDGPUISD::BFE_U32)
      Known.Zero = APInt::getHighBitsSet(32, 32 - Width);

    break;
  }
  case AMDGPUISD::FP_TO_FP16: {
    unsigned BitWidth = Known.getBitWidth();

    // High bits are zero.
    Known.Zero = APInt::getHighBitsSet(BitWidth, BitWidth - 16);
    break;
  }
  case AMDGPUISD::MUL_U24:
  case AMDGPUISD::MUL_I24: {
    KnownBits LHSKnown = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
    KnownBits RHSKnown = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
    unsigned BitWidth = Op.getScalarValueSizeInBits();

    // Sign/Zero extend from 24 bits.
    if (Opc == AMDGPUISD::MUL_I24) {
      LHSKnown = LHSKnown.trunc(24).sext(BitWidth);
      RHSKnown = RHSKnown.trunc(24).sext(BitWidth);
    } else {
      LHSKnown = LHSKnown.trunc(24).zext(BitWidth);
      RHSKnown = RHSKnown.trunc(24).zext(BitWidth);
    }

    // TODO: SelfMultiply can be poison, but not undef.
    bool SelfMultiply = Op.getOperand(0) == Op.getOperand(1);
    if (SelfMultiply)
      SelfMultiply &= DAG.isGuaranteedNotToBeUndefOrPoison(
          Op.getOperand(0), DemandedElts, UndefPoisonKind::UndefOrPoison,
          Depth + 1);

    Known = KnownBits::mul(LHSKnown, RHSKnown, SelfMultiply);
    break;
  }
  case AMDGPUISD::PERM: {
    ConstantSDNode *CMask = dyn_cast<ConstantSDNode>(Op.getOperand(2));
    if (!CMask)
      return;

    KnownBits LHSKnown = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
    KnownBits RHSKnown = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
    unsigned Sel = CMask->getZExtValue();

    for (unsigned I = 0; I < 32; I += 8) {
      unsigned SelBits = Sel & 0xff;
      if (SelBits < 4) {
        SelBits *= 8;
        Known.One |= ((RHSKnown.One.getZExtValue() >> SelBits) & 0xff) << I;
        Known.Zero |= ((RHSKnown.Zero.getZExtValue() >> SelBits) & 0xff) << I;
      } else if (SelBits < 7) {
        SelBits = (SelBits & 3) * 8;
        Known.One |= ((LHSKnown.One.getZExtValue() >> SelBits) & 0xff) << I;
        Known.Zero |= ((LHSKnown.Zero.getZExtValue() >> SelBits) & 0xff) << I;
      } else if (SelBits == 0x0c) {
        Known.Zero |= 0xFFull << I;
      } else if (SelBits > 0x0c) {
        Known.One |= 0xFFull << I;
      }
      Sel >>= 8;
    }
    break;
  }
  case AMDGPUISD::BUFFER_LOAD_UBYTE:  {
    Known.Zero.setHighBits(24);
    break;
  }
  case AMDGPUISD::BUFFER_LOAD_USHORT: {
    Known.Zero.setHighBits(16);
    break;
  }
  case AMDGPUISD::LDS: {
    auto *GA = cast<GlobalAddressSDNode>(Op.getOperand(0).getNode());
    Align Alignment = GA->getGlobal()->getPointerAlignment(DAG.getDataLayout());

    Known.Zero.setHighBits(16);
    Known.Zero.setLowBits(Log2(Alignment));
    break;
  }
  case AMDGPUISD::SMIN3:
  case AMDGPUISD::SMAX3:
  case AMDGPUISD::SMED3:
  case AMDGPUISD::UMIN3:
  case AMDGPUISD::UMAX3:
  case AMDGPUISD::UMED3: {
    KnownBits Known2 = DAG.computeKnownBits(Op.getOperand(2), Depth + 1);
    if (Known2.isUnknown())
      break;

    KnownBits Known1 = DAG.computeKnownBits(Op.getOperand(1), Depth + 1);
    if (Known1.isUnknown())
      break;

    KnownBits Known0 = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
    if (Known0.isUnknown())
      break;

    // TODO: Handle LeadZero/LeadOne from UMIN/UMAX handling.
    Known.Zero = Known0.Zero & Known1.Zero & Known2.Zero;
    Known.One = Known0.One & Known1.One & Known2.One;
    break;
  }
  case ISD::INTRINSIC_WO_CHAIN: {
    unsigned IID = Op.getConstantOperandVal(0);
    switch (IID) {
    case Intrinsic::amdgcn_workitem_id_x:
    case Intrinsic::amdgcn_workitem_id_y:
    case Intrinsic::amdgcn_workitem_id_z: {
      unsigned MaxValue = Subtarget->getMaxWorkitemID(
          DAG.getMachineFunction().getFunction(), workitemIntrinsicDim(IID));
      Known.Zero.setHighBits(llvm::countl_zero(MaxValue));
      break;
    }
    default:
      break;
    }
  }
  }
}

unsigned AMDGPUTargetLowering::ComputeNumSignBitsForTargetNode(
    SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
    unsigned Depth) const {
  switch (Op.getOpcode()) {
  case AMDGPUISD::BFE_I32: {
    ConstantSDNode *Width = dyn_cast<ConstantSDNode>(Op.getOperand(2));
    if (!Width)
      return 1;

    unsigned SignBits = 32 - (Width->getZExtValue() & 0x1f) + 1;
    if (!isNullConstant(Op.getOperand(1)))
      return SignBits;

    // TODO: Could probably figure something out with non-0 offsets.
    unsigned Op0SignBits = DAG.ComputeNumSignBits(Op.getOperand(0), Depth + 1);
    return std::max(SignBits, Op0SignBits);
  }

  case AMDGPUISD::BFE_U32: {
    ConstantSDNode *Width = dyn_cast<ConstantSDNode>(Op.getOperand(2));
    return Width ? 32 - (Width->getZExtValue() & 0x1f) : 1;
  }

  case AMDGPUISD::CARRY:
  case AMDGPUISD::BORROW:
    return 31;
  case AMDGPUISD::BUFFER_LOAD_BYTE:
    return 25;
  case AMDGPUISD::BUFFER_LOAD_SHORT:
    return 17;
  case AMDGPUISD::BUFFER_LOAD_UBYTE:
    return 24;
  case AMDGPUISD::BUFFER_LOAD_USHORT:
    return 16;
  case AMDGPUISD::FP_TO_FP16:
    return 16;
  case AMDGPUISD::SMIN3:
  case AMDGPUISD::SMAX3:
  case AMDGPUISD::SMED3:
  case AMDGPUISD::UMIN3:
  case AMDGPUISD::UMAX3:
  case AMDGPUISD::UMED3: {
    unsigned Tmp2 = DAG.ComputeNumSignBits(Op.getOperand(2), Depth + 1);
    if (Tmp2 == 1)
      return 1; // Early out.

    unsigned Tmp1 = DAG.ComputeNumSignBits(Op.getOperand(1), Depth + 1);
    if (Tmp1 == 1)
      return 1; // Early out.

    unsigned Tmp0 = DAG.ComputeNumSignBits(Op.getOperand(0), Depth + 1);
    if (Tmp0 == 1)
      return 1; // Early out.

    return std::min({Tmp0, Tmp1, Tmp2});
  }
  default:
    return 1;
  }
}

unsigned AMDGPUTargetLowering::computeNumSignBitsForTargetInstr(
    GISelValueTracking &Analysis, Register R, const APInt &DemandedElts,
    const MachineRegisterInfo &MRI, unsigned Depth) const {
  const MachineInstr *MI = MRI.getVRegDef(R);
  if (!MI)
    return 1;

  // TODO: Check range metadata on MMO.
  switch (MI->getOpcode()) {
  case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE:
    return 25;
  case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT:
    return 17;
  case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE:
    return 24;
  case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT:
    return 16;
  case AMDGPU::G_AMDGPU_SMED3:
  case AMDGPU::G_AMDGPU_UMED3: {
    auto [Dst, Src0, Src1, Src2] = MI->getFirst4Regs();
    unsigned Tmp2 = Analysis.computeNumSignBits(Src2, DemandedElts, Depth + 1);
    if (Tmp2 == 1)
      return 1;
    unsigned Tmp1 = Analysis.computeNumSignBits(Src1, DemandedElts, Depth + 1);
    if (Tmp1 == 1)
      return 1;
    unsigned Tmp0 = Analysis.computeNumSignBits(Src0, DemandedElts, Depth + 1);
    if (Tmp0 == 1)
      return 1;
    return std::min({Tmp0, Tmp1, Tmp2});
  }
  default:
    return 1;
  }
}

bool AMDGPUTargetLowering::canCreateUndefOrPoisonForTargetNode(
    SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
    UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
  unsigned Opcode = Op.getOpcode();
  switch (Opcode) {
  case AMDGPUISD::BFE_I32:
  case AMDGPUISD::BFE_U32:
    return false;
  }
  return TargetLowering::canCreateUndefOrPoisonForTargetNode(
      Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
}

bool AMDGPUTargetLowering::isKnownNeverNaNForTargetNode(
    SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, bool SNaN,
    unsigned Depth) const {
  unsigned Opcode = Op.getOpcode();
  switch (Opcode) {
  case AMDGPUISD::FMIN_LEGACY:
  case AMDGPUISD::FMAX_LEGACY: {
    if (SNaN)
      return true;

    // TODO: Can check no nans on one of the operands for each one, but which
    // one?
    return false;
  }
  case AMDGPUISD::FMUL_LEGACY:
  case AMDGPUISD::CVT_PKRTZ_F16_F32: {
    if (SNaN)
      return true;
    return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
           DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
  }
  case AMDGPUISD::FMED3:
  case AMDGPUISD::FMIN3:
  case AMDGPUISD::FMAX3:
  case AMDGPUISD::FMINIMUM3:
  case AMDGPUISD::FMAXIMUM3:
  case AMDGPUISD::FMAD_FTZ: {
    if (SNaN)
      return true;
    return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
           DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
           DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
  }
  case AMDGPUISD::CVT_F32_UBYTE0:
  case AMDGPUISD::CVT_F32_UBYTE1:
  case AMDGPUISD::CVT_F32_UBYTE2:
  case AMDGPUISD::CVT_F32_UBYTE3:
    return true;

  case AMDGPUISD::RCP:
  case AMDGPUISD::RSQ:
  case AMDGPUISD::RCP_LEGACY:
  case AMDGPUISD::RSQ_CLAMP: {
    if (SNaN)
      return true;

    // TODO: Need is known positive check.
    return false;
  }
  case ISD::FLDEXP:
  case AMDGPUISD::FRACT: {
    if (SNaN)
      return true;
    return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
  }
  case AMDGPUISD::DIV_SCALE:
  case AMDGPUISD::DIV_FMAS:
  case AMDGPUISD::DIV_FIXUP:
    // TODO: Refine on operands.
    return SNaN;
  case AMDGPUISD::SIN_HW:
  case AMDGPUISD::COS_HW: {
    // TODO: Need check for infinity
    return SNaN;
  }
  case ISD::INTRINSIC_WO_CHAIN: {
    unsigned IntrinsicID = Op.getConstantOperandVal(0);
    // TODO: Handle more intrinsics
    switch (IntrinsicID) {
    case Intrinsic::amdgcn_cubeid:
    case Intrinsic::amdgcn_cvt_off_f32_i4:
      return true;

    case Intrinsic::amdgcn_frexp_mant: {
      if (SNaN)
        return true;
      return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
    }
    case Intrinsic::amdgcn_cvt_pkrtz: {
      if (SNaN)
        return true;
      return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
             DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
    }
    case Intrinsic::amdgcn_rcp:
    case Intrinsic::amdgcn_rsq:
    case Intrinsic::amdgcn_rcp_legacy:
    case Intrinsic::amdgcn_rsq_legacy:
    case Intrinsic::amdgcn_rsq_clamp:
    case Intrinsic::amdgcn_tanh: {
      if (SNaN)
        return true;

      // TODO: Need is known positive check.
      return false;
    }
    case Intrinsic::amdgcn_trig_preop:
    case Intrinsic::amdgcn_fdot2:
      // TODO: Refine on operand
      return SNaN;
    case Intrinsic::amdgcn_fma_legacy:
      if (SNaN)
        return true;
      return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
             DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1) &&
             DAG.isKnownNeverNaN(Op.getOperand(3), SNaN, Depth + 1);
    default:
      return false;
    }
  }
  default:
    return false;
  }
}

bool AMDGPUTargetLowering::isReassocProfitable(MachineRegisterInfo &MRI,
                                               Register N0, Register N1) const {
  return MRI.hasOneNonDBGUse(N0); // FIXME: handle regbanks
}
