//===-- ConstantFolding.cpp - Fold instructions into constants ------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines routines for folding instructions into constants.
//
// Also, to supplement the basic IR ConstantExpr simplifications,
// this file defines some additional folding routines that can make use of
// DataLayout information. These functions cannot go in IR due to library
// dependency issues.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetFolder.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/Config/config.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantFold.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/NVVMIntrinsicUtils.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <cerrno>
#include <cfenv>
#include <cmath>
#include <cstdint>

using namespace llvm;

static cl::opt<bool> DisableFPCallFolding(
    "disable-fp-call-folding",
    cl::desc("Disable constant-folding of FP intrinsics and libcalls."),
    cl::init(false), cl::Hidden);

namespace {

//===----------------------------------------------------------------------===//
// Constant Folding internal helper functions
//===----------------------------------------------------------------------===//

static Constant *foldConstVectorToAPInt(APInt &Result, Type *DestTy,
                                        Constant *C, Type *SrcEltTy,
                                        unsigned NumSrcElts,
                                        const DataLayout &DL) {
  // Now that we know that the input value is a vector of integers, just shift
  // and insert them into our result.
  unsigned BitShift = DL.getTypeSizeInBits(SrcEltTy);
  for (unsigned i = 0; i != NumSrcElts; ++i) {
    Constant *Element;
    if (DL.isLittleEndian())
      Element = C->getAggregateElement(NumSrcElts - i - 1);
    else
      Element = C->getAggregateElement(i);

    if (isa_and_nonnull<UndefValue>(Element)) {
      Result <<= BitShift;
      continue;
    }

    auto *ElementCI = dyn_cast_or_null<ConstantInt>(Element);
    if (!ElementCI)
      return ConstantExpr::getBitCast(C, DestTy);

    Result <<= BitShift;
    Result |= ElementCI->getValue().zext(Result.getBitWidth());
  }

  return nullptr;
}

/// Constant fold bitcast, symbolically evaluating it with DataLayout.
/// This always returns a non-null constant, but it may be a
/// ConstantExpr if unfoldable.
Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
  assert(CastInst::castIsValid(Instruction::BitCast, C, DestTy) &&
         "Invalid constantexpr bitcast!");

  // Catch the obvious splat cases.
  if (Constant *Res = ConstantFoldLoadFromUniformValue(C, DestTy, DL))
    return Res;

  if (auto *VTy = dyn_cast<VectorType>(C->getType())) {
    // Handle a vector->scalar integer/fp cast.
    if (isa<IntegerType>(DestTy) || DestTy->isFloatingPointTy()) {
      unsigned NumSrcElts = cast<FixedVectorType>(VTy)->getNumElements();
      Type *SrcEltTy = VTy->getElementType();

      // If the vector is a vector of floating point, convert it to vector of int
      // to simplify things.
      if (SrcEltTy->isFloatingPointTy()) {
        unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
        auto *SrcIVTy = FixedVectorType::get(
            IntegerType::get(C->getContext(), FPWidth), NumSrcElts);
        // Ask IR to do the conversion now that #elts line up.
        C = ConstantExpr::getBitCast(C, SrcIVTy);
      }

      APInt Result(DL.getTypeSizeInBits(DestTy), 0);
      if (Constant *CE = foldConstVectorToAPInt(Result, DestTy, C,
                                                SrcEltTy, NumSrcElts, DL))
        return CE;

      if (isa<IntegerType>(DestTy))
        return ConstantInt::get(DestTy, Result);

      APFloat FP(DestTy->getFltSemantics(), Result);
      return ConstantFP::get(DestTy->getContext(), FP);
    }
  }

  // The code below only handles casts to vectors currently.
  auto *DestVTy = dyn_cast<VectorType>(DestTy);
  if (!DestVTy)
    return ConstantExpr::getBitCast(C, DestTy);

  // If this is a scalar -> vector cast, convert the input into a <1 x scalar>
  // vector so the code below can handle it uniformly.
  if (!isa<VectorType>(C->getType()) &&
      (isa<ConstantFP>(C) || isa<ConstantInt>(C))) {
    Constant *Ops = C; // don't take the address of C!
    return FoldBitCast(ConstantVector::get(Ops), DestTy, DL);
  }

  // Some of what follows may extend to cover scalable vectors but the current
  // implementation is fixed length specific.
  if (!isa<FixedVectorType>(C->getType()))
    return ConstantExpr::getBitCast(C, DestTy);

  // If this is a bitcast from constant vector -> vector, fold it.
  if (!isa<ConstantDataVector>(C) && !isa<ConstantVector>(C) &&
      !isa<ConstantInt>(C) && !isa<ConstantFP>(C))
    return ConstantExpr::getBitCast(C, DestTy);

  // If the element types match, IR can fold it.
  unsigned NumDstElt = cast<FixedVectorType>(DestVTy)->getNumElements();
  unsigned NumSrcElt = cast<FixedVectorType>(C->getType())->getNumElements();
  if (NumDstElt == NumSrcElt)
    return ConstantExpr::getBitCast(C, DestTy);

  Type *SrcEltTy = cast<VectorType>(C->getType())->getElementType();
  Type *DstEltTy = DestVTy->getElementType();

  // Otherwise, we're changing the number of elements in a vector, which
  // requires endianness information to do the right thing.  For example,
  //    bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>)
  // folds to (little endian):
  //    <4 x i32> <i32 0, i32 0, i32 1, i32 0>
  // and to (big endian):
  //    <4 x i32> <i32 0, i32 0, i32 0, i32 1>

  // First thing is first.  We only want to think about integer here, so if
  // we have something in FP form, recast it as integer.
  if (DstEltTy->isFloatingPointTy()) {
    // Fold to an vector of integers with same size as our FP type.
    unsigned FPWidth = DstEltTy->getPrimitiveSizeInBits();
    auto *DestIVTy = FixedVectorType::get(
        IntegerType::get(C->getContext(), FPWidth), NumDstElt);
    // Recursively handle this integer conversion, if possible.
    C = FoldBitCast(C, DestIVTy, DL);

    // Finally, IR can handle this now that #elts line up.
    return ConstantExpr::getBitCast(C, DestTy);
  }

  // Okay, we know the destination is integer, if the input is FP, convert
  // it to integer first.
  if (SrcEltTy->isFloatingPointTy()) {
    unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
    auto *SrcIVTy = FixedVectorType::get(
        IntegerType::get(C->getContext(), FPWidth), NumSrcElt);
    // Ask IR to do the conversion now that #elts line up.
    C = ConstantExpr::getBitCast(C, SrcIVTy);
    assert((isa<ConstantVector>(C) || // FIXME: Remove ConstantVector.
            isa<ConstantDataVector>(C) || isa<ConstantInt>(C)) &&
           "Constant folding cannot fail for plain fp->int bitcast!");
  }

  // Now we know that the input and output vectors are both integer vectors
  // of the same size, and that their #elements is not the same.  Do the
  // conversion here, which depends on whether the input or output has
  // more elements.
  bool isLittleEndian = DL.isLittleEndian();

  SmallVector<Constant*, 32> Result;
  if (NumDstElt < NumSrcElt) {
    // Handle: bitcast (<4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x i64>)
    Constant *Zero = Constant::getNullValue(DstEltTy);
    unsigned Ratio = NumSrcElt/NumDstElt;
    unsigned SrcBitSize = SrcEltTy->getPrimitiveSizeInBits();
    unsigned SrcElt = 0;
    for (unsigned i = 0; i != NumDstElt; ++i) {
      // Build each element of the result.
      Constant *Elt = Zero;
      unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize*(Ratio-1);
      for (unsigned j = 0; j != Ratio; ++j) {
        Constant *Src = C->getAggregateElement(SrcElt++);
        if (isa_and_nonnull<UndefValue>(Src))
          Src = Constant::getNullValue(
              cast<VectorType>(C->getType())->getElementType());
        else
          Src = dyn_cast_or_null<ConstantInt>(Src);
        if (!Src)  // Reject constantexpr elements.
          return ConstantExpr::getBitCast(C, DestTy);

        // Zero extend the element to the right size.
        Src = ConstantFoldCastOperand(Instruction::ZExt, Src, Elt->getType(),
                                      DL);
        assert(Src && "Constant folding cannot fail on plain integers");

        // Shift it to the right place, depending on endianness.
        Src = ConstantFoldBinaryOpOperands(
            Instruction::Shl, Src, ConstantInt::get(Src->getType(), ShiftAmt),
            DL);
        assert(Src && "Constant folding cannot fail on plain integers");

        ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;

        // Mix it in.
        Elt = ConstantFoldBinaryOpOperands(Instruction::Or, Elt, Src, DL);
        assert(Elt && "Constant folding cannot fail on plain integers");
      }
      Result.push_back(Elt);
    }
    return ConstantVector::get(Result);
  }

  // Handle: bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>)
  unsigned Ratio = NumDstElt/NumSrcElt;
  unsigned DstBitSize = DL.getTypeSizeInBits(DstEltTy);

  // Loop over each source value, expanding into multiple results.
  for (unsigned i = 0; i != NumSrcElt; ++i) {
    auto *Element = C->getAggregateElement(i);

    if (!Element) // Reject constantexpr elements.
      return ConstantExpr::getBitCast(C, DestTy);

    if (isa<UndefValue>(Element)) {
      // Correctly Propagate undef values.
      Result.append(Ratio, UndefValue::get(DstEltTy));
      continue;
    }

    auto *Src = dyn_cast<ConstantInt>(Element);
    if (!Src)
      return ConstantExpr::getBitCast(C, DestTy);

    unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize*(Ratio-1);
    for (unsigned j = 0; j != Ratio; ++j) {
      // Shift the piece of the value into the right place, depending on
      // endianness.
      APInt Elt = Src->getValue().lshr(ShiftAmt);
      ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;

      // Truncate and remember this piece.
      Result.push_back(ConstantInt::get(DstEltTy, Elt.trunc(DstBitSize)));
    }
  }

  return ConstantVector::get(Result);
}

} // end anonymous namespace

/// If this constant is a constant offset from a global, return the global and
/// the constant. Because of constantexprs, this function is recursive.
bool llvm::IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
                                      APInt &Offset, const DataLayout &DL,
                                      DSOLocalEquivalent **DSOEquiv) {
  if (DSOEquiv)
    *DSOEquiv = nullptr;

  // Trivial case, constant is the global.
  if ((GV = dyn_cast<GlobalValue>(C))) {
    unsigned BitWidth = DL.getIndexTypeSizeInBits(GV->getType());
    Offset = APInt(BitWidth, 0);
    return true;
  }

  if (auto *FoundDSOEquiv = dyn_cast<DSOLocalEquivalent>(C)) {
    if (DSOEquiv)
      *DSOEquiv = FoundDSOEquiv;
    GV = FoundDSOEquiv->getGlobalValue();
    unsigned BitWidth = DL.getIndexTypeSizeInBits(GV->getType());
    Offset = APInt(BitWidth, 0);
    return true;
  }

  // Otherwise, if this isn't a constant expr, bail out.
  auto *CE = dyn_cast<ConstantExpr>(C);
  if (!CE) return false;

  // Look through ptr->int and ptr->ptr casts.
  if (CE->getOpcode() == Instruction::PtrToInt ||
      CE->getOpcode() == Instruction::BitCast)
    return IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, DL,
                                      DSOEquiv);

  // i32* getelementptr ([5 x i32]* @a, i32 0, i32 5)
  auto *GEP = dyn_cast<GEPOperator>(CE);
  if (!GEP)
    return false;

  unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
  APInt TmpOffset(BitWidth, 0);

  // If the base isn't a global+constant, we aren't either.
  if (!IsConstantOffsetFromGlobal(CE->getOperand(0), GV, TmpOffset, DL,
                                  DSOEquiv))
    return false;

  // Otherwise, add any offset that our operands provide.
  if (!GEP->accumulateConstantOffset(DL, TmpOffset))
    return false;

  Offset = TmpOffset;
  return true;
}

Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy,
                                               const DataLayout &DL) {
  do {
    Type *SrcTy = C->getType();
    if (SrcTy == DestTy)
      return C;

    TypeSize DestSize = DL.getTypeSizeInBits(DestTy);
    TypeSize SrcSize = DL.getTypeSizeInBits(SrcTy);
    if (!TypeSize::isKnownGE(SrcSize, DestSize))
      return nullptr;

    // Catch the obvious splat cases (since all-zeros can coerce non-integral
    // pointers legally).
    if (Constant *Res = ConstantFoldLoadFromUniformValue(C, DestTy, DL))
      return Res;

    // If the type sizes are the same and a cast is legal, just directly
    // cast the constant.
    // But be careful not to coerce non-integral pointers illegally.
    if (SrcSize == DestSize &&
        DL.isNonIntegralPointerType(SrcTy->getScalarType()) ==
            DL.isNonIntegralPointerType(DestTy->getScalarType())) {
      Instruction::CastOps Cast = Instruction::BitCast;
      // If we are going from a pointer to int or vice versa, we spell the cast
      // differently.
      if (SrcTy->isIntegerTy() && DestTy->isPointerTy())
        Cast = Instruction::IntToPtr;
      else if (SrcTy->isPointerTy() && DestTy->isIntegerTy())
        Cast = Instruction::PtrToInt;

      if (CastInst::castIsValid(Cast, C, DestTy))
        return ConstantFoldCastOperand(Cast, C, DestTy, DL);
    }

    // If this isn't an aggregate type, there is nothing we can do to drill down
    // and find a bitcastable constant.
    if (!SrcTy->isAggregateType() && !SrcTy->isVectorTy())
      return nullptr;

    // We're simulating a load through a pointer that was bitcast to point to
    // a different type, so we can try to walk down through the initial
    // elements of an aggregate to see if some part of the aggregate is
    // castable to implement the "load" semantic model.
    if (SrcTy->isStructTy()) {
      // Struct types might have leading zero-length elements like [0 x i32],
      // which are certainly not what we are looking for, so skip them.
      unsigned Elem = 0;
      Constant *ElemC;
      do {
        ElemC = C->getAggregateElement(Elem++);
      } while (ElemC && DL.getTypeSizeInBits(ElemC->getType()).isZero());
      C = ElemC;
    } else {
      // For non-byte-sized vector elements, the first element is not
      // necessarily located at the vector base address.
      if (auto *VT = dyn_cast<VectorType>(SrcTy))
        if (!DL.typeSizeEqualsStoreSize(VT->getElementType()))
          return nullptr;

      C = C->getAggregateElement(0u);
    }
  } while (C);

  return nullptr;
}

namespace {

/// Recursive helper to read bits out of global. C is the constant being copied
/// out of. ByteOffset is an offset into C. CurPtr is the pointer to copy
/// results into and BytesLeft is the number of bytes left in
/// the CurPtr buffer. DL is the DataLayout.
bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, unsigned char *CurPtr,
                        unsigned BytesLeft, const DataLayout &DL) {
  assert(ByteOffset <= DL.getTypeAllocSize(C->getType()) &&
         "Out of range access");

  // Reading type padding, return zero.
  if (ByteOffset >= DL.getTypeStoreSize(C->getType()))
    return true;

  // If this element is zero or undefined, we can just return since *CurPtr is
  // zero initialized.
  if (isa<ConstantAggregateZero>(C) || isa<UndefValue>(C))
    return true;

  if (auto *CI = dyn_cast<ConstantInt>(C)) {
    if ((CI->getBitWidth() & 7) != 0)
      return false;
    const APInt &Val = CI->getValue();
    unsigned IntBytes = unsigned(CI->getBitWidth()/8);

    for (unsigned i = 0; i != BytesLeft && ByteOffset != IntBytes; ++i) {
      unsigned n = ByteOffset;
      if (!DL.isLittleEndian())
        n = IntBytes - n - 1;
      CurPtr[i] = Val.extractBits(8, n * 8).getZExtValue();
      ++ByteOffset;
    }
    return true;
  }

  if (auto *CFP = dyn_cast<ConstantFP>(C)) {
    if (CFP->getType()->isDoubleTy()) {
      C = FoldBitCast(C, Type::getInt64Ty(C->getContext()), DL);
      return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, DL);
    }
    if (CFP->getType()->isFloatTy()){
      C = FoldBitCast(C, Type::getInt32Ty(C->getContext()), DL);
      return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, DL);
    }
    if (CFP->getType()->isHalfTy()){
      C = FoldBitCast(C, Type::getInt16Ty(C->getContext()), DL);
      return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, DL);
    }
    return false;
  }

  if (auto *CS = dyn_cast<ConstantStruct>(C)) {
    const StructLayout *SL = DL.getStructLayout(CS->getType());
    unsigned Index = SL->getElementContainingOffset(ByteOffset);
    uint64_t CurEltOffset = SL->getElementOffset(Index);
    ByteOffset -= CurEltOffset;

    while (true) {
      // If the element access is to the element itself and not to tail padding,
      // read the bytes from the element.
      uint64_t EltSize = DL.getTypeAllocSize(CS->getOperand(Index)->getType());

      if (ByteOffset < EltSize &&
          !ReadDataFromGlobal(CS->getOperand(Index), ByteOffset, CurPtr,
                              BytesLeft, DL))
        return false;

      ++Index;

      // Check to see if we read from the last struct element, if so we're done.
      if (Index == CS->getType()->getNumElements())
        return true;

      // If we read all of the bytes we needed from this element we're done.
      uint64_t NextEltOffset = SL->getElementOffset(Index);

      if (BytesLeft <= NextEltOffset - CurEltOffset - ByteOffset)
        return true;

      // Move to the next element of the struct.
      CurPtr += NextEltOffset - CurEltOffset - ByteOffset;
      BytesLeft -= NextEltOffset - CurEltOffset - ByteOffset;
      ByteOffset = 0;
      CurEltOffset = NextEltOffset;
    }
    // not reached.
  }

  if (isa<ConstantArray>(C) || isa<ConstantVector>(C) ||
      isa<ConstantDataSequential>(C)) {
    uint64_t NumElts, EltSize;
    Type *EltTy;
    if (auto *AT = dyn_cast<ArrayType>(C->getType())) {
      NumElts = AT->getNumElements();
      EltTy = AT->getElementType();
      EltSize = DL.getTypeAllocSize(EltTy);
    } else {
      NumElts = cast<FixedVectorType>(C->getType())->getNumElements();
      EltTy = cast<FixedVectorType>(C->getType())->getElementType();
      // TODO: For non-byte-sized vectors, current implementation assumes there is
      // padding to the next byte boundary between elements.
      if (!DL.typeSizeEqualsStoreSize(EltTy))
        return false;

      EltSize = DL.getTypeStoreSize(EltTy);
    }
    uint64_t Index = ByteOffset / EltSize;
    uint64_t Offset = ByteOffset - Index * EltSize;

    for (; Index != NumElts; ++Index) {
      if (!ReadDataFromGlobal(C->getAggregateElement(Index), Offset, CurPtr,
                              BytesLeft, DL))
        return false;

      uint64_t BytesWritten = EltSize - Offset;
      assert(BytesWritten <= EltSize && "Not indexing into this element?");
      if (BytesWritten >= BytesLeft)
        return true;

      Offset = 0;
      BytesLeft -= BytesWritten;
      CurPtr += BytesWritten;
    }
    return true;
  }

  if (auto *CE = dyn_cast<ConstantExpr>(C)) {
    if (CE->getOpcode() == Instruction::IntToPtr &&
        CE->getOperand(0)->getType() == DL.getIntPtrType(CE->getType())) {
      return ReadDataFromGlobal(CE->getOperand(0), ByteOffset, CurPtr,
                                BytesLeft, DL);
    }
  }

  // Otherwise, unknown initializer type.
  return false;
}

Constant *FoldReinterpretLoadFromConst(Constant *C, Type *LoadTy,
                                       int64_t Offset, const DataLayout &DL) {
  // Bail out early. Not expect to load from scalable global variable.
  if (isa<ScalableVectorType>(LoadTy))
    return nullptr;

  auto *IntType = dyn_cast<IntegerType>(LoadTy);

  // If this isn't an integer load we can't fold it directly.
  if (!IntType) {
    // If this is a non-integer load, we can try folding it as an int load and
    // then bitcast the result.  This can be useful for union cases.  Note
    // that address spaces don't matter here since we're not going to result in
    // an actual new load.
    if (!LoadTy->isFloatingPointTy() && !LoadTy->isPointerTy() &&
        !LoadTy->isVectorTy())
      return nullptr;

    Type *MapTy = Type::getIntNTy(C->getContext(),
                                  DL.getTypeSizeInBits(LoadTy).getFixedValue());
    if (Constant *Res = FoldReinterpretLoadFromConst(C, MapTy, Offset, DL)) {
      if (Res->isNullValue() && !LoadTy->isX86_AMXTy())
        // Materializing a zero can be done trivially without a bitcast
        return Constant::getNullValue(LoadTy);
      Type *CastTy = LoadTy->isPtrOrPtrVectorTy() ? DL.getIntPtrType(LoadTy) : LoadTy;
      Res = FoldBitCast(Res, CastTy, DL);
      if (LoadTy->isPtrOrPtrVectorTy()) {
        // For vector of pointer, we needed to first convert to a vector of integer, then do vector inttoptr
        if (Res->isNullValue() && !LoadTy->isX86_AMXTy())
          return Constant::getNullValue(LoadTy);
        if (DL.isNonIntegralPointerType(LoadTy->getScalarType()))
          // Be careful not to replace a load of an addrspace value with an inttoptr here
          return nullptr;
        Res = ConstantExpr::getIntToPtr(Res, LoadTy);
      }
      return Res;
    }
    return nullptr;
  }

  unsigned BytesLoaded = (IntType->getBitWidth() + 7) / 8;
  if (BytesLoaded > 32 || BytesLoaded == 0)
    return nullptr;

  // If we're not accessing anything in this constant, the result is undefined.
  if (Offset <= -1 * static_cast<int64_t>(BytesLoaded))
    return PoisonValue::get(IntType);

  // TODO: We should be able to support scalable types.
  TypeSize InitializerSize = DL.getTypeAllocSize(C->getType());
  if (InitializerSize.isScalable())
    return nullptr;

  // If we're not accessing anything in this constant, the result is undefined.
  if (Offset >= (int64_t)InitializerSize.getFixedValue())
    return PoisonValue::get(IntType);

  unsigned char RawBytes[32] = {0};
  unsigned char *CurPtr = RawBytes;
  unsigned BytesLeft = BytesLoaded;

  // If we're loading off the beginning of the global, some bytes may be valid.
  if (Offset < 0) {
    CurPtr += -Offset;
    BytesLeft += Offset;
    Offset = 0;
  }

  if (!ReadDataFromGlobal(C, Offset, CurPtr, BytesLeft, DL))
    return nullptr;

  APInt ResultVal = APInt(IntType->getBitWidth(), 0);
  if (DL.isLittleEndian()) {
    ResultVal = RawBytes[BytesLoaded - 1];
    for (unsigned i = 1; i != BytesLoaded; ++i) {
      ResultVal <<= 8;
      ResultVal |= RawBytes[BytesLoaded - 1 - i];
    }
  } else {
    ResultVal = RawBytes[0];
    for (unsigned i = 1; i != BytesLoaded; ++i) {
      ResultVal <<= 8;
      ResultVal |= RawBytes[i];
    }
  }

  return ConstantInt::get(IntType->getContext(), ResultVal);
}

} // anonymous namespace

// If GV is a constant with an initializer read its representation starting
// at Offset and return it as a constant array of unsigned char.  Otherwise
// return null.
Constant *llvm::ReadByteArrayFromGlobal(const GlobalVariable *GV,
                                        uint64_t Offset) {
  if (!GV->isConstant() || !GV->hasDefinitiveInitializer())
    return nullptr;

  const DataLayout &DL = GV->getDataLayout();
  Constant *Init = const_cast<Constant *>(GV->getInitializer());
  TypeSize InitSize = DL.getTypeAllocSize(Init->getType());
  if (InitSize < Offset)
    return nullptr;

  uint64_t NBytes = InitSize - Offset;
  if (NBytes > UINT16_MAX)
    // Bail for large initializers in excess of 64K to avoid allocating
    // too much memory.
    // Offset is assumed to be less than or equal than InitSize (this
    // is enforced in ReadDataFromGlobal).
    return nullptr;

  SmallVector<unsigned char, 256> RawBytes(static_cast<size_t>(NBytes));
  unsigned char *CurPtr = RawBytes.data();

  if (!ReadDataFromGlobal(Init, Offset, CurPtr, NBytes, DL))
    return nullptr;

  return ConstantDataArray::get(GV->getContext(), RawBytes);
}

/// If this Offset points exactly to the start of an aggregate element, return
/// that element, otherwise return nullptr.
Constant *getConstantAtOffset(Constant *Base, APInt Offset,
                              const DataLayout &DL) {
  if (Offset.isZero())
    return Base;

  if (!isa<ConstantAggregate>(Base) && !isa<ConstantDataSequential>(Base))
    return nullptr;

  Type *ElemTy = Base->getType();
  SmallVector<APInt> Indices = DL.getGEPIndicesForOffset(ElemTy, Offset);
  if (!Offset.isZero() || !Indices[0].isZero())
    return nullptr;

  Constant *C = Base;
  for (const APInt &Index : drop_begin(Indices)) {
    if (Index.isNegative() || Index.getActiveBits() >= 32)
      return nullptr;

    C = C->getAggregateElement(Index.getZExtValue());
    if (!C)
      return nullptr;
  }

  return C;
}

Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,
                                          const APInt &Offset,
                                          const DataLayout &DL) {
  if (Constant *AtOffset = getConstantAtOffset(C, Offset, DL))
    if (Constant *Result = ConstantFoldLoadThroughBitcast(AtOffset, Ty, DL))
      return Result;

  // Explicitly check for out-of-bounds access, so we return poison even if the
  // constant is a uniform value.
  TypeSize Size = DL.getTypeAllocSize(C->getType());
  if (!Size.isScalable() && Offset.sge(Size.getFixedValue()))
    return PoisonValue::get(Ty);

  // Try an offset-independent fold of a uniform value.
  if (Constant *Result = ConstantFoldLoadFromUniformValue(C, Ty, DL))
    return Result;

  // Try hard to fold loads from bitcasted strange and non-type-safe things.
  if (Offset.getSignificantBits() <= 64)
    if (Constant *Result =
            FoldReinterpretLoadFromConst(C, Ty, Offset.getSExtValue(), DL))
      return Result;

  return nullptr;
}

Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,
                                          const DataLayout &DL) {
  return ConstantFoldLoadFromConst(C, Ty, APInt(64, 0), DL);
}

Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty,
                                             APInt Offset,
                                             const DataLayout &DL) {
  // We can only fold loads from constant globals with a definitive initializer.
  // Check this upfront, to skip expensive offset calculations.
  auto *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(C));
  if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
    return nullptr;

  C = cast<Constant>(C->stripAndAccumulateConstantOffsets(
          DL, Offset, /* AllowNonInbounds */ true));

  if (C == GV)
    if (Constant *Result = ConstantFoldLoadFromConst(GV->getInitializer(), Ty,
                                                     Offset, DL))
      return Result;

  // If this load comes from anywhere in a uniform constant global, the value
  // is always the same, regardless of the loaded offset.
  return ConstantFoldLoadFromUniformValue(GV->getInitializer(), Ty, DL);
}

Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty,
                                             const DataLayout &DL) {
  APInt Offset(DL.getIndexTypeSizeInBits(C->getType()), 0);
  return ConstantFoldLoadFromConstPtr(C, Ty, std::move(Offset), DL);
}

Constant *llvm::ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty,
                                                 const DataLayout &DL) {
  if (isa<PoisonValue>(C))
    return PoisonValue::get(Ty);
  if (isa<UndefValue>(C))
    return UndefValue::get(Ty);
  // If padding is needed when storing C to memory, then it isn't considered as
  // uniform.
  if (!DL.typeSizeEqualsStoreSize(C->getType()))
    return nullptr;
  if (C->isNullValue() && !Ty->isX86_AMXTy())
    return Constant::getNullValue(Ty);
  if (C->isAllOnesValue() &&
      (Ty->isIntOrIntVectorTy() || Ty->isFPOrFPVectorTy()))
    return Constant::getAllOnesValue(Ty);
  return nullptr;
}

namespace {

/// One of Op0/Op1 is a constant expression.
/// Attempt to symbolically evaluate the result of a binary operator merging
/// these together.  If target data info is available, it is provided as DL,
/// otherwise DL is null.
Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0, Constant *Op1,
                                    const DataLayout &DL) {
  // SROA

  // Fold (and 0xffffffff00000000, (shl x, 32)) -> shl.
  // Fold (lshr (or X, Y), 32) -> (lshr [X/Y], 32) if one doesn't contribute
  // bits.

  if (Opc == Instruction::And) {
    KnownBits Known0 = computeKnownBits(Op0, DL);
    KnownBits Known1 = computeKnownBits(Op1, DL);
    if ((Known1.One | Known0.Zero).isAllOnes()) {
      // All the bits of Op0 that the 'and' could be masking are already zero.
      return Op0;
    }
    if ((Known0.One | Known1.Zero).isAllOnes()) {
      // All the bits of Op1 that the 'and' could be masking are already zero.
      return Op1;
    }

    Known0 &= Known1;
    if (Known0.isConstant())
      return ConstantInt::get(Op0->getType(), Known0.getConstant());
  }

  // If the constant expr is something like &A[123] - &A[4].f, fold this into a
  // constant.  This happens frequently when iterating over a global array.
  if (Opc == Instruction::Sub) {
    GlobalValue *GV1, *GV2;
    APInt Offs1, Offs2;

    if (IsConstantOffsetFromGlobal(Op0, GV1, Offs1, DL))
      if (IsConstantOffsetFromGlobal(Op1, GV2, Offs2, DL) && GV1 == GV2) {
        unsigned OpSize = DL.getTypeSizeInBits(Op0->getType());

        // (&GV+C1) - (&GV+C2) -> C1-C2, pointer arithmetic cannot overflow.
        // PtrToInt may change the bitwidth so we have convert to the right size
        // first.
        return ConstantInt::get(Op0->getType(), Offs1.zextOrTrunc(OpSize) -
                                                Offs2.zextOrTrunc(OpSize));
      }
  }

  return nullptr;
}

/// If array indices are not pointer-sized integers, explicitly cast them so
/// that they aren't implicitly casted by the getelementptr.
Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops,
                         Type *ResultTy, GEPNoWrapFlags NW,
                         std::optional<ConstantRange> InRange,
                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
  Type *IntIdxTy = DL.getIndexType(ResultTy);
  Type *IntIdxScalarTy = IntIdxTy->getScalarType();

  bool Any = false;
  SmallVector<Constant*, 32> NewIdxs;
  for (unsigned i = 1, e = Ops.size(); i != e; ++i) {
    if ((i == 1 ||
         !isa<StructType>(GetElementPtrInst::getIndexedType(
             SrcElemTy, Ops.slice(1, i - 1)))) &&
        Ops[i]->getType()->getScalarType() != IntIdxScalarTy) {
      Any = true;
      Type *NewType =
          Ops[i]->getType()->isVectorTy() ? IntIdxTy : IntIdxScalarTy;
      Constant *NewIdx = ConstantFoldCastOperand(
          CastInst::getCastOpcode(Ops[i], true, NewType, true), Ops[i], NewType,
          DL);
      if (!NewIdx)
        return nullptr;
      NewIdxs.push_back(NewIdx);
    } else
      NewIdxs.push_back(Ops[i]);
  }

  if (!Any)
    return nullptr;

  Constant *C =
      ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], NewIdxs, NW, InRange);
  return ConstantFoldConstant(C, DL, TLI);
}

/// If we can symbolically evaluate the GEP constant expression, do so.
Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
                                  ArrayRef<Constant *> Ops,
                                  const DataLayout &DL,
                                  const TargetLibraryInfo *TLI) {
  Type *SrcElemTy = GEP->getSourceElementType();
  Type *ResTy = GEP->getType();
  if (!SrcElemTy->isSized() || isa<ScalableVectorType>(SrcElemTy))
    return nullptr;

  if (Constant *C = CastGEPIndices(SrcElemTy, Ops, ResTy, GEP->getNoWrapFlags(),
                                   GEP->getInRange(), DL, TLI))
    return C;

  Constant *Ptr = Ops[0];
  if (!Ptr->getType()->isPointerTy())
    return nullptr;

  Type *IntIdxTy = DL.getIndexType(Ptr->getType());

  for (unsigned i = 1, e = Ops.size(); i != e; ++i)
    if (!isa<ConstantInt>(Ops[i]) || !Ops[i]->getType()->isIntegerTy())
      return nullptr;

  unsigned BitWidth = DL.getTypeSizeInBits(IntIdxTy);
  APInt Offset = APInt(
      BitWidth,
      DL.getIndexedOffsetInType(
          SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)),
      /*isSigned=*/true, /*implicitTrunc=*/true);

  std::optional<ConstantRange> InRange = GEP->getInRange();
  if (InRange)
    InRange = InRange->sextOrTrunc(BitWidth);

  // If this is a GEP of a GEP, fold it all into a single GEP.
  GEPNoWrapFlags NW = GEP->getNoWrapFlags();
  bool Overflow = false;
  while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
    NW &= GEP->getNoWrapFlags();

    SmallVector<Value *, 4> NestedOps(llvm::drop_begin(GEP->operands()));

    // Do not try the incorporate the sub-GEP if some index is not a number.
    bool AllConstantInt = true;
    for (Value *NestedOp : NestedOps)
      if (!isa<ConstantInt>(NestedOp)) {
        AllConstantInt = false;
        break;
      }
    if (!AllConstantInt)
      break;

    // Adjust inrange offset and intersect inrange attributes
    if (auto GEPRange = GEP->getInRange()) {
      auto AdjustedGEPRange = GEPRange->sextOrTrunc(BitWidth).subtract(Offset);
      InRange =
          InRange ? InRange->intersectWith(AdjustedGEPRange) : AdjustedGEPRange;
    }

    Ptr = cast<Constant>(GEP->getOperand(0));
    SrcElemTy = GEP->getSourceElementType();
    Offset = Offset.sadd_ov(
        APInt(BitWidth, DL.getIndexedOffsetInType(SrcElemTy, NestedOps),
              /*isSigned=*/true, /*implicitTrunc=*/true),
        Overflow);
  }

  // Preserving nusw (without inbounds) also requires that the offset
  // additions did not overflow.
  if (NW.hasNoUnsignedSignedWrap() && !NW.isInBounds() && Overflow)
    NW = NW.withoutNoUnsignedSignedWrap();

  // If the base value for this address is a literal integer value, fold the
  // getelementptr to the resulting integer value casted to the pointer type.
  APInt BasePtr(DL.getPointerTypeSizeInBits(Ptr->getType()), 0);
  if (auto *CE = dyn_cast<ConstantExpr>(Ptr)) {
    if (CE->getOpcode() == Instruction::IntToPtr) {
      if (auto *Base = dyn_cast<ConstantInt>(CE->getOperand(0)))
        BasePtr = Base->getValue().zextOrTrunc(BasePtr.getBitWidth());
    }
  }

  auto *PTy = cast<PointerType>(Ptr->getType());
  if ((Ptr->isNullValue() || BasePtr != 0) &&
      !DL.isNonIntegralPointerType(PTy)) {
    // If the index size is smaller than the pointer size, add to the low
    // bits only.
    BasePtr.insertBits(BasePtr.trunc(BitWidth) + Offset, 0);
    Constant *C = ConstantInt::get(Ptr->getContext(), BasePtr);
    return ConstantExpr::getIntToPtr(C, ResTy);
  }

  // Try to infer inbounds for GEPs of globals.
  if (!NW.isInBounds() && Offset.isNonNegative()) {
    bool CanBeNull, CanBeFreed;
    uint64_t DerefBytes =
        Ptr->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
    if (DerefBytes != 0 && !CanBeNull && Offset.sle(DerefBytes))
      NW |= GEPNoWrapFlags::inBounds();
  }

  // nusw + nneg -> nuw
  if (NW.hasNoUnsignedSignedWrap() && Offset.isNonNegative())
    NW |= GEPNoWrapFlags::noUnsignedWrap();

  // Otherwise canonicalize this to a single ptradd.
  LLVMContext &Ctx = Ptr->getContext();
  return ConstantExpr::getGetElementPtr(Type::getInt8Ty(Ctx), Ptr,
                                        ConstantInt::get(Ctx, Offset), NW,
                                        InRange);
}

/// Attempt to constant fold an instruction with the
/// specified opcode and operands.  If successful, the constant result is
/// returned, if not, null is returned.  Note that this function can fail when
/// attempting to fold instructions like loads and stores, which have no
/// constant expression form.
Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode,
                                       ArrayRef<Constant *> Ops,
                                       const DataLayout &DL,
                                       const TargetLibraryInfo *TLI,
                                       bool AllowNonDeterministic) {
  Type *DestTy = InstOrCE->getType();

  if (Instruction::isUnaryOp(Opcode))
    return ConstantFoldUnaryOpOperand(Opcode, Ops[0], DL);

  if (Instruction::isBinaryOp(Opcode)) {
    switch (Opcode) {
    default:
      break;
    case Instruction::FAdd:
    case Instruction::FSub:
    case Instruction::FMul:
    case Instruction::FDiv:
    case Instruction::FRem:
      // Handle floating point instructions separately to account for denormals
      // TODO: If a constant expression is being folded rather than an
      // instruction, denormals will not be flushed/treated as zero
      if (const auto *I = dyn_cast<Instruction>(InstOrCE)) {
        return ConstantFoldFPInstOperands(Opcode, Ops[0], Ops[1], DL, I,
                                          AllowNonDeterministic);
      }
    }
    return ConstantFoldBinaryOpOperands(Opcode, Ops[0], Ops[1], DL);
  }

  if (Instruction::isCast(Opcode))
    return ConstantFoldCastOperand(Opcode, Ops[0], DestTy, DL);

  if (auto *GEP = dyn_cast<GEPOperator>(InstOrCE)) {
    Type *SrcElemTy = GEP->getSourceElementType();
    if (!ConstantExpr::isSupportedGetElementPtr(SrcElemTy))
      return nullptr;

    if (Constant *C = SymbolicallyEvaluateGEP(GEP, Ops, DL, TLI))
      return C;

    return ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], Ops.slice(1),
                                          GEP->getNoWrapFlags(),
                                          GEP->getInRange());
  }

  if (auto *CE = dyn_cast<ConstantExpr>(InstOrCE))
    return CE->getWithOperands(Ops);

  switch (Opcode) {
  default: return nullptr;
  case Instruction::ICmp:
  case Instruction::FCmp: {
    auto *C = cast<CmpInst>(InstOrCE);
    return ConstantFoldCompareInstOperands(C->getPredicate(), Ops[0], Ops[1],
                                           DL, TLI, C);
  }
  case Instruction::Freeze:
    return isGuaranteedNotToBeUndefOrPoison(Ops[0]) ? Ops[0] : nullptr;
  case Instruction::Call:
    if (auto *F = dyn_cast<Function>(Ops.back())) {
      const auto *Call = cast<CallBase>(InstOrCE);
      if (canConstantFoldCallTo(Call, F))
        return ConstantFoldCall(Call, F, Ops.slice(0, Ops.size() - 1), TLI,
                                AllowNonDeterministic);
    }
    return nullptr;
  case Instruction::Select:
    return ConstantFoldSelectInstruction(Ops[0], Ops[1], Ops[2]);
  case Instruction::ExtractElement:
    return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
  case Instruction::ExtractValue:
    return ConstantFoldExtractValueInstruction(
        Ops[0], cast<ExtractValueInst>(InstOrCE)->getIndices());
  case Instruction::InsertElement:
    return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);
  case Instruction::InsertValue:
    return ConstantFoldInsertValueInstruction(
        Ops[0], Ops[1], cast<InsertValueInst>(InstOrCE)->getIndices());
  case Instruction::ShuffleVector:
    return ConstantExpr::getShuffleVector(
        Ops[0], Ops[1], cast<ShuffleVectorInst>(InstOrCE)->getShuffleMask());
  case Instruction::Load: {
    const auto *LI = dyn_cast<LoadInst>(InstOrCE);
    if (LI->isVolatile())
      return nullptr;
    return ConstantFoldLoadFromConstPtr(Ops[0], LI->getType(), DL);
  }
  }
}

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Constant Folding public APIs
//===----------------------------------------------------------------------===//

namespace {

Constant *
ConstantFoldConstantImpl(const Constant *C, const DataLayout &DL,
                         const TargetLibraryInfo *TLI,
                         SmallDenseMap<Constant *, Constant *> &FoldedOps) {
  if (!isa<ConstantVector>(C) && !isa<ConstantExpr>(C))
    return const_cast<Constant *>(C);

  SmallVector<Constant *, 8> Ops;
  for (const Use &OldU : C->operands()) {
    Constant *OldC = cast<Constant>(&OldU);
    Constant *NewC = OldC;
    // Recursively fold the ConstantExpr's operands. If we have already folded
    // a ConstantExpr, we don't have to process it again.
    if (isa<ConstantVector>(OldC) || isa<ConstantExpr>(OldC)) {
      auto It = FoldedOps.find(OldC);
      if (It == FoldedOps.end()) {
        NewC = ConstantFoldConstantImpl(OldC, DL, TLI, FoldedOps);
        FoldedOps.insert({OldC, NewC});
      } else {
        NewC = It->second;
      }
    }
    Ops.push_back(NewC);
  }

  if (auto *CE = dyn_cast<ConstantExpr>(C)) {
    if (Constant *Res = ConstantFoldInstOperandsImpl(
            CE, CE->getOpcode(), Ops, DL, TLI, /*AllowNonDeterministic=*/true))
      return Res;
    return const_cast<Constant *>(C);
  }

  assert(isa<ConstantVector>(C));
  return ConstantVector::get(Ops);
}

} // end anonymous namespace

Constant *llvm::ConstantFoldInstruction(const Instruction *I,
                                        const DataLayout &DL,
                                        const TargetLibraryInfo *TLI) {
  // Handle PHI nodes quickly here...
  if (auto *PN = dyn_cast<PHINode>(I)) {
    Constant *CommonValue = nullptr;

    SmallDenseMap<Constant *, Constant *> FoldedOps;
    for (Value *Incoming : PN->incoming_values()) {
      // If the incoming value is undef then skip it.  Note that while we could
      // skip the value if it is equal to the phi node itself we choose not to
      // because that would break the rule that constant folding only applies if
      // all operands are constants.
      if (isa<UndefValue>(Incoming))
        continue;
      // If the incoming value is not a constant, then give up.
      auto *C = dyn_cast<Constant>(Incoming);
      if (!C)
        return nullptr;
      // Fold the PHI's operands.
      C = ConstantFoldConstantImpl(C, DL, TLI, FoldedOps);
      // If the incoming value is a different constant to
      // the one we saw previously, then give up.
      if (CommonValue && C != CommonValue)
        return nullptr;
      CommonValue = C;
    }

    // If we reach here, all incoming values are the same constant or undef.
    return CommonValue ? CommonValue : UndefValue::get(PN->getType());
  }

  // Scan the operand list, checking to see if they are all constants, if so,
  // hand off to ConstantFoldInstOperandsImpl.
  if (!all_of(I->operands(), [](const Use &U) { return isa<Constant>(U); }))
    return nullptr;

  SmallDenseMap<Constant *, Constant *> FoldedOps;
  SmallVector<Constant *, 8> Ops;
  for (const Use &OpU : I->operands()) {
    auto *Op = cast<Constant>(&OpU);
    // Fold the Instruction's operands.
    Op = ConstantFoldConstantImpl(Op, DL, TLI, FoldedOps);
    Ops.push_back(Op);
  }

  return ConstantFoldInstOperands(I, Ops, DL, TLI);
}

Constant *llvm::ConstantFoldConstant(const Constant *C, const DataLayout &DL,
                                     const TargetLibraryInfo *TLI) {
  SmallDenseMap<Constant *, Constant *> FoldedOps;
  return ConstantFoldConstantImpl(C, DL, TLI, FoldedOps);
}

Constant *llvm::ConstantFoldInstOperands(const Instruction *I,
                                         ArrayRef<Constant *> Ops,
                                         const DataLayout &DL,
                                         const TargetLibraryInfo *TLI,
                                         bool AllowNonDeterministic) {
  return ConstantFoldInstOperandsImpl(I, I->getOpcode(), Ops, DL, TLI,
                                      AllowNonDeterministic);
}

Constant *llvm::ConstantFoldCompareInstOperands(
    unsigned IntPredicate, Constant *Ops0, Constant *Ops1, const DataLayout &DL,
    const TargetLibraryInfo *TLI, const Instruction *I) {
  CmpInst::Predicate Predicate = (CmpInst::Predicate)IntPredicate;
  // fold: icmp (inttoptr x), null         -> icmp x, 0
  // fold: icmp null, (inttoptr x)         -> icmp 0, x
  // fold: icmp (ptrtoint x), 0            -> icmp x, null
  // fold: icmp 0, (ptrtoint x)            -> icmp null, x
  // fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y
  // fold: icmp (ptrtoint x), (ptrtoint y) -> icmp x, y
  //
  // FIXME: The following comment is out of data and the DataLayout is here now.
  // ConstantExpr::getCompare cannot do this, because it doesn't have DL
  // around to know if bit truncation is happening.
  if (auto *CE0 = dyn_cast<ConstantExpr>(Ops0)) {
    if (Ops1->isNullValue()) {
      if (CE0->getOpcode() == Instruction::IntToPtr) {
        Type *IntPtrTy = DL.getIntPtrType(CE0->getType());
        // Convert the integer value to the right size to ensure we get the
        // proper extension or truncation.
        if (Constant *C = ConstantFoldIntegerCast(CE0->getOperand(0), IntPtrTy,
                                                  /*IsSigned*/ false, DL)) {
          Constant *Null = Constant::getNullValue(C->getType());
          return ConstantFoldCompareInstOperands(Predicate, C, Null, DL, TLI);
        }
      }

      // Only do this transformation if the int is intptrty in size, otherwise
      // there is a truncation or extension that we aren't modeling.
      if (CE0->getOpcode() == Instruction::PtrToInt) {
        Type *IntPtrTy = DL.getIntPtrType(CE0->getOperand(0)->getType());
        if (CE0->getType() == IntPtrTy) {
          Constant *C = CE0->getOperand(0);
          Constant *Null = Constant::getNullValue(C->getType());
          return ConstantFoldCompareInstOperands(Predicate, C, Null, DL, TLI);
        }
      }
    }

    if (auto *CE1 = dyn_cast<ConstantExpr>(Ops1)) {
      if (CE0->getOpcode() == CE1->getOpcode()) {
        if (CE0->getOpcode() == Instruction::IntToPtr) {
          Type *IntPtrTy = DL.getIntPtrType(CE0->getType());

          // Convert the integer value to the right size to ensure we get the
          // proper extension or truncation.
          Constant *C0 = ConstantFoldIntegerCast(CE0->getOperand(0), IntPtrTy,
                                                 /*IsSigned*/ false, DL);
          Constant *C1 = ConstantFoldIntegerCast(CE1->getOperand(0), IntPtrTy,
                                                 /*IsSigned*/ false, DL);
          if (C0 && C1)
            return ConstantFoldCompareInstOperands(Predicate, C0, C1, DL, TLI);
        }

        // Only do this transformation if the int is intptrty in size, otherwise
        // there is a truncation or extension that we aren't modeling.
        if (CE0->getOpcode() == Instruction::PtrToInt) {
          Type *IntPtrTy = DL.getIntPtrType(CE0->getOperand(0)->getType());
          if (CE0->getType() == IntPtrTy &&
              CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType()) {
            return ConstantFoldCompareInstOperands(
                Predicate, CE0->getOperand(0), CE1->getOperand(0), DL, TLI);
          }
        }
      }
    }

    // Convert pointer comparison (base+offset1) pred (base+offset2) into
    // offset1 pred offset2, for the case where the offset is inbounds. This
    // only works for equality and unsigned comparison, as inbounds permits
    // crossing the sign boundary. However, the offset comparison itself is
    // signed.
    if (Ops0->getType()->isPointerTy() && !ICmpInst::isSigned(Predicate)) {
      unsigned IndexWidth = DL.getIndexTypeSizeInBits(Ops0->getType());
      APInt Offset0(IndexWidth, 0);
      bool IsEqPred = ICmpInst::isEquality(Predicate);
      Value *Stripped0 = Ops0->stripAndAccumulateConstantOffsets(
          DL, Offset0, /*AllowNonInbounds=*/IsEqPred,
          /*AllowInvariantGroup=*/false, /*ExternalAnalysis=*/nullptr,
          /*LookThroughIntToPtr=*/IsEqPred);
      APInt Offset1(IndexWidth, 0);
      Value *Stripped1 = Ops1->stripAndAccumulateConstantOffsets(
          DL, Offset1, /*AllowNonInbounds=*/IsEqPred,
          /*AllowInvariantGroup=*/false, /*ExternalAnalysis=*/nullptr,
          /*LookThroughIntToPtr=*/IsEqPred);
      if (Stripped0 == Stripped1)
        return ConstantInt::getBool(
            Ops0->getContext(),
            ICmpInst::compare(Offset0, Offset1,
                              ICmpInst::getSignedPredicate(Predicate)));
    }
  } else if (isa<ConstantExpr>(Ops1)) {
    // If RHS is a constant expression, but the left side isn't, swap the
    // operands and try again.
    Predicate = ICmpInst::getSwappedPredicate(Predicate);
    return ConstantFoldCompareInstOperands(Predicate, Ops1, Ops0, DL, TLI);
  }

  if (CmpInst::isFPPredicate(Predicate)) {
    // Flush any denormal constant float input according to denormal handling
    // mode.
    Ops0 = FlushFPConstant(Ops0, I, /*IsOutput=*/false);
    if (!Ops0)
      return nullptr;
    Ops1 = FlushFPConstant(Ops1, I, /*IsOutput=*/false);
    if (!Ops1)
      return nullptr;
  }

  return ConstantFoldCompareInstruction(Predicate, Ops0, Ops1);
}

Constant *llvm::ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op,
                                           const DataLayout &DL) {
  assert(Instruction::isUnaryOp(Opcode));

  return ConstantFoldUnaryInstruction(Opcode, Op);
}

Constant *llvm::ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS,
                                             Constant *RHS,
                                             const DataLayout &DL) {
  assert(Instruction::isBinaryOp(Opcode));
  if (isa<ConstantExpr>(LHS) || isa<ConstantExpr>(RHS))
    if (Constant *C = SymbolicallyEvaluateBinop(Opcode, LHS, RHS, DL))
      return C;

  if (ConstantExpr::isDesirableBinOp(Opcode))
    return ConstantExpr::get(Opcode, LHS, RHS);
  return ConstantFoldBinaryInstruction(Opcode, LHS, RHS);
}

static ConstantFP *flushDenormalConstant(Type *Ty, const APFloat &APF,
                                         DenormalMode::DenormalModeKind Mode) {
  switch (Mode) {
  case DenormalMode::Dynamic:
    return nullptr;
  case DenormalMode::IEEE:
    return ConstantFP::get(Ty->getContext(), APF);
  case DenormalMode::PreserveSign:
    return ConstantFP::get(
        Ty->getContext(),
        APFloat::getZero(APF.getSemantics(), APF.isNegative()));
  case DenormalMode::PositiveZero:
    return ConstantFP::get(Ty->getContext(),
                           APFloat::getZero(APF.getSemantics(), false));
  default:
    break;
  }

  llvm_unreachable("unknown denormal mode");
}

/// Return the denormal mode that can be assumed when executing a floating point
/// operation at \p CtxI.
static DenormalMode getInstrDenormalMode(const Instruction *CtxI, Type *Ty) {
  if (!CtxI || !CtxI->getParent() || !CtxI->getFunction())
    return DenormalMode::getDynamic();
  return CtxI->getFunction()->getDenormalMode(Ty->getFltSemantics());
}

static ConstantFP *flushDenormalConstantFP(ConstantFP *CFP,
                                           const Instruction *Inst,
                                           bool IsOutput) {
  const APFloat &APF = CFP->getValueAPF();
  if (!APF.isDenormal())
    return CFP;

  DenormalMode Mode = getInstrDenormalMode(Inst, CFP->getType());
  return flushDenormalConstant(CFP->getType(), APF,
                               IsOutput ? Mode.Output : Mode.Input);
}

Constant *llvm::FlushFPConstant(Constant *Operand, const Instruction *Inst,
                                bool IsOutput) {
  if (ConstantFP *CFP = dyn_cast<ConstantFP>(Operand))
    return flushDenormalConstantFP(CFP, Inst, IsOutput);

  if (isa<ConstantAggregateZero, UndefValue>(Operand))
    return Operand;

  Type *Ty = Operand->getType();
  VectorType *VecTy = dyn_cast<VectorType>(Ty);
  if (VecTy) {
    if (auto *Splat = dyn_cast_or_null<ConstantFP>(Operand->getSplatValue())) {
      ConstantFP *Folded = flushDenormalConstantFP(Splat, Inst, IsOutput);
      if (!Folded)
        return nullptr;
      return ConstantVector::getSplat(VecTy->getElementCount(), Folded);
    }

    Ty = VecTy->getElementType();
  }

  if (isa<ConstantExpr>(Operand))
    return Operand;

  if (const auto *CV = dyn_cast<ConstantVector>(Operand)) {
    SmallVector<Constant *, 16> NewElts;
    for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {
      Constant *Element = CV->getAggregateElement(i);
      if (isa<UndefValue>(Element)) {
        NewElts.push_back(Element);
        continue;
      }

      ConstantFP *CFP = dyn_cast<ConstantFP>(Element);
      if (!CFP)
        return nullptr;

      ConstantFP *Folded = flushDenormalConstantFP(CFP, Inst, IsOutput);
      if (!Folded)
        return nullptr;
      NewElts.push_back(Folded);
    }

    return ConstantVector::get(NewElts);
  }

  if (const auto *CDV = dyn_cast<ConstantDataVector>(Operand)) {
    SmallVector<Constant *, 16> NewElts;
    for (unsigned I = 0, E = CDV->getNumElements(); I < E; ++I) {
      const APFloat &Elt = CDV->getElementAsAPFloat(I);
      if (!Elt.isDenormal()) {
        NewElts.push_back(ConstantFP::get(Ty, Elt));
      } else {
        DenormalMode Mode = getInstrDenormalMode(Inst, Ty);
        ConstantFP *Folded =
            flushDenormalConstant(Ty, Elt, IsOutput ? Mode.Output : Mode.Input);
        if (!Folded)
          return nullptr;
        NewElts.push_back(Folded);
      }
    }

    return ConstantVector::get(NewElts);
  }

  return nullptr;
}

Constant *llvm::ConstantFoldFPInstOperands(unsigned Opcode, Constant *LHS,
                                           Constant *RHS, const DataLayout &DL,
                                           const Instruction *I,
                                           bool AllowNonDeterministic) {
  if (Instruction::isBinaryOp(Opcode)) {
    // Flush denormal inputs if needed.
    Constant *Op0 = FlushFPConstant(LHS, I, /* IsOutput */ false);
    if (!Op0)
      return nullptr;
    Constant *Op1 = FlushFPConstant(RHS, I, /* IsOutput */ false);
    if (!Op1)
      return nullptr;

    // If nsz or an algebraic FMF flag is set, the result of the FP operation
    // may change due to future optimization. Don't constant fold them if
    // non-deterministic results are not allowed.
    if (!AllowNonDeterministic)
      if (auto *FP = dyn_cast_or_null<FPMathOperator>(I))
        if (FP->hasNoSignedZeros() || FP->hasAllowReassoc() ||
            FP->hasAllowContract() || FP->hasAllowReciprocal())
          return nullptr;

    // Calculate constant result.
    Constant *C = ConstantFoldBinaryOpOperands(Opcode, Op0, Op1, DL);
    if (!C)
      return nullptr;

    // Flush denormal output if needed.
    C = FlushFPConstant(C, I, /* IsOutput */ true);
    if (!C)
      return nullptr;

    // The precise NaN value is non-deterministic.
    if (!AllowNonDeterministic && C->isNaN())
      return nullptr;

    return C;
  }
  // If instruction lacks a parent/function and the denormal mode cannot be
  // determined, use the default (IEEE).
  return ConstantFoldBinaryOpOperands(Opcode, LHS, RHS, DL);
}

Constant *llvm::ConstantFoldCastOperand(unsigned Opcode, Constant *C,
                                        Type *DestTy, const DataLayout &DL) {
  assert(Instruction::isCast(Opcode));
  switch (Opcode) {
  default:
    llvm_unreachable("Missing case");
  case Instruction::PtrToAddr:
    // TODO: Add some of the ptrtoint folds here as well.
    break;
  case Instruction::PtrToInt:
    if (auto *CE = dyn_cast<ConstantExpr>(C)) {
      Constant *FoldedValue = nullptr;
      // If the input is a inttoptr, eliminate the pair.  This requires knowing
      // the width of a pointer, so it can't be done in ConstantExpr::getCast.
      if (CE->getOpcode() == Instruction::IntToPtr) {
        // zext/trunc the inttoptr to pointer size.
        FoldedValue = ConstantFoldIntegerCast(CE->getOperand(0),
                                              DL.getIntPtrType(CE->getType()),
                                              /*IsSigned=*/false, DL);
      } else if (auto *GEP = dyn_cast<GEPOperator>(CE)) {
        // If we have GEP, we can perform the following folds:
        // (ptrtoint (gep null, x)) -> x
        // (ptrtoint (gep (gep null, x), y) -> x + y, etc.
        unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
        APInt BaseOffset(BitWidth, 0);
        auto *Base = cast<Constant>(GEP->stripAndAccumulateConstantOffsets(
            DL, BaseOffset, /*AllowNonInbounds=*/true));
        if (Base->isNullValue()) {
          FoldedValue = ConstantInt::get(CE->getContext(), BaseOffset);
        } else {
          // ptrtoint (gep i8, Ptr, (sub 0, V)) -> sub (ptrtoint Ptr), V
          if (GEP->getNumIndices() == 1 &&
              GEP->getSourceElementType()->isIntegerTy(8)) {
            auto *Ptr = cast<Constant>(GEP->getPointerOperand());
            auto *Sub = dyn_cast<ConstantExpr>(GEP->getOperand(1));
            Type *IntIdxTy = DL.getIndexType(Ptr->getType());
            if (Sub && Sub->getType() == IntIdxTy &&
                Sub->getOpcode() == Instruction::Sub &&
                Sub->getOperand(0)->isNullValue())
              FoldedValue = ConstantExpr::getSub(
                  ConstantExpr::getPtrToInt(Ptr, IntIdxTy), Sub->getOperand(1));
          }
        }
      }
      if (FoldedValue) {
        // Do a zext or trunc to get to the ptrtoint dest size.
        return ConstantFoldIntegerCast(FoldedValue, DestTy, /*IsSigned=*/false,
                                       DL);
      }
    }
    break;
  case Instruction::IntToPtr:
    // If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if
    // the int size is >= the ptr size and the address spaces are the same.
    // This requires knowing the width of a pointer, so it can't be done in
    // ConstantExpr::getCast.
    if (auto *CE = dyn_cast<ConstantExpr>(C)) {
      if (CE->getOpcode() == Instruction::PtrToInt) {
        Constant *SrcPtr = CE->getOperand(0);
        unsigned SrcPtrSize = DL.getPointerTypeSizeInBits(SrcPtr->getType());
        unsigned MidIntSize = CE->getType()->getScalarSizeInBits();

        if (MidIntSize >= SrcPtrSize) {
          unsigned SrcAS = SrcPtr->getType()->getPointerAddressSpace();
          if (SrcAS == DestTy->getPointerAddressSpace())
            return FoldBitCast(CE->getOperand(0), DestTy, DL);
        }
      }
    }
    break;
  case Instruction::Trunc:
  case Instruction::ZExt:
  case Instruction::SExt:
  case Instruction::FPTrunc:
  case Instruction::FPExt:
  case Instruction::UIToFP:
  case Instruction::SIToFP:
  case Instruction::FPToUI:
  case Instruction::FPToSI:
  case Instruction::AddrSpaceCast:
    break;
  case Instruction::BitCast:
    return FoldBitCast(C, DestTy, DL);
  }

  if (ConstantExpr::isDesirableCastOp(Opcode))
    return ConstantExpr::getCast(Opcode, C, DestTy);
  return ConstantFoldCastInstruction(Opcode, C, DestTy);
}

Constant *llvm::ConstantFoldIntegerCast(Constant *C, Type *DestTy,
                                        bool IsSigned, const DataLayout &DL) {
  Type *SrcTy = C->getType();
  if (SrcTy == DestTy)
    return C;
  if (SrcTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits())
    return ConstantFoldCastOperand(Instruction::Trunc, C, DestTy, DL);
  if (IsSigned)
    return ConstantFoldCastOperand(Instruction::SExt, C, DestTy, DL);
  return ConstantFoldCastOperand(Instruction::ZExt, C, DestTy, DL);
}

//===----------------------------------------------------------------------===//
//  Constant Folding for Calls
//

bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
  if (Call->isNoBuiltin())
    return false;
  if (Call->getFunctionType() != F->getFunctionType())
    return false;

  // Allow FP calls (both libcalls and intrinsics) to avoid being folded.
  // This can be useful for GPU targets or in cross-compilation scenarios
  // when the exact target FP behaviour is required, and the host compiler's
  // behaviour may be slightly different from the device's run-time behaviour.
  if (DisableFPCallFolding && (F->getReturnType()->isFloatingPointTy() ||
                               any_of(F->args(), [](const Argument &Arg) {
                                 return Arg.getType()->isFloatingPointTy();
                               })))
    return false;

  switch (F->getIntrinsicID()) {
  // Operations that do not operate floating-point numbers and do not depend on
  // FP environment can be folded even in strictfp functions.
  case Intrinsic::bswap:
  case Intrinsic::ctpop:
  case Intrinsic::ctlz:
  case Intrinsic::cttz:
  case Intrinsic::fshl:
  case Intrinsic::fshr:
  case Intrinsic::launder_invariant_group:
  case Intrinsic::strip_invariant_group:
  case Intrinsic::masked_load:
  case Intrinsic::get_active_lane_mask:
  case Intrinsic::abs:
  case Intrinsic::smax:
  case Intrinsic::smin:
  case Intrinsic::umax:
  case Intrinsic::umin:
  case Intrinsic::scmp:
  case Intrinsic::ucmp:
  case Intrinsic::sadd_with_overflow:
  case Intrinsic::uadd_with_overflow:
  case Intrinsic::ssub_with_overflow:
  case Intrinsic::usub_with_overflow:
  case Intrinsic::smul_with_overflow:
  case Intrinsic::umul_with_overflow:
  case Intrinsic::sadd_sat:
  case Intrinsic::uadd_sat:
  case Intrinsic::ssub_sat:
  case Intrinsic::usub_sat:
  case Intrinsic::smul_fix:
  case Intrinsic::smul_fix_sat:
  case Intrinsic::bitreverse:
  case Intrinsic::is_constant:
  case Intrinsic::vector_reduce_add:
  case Intrinsic::vector_reduce_mul:
  case Intrinsic::vector_reduce_and:
  case Intrinsic::vector_reduce_or:
  case Intrinsic::vector_reduce_xor:
  case Intrinsic::vector_reduce_smin:
  case Intrinsic::vector_reduce_smax:
  case Intrinsic::vector_reduce_umin:
  case Intrinsic::vector_reduce_umax:
  case Intrinsic::vector_extract:
  case Intrinsic::vector_insert:
  case Intrinsic::vector_interleave2:
  case Intrinsic::vector_deinterleave2:
  // Target intrinsics
  case Intrinsic::amdgcn_perm:
  case Intrinsic::amdgcn_wave_reduce_umin:
  case Intrinsic::amdgcn_wave_reduce_umax:
  case Intrinsic::amdgcn_s_wqm:
  case Intrinsic::amdgcn_s_quadmask:
  case Intrinsic::amdgcn_s_bitreplicate:
  case Intrinsic::arm_mve_vctp8:
  case Intrinsic::arm_mve_vctp16:
  case Intrinsic::arm_mve_vctp32:
  case Intrinsic::arm_mve_vctp64:
  case Intrinsic::aarch64_sve_convert_from_svbool:
  case Intrinsic::wasm_alltrue:
  case Intrinsic::wasm_anytrue:
  // WebAssembly float semantics are always known
  case Intrinsic::wasm_trunc_signed:
  case Intrinsic::wasm_trunc_unsigned:
    return true;

  // Floating point operations cannot be folded in strictfp functions in
  // general case. They can be folded if FP environment is known to compiler.
  case Intrinsic::minnum:
  case Intrinsic::maxnum:
  case Intrinsic::minimum:
  case Intrinsic::maximum:
  case Intrinsic::minimumnum:
  case Intrinsic::maximumnum:
  case Intrinsic::log:
  case Intrinsic::log2:
  case Intrinsic::log10:
  case Intrinsic::exp:
  case Intrinsic::exp2:
  case Intrinsic::exp10:
  case Intrinsic::sqrt:
  case Intrinsic::sin:
  case Intrinsic::cos:
  case Intrinsic::sincos:
  case Intrinsic::sinh:
  case Intrinsic::cosh:
  case Intrinsic::atan:
  case Intrinsic::pow:
  case Intrinsic::powi:
  case Intrinsic::ldexp:
  case Intrinsic::fma:
  case Intrinsic::fmuladd:
  case Intrinsic::frexp:
  case Intrinsic::fptoui_sat:
  case Intrinsic::fptosi_sat:
  case Intrinsic::convert_from_fp16:
  case Intrinsic::convert_to_fp16:
  case Intrinsic::amdgcn_cos:
  case Intrinsic::amdgcn_cubeid:
  case Intrinsic::amdgcn_cubema:
  case Intrinsic::amdgcn_cubesc:
  case Intrinsic::amdgcn_cubetc:
  case Intrinsic::amdgcn_fmul_legacy:
  case Intrinsic::amdgcn_fma_legacy:
  case Intrinsic::amdgcn_fract:
  case Intrinsic::amdgcn_sin:
  // The intrinsics below depend on rounding mode in MXCSR.
  case Intrinsic::x86_sse_cvtss2si:
  case Intrinsic::x86_sse_cvtss2si64:
  case Intrinsic::x86_sse_cvttss2si:
  case Intrinsic::x86_sse_cvttss2si64:
  case Intrinsic::x86_sse2_cvtsd2si:
  case Intrinsic::x86_sse2_cvtsd2si64:
  case Intrinsic::x86_sse2_cvttsd2si:
  case Intrinsic::x86_sse2_cvttsd2si64:
  case Intrinsic::x86_avx512_vcvtss2si32:
  case Intrinsic::x86_avx512_vcvtss2si64:
  case Intrinsic::x86_avx512_cvttss2si:
  case Intrinsic::x86_avx512_cvttss2si64:
  case Intrinsic::x86_avx512_vcvtsd2si32:
  case Intrinsic::x86_avx512_vcvtsd2si64:
  case Intrinsic::x86_avx512_cvttsd2si:
  case Intrinsic::x86_avx512_cvttsd2si64:
  case Intrinsic::x86_avx512_vcvtss2usi32:
  case Intrinsic::x86_avx512_vcvtss2usi64:
  case Intrinsic::x86_avx512_cvttss2usi:
  case Intrinsic::x86_avx512_cvttss2usi64:
  case Intrinsic::x86_avx512_vcvtsd2usi32:
  case Intrinsic::x86_avx512_vcvtsd2usi64:
  case Intrinsic::x86_avx512_cvttsd2usi:
  case Intrinsic::x86_avx512_cvttsd2usi64:

  // NVVM FMax intrinsics
  case Intrinsic::nvvm_fmax_d:
  case Intrinsic::nvvm_fmax_f:
  case Intrinsic::nvvm_fmax_ftz_f:
  case Intrinsic::nvvm_fmax_ftz_nan_f:
  case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:
  case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:
  case Intrinsic::nvvm_fmax_nan_f:
  case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:
  case Intrinsic::nvvm_fmax_xorsign_abs_f:

  // NVVM FMin intrinsics
  case Intrinsic::nvvm_fmin_d:
  case Intrinsic::nvvm_fmin_f:
  case Intrinsic::nvvm_fmin_ftz_f:
  case Intrinsic::nvvm_fmin_ftz_nan_f:
  case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f:
  case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f:
  case Intrinsic::nvvm_fmin_nan_f:
  case Intrinsic::nvvm_fmin_nan_xorsign_abs_f:
  case Intrinsic::nvvm_fmin_xorsign_abs_f:

  // NVVM float/double to int32/uint32 conversion intrinsics
  case Intrinsic::nvvm_f2i_rm:
  case Intrinsic::nvvm_f2i_rn:
  case Intrinsic::nvvm_f2i_rp:
  case Intrinsic::nvvm_f2i_rz:
  case Intrinsic::nvvm_f2i_rm_ftz:
  case Intrinsic::nvvm_f2i_rn_ftz:
  case Intrinsic::nvvm_f2i_rp_ftz:
  case Intrinsic::nvvm_f2i_rz_ftz:
  case Intrinsic::nvvm_f2ui_rm:
  case Intrinsic::nvvm_f2ui_rn:
  case Intrinsic::nvvm_f2ui_rp:
  case Intrinsic::nvvm_f2ui_rz:
  case Intrinsic::nvvm_f2ui_rm_ftz:
  case Intrinsic::nvvm_f2ui_rn_ftz:
  case Intrinsic::nvvm_f2ui_rp_ftz:
  case Intrinsic::nvvm_f2ui_rz_ftz:
  case Intrinsic::nvvm_d2i_rm:
  case Intrinsic::nvvm_d2i_rn:
  case Intrinsic::nvvm_d2i_rp:
  case Intrinsic::nvvm_d2i_rz:
  case Intrinsic::nvvm_d2ui_rm:
  case Intrinsic::nvvm_d2ui_rn:
  case Intrinsic::nvvm_d2ui_rp:
  case Intrinsic::nvvm_d2ui_rz:

  // NVVM float/double to int64/uint64 conversion intrinsics
  case Intrinsic::nvvm_f2ll_rm:
  case Intrinsic::nvvm_f2ll_rn:
  case Intrinsic::nvvm_f2ll_rp:
  case Intrinsic::nvvm_f2ll_rz:
  case Intrinsic::nvvm_f2ll_rm_ftz:
  case Intrinsic::nvvm_f2ll_rn_ftz:
  case Intrinsic::nvvm_f2ll_rp_ftz:
  case Intrinsic::nvvm_f2ll_rz_ftz:
  case Intrinsic::nvvm_f2ull_rm:
  case Intrinsic::nvvm_f2ull_rn:
  case Intrinsic::nvvm_f2ull_rp:
  case Intrinsic::nvvm_f2ull_rz:
  case Intrinsic::nvvm_f2ull_rm_ftz:
  case Intrinsic::nvvm_f2ull_rn_ftz:
  case Intrinsic::nvvm_f2ull_rp_ftz:
  case Intrinsic::nvvm_f2ull_rz_ftz:
  case Intrinsic::nvvm_d2ll_rm:
  case Intrinsic::nvvm_d2ll_rn:
  case Intrinsic::nvvm_d2ll_rp:
  case Intrinsic::nvvm_d2ll_rz:
  case Intrinsic::nvvm_d2ull_rm:
  case Intrinsic::nvvm_d2ull_rn:
  case Intrinsic::nvvm_d2ull_rp:
  case Intrinsic::nvvm_d2ull_rz:

  // NVVM math intrinsics:
  case Intrinsic::nvvm_ceil_d:
  case Intrinsic::nvvm_ceil_f:
  case Intrinsic::nvvm_ceil_ftz_f:

  case Intrinsic::nvvm_fabs:
  case Intrinsic::nvvm_fabs_ftz:

  case Intrinsic::nvvm_floor_d:
  case Intrinsic::nvvm_floor_f:
  case Intrinsic::nvvm_floor_ftz_f:

  case Intrinsic::nvvm_rcp_rm_d:
  case Intrinsic::nvvm_rcp_rm_f:
  case Intrinsic::nvvm_rcp_rm_ftz_f:
  case Intrinsic::nvvm_rcp_rn_d:
  case Intrinsic::nvvm_rcp_rn_f:
  case Intrinsic::nvvm_rcp_rn_ftz_f:
  case Intrinsic::nvvm_rcp_rp_d:
  case Intrinsic::nvvm_rcp_rp_f:
  case Intrinsic::nvvm_rcp_rp_ftz_f:
  case Intrinsic::nvvm_rcp_rz_d:
  case Intrinsic::nvvm_rcp_rz_f:
  case Intrinsic::nvvm_rcp_rz_ftz_f:

  case Intrinsic::nvvm_round_d:
  case Intrinsic::nvvm_round_f:
  case Intrinsic::nvvm_round_ftz_f:

  case Intrinsic::nvvm_saturate_d:
  case Intrinsic::nvvm_saturate_f:
  case Intrinsic::nvvm_saturate_ftz_f:

  case Intrinsic::nvvm_sqrt_f:
  case Intrinsic::nvvm_sqrt_rn_d:
  case Intrinsic::nvvm_sqrt_rn_f:
  case Intrinsic::nvvm_sqrt_rn_ftz_f:
    return !Call->isStrictFP();

  // Sign operations are actually bitwise operations, they do not raise
  // exceptions even for SNANs.
  case Intrinsic::fabs:
  case Intrinsic::copysign:
  case Intrinsic::is_fpclass:
  // Non-constrained variants of rounding operations means default FP
  // environment, they can be folded in any case.
  case Intrinsic::ceil:
  case Intrinsic::floor:
  case Intrinsic::round:
  case Intrinsic::roundeven:
  case Intrinsic::trunc:
  case Intrinsic::nearbyint:
  case Intrinsic::rint:
  case Intrinsic::canonicalize:

  // Constrained intrinsics can be folded if FP environment is known
  // to compiler.
  case Intrinsic::experimental_constrained_fma:
  case Intrinsic::experimental_constrained_fmuladd:
  case Intrinsic::experimental_constrained_fadd:
  case Intrinsic::experimental_constrained_fsub:
  case Intrinsic::experimental_constrained_fmul:
  case Intrinsic::experimental_constrained_fdiv:
  case Intrinsic::experimental_constrained_frem:
  case Intrinsic::experimental_constrained_ceil:
  case Intrinsic::experimental_constrained_floor:
  case Intrinsic::experimental_constrained_round:
  case Intrinsic::experimental_constrained_roundeven:
  case Intrinsic::experimental_constrained_trunc:
  case Intrinsic::experimental_constrained_nearbyint:
  case Intrinsic::experimental_constrained_rint:
  case Intrinsic::experimental_constrained_fcmp:
  case Intrinsic::experimental_constrained_fcmps:
    return true;
  default:
    return false;
  case Intrinsic::not_intrinsic: break;
  }

  if (!F->hasName() || Call->isStrictFP())
    return false;

  // In these cases, the check of the length is required.  We don't want to
  // return true for a name like "cos\0blah" which strcmp would return equal to
  // "cos", but has length 8.
  StringRef Name = F->getName();
  switch (Name[0]) {
  default:
    return false;
  case 'a':
    return Name == "acos" || Name == "acosf" ||
           Name == "asin" || Name == "asinf" ||
           Name == "atan" || Name == "atanf" ||
           Name == "atan2" || Name == "atan2f";
  case 'c':
    return Name == "ceil" || Name == "ceilf" ||
           Name == "cos" || Name == "cosf" ||
           Name == "cosh" || Name == "coshf";
  case 'e':
    return Name == "exp" || Name == "expf" || Name == "exp2" ||
           Name == "exp2f" || Name == "erf" || Name == "erff";
  case 'f':
    return Name == "fabs" || Name == "fabsf" ||
           Name == "floor" || Name == "floorf" ||
           Name == "fmod" || Name == "fmodf";
  case 'i':
    return Name == "ilogb" || Name == "ilogbf";
  case 'l':
    return Name == "log" || Name == "logf" || Name == "logl" ||
           Name == "log2" || Name == "log2f" || Name == "log10" ||
           Name == "log10f" || Name == "logb" || Name == "logbf" ||
           Name == "log1p" || Name == "log1pf";
  case 'n':
    return Name == "nearbyint" || Name == "nearbyintf";
  case 'p':
    return Name == "pow" || Name == "powf";
  case 'r':
    return Name == "remainder" || Name == "remainderf" ||
           Name == "rint" || Name == "rintf" ||
           Name == "round" || Name == "roundf";
  case 's':
    return Name == "sin" || Name == "sinf" ||
           Name == "sinh" || Name == "sinhf" ||
           Name == "sqrt" || Name == "sqrtf";
  case 't':
    return Name == "tan" || Name == "tanf" ||
           Name == "tanh" || Name == "tanhf" ||
           Name == "trunc" || Name == "truncf";
  case '_':
    // Check for various function names that get used for the math functions
    // when the header files are preprocessed with the macro
    // __FINITE_MATH_ONLY__ enabled.
    // The '12' here is the length of the shortest name that can match.
    // We need to check the size before looking at Name[1] and Name[2]
    // so we may as well check a limit that will eliminate mismatches.
    if (Name.size() < 12 || Name[1] != '_')
      return false;
    switch (Name[2]) {
    default:
      return false;
    case 'a':
      return Name == "__acos_finite" || Name == "__acosf_finite" ||
             Name == "__asin_finite" || Name == "__asinf_finite" ||
             Name == "__atan2_finite" || Name == "__atan2f_finite";
    case 'c':
      return Name == "__cosh_finite" || Name == "__coshf_finite";
    case 'e':
      return Name == "__exp_finite" || Name == "__expf_finite" ||
             Name == "__exp2_finite" || Name == "__exp2f_finite";
    case 'l':
      return Name == "__log_finite" || Name == "__logf_finite" ||
             Name == "__log10_finite" || Name == "__log10f_finite";
    case 'p':
      return Name == "__pow_finite" || Name == "__powf_finite";
    case 's':
      return Name == "__sinh_finite" || Name == "__sinhf_finite";
    }
  }
}

namespace {

Constant *GetConstantFoldFPValue(double V, Type *Ty) {
  if (Ty->isHalfTy() || Ty->isFloatTy()) {
    APFloat APF(V);
    bool unused;
    APF.convert(Ty->getFltSemantics(), APFloat::rmNearestTiesToEven, &unused);
    return ConstantFP::get(Ty->getContext(), APF);
  }
  if (Ty->isDoubleTy())
    return ConstantFP::get(Ty->getContext(), APFloat(V));
  llvm_unreachable("Can only constant fold half/float/double");
}

#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
Constant *GetConstantFoldFPValue128(float128 V, Type *Ty) {
  if (Ty->isFP128Ty())
    return ConstantFP::get(Ty, V);
  llvm_unreachable("Can only constant fold fp128");
}
#endif

/// Clear the floating-point exception state.
inline void llvm_fenv_clearexcept() {
#if HAVE_DECL_FE_ALL_EXCEPT
  feclearexcept(FE_ALL_EXCEPT);
#endif
  errno = 0;
}

/// Test if a floating-point exception was raised.
inline bool llvm_fenv_testexcept() {
  int errno_val = errno;
  if (errno_val == ERANGE || errno_val == EDOM)
    return true;
#if HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
  if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
    return true;
#endif
  return false;
}

static APFloat FTZPreserveSign(const APFloat &V) {
  if (V.isDenormal())
    return APFloat::getZero(V.getSemantics(), V.isNegative());
  return V;
}

static APFloat FlushToPositiveZero(const APFloat &V) {
  if (V.isDenormal())
    return APFloat::getZero(V.getSemantics(), false);
  return V;
}

static APFloat FlushWithDenormKind(const APFloat &V,
                                   DenormalMode::DenormalModeKind DenormKind) {
  assert(DenormKind != DenormalMode::DenormalModeKind::Invalid &&
         DenormKind != DenormalMode::DenormalModeKind::Dynamic);
  switch (DenormKind) {
  case DenormalMode::DenormalModeKind::IEEE:
    return V;
  case DenormalMode::DenormalModeKind::PreserveSign:
    return FTZPreserveSign(V);
  case DenormalMode::DenormalModeKind::PositiveZero:
    return FlushToPositiveZero(V);
  default:
    llvm_unreachable("Invalid denormal mode!");
  }
}

Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V, Type *Ty,
                         DenormalMode DenormMode = DenormalMode::getIEEE()) {
  if (!DenormMode.isValid() ||
      DenormMode.Input == DenormalMode::DenormalModeKind::Dynamic ||
      DenormMode.Output == DenormalMode::DenormalModeKind::Dynamic)
    return nullptr;

  llvm_fenv_clearexcept();
  auto Input = FlushWithDenormKind(V, DenormMode.Input);
  double Result = NativeFP(Input.convertToDouble());
  if (llvm_fenv_testexcept()) {
    llvm_fenv_clearexcept();
    return nullptr;
  }

  Constant *Output = GetConstantFoldFPValue(Result, Ty);
  if (DenormMode.Output == DenormalMode::DenormalModeKind::IEEE)
    return Output;
  const auto *CFP = static_cast<ConstantFP *>(Output);
  const auto Res = FlushWithDenormKind(CFP->getValueAPF(), DenormMode.Output);
  return ConstantFP::get(Ty->getContext(), Res);
}

#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
Constant *ConstantFoldFP128(float128 (*NativeFP)(float128), const APFloat &V,
                            Type *Ty) {
  llvm_fenv_clearexcept();
  float128 Result = NativeFP(V.convertToQuad());
  if (llvm_fenv_testexcept()) {
    llvm_fenv_clearexcept();
    return nullptr;
  }

  return GetConstantFoldFPValue128(Result, Ty);
}
#endif

Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
                               const APFloat &V, const APFloat &W, Type *Ty) {
  llvm_fenv_clearexcept();
  double Result = NativeFP(V.convertToDouble(), W.convertToDouble());
  if (llvm_fenv_testexcept()) {
    llvm_fenv_clearexcept();
    return nullptr;
  }

  return GetConstantFoldFPValue(Result, Ty);
}

Constant *constantFoldVectorReduce(Intrinsic::ID IID, Constant *Op) {
  FixedVectorType *VT = dyn_cast<FixedVectorType>(Op->getType());
  if (!VT)
    return nullptr;

  // This isn't strictly necessary, but handle the special/common case of zero:
  // all integer reductions of a zero input produce zero.
  if (isa<ConstantAggregateZero>(Op))
    return ConstantInt::get(VT->getElementType(), 0);

  // This is the same as the underlying binops - poison propagates.
  if (isa<PoisonValue>(Op) || Op->containsPoisonElement())
    return PoisonValue::get(VT->getElementType());

  // TODO: Handle undef.
  if (!isa<ConstantVector>(Op) && !isa<ConstantDataVector>(Op))
    return nullptr;

  auto *EltC = dyn_cast<ConstantInt>(Op->getAggregateElement(0U));
  if (!EltC)
    return nullptr;

  APInt Acc = EltC->getValue();
  for (unsigned I = 1, E = VT->getNumElements(); I != E; I++) {
    if (!(EltC = dyn_cast<ConstantInt>(Op->getAggregateElement(I))))
      return nullptr;
    const APInt &X = EltC->getValue();
    switch (IID) {
    case Intrinsic::vector_reduce_add:
      Acc = Acc + X;
      break;
    case Intrinsic::vector_reduce_mul:
      Acc = Acc * X;
      break;
    case Intrinsic::vector_reduce_and:
      Acc = Acc & X;
      break;
    case Intrinsic::vector_reduce_or:
      Acc = Acc | X;
      break;
    case Intrinsic::vector_reduce_xor:
      Acc = Acc ^ X;
      break;
    case Intrinsic::vector_reduce_smin:
      Acc = APIntOps::smin(Acc, X);
      break;
    case Intrinsic::vector_reduce_smax:
      Acc = APIntOps::smax(Acc, X);
      break;
    case Intrinsic::vector_reduce_umin:
      Acc = APIntOps::umin(Acc, X);
      break;
    case Intrinsic::vector_reduce_umax:
      Acc = APIntOps::umax(Acc, X);
      break;
    }
  }

  return ConstantInt::get(Op->getContext(), Acc);
}

/// Attempt to fold an SSE floating point to integer conversion of a constant
/// floating point. If roundTowardZero is false, the default IEEE rounding is
/// used (toward nearest, ties to even). This matches the behavior of the
/// non-truncating SSE instructions in the default rounding mode. The desired
/// integer type Ty is used to select how many bits are available for the
/// result. Returns null if the conversion cannot be performed, otherwise
/// returns the Constant value resulting from the conversion.
Constant *ConstantFoldSSEConvertToInt(const APFloat &Val, bool roundTowardZero,
                                      Type *Ty, bool IsSigned) {
  // All of these conversion intrinsics form an integer of at most 64bits.
  unsigned ResultWidth = Ty->getIntegerBitWidth();
  assert(ResultWidth <= 64 &&
         "Can only constant fold conversions to 64 and 32 bit ints");

  uint64_t UIntVal;
  bool isExact = false;
  APFloat::roundingMode mode = roundTowardZero? APFloat::rmTowardZero
                                              : APFloat::rmNearestTiesToEven;
  APFloat::opStatus status =
      Val.convertToInteger(MutableArrayRef(UIntVal), ResultWidth,
                           IsSigned, mode, &isExact);
  if (status != APFloat::opOK &&
      (!roundTowardZero || status != APFloat::opInexact))
    return nullptr;
  return ConstantInt::get(Ty, UIntVal, IsSigned);
}

double getValueAsDouble(ConstantFP *Op) {
  Type *Ty = Op->getType();

  if (Ty->isBFloatTy() || Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())
    return Op->getValueAPF().convertToDouble();

  bool unused;
  APFloat APF = Op->getValueAPF();
  APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &unused);
  return APF.convertToDouble();
}

static bool getConstIntOrUndef(Value *Op, const APInt *&C) {
  if (auto *CI = dyn_cast<ConstantInt>(Op)) {
    C = &CI->getValue();
    return true;
  }
  if (isa<UndefValue>(Op)) {
    C = nullptr;
    return true;
  }
  return false;
}

/// Checks if the given intrinsic call, which evaluates to constant, is allowed
/// to be folded.
///
/// \param CI Constrained intrinsic call.
/// \param St Exception flags raised during constant evaluation.
static bool mayFoldConstrained(ConstrainedFPIntrinsic *CI,
                               APFloat::opStatus St) {
  std::optional<RoundingMode> ORM = CI->getRoundingMode();
  std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();

  // If the operation does not change exception status flags, it is safe
  // to fold.
  if (St == APFloat::opStatus::opOK)
    return true;

  // If evaluation raised FP exception, the result can depend on rounding
  // mode. If the latter is unknown, folding is not possible.
  if (ORM == RoundingMode::Dynamic)
    return false;

  // If FP exceptions are ignored, fold the call, even if such exception is
  // raised.
  if (EB && *EB != fp::ExceptionBehavior::ebStrict)
    return true;

  // Leave the calculation for runtime so that exception flags be correctly set
  // in hardware.
  return false;
}

/// Returns the rounding mode that should be used for constant evaluation.
static RoundingMode
getEvaluationRoundingMode(const ConstrainedFPIntrinsic *CI) {
  std::optional<RoundingMode> ORM = CI->getRoundingMode();
  if (!ORM || *ORM == RoundingMode::Dynamic)
    // Even if the rounding mode is unknown, try evaluating the operation.
    // If it does not raise inexact exception, rounding was not applied,
    // so the result is exact and does not depend on rounding mode. Whether
    // other FP exceptions are raised, it does not depend on rounding mode.
    return RoundingMode::NearestTiesToEven;
  return *ORM;
}

/// Try to constant fold llvm.canonicalize for the given caller and value.
static Constant *constantFoldCanonicalize(const Type *Ty, const CallBase *CI,
                                          const APFloat &Src) {
  // Zero, positive and negative, is always OK to fold.
  if (Src.isZero()) {
    // Get a fresh 0, since ppc_fp128 does have non-canonical zeros.
    return ConstantFP::get(
        CI->getContext(),
        APFloat::getZero(Src.getSemantics(), Src.isNegative()));
  }

  if (!Ty->isIEEELikeFPTy())
    return nullptr;

  // Zero is always canonical and the sign must be preserved.
  //
  // Denorms and nans may have special encodings, but it should be OK to fold a
  // totally average number.
  if (Src.isNormal() || Src.isInfinity())
    return ConstantFP::get(CI->getContext(), Src);

  if (Src.isDenormal() && CI->getParent() && CI->getFunction()) {
    DenormalMode DenormMode =
        CI->getFunction()->getDenormalMode(Src.getSemantics());

    if (DenormMode == DenormalMode::getIEEE())
      return ConstantFP::get(CI->getContext(), Src);

    if (DenormMode.Input == DenormalMode::Dynamic)
      return nullptr;

    // If we know if either input or output is flushed, we can fold.
    if ((DenormMode.Input == DenormalMode::Dynamic &&
         DenormMode.Output == DenormalMode::IEEE) ||
        (DenormMode.Input == DenormalMode::IEEE &&
         DenormMode.Output == DenormalMode::Dynamic))
      return nullptr;

    bool IsPositive =
        (!Src.isNegative() || DenormMode.Input == DenormalMode::PositiveZero ||
         (DenormMode.Output == DenormalMode::PositiveZero &&
          DenormMode.Input == DenormalMode::IEEE));

    return ConstantFP::get(CI->getContext(),
                           APFloat::getZero(Src.getSemantics(), !IsPositive));
  }

  return nullptr;
}

static Constant *ConstantFoldScalarCall1(StringRef Name,
                                         Intrinsic::ID IntrinsicID,
                                         Type *Ty,
                                         ArrayRef<Constant *> Operands,
                                         const TargetLibraryInfo *TLI,
                                         const CallBase *Call) {
  assert(Operands.size() == 1 && "Wrong number of operands.");

  if (IntrinsicID == Intrinsic::is_constant) {
    // We know we have a "Constant" argument. But we want to only
    // return true for manifest constants, not those that depend on
    // constants with unknowable values, e.g. GlobalValue or BlockAddress.
    if (Operands[0]->isManifestConstant())
      return ConstantInt::getTrue(Ty->getContext());
    return nullptr;
  }

  if (isa<UndefValue>(Operands[0])) {
    // cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN.
    // ctpop() is between 0 and bitwidth, pick 0 for undef.
    // fptoui.sat and fptosi.sat can always fold to zero (for a zero input).
    if (IntrinsicID == Intrinsic::cos ||
        IntrinsicID == Intrinsic::ctpop ||
        IntrinsicID == Intrinsic::fptoui_sat ||
        IntrinsicID == Intrinsic::fptosi_sat ||
        IntrinsicID == Intrinsic::canonicalize)
      return Constant::getNullValue(Ty);
    if (IntrinsicID == Intrinsic::bswap ||
        IntrinsicID == Intrinsic::bitreverse ||
        IntrinsicID == Intrinsic::launder_invariant_group ||
        IntrinsicID == Intrinsic::strip_invariant_group)
      return Operands[0];
  }

  if (isa<ConstantPointerNull>(Operands[0])) {
    // launder(null) == null == strip(null) iff in addrspace 0
    if (IntrinsicID == Intrinsic::launder_invariant_group ||
        IntrinsicID == Intrinsic::strip_invariant_group) {
      // If instruction is not yet put in a basic block (e.g. when cloning
      // a function during inlining), Call's caller may not be available.
      // So check Call's BB first before querying Call->getCaller.
      const Function *Caller =
          Call->getParent() ? Call->getCaller() : nullptr;
      if (Caller &&
          !NullPointerIsDefined(
              Caller, Operands[0]->getType()->getPointerAddressSpace())) {
        return Operands[0];
      }
      return nullptr;
    }
  }

  if (auto *Op = dyn_cast<ConstantFP>(Operands[0])) {
    if (IntrinsicID == Intrinsic::convert_to_fp16) {
      APFloat Val(Op->getValueAPF());

      bool lost = false;
      Val.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &lost);

      return ConstantInt::get(Ty->getContext(), Val.bitcastToAPInt());
    }

    APFloat U = Op->getValueAPF();

    if (IntrinsicID == Intrinsic::wasm_trunc_signed ||
        IntrinsicID == Intrinsic::wasm_trunc_unsigned) {
      bool Signed = IntrinsicID == Intrinsic::wasm_trunc_signed;

      if (U.isNaN())
        return nullptr;

      unsigned Width = Ty->getIntegerBitWidth();
      APSInt Int(Width, !Signed);
      bool IsExact = false;
      APFloat::opStatus Status =
          U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);

      if (Status == APFloat::opOK || Status == APFloat::opInexact)
        return ConstantInt::get(Ty, Int);

      return nullptr;
    }

    if (IntrinsicID == Intrinsic::fptoui_sat ||
        IntrinsicID == Intrinsic::fptosi_sat) {
      // convertToInteger() already has the desired saturation semantics.
      APSInt Int(Ty->getIntegerBitWidth(),
                 IntrinsicID == Intrinsic::fptoui_sat);
      bool IsExact;
      U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);
      return ConstantInt::get(Ty, Int);
    }

    if (IntrinsicID == Intrinsic::canonicalize)
      return constantFoldCanonicalize(Ty, Call, U);

#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
    if (Ty->isFP128Ty()) {
      if (IntrinsicID == Intrinsic::log) {
        float128 Result = logf128(Op->getValueAPF().convertToQuad());
        return GetConstantFoldFPValue128(Result, Ty);
      }

      LibFunc Fp128Func = NotLibFunc;
      if (TLI && TLI->getLibFunc(Name, Fp128Func) && TLI->has(Fp128Func) &&
          Fp128Func == LibFunc_logl)
        return ConstantFoldFP128(logf128, Op->getValueAPF(), Ty);
    }
#endif

    if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy() &&
        !Ty->isIntegerTy())
      return nullptr;

    // Use internal versions of these intrinsics.

    if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) {
      U.roundToIntegral(APFloat::rmNearestTiesToEven);
      return ConstantFP::get(Ty->getContext(), U);
    }

    if (IntrinsicID == Intrinsic::round) {
      U.roundToIntegral(APFloat::rmNearestTiesToAway);
      return ConstantFP::get(Ty->getContext(), U);
    }

    if (IntrinsicID == Intrinsic::roundeven) {
      U.roundToIntegral(APFloat::rmNearestTiesToEven);
      return ConstantFP::get(Ty->getContext(), U);
    }

    if (IntrinsicID == Intrinsic::ceil) {
      U.roundToIntegral(APFloat::rmTowardPositive);
      return ConstantFP::get(Ty->getContext(), U);
    }

    if (IntrinsicID == Intrinsic::floor) {
      U.roundToIntegral(APFloat::rmTowardNegative);
      return ConstantFP::get(Ty->getContext(), U);
    }

    if (IntrinsicID == Intrinsic::trunc) {
      U.roundToIntegral(APFloat::rmTowardZero);
      return ConstantFP::get(Ty->getContext(), U);
    }

    if (IntrinsicID == Intrinsic::fabs) {
      U.clearSign();
      return ConstantFP::get(Ty->getContext(), U);
    }

    if (IntrinsicID == Intrinsic::amdgcn_fract) {
      // The v_fract instruction behaves like the OpenCL spec, which defines
      // fract(x) as fmin(x - floor(x), 0x1.fffffep-1f): "The min() operator is
      //   there to prevent fract(-small) from returning 1.0. It returns the
      //   largest positive floating-point number less than 1.0."
      APFloat FloorU(U);
      FloorU.roundToIntegral(APFloat::rmTowardNegative);
      APFloat FractU(U - FloorU);
      APFloat AlmostOne(U.getSemantics(), 1);
      AlmostOne.next(/*nextDown*/ true);
      return ConstantFP::get(Ty->getContext(), minimum(FractU, AlmostOne));
    }

    // Rounding operations (floor, trunc, ceil, round and nearbyint) do not
    // raise FP exceptions, unless the argument is signaling NaN.

    std::optional<APFloat::roundingMode> RM;
    switch (IntrinsicID) {
    default:
      break;
    case Intrinsic::experimental_constrained_nearbyint:
    case Intrinsic::experimental_constrained_rint: {
      auto CI = cast<ConstrainedFPIntrinsic>(Call);
      RM = CI->getRoundingMode();
      if (!RM || *RM == RoundingMode::Dynamic)
        return nullptr;
      break;
    }
    case Intrinsic::experimental_constrained_round:
      RM = APFloat::rmNearestTiesToAway;
      break;
    case Intrinsic::experimental_constrained_ceil:
      RM = APFloat::rmTowardPositive;
      break;
    case Intrinsic::experimental_constrained_floor:
      RM = APFloat::rmTowardNegative;
      break;
    case Intrinsic::experimental_constrained_trunc:
      RM = APFloat::rmTowardZero;
      break;
    }
    if (RM) {
      auto CI = cast<ConstrainedFPIntrinsic>(Call);
      if (U.isFinite()) {
        APFloat::opStatus St = U.roundToIntegral(*RM);
        if (IntrinsicID == Intrinsic::experimental_constrained_rint &&
            St == APFloat::opInexact) {
          std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();
          if (EB == fp::ebStrict)
            return nullptr;
        }
      } else if (U.isSignaling()) {
        std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();
        if (EB && *EB != fp::ebIgnore)
          return nullptr;
        U = APFloat::getQNaN(U.getSemantics());
      }
      return ConstantFP::get(Ty->getContext(), U);
    }

    // NVVM float/double to signed/unsigned int32/int64 conversions:
    switch (IntrinsicID) {
    // f2i
    case Intrinsic::nvvm_f2i_rm:
    case Intrinsic::nvvm_f2i_rn:
    case Intrinsic::nvvm_f2i_rp:
    case Intrinsic::nvvm_f2i_rz:
    case Intrinsic::nvvm_f2i_rm_ftz:
    case Intrinsic::nvvm_f2i_rn_ftz:
    case Intrinsic::nvvm_f2i_rp_ftz:
    case Intrinsic::nvvm_f2i_rz_ftz:
    // f2ui
    case Intrinsic::nvvm_f2ui_rm:
    case Intrinsic::nvvm_f2ui_rn:
    case Intrinsic::nvvm_f2ui_rp:
    case Intrinsic::nvvm_f2ui_rz:
    case Intrinsic::nvvm_f2ui_rm_ftz:
    case Intrinsic::nvvm_f2ui_rn_ftz:
    case Intrinsic::nvvm_f2ui_rp_ftz:
    case Intrinsic::nvvm_f2ui_rz_ftz:
    // d2i
    case Intrinsic::nvvm_d2i_rm:
    case Intrinsic::nvvm_d2i_rn:
    case Intrinsic::nvvm_d2i_rp:
    case Intrinsic::nvvm_d2i_rz:
    // d2ui
    case Intrinsic::nvvm_d2ui_rm:
    case Intrinsic::nvvm_d2ui_rn:
    case Intrinsic::nvvm_d2ui_rp:
    case Intrinsic::nvvm_d2ui_rz:
    // f2ll
    case Intrinsic::nvvm_f2ll_rm:
    case Intrinsic::nvvm_f2ll_rn:
    case Intrinsic::nvvm_f2ll_rp:
    case Intrinsic::nvvm_f2ll_rz:
    case Intrinsic::nvvm_f2ll_rm_ftz:
    case Intrinsic::nvvm_f2ll_rn_ftz:
    case Intrinsic::nvvm_f2ll_rp_ftz:
    case Intrinsic::nvvm_f2ll_rz_ftz:
    // f2ull
    case Intrinsic::nvvm_f2ull_rm:
    case Intrinsic::nvvm_f2ull_rn:
    case Intrinsic::nvvm_f2ull_rp:
    case Intrinsic::nvvm_f2ull_rz:
    case Intrinsic::nvvm_f2ull_rm_ftz:
    case Intrinsic::nvvm_f2ull_rn_ftz:
    case Intrinsic::nvvm_f2ull_rp_ftz:
    case Intrinsic::nvvm_f2ull_rz_ftz:
    // d2ll
    case Intrinsic::nvvm_d2ll_rm:
    case Intrinsic::nvvm_d2ll_rn:
    case Intrinsic::nvvm_d2ll_rp:
    case Intrinsic::nvvm_d2ll_rz:
    // d2ull
    case Intrinsic::nvvm_d2ull_rm:
    case Intrinsic::nvvm_d2ull_rn:
    case Intrinsic::nvvm_d2ull_rp:
    case Intrinsic::nvvm_d2ull_rz: {
      // In float-to-integer conversion, NaN inputs are converted to 0.
      if (U.isNaN())
        return ConstantInt::get(Ty, 0);

      APFloat::roundingMode RMode =
          nvvm::GetFPToIntegerRoundingMode(IntrinsicID);
      bool IsFTZ = nvvm::FPToIntegerIntrinsicShouldFTZ(IntrinsicID);
      bool IsSigned = nvvm::FPToIntegerIntrinsicResultIsSigned(IntrinsicID);

      APSInt ResInt(Ty->getIntegerBitWidth(), !IsSigned);
      auto FloatToRound = IsFTZ ? FTZPreserveSign(U) : U;

      bool IsExact = false;
      APFloat::opStatus Status =
          FloatToRound.convertToInteger(ResInt, RMode, &IsExact);

      if (Status != APFloat::opInvalidOp)
        return ConstantInt::get(Ty, ResInt);
      return nullptr;
    }
    }

    /// We only fold functions with finite arguments. Folding NaN and inf is
    /// likely to be aborted with an exception anyway, and some host libms
    /// have known errors raising exceptions.
    if (!U.isFinite())
      return nullptr;

    /// Currently APFloat versions of these functions do not exist, so we use
    /// the host native double versions.  Float versions are not called
    /// directly but for all these it is true (float)(f((double)arg)) ==
    /// f(arg).  Long double not supported yet.
    const APFloat &APF = Op->getValueAPF();

    switch (IntrinsicID) {
      default: break;
      case Intrinsic::log:
        return ConstantFoldFP(log, APF, Ty);
      case Intrinsic::log2:
        // TODO: What about hosts that lack a C99 library?
        return ConstantFoldFP(log2, APF, Ty);
      case Intrinsic::log10:
        // TODO: What about hosts that lack a C99 library?
        return ConstantFoldFP(log10, APF, Ty);
      case Intrinsic::exp:
        return ConstantFoldFP(exp, APF, Ty);
      case Intrinsic::exp2:
        // Fold exp2(x) as pow(2, x), in case the host lacks a C99 library.
        return ConstantFoldBinaryFP(pow, APFloat(2.0), APF, Ty);
      case Intrinsic::exp10:
        // Fold exp10(x) as pow(10, x), in case the host lacks a C99 library.
        return ConstantFoldBinaryFP(pow, APFloat(10.0), APF, Ty);
      case Intrinsic::sin:
        return ConstantFoldFP(sin, APF, Ty);
      case Intrinsic::cos:
        return ConstantFoldFP(cos, APF, Ty);
      case Intrinsic::sinh:
        return ConstantFoldFP(sinh, APF, Ty);
      case Intrinsic::cosh:
        return ConstantFoldFP(cosh, APF, Ty);
      case Intrinsic::atan:
        // Implement optional behavior from C's Annex F for +/-0.0.
        if (U.isZero())
          return ConstantFP::get(Ty->getContext(), U);
        return ConstantFoldFP(atan, APF, Ty);
      case Intrinsic::sqrt:
        return ConstantFoldFP(sqrt, APF, Ty);

      // NVVM Intrinsics:
      case Intrinsic::nvvm_ceil_ftz_f:
      case Intrinsic::nvvm_ceil_f:
      case Intrinsic::nvvm_ceil_d:
        return ConstantFoldFP(
            ceil, APF, Ty,
            nvvm::GetNVVMDenormMode(
                nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID)));

      case Intrinsic::nvvm_fabs_ftz:
      case Intrinsic::nvvm_fabs:
        return ConstantFoldFP(
            fabs, APF, Ty,
            nvvm::GetNVVMDenormMode(
                nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID)));

      case Intrinsic::nvvm_floor_ftz_f:
      case Intrinsic::nvvm_floor_f:
      case Intrinsic::nvvm_floor_d:
        return ConstantFoldFP(
            floor, APF, Ty,
            nvvm::GetNVVMDenormMode(
                nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID)));

      case Intrinsic::nvvm_rcp_rm_ftz_f:
      case Intrinsic::nvvm_rcp_rn_ftz_f:
      case Intrinsic::nvvm_rcp_rp_ftz_f:
      case Intrinsic::nvvm_rcp_rz_ftz_f:
      case Intrinsic::nvvm_rcp_rm_d:
      case Intrinsic::nvvm_rcp_rm_f:
      case Intrinsic::nvvm_rcp_rn_d:
      case Intrinsic::nvvm_rcp_rn_f:
      case Intrinsic::nvvm_rcp_rp_d:
      case Intrinsic::nvvm_rcp_rp_f:
      case Intrinsic::nvvm_rcp_rz_d:
      case Intrinsic::nvvm_rcp_rz_f: {
        APFloat::roundingMode RoundMode = nvvm::GetRCPRoundingMode(IntrinsicID);
        bool IsFTZ = nvvm::RCPShouldFTZ(IntrinsicID);

        auto Denominator = IsFTZ ? FTZPreserveSign(APF) : APF;
        APFloat Res = APFloat::getOne(APF.getSemantics());
        APFloat::opStatus Status = Res.divide(Denominator, RoundMode);

        if (Status == APFloat::opOK || Status == APFloat::opInexact) {
          if (IsFTZ)
            Res = FTZPreserveSign(Res);
          return ConstantFP::get(Ty->getContext(), Res);
        }
        return nullptr;
      }

      case Intrinsic::nvvm_round_ftz_f:
      case Intrinsic::nvvm_round_f:
      case Intrinsic::nvvm_round_d: {
        // nvvm_round is lowered to PTX cvt.rni, which will round to nearest
        // integer, choosing even integer if source is equidistant between two
        // integers, so the semantics are closer to "rint" rather than "round".
        bool IsFTZ = nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID);
        auto V = IsFTZ ? FTZPreserveSign(APF) : APF;
        V.roundToIntegral(APFloat::rmNearestTiesToEven);
        return ConstantFP::get(Ty->getContext(), V);
      }

      case Intrinsic::nvvm_saturate_ftz_f:
      case Intrinsic::nvvm_saturate_d:
      case Intrinsic::nvvm_saturate_f: {
        bool IsFTZ = nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID);
        auto V = IsFTZ ? FTZPreserveSign(APF) : APF;
        if (V.isNegative() || V.isZero() || V.isNaN())
          return ConstantFP::getZero(Ty);
        APFloat One = APFloat::getOne(APF.getSemantics());
        if (V > One)
          return ConstantFP::get(Ty->getContext(), One);
        return ConstantFP::get(Ty->getContext(), APF);
      }

      case Intrinsic::nvvm_sqrt_rn_ftz_f:
      case Intrinsic::nvvm_sqrt_f:
      case Intrinsic::nvvm_sqrt_rn_d:
      case Intrinsic::nvvm_sqrt_rn_f:
        if (APF.isNegative())
          return nullptr;
        return ConstantFoldFP(
            sqrt, APF, Ty,
            nvvm::GetNVVMDenormMode(
                nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID)));

      // AMDGCN Intrinsics:
      case Intrinsic::amdgcn_cos:
      case Intrinsic::amdgcn_sin: {
        double V = getValueAsDouble(Op);
        if (V < -256.0 || V > 256.0)
          // The gfx8 and gfx9 architectures handle arguments outside the range
          // [-256, 256] differently. This should be a rare case so bail out
          // rather than trying to handle the difference.
          return nullptr;
        bool IsCos = IntrinsicID == Intrinsic::amdgcn_cos;
        double V4 = V * 4.0;
        if (V4 == floor(V4)) {
          // Force exact results for quarter-integer inputs.
          const double SinVals[4] = { 0.0, 1.0, 0.0, -1.0 };
          V = SinVals[((int)V4 + (IsCos ? 1 : 0)) & 3];
        } else {
          if (IsCos)
            V = cos(V * 2.0 * numbers::pi);
          else
            V = sin(V * 2.0 * numbers::pi);
        }
        return GetConstantFoldFPValue(V, Ty);
      }
    }

    if (!TLI)
      return nullptr;

    LibFunc Func = NotLibFunc;
    if (!TLI->getLibFunc(Name, Func))
      return nullptr;

    switch (Func) {
    default:
      break;
    case LibFunc_acos:
    case LibFunc_acosf:
    case LibFunc_acos_finite:
    case LibFunc_acosf_finite:
      if (TLI->has(Func))
        return ConstantFoldFP(acos, APF, Ty);
      break;
    case LibFunc_asin:
    case LibFunc_asinf:
    case LibFunc_asin_finite:
    case LibFunc_asinf_finite:
      if (TLI->has(Func))
        return ConstantFoldFP(asin, APF, Ty);
      break;
    case LibFunc_atan:
    case LibFunc_atanf:
      // Implement optional behavior from C's Annex F for +/-0.0.
      if (U.isZero())
        return ConstantFP::get(Ty->getContext(), U);
      if (TLI->has(Func))
        return ConstantFoldFP(atan, APF, Ty);
      break;
    case LibFunc_ceil:
    case LibFunc_ceilf:
      if (TLI->has(Func)) {
        U.roundToIntegral(APFloat::rmTowardPositive);
        return ConstantFP::get(Ty->getContext(), U);
      }
      break;
    case LibFunc_cos:
    case LibFunc_cosf:
      if (TLI->has(Func))
        return ConstantFoldFP(cos, APF, Ty);
      break;
    case LibFunc_cosh:
    case LibFunc_coshf:
    case LibFunc_cosh_finite:
    case LibFunc_coshf_finite:
      if (TLI->has(Func))
        return ConstantFoldFP(cosh, APF, Ty);
      break;
    case LibFunc_exp:
    case LibFunc_expf:
    case LibFunc_exp_finite:
    case LibFunc_expf_finite:
      if (TLI->has(Func))
        return ConstantFoldFP(exp, APF, Ty);
      break;
    case LibFunc_exp2:
    case LibFunc_exp2f:
    case LibFunc_exp2_finite:
    case LibFunc_exp2f_finite:
      if (TLI->has(Func))
        // Fold exp2(x) as pow(2, x), in case the host lacks a C99 library.
        return ConstantFoldBinaryFP(pow, APFloat(2.0), APF, Ty);
      break;
    case LibFunc_fabs:
    case LibFunc_fabsf:
      if (TLI->has(Func)) {
        U.clearSign();
        return ConstantFP::get(Ty->getContext(), U);
      }
      break;
    case LibFunc_floor:
    case LibFunc_floorf:
      if (TLI->has(Func)) {
        U.roundToIntegral(APFloat::rmTowardNegative);
        return ConstantFP::get(Ty->getContext(), U);
      }
      break;
    case LibFunc_log:
    case LibFunc_logf:
    case LibFunc_log_finite:
    case LibFunc_logf_finite:
      if (!APF.isNegative() && !APF.isZero() && TLI->has(Func))
        return ConstantFoldFP(log, APF, Ty);
      break;
    case LibFunc_log2:
    case LibFunc_log2f:
    case LibFunc_log2_finite:
    case LibFunc_log2f_finite:
      if (!APF.isNegative() && !APF.isZero() && TLI->has(Func))
        // TODO: What about hosts that lack a C99 library?
        return ConstantFoldFP(log2, APF, Ty);
      break;
    case LibFunc_log10:
    case LibFunc_log10f:
    case LibFunc_log10_finite:
    case LibFunc_log10f_finite:
      if (!APF.isNegative() && !APF.isZero() && TLI->has(Func))
        // TODO: What about hosts that lack a C99 library?
        return ConstantFoldFP(log10, APF, Ty);
      break;
    case LibFunc_ilogb:
    case LibFunc_ilogbf:
      if (!APF.isZero() && TLI->has(Func))
        return ConstantInt::get(Ty, ilogb(APF), true);
      break;
    case LibFunc_logb:
    case LibFunc_logbf:
      if (!APF.isZero() && TLI->has(Func))
        return ConstantFoldFP(logb, APF, Ty);
      break;
    case LibFunc_log1p:
    case LibFunc_log1pf:
      // Implement optional behavior from C's Annex F for +/-0.0.
      if (U.isZero())
        return ConstantFP::get(Ty->getContext(), U);
      if (APF > APFloat::getOne(APF.getSemantics(), true) && TLI->has(Func))
        return ConstantFoldFP(log1p, APF, Ty);
      break;
    case LibFunc_logl:
      return nullptr;
    case LibFunc_erf:
    case LibFunc_erff:
      if (TLI->has(Func))
        return ConstantFoldFP(erf, APF, Ty);
      break;
    case LibFunc_nearbyint:
    case LibFunc_nearbyintf:
    case LibFunc_rint:
    case LibFunc_rintf:
      if (TLI->has(Func)) {
        U.roundToIntegral(APFloat::rmNearestTiesToEven);
        return ConstantFP::get(Ty->getContext(), U);
      }
      break;
    case LibFunc_round:
    case LibFunc_roundf:
      if (TLI->has(Func)) {
        U.roundToIntegral(APFloat::rmNearestTiesToAway);
        return ConstantFP::get(Ty->getContext(), U);
      }
      break;
    case LibFunc_sin:
    case LibFunc_sinf:
      if (TLI->has(Func))
        return ConstantFoldFP(sin, APF, Ty);
      break;
    case LibFunc_sinh:
    case LibFunc_sinhf:
    case LibFunc_sinh_finite:
    case LibFunc_sinhf_finite:
      if (TLI->has(Func))
        return ConstantFoldFP(sinh, APF, Ty);
      break;
    case LibFunc_sqrt:
    case LibFunc_sqrtf:
      if (!APF.isNegative() && TLI->has(Func))
        return ConstantFoldFP(sqrt, APF, Ty);
      break;
    case LibFunc_tan:
    case LibFunc_tanf:
      if (TLI->has(Func))
        return ConstantFoldFP(tan, APF, Ty);
      break;
    case LibFunc_tanh:
    case LibFunc_tanhf:
      if (TLI->has(Func))
        return ConstantFoldFP(tanh, APF, Ty);
      break;
    case LibFunc_trunc:
    case LibFunc_truncf:
      if (TLI->has(Func)) {
        U.roundToIntegral(APFloat::rmTowardZero);
        return ConstantFP::get(Ty->getContext(), U);
      }
      break;
    }
    return nullptr;
  }

  if (auto *Op = dyn_cast<ConstantInt>(Operands[0])) {
    switch (IntrinsicID) {
    case Intrinsic::bswap:
      return ConstantInt::get(Ty->getContext(), Op->getValue().byteSwap());
    case Intrinsic::ctpop:
      return ConstantInt::get(Ty, Op->getValue().popcount());
    case Intrinsic::bitreverse:
      return ConstantInt::get(Ty->getContext(), Op->getValue().reverseBits());
    case Intrinsic::convert_from_fp16: {
      APFloat Val(APFloat::IEEEhalf(), Op->getValue());

      bool lost = false;
      APFloat::opStatus status = Val.convert(
          Ty->getFltSemantics(), APFloat::rmNearestTiesToEven, &lost);

      // Conversion is always precise.
      (void)status;
      assert(status != APFloat::opInexact && !lost &&
             "Precision lost during fp16 constfolding");

      return ConstantFP::get(Ty->getContext(), Val);
    }

    case Intrinsic::amdgcn_s_wqm: {
      uint64_t Val = Op->getZExtValue();
      Val |= (Val & 0x5555555555555555ULL) << 1 |
             ((Val >> 1) & 0x5555555555555555ULL);
      Val |= (Val & 0x3333333333333333ULL) << 2 |
             ((Val >> 2) & 0x3333333333333333ULL);
      return ConstantInt::get(Ty, Val);
    }

    case Intrinsic::amdgcn_s_quadmask: {
      uint64_t Val = Op->getZExtValue();
      uint64_t QuadMask = 0;
      for (unsigned I = 0; I < Op->getBitWidth() / 4; ++I, Val >>= 4) {
        if (!(Val & 0xF))
          continue;

        QuadMask |= (1ULL << I);
      }
      return ConstantInt::get(Ty, QuadMask);
    }

    case Intrinsic::amdgcn_s_bitreplicate: {
      uint64_t Val = Op->getZExtValue();
      Val = (Val & 0x000000000000FFFFULL) | (Val & 0x00000000FFFF0000ULL) << 16;
      Val = (Val & 0x000000FF000000FFULL) | (Val & 0x0000FF000000FF00ULL) << 8;
      Val = (Val & 0x000F000F000F000FULL) | (Val & 0x00F000F000F000F0ULL) << 4;
      Val = (Val & 0x0303030303030303ULL) | (Val & 0x0C0C0C0C0C0C0C0CULL) << 2;
      Val = (Val & 0x1111111111111111ULL) | (Val & 0x2222222222222222ULL) << 1;
      Val = Val | Val << 1;
      return ConstantInt::get(Ty, Val);
    }

    default:
      return nullptr;
    }
  }

  switch (IntrinsicID) {
  default: break;
  case Intrinsic::vector_reduce_add:
  case Intrinsic::vector_reduce_mul:
  case Intrinsic::vector_reduce_and:
  case Intrinsic::vector_reduce_or:
  case Intrinsic::vector_reduce_xor:
  case Intrinsic::vector_reduce_smin:
  case Intrinsic::vector_reduce_smax:
  case Intrinsic::vector_reduce_umin:
  case Intrinsic::vector_reduce_umax:
    if (Constant *C = constantFoldVectorReduce(IntrinsicID, Operands[0]))
      return C;
    break;
  }

  // Support ConstantVector in case we have an Undef in the top.
  if (isa<ConstantVector>(Operands[0]) ||
      isa<ConstantDataVector>(Operands[0]) ||
      isa<ConstantAggregateZero>(Operands[0])) {
    auto *Op = cast<Constant>(Operands[0]);
    switch (IntrinsicID) {
    default: break;
    case Intrinsic::x86_sse_cvtss2si:
    case Intrinsic::x86_sse_cvtss2si64:
    case Intrinsic::x86_sse2_cvtsd2si:
    case Intrinsic::x86_sse2_cvtsd2si64:
      if (ConstantFP *FPOp =
              dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
        return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
                                           /*roundTowardZero=*/false, Ty,
                                           /*IsSigned*/true);
      break;
    case Intrinsic::x86_sse_cvttss2si:
    case Intrinsic::x86_sse_cvttss2si64:
    case Intrinsic::x86_sse2_cvttsd2si:
    case Intrinsic::x86_sse2_cvttsd2si64:
      if (ConstantFP *FPOp =
              dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
        return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
                                           /*roundTowardZero=*/true, Ty,
                                           /*IsSigned*/true);
      break;

    case Intrinsic::wasm_anytrue:
      return Op->isZeroValue() ? ConstantInt::get(Ty, 0)
                               : ConstantInt::get(Ty, 1);

    case Intrinsic::wasm_alltrue:
      // Check each element individually
      unsigned E = cast<FixedVectorType>(Op->getType())->getNumElements();
      for (unsigned I = 0; I != E; ++I)
        if (Constant *Elt = Op->getAggregateElement(I))
          if (Elt->isZeroValue())
            return ConstantInt::get(Ty, 0);

      return ConstantInt::get(Ty, 1);
    }
  }

  return nullptr;
}

static Constant *evaluateCompare(const APFloat &Op1, const APFloat &Op2,
                                 const ConstrainedFPIntrinsic *Call) {
  APFloat::opStatus St = APFloat::opOK;
  auto *FCmp = cast<ConstrainedFPCmpIntrinsic>(Call);
  FCmpInst::Predicate Cond = FCmp->getPredicate();
  if (FCmp->isSignaling()) {
    if (Op1.isNaN() || Op2.isNaN())
      St = APFloat::opInvalidOp;
  } else {
    if (Op1.isSignaling() || Op2.isSignaling())
      St = APFloat::opInvalidOp;
  }
  bool Result = FCmpInst::compare(Op1, Op2, Cond);
  if (mayFoldConstrained(const_cast<ConstrainedFPCmpIntrinsic *>(FCmp), St))
    return ConstantInt::get(Call->getType()->getScalarType(), Result);
  return nullptr;
}

static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
                                      ArrayRef<Constant *> Operands,
                                      const TargetLibraryInfo *TLI) {
  if (!TLI)
    return nullptr;

  LibFunc Func = NotLibFunc;
  if (!TLI->getLibFunc(Name, Func))
    return nullptr;

  const auto *Op1 = dyn_cast<ConstantFP>(Operands[0]);
  if (!Op1)
    return nullptr;

  const auto *Op2 = dyn_cast<ConstantFP>(Operands[1]);
  if (!Op2)
    return nullptr;

  const APFloat &Op1V = Op1->getValueAPF();
  const APFloat &Op2V = Op2->getValueAPF();

  switch (Func) {
  default:
    break;
  case LibFunc_pow:
  case LibFunc_powf:
  case LibFunc_pow_finite:
  case LibFunc_powf_finite:
    if (TLI->has(Func))
      return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
    break;
  case LibFunc_fmod:
  case LibFunc_fmodf:
    if (TLI->has(Func)) {
      APFloat V = Op1->getValueAPF();
      if (APFloat::opStatus::opOK == V.mod(Op2->getValueAPF()))
        return ConstantFP::get(Ty->getContext(), V);
    }
    break;
  case LibFunc_remainder:
  case LibFunc_remainderf:
    if (TLI->has(Func)) {
      APFloat V = Op1->getValueAPF();
      if (APFloat::opStatus::opOK == V.remainder(Op2->getValueAPF()))
        return ConstantFP::get(Ty->getContext(), V);
    }
    break;
  case LibFunc_atan2:
  case LibFunc_atan2f:
    // atan2(+/-0.0, +/-0.0) is known to raise an exception on some libm
    // (Solaris), so we do not assume a known result for that.
    if (Op1V.isZero() && Op2V.isZero())
      return nullptr;
    [[fallthrough]];
  case LibFunc_atan2_finite:
  case LibFunc_atan2f_finite:
    if (TLI->has(Func))
      return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);
    break;
  }

  return nullptr;
}

static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
                                            ArrayRef<Constant *> Operands,
                                            const CallBase *Call) {
  assert(Operands.size() == 2 && "Wrong number of operands.");

  if (Ty->isFloatingPointTy()) {
    // TODO: We should have undef handling for all of the FP intrinsics that
    //       are attempted to be folded in this function.
    bool IsOp0Undef = isa<UndefValue>(Operands[0]);
    bool IsOp1Undef = isa<UndefValue>(Operands[1]);
    switch (IntrinsicID) {
    case Intrinsic::maxnum:
    case Intrinsic::minnum:
    case Intrinsic::maximum:
    case Intrinsic::minimum:
    case Intrinsic::maximumnum:
    case Intrinsic::minimumnum:
    case Intrinsic::nvvm_fmax_d:
    case Intrinsic::nvvm_fmin_d:
      // If one argument is undef, return the other argument.
      if (IsOp0Undef)
        return Operands[1];
      if (IsOp1Undef)
        return Operands[0];
      break;

    case Intrinsic::nvvm_fmax_f:
    case Intrinsic::nvvm_fmax_ftz_f:
    case Intrinsic::nvvm_fmax_ftz_nan_f:
    case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:
    case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:
    case Intrinsic::nvvm_fmax_nan_f:
    case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:
    case Intrinsic::nvvm_fmax_xorsign_abs_f:

    case Intrinsic::nvvm_fmin_f:
    case Intrinsic::nvvm_fmin_ftz_f:
    case Intrinsic::nvvm_fmin_ftz_nan_f:
    case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f:
    case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f:
    case Intrinsic::nvvm_fmin_nan_f:
    case Intrinsic::nvvm_fmin_nan_xorsign_abs_f:
    case Intrinsic::nvvm_fmin_xorsign_abs_f:
      // If one arg is undef, the other arg can be returned only if it is
      // constant, as we may need to flush it to sign-preserving zero or
      // canonicalize the NaN.
      if (!IsOp0Undef && !IsOp1Undef)
        break;
      if (auto *Op = dyn_cast<ConstantFP>(Operands[IsOp0Undef ? 1 : 0])) {
        if (Op->isNaN()) {
          APInt NVCanonicalNaN(32, 0x7fffffff);
          return ConstantFP::get(
              Ty, APFloat(Ty->getFltSemantics(), NVCanonicalNaN));
        }
        if (nvvm::FMinFMaxShouldFTZ(IntrinsicID))
          return ConstantFP::get(Ty, FTZPreserveSign(Op->getValueAPF()));
        else
          return Op;
      }
      break;
    }
  }

  if (const auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
    const APFloat &Op1V = Op1->getValueAPF();

    if (const auto *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
      if (Op2->getType() != Op1->getType())
        return nullptr;
      const APFloat &Op2V = Op2->getValueAPF();

      if (const auto *ConstrIntr =
              dyn_cast_if_present<ConstrainedFPIntrinsic>(Call)) {
        RoundingMode RM = getEvaluationRoundingMode(ConstrIntr);
        APFloat Res = Op1V;
        APFloat::opStatus St;
        switch (IntrinsicID) {
        default:
          return nullptr;
        case Intrinsic::experimental_constrained_fadd:
          St = Res.add(Op2V, RM);
          break;
        case Intrinsic::experimental_constrained_fsub:
          St = Res.subtract(Op2V, RM);
          break;
        case Intrinsic::experimental_constrained_fmul:
          St = Res.multiply(Op2V, RM);
          break;
        case Intrinsic::experimental_constrained_fdiv:
          St = Res.divide(Op2V, RM);
          break;
        case Intrinsic::experimental_constrained_frem:
          St = Res.mod(Op2V);
          break;
        case Intrinsic::experimental_constrained_fcmp:
        case Intrinsic::experimental_constrained_fcmps:
          return evaluateCompare(Op1V, Op2V, ConstrIntr);
        }
        if (mayFoldConstrained(const_cast<ConstrainedFPIntrinsic *>(ConstrIntr),
                               St))
          return ConstantFP::get(Ty->getContext(), Res);
        return nullptr;
      }

      switch (IntrinsicID) {
      default:
        break;
      case Intrinsic::copysign:
        return ConstantFP::get(Ty->getContext(), APFloat::copySign(Op1V, Op2V));
      case Intrinsic::minnum:
        return ConstantFP::get(Ty->getContext(), minnum(Op1V, Op2V));
      case Intrinsic::maxnum:
        return ConstantFP::get(Ty->getContext(), maxnum(Op1V, Op2V));
      case Intrinsic::minimum:
        return ConstantFP::get(Ty->getContext(), minimum(Op1V, Op2V));
      case Intrinsic::maximum:
        return ConstantFP::get(Ty->getContext(), maximum(Op1V, Op2V));
      case Intrinsic::minimumnum:
        return ConstantFP::get(Ty->getContext(), minimumnum(Op1V, Op2V));
      case Intrinsic::maximumnum:
        return ConstantFP::get(Ty->getContext(), maximumnum(Op1V, Op2V));

      case Intrinsic::nvvm_fmax_d:
      case Intrinsic::nvvm_fmax_f:
      case Intrinsic::nvvm_fmax_ftz_f:
      case Intrinsic::nvvm_fmax_ftz_nan_f:
      case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:
      case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:
      case Intrinsic::nvvm_fmax_nan_f:
      case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:
      case Intrinsic::nvvm_fmax_xorsign_abs_f:

      case Intrinsic::nvvm_fmin_d:
      case Intrinsic::nvvm_fmin_f:
      case Intrinsic::nvvm_fmin_ftz_f:
      case Intrinsic::nvvm_fmin_ftz_nan_f:
      case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f:
      case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f:
      case Intrinsic::nvvm_fmin_nan_f:
      case Intrinsic::nvvm_fmin_nan_xorsign_abs_f:
      case Intrinsic::nvvm_fmin_xorsign_abs_f: {

        bool ShouldCanonicalizeNaNs = !(IntrinsicID == Intrinsic::nvvm_fmax_d ||
                                        IntrinsicID == Intrinsic::nvvm_fmin_d);
        bool IsFTZ = nvvm::FMinFMaxShouldFTZ(IntrinsicID);
        bool IsNaNPropagating = nvvm::FMinFMaxPropagatesNaNs(IntrinsicID);
        bool IsXorSignAbs = nvvm::FMinFMaxIsXorSignAbs(IntrinsicID);

        APFloat A = IsFTZ ? FTZPreserveSign(Op1V) : Op1V;
        APFloat B = IsFTZ ? FTZPreserveSign(Op2V) : Op2V;

        bool XorSign = false;
        if (IsXorSignAbs) {
          XorSign = A.isNegative() ^ B.isNegative();
          A = abs(A);
          B = abs(B);
        }

        bool IsFMax = false;
        switch (IntrinsicID) {
        case Intrinsic::nvvm_fmax_d:
        case Intrinsic::nvvm_fmax_f:
        case Intrinsic::nvvm_fmax_ftz_f:
        case Intrinsic::nvvm_fmax_ftz_nan_f:
        case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:
        case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:
        case Intrinsic::nvvm_fmax_nan_f:
        case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:
        case Intrinsic::nvvm_fmax_xorsign_abs_f:
          IsFMax = true;
          break;
        }
        APFloat Res = IsFMax ? maximum(A, B) : minimum(A, B);

        if (ShouldCanonicalizeNaNs) {
          APFloat NVCanonicalNaN(Res.getSemantics(), APInt(32, 0x7fffffff));
          if (A.isNaN() && B.isNaN())
            return ConstantFP::get(Ty, NVCanonicalNaN);
          else if (IsNaNPropagating && (A.isNaN() || B.isNaN()))
            return ConstantFP::get(Ty, NVCanonicalNaN);
        }

        if (A.isNaN() && B.isNaN())
          return Operands[1];
        else if (A.isNaN())
          Res = B;
        else if (B.isNaN())
          Res = A;

        if (IsXorSignAbs && XorSign != Res.isNegative())
          Res.changeSign();

        return ConstantFP::get(Ty->getContext(), Res);
      }
      }

      if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
        return nullptr;

      switch (IntrinsicID) {
      default:
        break;
      case Intrinsic::pow:
        return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
      case Intrinsic::amdgcn_fmul_legacy:
        // The legacy behaviour is that multiplying +/- 0.0 by anything, even
        // NaN or infinity, gives +0.0.
        if (Op1V.isZero() || Op2V.isZero())
          return ConstantFP::getZero(Ty);
        return ConstantFP::get(Ty->getContext(), Op1V * Op2V);
      }

    } else if (auto *Op2C = dyn_cast<ConstantInt>(Operands[1])) {
      switch (IntrinsicID) {
      case Intrinsic::ldexp: {
        return ConstantFP::get(
            Ty->getContext(),
            scalbn(Op1V, Op2C->getSExtValue(), APFloat::rmNearestTiesToEven));
      }
      case Intrinsic::is_fpclass: {
        FPClassTest Mask = static_cast<FPClassTest>(Op2C->getZExtValue());
        bool Result =
          ((Mask & fcSNan) && Op1V.isNaN() && Op1V.isSignaling()) ||
          ((Mask & fcQNan) && Op1V.isNaN() && !Op1V.isSignaling()) ||
          ((Mask & fcNegInf) && Op1V.isNegInfinity()) ||
          ((Mask & fcNegNormal) && Op1V.isNormal() && Op1V.isNegative()) ||
          ((Mask & fcNegSubnormal) && Op1V.isDenormal() && Op1V.isNegative()) ||
          ((Mask & fcNegZero) && Op1V.isZero() && Op1V.isNegative()) ||
          ((Mask & fcPosZero) && Op1V.isZero() && !Op1V.isNegative()) ||
          ((Mask & fcPosSubnormal) && Op1V.isDenormal() && !Op1V.isNegative()) ||
          ((Mask & fcPosNormal) && Op1V.isNormal() && !Op1V.isNegative()) ||
          ((Mask & fcPosInf) && Op1V.isPosInfinity());
        return ConstantInt::get(Ty, Result);
      }
      case Intrinsic::powi: {
        int Exp = static_cast<int>(Op2C->getSExtValue());
        switch (Ty->getTypeID()) {
        case Type::HalfTyID:
        case Type::FloatTyID: {
          APFloat Res(static_cast<float>(std::pow(Op1V.convertToFloat(), Exp)));
          if (Ty->isHalfTy()) {
            bool Unused;
            Res.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,
                        &Unused);
          }
          return ConstantFP::get(Ty->getContext(), Res);
        }
        case Type::DoubleTyID:
          return ConstantFP::get(Ty, std::pow(Op1V.convertToDouble(), Exp));
        default:
          return nullptr;
        }
      }
      default:
        break;
      }
    }
    return nullptr;
  }

  if (Operands[0]->getType()->isIntegerTy() &&
      Operands[1]->getType()->isIntegerTy()) {
    const APInt *C0, *C1;
    if (!getConstIntOrUndef(Operands[0], C0) ||
        !getConstIntOrUndef(Operands[1], C1))
      return nullptr;

    switch (IntrinsicID) {
    default: break;
    case Intrinsic::smax:
    case Intrinsic::smin:
    case Intrinsic::umax:
    case Intrinsic::umin:
      if (!C0 && !C1)
        return UndefValue::get(Ty);
      if (!C0 || !C1)
        return MinMaxIntrinsic::getSaturationPoint(IntrinsicID, Ty);
      return ConstantInt::get(
          Ty, ICmpInst::compare(*C0, *C1,
                                MinMaxIntrinsic::getPredicate(IntrinsicID))
                  ? *C0
                  : *C1);

    case Intrinsic::scmp:
    case Intrinsic::ucmp:
      if (!C0 || !C1)
        return ConstantInt::get(Ty, 0);

      int Res;
      if (IntrinsicID == Intrinsic::scmp)
        Res = C0->sgt(*C1) ? 1 : C0->slt(*C1) ? -1 : 0;
      else
        Res = C0->ugt(*C1) ? 1 : C0->ult(*C1) ? -1 : 0;
      return ConstantInt::get(Ty, Res, /*IsSigned=*/true);

    case Intrinsic::usub_with_overflow:
    case Intrinsic::ssub_with_overflow:
      // X - undef -> { 0, false }
      // undef - X -> { 0, false }
      if (!C0 || !C1)
        return Constant::getNullValue(Ty);
      [[fallthrough]];
    case Intrinsic::uadd_with_overflow:
    case Intrinsic::sadd_with_overflow:
      // X + undef -> { -1, false }
      // undef + x -> { -1, false }
      if (!C0 || !C1) {
        return ConstantStruct::get(
            cast<StructType>(Ty),
            {Constant::getAllOnesValue(Ty->getStructElementType(0)),
             Constant::getNullValue(Ty->getStructElementType(1))});
      }
      [[fallthrough]];
    case Intrinsic::smul_with_overflow:
    case Intrinsic::umul_with_overflow: {
      // undef * X -> { 0, false }
      // X * undef -> { 0, false }
      if (!C0 || !C1)
        return Constant::getNullValue(Ty);

      APInt Res;
      bool Overflow;
      switch (IntrinsicID) {
      default: llvm_unreachable("Invalid case");
      case Intrinsic::sadd_with_overflow:
        Res = C0->sadd_ov(*C1, Overflow);
        break;
      case Intrinsic::uadd_with_overflow:
        Res = C0->uadd_ov(*C1, Overflow);
        break;
      case Intrinsic::ssub_with_overflow:
        Res = C0->ssub_ov(*C1, Overflow);
        break;
      case Intrinsic::usub_with_overflow:
        Res = C0->usub_ov(*C1, Overflow);
        break;
      case Intrinsic::smul_with_overflow:
        Res = C0->smul_ov(*C1, Overflow);
        break;
      case Intrinsic::umul_with_overflow:
        Res = C0->umul_ov(*C1, Overflow);
        break;
      }
      Constant *Ops[] = {
        ConstantInt::get(Ty->getContext(), Res),
        ConstantInt::get(Type::getInt1Ty(Ty->getContext()), Overflow)
      };
      return ConstantStruct::get(cast<StructType>(Ty), Ops);
    }
    case Intrinsic::uadd_sat:
    case Intrinsic::sadd_sat:
      if (!C0 && !C1)
        return UndefValue::get(Ty);
      if (!C0 || !C1)
        return Constant::getAllOnesValue(Ty);
      if (IntrinsicID == Intrinsic::uadd_sat)
        return ConstantInt::get(Ty, C0->uadd_sat(*C1));
      else
        return ConstantInt::get(Ty, C0->sadd_sat(*C1));
    case Intrinsic::usub_sat:
    case Intrinsic::ssub_sat:
      if (!C0 && !C1)
        return UndefValue::get(Ty);
      if (!C0 || !C1)
        return Constant::getNullValue(Ty);
      if (IntrinsicID == Intrinsic::usub_sat)
        return ConstantInt::get(Ty, C0->usub_sat(*C1));
      else
        return ConstantInt::get(Ty, C0->ssub_sat(*C1));
    case Intrinsic::cttz:
    case Intrinsic::ctlz:
      assert(C1 && "Must be constant int");

      // cttz(0, 1) and ctlz(0, 1) are poison.
      if (C1->isOne() && (!C0 || C0->isZero()))
        return PoisonValue::get(Ty);
      if (!C0)
        return Constant::getNullValue(Ty);
      if (IntrinsicID == Intrinsic::cttz)
        return ConstantInt::get(Ty, C0->countr_zero());
      else
        return ConstantInt::get(Ty, C0->countl_zero());

    case Intrinsic::abs:
      assert(C1 && "Must be constant int");
      assert((C1->isOne() || C1->isZero()) && "Must be 0 or 1");

      // Undef or minimum val operand with poison min --> poison
      if (C1->isOne() && (!C0 || C0->isMinSignedValue()))
        return PoisonValue::get(Ty);

      // Undef operand with no poison min --> 0 (sign bit must be clear)
      if (!C0)
        return Constant::getNullValue(Ty);

      return ConstantInt::get(Ty, C0->abs());
    case Intrinsic::amdgcn_wave_reduce_umin:
    case Intrinsic::amdgcn_wave_reduce_umax:
      return dyn_cast<Constant>(Operands[0]);
    }

    return nullptr;
  }

  // Support ConstantVector in case we have an Undef in the top.
  if ((isa<ConstantVector>(Operands[0]) ||
       isa<ConstantDataVector>(Operands[0])) &&
      // Check for default rounding mode.
      // FIXME: Support other rounding modes?
      isa<ConstantInt>(Operands[1]) &&
      cast<ConstantInt>(Operands[1])->getValue() == 4) {
    auto *Op = cast<Constant>(Operands[0]);
    switch (IntrinsicID) {
    default: break;
    case Intrinsic::x86_avx512_vcvtss2si32:
    case Intrinsic::x86_avx512_vcvtss2si64:
    case Intrinsic::x86_avx512_vcvtsd2si32:
    case Intrinsic::x86_avx512_vcvtsd2si64:
      if (ConstantFP *FPOp =
              dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
        return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
                                           /*roundTowardZero=*/false, Ty,
                                           /*IsSigned*/true);
      break;
    case Intrinsic::x86_avx512_vcvtss2usi32:
    case Intrinsic::x86_avx512_vcvtss2usi64:
    case Intrinsic::x86_avx512_vcvtsd2usi32:
    case Intrinsic::x86_avx512_vcvtsd2usi64:
      if (ConstantFP *FPOp =
              dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
        return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
                                           /*roundTowardZero=*/false, Ty,
                                           /*IsSigned*/false);
      break;
    case Intrinsic::x86_avx512_cvttss2si:
    case Intrinsic::x86_avx512_cvttss2si64:
    case Intrinsic::x86_avx512_cvttsd2si:
    case Intrinsic::x86_avx512_cvttsd2si64:
      if (ConstantFP *FPOp =
              dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
        return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
                                           /*roundTowardZero=*/true, Ty,
                                           /*IsSigned*/true);
      break;
    case Intrinsic::x86_avx512_cvttss2usi:
    case Intrinsic::x86_avx512_cvttss2usi64:
    case Intrinsic::x86_avx512_cvttsd2usi:
    case Intrinsic::x86_avx512_cvttsd2usi64:
      if (ConstantFP *FPOp =
              dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
        return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
                                           /*roundTowardZero=*/true, Ty,
                                           /*IsSigned*/false);
      break;
    }
  }
  return nullptr;
}

static APFloat ConstantFoldAMDGCNCubeIntrinsic(Intrinsic::ID IntrinsicID,
                                               const APFloat &S0,
                                               const APFloat &S1,
                                               const APFloat &S2) {
  unsigned ID;
  const fltSemantics &Sem = S0.getSemantics();
  APFloat MA(Sem), SC(Sem), TC(Sem);
  if (abs(S2) >= abs(S0) && abs(S2) >= abs(S1)) {
    if (S2.isNegative() && S2.isNonZero() && !S2.isNaN()) {
      // S2 < 0
      ID = 5;
      SC = -S0;
    } else {
      ID = 4;
      SC = S0;
    }
    MA = S2;
    TC = -S1;
  } else if (abs(S1) >= abs(S0)) {
    if (S1.isNegative() && S1.isNonZero() && !S1.isNaN()) {
      // S1 < 0
      ID = 3;
      TC = -S2;
    } else {
      ID = 2;
      TC = S2;
    }
    MA = S1;
    SC = S0;
  } else {
    if (S0.isNegative() && S0.isNonZero() && !S0.isNaN()) {
      // S0 < 0
      ID = 1;
      SC = S2;
    } else {
      ID = 0;
      SC = -S2;
    }
    MA = S0;
    TC = -S1;
  }
  switch (IntrinsicID) {
  default:
    llvm_unreachable("unhandled amdgcn cube intrinsic");
  case Intrinsic::amdgcn_cubeid:
    return APFloat(Sem, ID);
  case Intrinsic::amdgcn_cubema:
    return MA + MA;
  case Intrinsic::amdgcn_cubesc:
    return SC;
  case Intrinsic::amdgcn_cubetc:
    return TC;
  }
}

static Constant *ConstantFoldAMDGCNPermIntrinsic(ArrayRef<Constant *> Operands,
                                                 Type *Ty) {
  const APInt *C0, *C1, *C2;
  if (!getConstIntOrUndef(Operands[0], C0) ||
      !getConstIntOrUndef(Operands[1], C1) ||
      !getConstIntOrUndef(Operands[2], C2))
    return nullptr;

  if (!C2)
    return UndefValue::get(Ty);

  APInt Val(32, 0);
  unsigned NumUndefBytes = 0;
  for (unsigned I = 0; I < 32; I += 8) {
    unsigned Sel = C2->extractBitsAsZExtValue(8, I);
    unsigned B = 0;

    if (Sel >= 13)
      B = 0xff;
    else if (Sel == 12)
      B = 0x00;
    else {
      const APInt *Src = ((Sel & 10) == 10 || (Sel & 12) == 4) ? C0 : C1;
      if (!Src)
        ++NumUndefBytes;
      else if (Sel < 8)
        B = Src->extractBitsAsZExtValue(8, (Sel & 3) * 8);
      else
        B = Src->extractBitsAsZExtValue(1, (Sel & 1) ? 31 : 15) * 0xff;
    }

    Val.insertBits(B, I, 8);
  }

  if (NumUndefBytes == 4)
    return UndefValue::get(Ty);

  return ConstantInt::get(Ty, Val);
}

static Constant *ConstantFoldScalarCall3(StringRef Name,
                                         Intrinsic::ID IntrinsicID,
                                         Type *Ty,
                                         ArrayRef<Constant *> Operands,
                                         const TargetLibraryInfo *TLI,
                                         const CallBase *Call) {
  assert(Operands.size() == 3 && "Wrong number of operands.");

  if (const auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
    if (const auto *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
      if (const auto *Op3 = dyn_cast<ConstantFP>(Operands[2])) {
        const APFloat &C1 = Op1->getValueAPF();
        const APFloat &C2 = Op2->getValueAPF();
        const APFloat &C3 = Op3->getValueAPF();

        if (const auto *ConstrIntr = dyn_cast<ConstrainedFPIntrinsic>(Call)) {
          RoundingMode RM = getEvaluationRoundingMode(ConstrIntr);
          APFloat Res = C1;
          APFloat::opStatus St;
          switch (IntrinsicID) {
          default:
            return nullptr;
          case Intrinsic::experimental_constrained_fma:
          case Intrinsic::experimental_constrained_fmuladd:
            St = Res.fusedMultiplyAdd(C2, C3, RM);
            break;
          }
          if (mayFoldConstrained(
                  const_cast<ConstrainedFPIntrinsic *>(ConstrIntr), St))
            return ConstantFP::get(Ty->getContext(), Res);
          return nullptr;
        }

        switch (IntrinsicID) {
        default: break;
        case Intrinsic::amdgcn_fma_legacy: {
          // The legacy behaviour is that multiplying +/- 0.0 by anything, even
          // NaN or infinity, gives +0.0.
          if (C1.isZero() || C2.isZero()) {
            // It's tempting to just return C3 here, but that would give the
            // wrong result if C3 was -0.0.
            return ConstantFP::get(Ty->getContext(), APFloat(0.0f) + C3);
          }
          [[fallthrough]];
        }
        case Intrinsic::fma:
        case Intrinsic::fmuladd: {
          APFloat V = C1;
          V.fusedMultiplyAdd(C2, C3, APFloat::rmNearestTiesToEven);
          return ConstantFP::get(Ty->getContext(), V);
        }
        case Intrinsic::amdgcn_cubeid:
        case Intrinsic::amdgcn_cubema:
        case Intrinsic::amdgcn_cubesc:
        case Intrinsic::amdgcn_cubetc: {
          APFloat V = ConstantFoldAMDGCNCubeIntrinsic(IntrinsicID, C1, C2, C3);
          return ConstantFP::get(Ty->getContext(), V);
        }
        }
      }
    }
  }

  if (IntrinsicID == Intrinsic::smul_fix ||
      IntrinsicID == Intrinsic::smul_fix_sat) {
    const APInt *C0, *C1;
    if (!getConstIntOrUndef(Operands[0], C0) ||
        !getConstIntOrUndef(Operands[1], C1))
      return nullptr;

    // undef * C -> 0
    // C * undef -> 0
    if (!C0 || !C1)
      return Constant::getNullValue(Ty);

    // This code performs rounding towards negative infinity in case the result
    // cannot be represented exactly for the given scale. Targets that do care
    // about rounding should use a target hook for specifying how rounding
    // should be done, and provide their own folding to be consistent with
    // rounding. This is the same approach as used by
    // DAGTypeLegalizer::ExpandIntRes_MULFIX.
    unsigned Scale = cast<ConstantInt>(Operands[2])->getZExtValue();
    unsigned Width = C0->getBitWidth();
    assert(Scale < Width && "Illegal scale.");
    unsigned ExtendedWidth = Width * 2;
    APInt Product =
        (C0->sext(ExtendedWidth) * C1->sext(ExtendedWidth)).ashr(Scale);
    if (IntrinsicID == Intrinsic::smul_fix_sat) {
      APInt Max = APInt::getSignedMaxValue(Width).sext(ExtendedWidth);
      APInt Min = APInt::getSignedMinValue(Width).sext(ExtendedWidth);
      Product = APIntOps::smin(Product, Max);
      Product = APIntOps::smax(Product, Min);
    }
    return ConstantInt::get(Ty->getContext(), Product.sextOrTrunc(Width));
  }

  if (IntrinsicID == Intrinsic::fshl || IntrinsicID == Intrinsic::fshr) {
    const APInt *C0, *C1, *C2;
    if (!getConstIntOrUndef(Operands[0], C0) ||
        !getConstIntOrUndef(Operands[1], C1) ||
        !getConstIntOrUndef(Operands[2], C2))
      return nullptr;

    bool IsRight = IntrinsicID == Intrinsic::fshr;
    if (!C2)
      return Operands[IsRight ? 1 : 0];
    if (!C0 && !C1)
      return UndefValue::get(Ty);

    // The shift amount is interpreted as modulo the bitwidth. If the shift
    // amount is effectively 0, avoid UB due to oversized inverse shift below.
    unsigned BitWidth = C2->getBitWidth();
    unsigned ShAmt = C2->urem(BitWidth);
    if (!ShAmt)
      return Operands[IsRight ? 1 : 0];

    // (C0 << ShlAmt) | (C1 >> LshrAmt)
    unsigned LshrAmt = IsRight ? ShAmt : BitWidth - ShAmt;
    unsigned ShlAmt = !IsRight ? ShAmt : BitWidth - ShAmt;
    if (!C0)
      return ConstantInt::get(Ty, C1->lshr(LshrAmt));
    if (!C1)
      return ConstantInt::get(Ty, C0->shl(ShlAmt));
    return ConstantInt::get(Ty, C0->shl(ShlAmt) | C1->lshr(LshrAmt));
  }

  if (IntrinsicID == Intrinsic::amdgcn_perm)
    return ConstantFoldAMDGCNPermIntrinsic(Operands, Ty);

  return nullptr;
}

static Constant *ConstantFoldScalarCall(StringRef Name,
                                        Intrinsic::ID IntrinsicID,
                                        Type *Ty,
                                        ArrayRef<Constant *> Operands,
                                        const TargetLibraryInfo *TLI,
                                        const CallBase *Call) {
  if (IntrinsicID != Intrinsic::not_intrinsic &&
      any_of(Operands, IsaPred<PoisonValue>) &&
      intrinsicPropagatesPoison(IntrinsicID))
    return PoisonValue::get(Ty);

  if (Operands.size() == 1)
    return ConstantFoldScalarCall1(Name, IntrinsicID, Ty, Operands, TLI, Call);

  if (Operands.size() == 2) {
    if (Constant *FoldedLibCall =
            ConstantFoldLibCall2(Name, Ty, Operands, TLI)) {
      return FoldedLibCall;
    }
    return ConstantFoldIntrinsicCall2(IntrinsicID, Ty, Operands, Call);
  }

  if (Operands.size() == 3)
    return ConstantFoldScalarCall3(Name, IntrinsicID, Ty, Operands, TLI, Call);

  return nullptr;
}

static Constant *ConstantFoldFixedVectorCall(
    StringRef Name, Intrinsic::ID IntrinsicID, FixedVectorType *FVTy,
    ArrayRef<Constant *> Operands, const DataLayout &DL,
    const TargetLibraryInfo *TLI, const CallBase *Call) {
  SmallVector<Constant *, 4> Result(FVTy->getNumElements());
  SmallVector<Constant *, 4> Lane(Operands.size());
  Type *Ty = FVTy->getElementType();

  switch (IntrinsicID) {
  case Intrinsic::masked_load: {
    auto *SrcPtr = Operands[0];
    auto *Mask = Operands[2];
    auto *Passthru = Operands[3];

    Constant *VecData = ConstantFoldLoadFromConstPtr(SrcPtr, FVTy, DL);

    SmallVector<Constant *, 32> NewElements;
    for (unsigned I = 0, E = FVTy->getNumElements(); I != E; ++I) {
      auto *MaskElt = Mask->getAggregateElement(I);
      if (!MaskElt)
        break;
      auto *PassthruElt = Passthru->getAggregateElement(I);
      auto *VecElt = VecData ? VecData->getAggregateElement(I) : nullptr;
      if (isa<UndefValue>(MaskElt)) {
        if (PassthruElt)
          NewElements.push_back(PassthruElt);
        else if (VecElt)
          NewElements.push_back(VecElt);
        else
          return nullptr;
      }
      if (MaskElt->isNullValue()) {
        if (!PassthruElt)
          return nullptr;
        NewElements.push_back(PassthruElt);
      } else if (MaskElt->isOneValue()) {
        if (!VecElt)
          return nullptr;
        NewElements.push_back(VecElt);
      } else {
        return nullptr;
      }
    }
    if (NewElements.size() != FVTy->getNumElements())
      return nullptr;
    return ConstantVector::get(NewElements);
  }
  case Intrinsic::arm_mve_vctp8:
  case Intrinsic::arm_mve_vctp16:
  case Intrinsic::arm_mve_vctp32:
  case Intrinsic::arm_mve_vctp64: {
    if (auto *Op = dyn_cast<ConstantInt>(Operands[0])) {
      unsigned Lanes = FVTy->getNumElements();
      uint64_t Limit = Op->getZExtValue();

      SmallVector<Constant *, 16> NCs;
      for (unsigned i = 0; i < Lanes; i++) {
        if (i < Limit)
          NCs.push_back(ConstantInt::getTrue(Ty));
        else
          NCs.push_back(ConstantInt::getFalse(Ty));
      }
      return ConstantVector::get(NCs);
    }
    return nullptr;
  }
  case Intrinsic::get_active_lane_mask: {
    auto *Op0 = dyn_cast<ConstantInt>(Operands[0]);
    auto *Op1 = dyn_cast<ConstantInt>(Operands[1]);
    if (Op0 && Op1) {
      unsigned Lanes = FVTy->getNumElements();
      uint64_t Base = Op0->getZExtValue();
      uint64_t Limit = Op1->getZExtValue();

      SmallVector<Constant *, 16> NCs;
      for (unsigned i = 0; i < Lanes; i++) {
        if (Base + i < Limit)
          NCs.push_back(ConstantInt::getTrue(Ty));
        else
          NCs.push_back(ConstantInt::getFalse(Ty));
      }
      return ConstantVector::get(NCs);
    }
    return nullptr;
  }
  case Intrinsic::vector_extract: {
    auto *Idx = dyn_cast<ConstantInt>(Operands[1]);
    Constant *Vec = Operands[0];
    if (!Idx || !isa<FixedVectorType>(Vec->getType()))
      return nullptr;

    unsigned NumElements = FVTy->getNumElements();
    unsigned VecNumElements =
        cast<FixedVectorType>(Vec->getType())->getNumElements();
    unsigned StartingIndex = Idx->getZExtValue();

    // Extracting entire vector is nop
    if (NumElements == VecNumElements && StartingIndex == 0)
      return Vec;

    for (unsigned I = StartingIndex, E = StartingIndex + NumElements; I < E;
         ++I) {
      Constant *Elt = Vec->getAggregateElement(I);
      if (!Elt)
        return nullptr;
      Result[I - StartingIndex] = Elt;
    }

    return ConstantVector::get(Result);
  }
  case Intrinsic::vector_insert: {
    Constant *Vec = Operands[0];
    Constant *SubVec = Operands[1];
    auto *Idx = dyn_cast<ConstantInt>(Operands[2]);
    if (!Idx || !isa<FixedVectorType>(Vec->getType()))
      return nullptr;

    unsigned SubVecNumElements =
        cast<FixedVectorType>(SubVec->getType())->getNumElements();
    unsigned VecNumElements =
        cast<FixedVectorType>(Vec->getType())->getNumElements();
    unsigned IdxN = Idx->getZExtValue();
    // Replacing entire vector with a subvec is nop
    if (SubVecNumElements == VecNumElements && IdxN == 0)
      return SubVec;

    for (unsigned I = 0; I < VecNumElements; ++I) {
      Constant *Elt;
      if (I < IdxN + SubVecNumElements)
        Elt = SubVec->getAggregateElement(I - IdxN);
      else
        Elt = Vec->getAggregateElement(I);
      if (!Elt)
        return nullptr;
      Result[I] = Elt;
    }
    return ConstantVector::get(Result);
  }
  case Intrinsic::vector_interleave2: {
    unsigned NumElements =
        cast<FixedVectorType>(Operands[0]->getType())->getNumElements();
    for (unsigned I = 0; I < NumElements; ++I) {
      Constant *Elt0 = Operands[0]->getAggregateElement(I);
      Constant *Elt1 = Operands[1]->getAggregateElement(I);
      if (!Elt0 || !Elt1)
        return nullptr;
      Result[2 * I] = Elt0;
      Result[2 * I + 1] = Elt1;
    }
    return ConstantVector::get(Result);
  }
  default:
    break;
  }

  for (unsigned I = 0, E = FVTy->getNumElements(); I != E; ++I) {
    // Gather a column of constants.
    for (unsigned J = 0, JE = Operands.size(); J != JE; ++J) {
      // Some intrinsics use a scalar type for certain arguments.
      if (isVectorIntrinsicWithScalarOpAtArg(IntrinsicID, J, /*TTI=*/nullptr)) {
        Lane[J] = Operands[J];
        continue;
      }

      Constant *Agg = Operands[J]->getAggregateElement(I);
      if (!Agg)
        return nullptr;

      Lane[J] = Agg;
    }

    // Use the regular scalar folding to simplify this column.
    Constant *Folded =
        ConstantFoldScalarCall(Name, IntrinsicID, Ty, Lane, TLI, Call);
    if (!Folded)
      return nullptr;
    Result[I] = Folded;
  }

  return ConstantVector::get(Result);
}

static Constant *ConstantFoldScalableVectorCall(
    StringRef Name, Intrinsic::ID IntrinsicID, ScalableVectorType *SVTy,
    ArrayRef<Constant *> Operands, const DataLayout &DL,
    const TargetLibraryInfo *TLI, const CallBase *Call) {
  switch (IntrinsicID) {
  case Intrinsic::aarch64_sve_convert_from_svbool: {
    auto *Src = dyn_cast<Constant>(Operands[0]);
    if (!Src || !Src->isNullValue())
      break;

    return ConstantInt::getFalse(SVTy);
  }
  default:
    break;
  }

  // If trivially vectorizable, try folding it via the scalar call if all
  // operands are splats.

  // TODO: ConstantFoldFixedVectorCall should probably check this too?
  if (!isTriviallyVectorizable(IntrinsicID))
    return nullptr;

  SmallVector<Constant *, 4> SplatOps;
  for (auto [I, Op] : enumerate(Operands)) {
    if (isVectorIntrinsicWithScalarOpAtArg(IntrinsicID, I, /*TTI=*/nullptr)) {
      SplatOps.push_back(Op);
      continue;
    }
    Constant *Splat = Op->getSplatValue();
    if (!Splat)
      return nullptr;
    SplatOps.push_back(Splat);
  }
  Constant *Folded = ConstantFoldScalarCall(
      Name, IntrinsicID, SVTy->getElementType(), SplatOps, TLI, Call);
  if (!Folded)
    return nullptr;
  return ConstantVector::getSplat(SVTy->getElementCount(), Folded);
}

static std::pair<Constant *, Constant *>
ConstantFoldScalarFrexpCall(Constant *Op, Type *IntTy) {
  if (isa<PoisonValue>(Op))
    return {Op, PoisonValue::get(IntTy)};

  auto *ConstFP = dyn_cast<ConstantFP>(Op);
  if (!ConstFP)
    return {};

  const APFloat &U = ConstFP->getValueAPF();
  int FrexpExp;
  APFloat FrexpMant = frexp(U, FrexpExp, APFloat::rmNearestTiesToEven);
  Constant *Result0 = ConstantFP::get(ConstFP->getType(), FrexpMant);

  // The exponent is an "unspecified value" for inf/nan. We use zero to avoid
  // using undef.
  Constant *Result1 = FrexpMant.isFinite()
                          ? ConstantInt::getSigned(IntTy, FrexpExp)
                          : ConstantInt::getNullValue(IntTy);
  return {Result0, Result1};
}

/// Handle intrinsics that return tuples, which may be tuples of vectors.
static Constant *
ConstantFoldStructCall(StringRef Name, Intrinsic::ID IntrinsicID,
                       StructType *StTy, ArrayRef<Constant *> Operands,
                       const DataLayout &DL, const TargetLibraryInfo *TLI,
                       const CallBase *Call) {

  switch (IntrinsicID) {
  case Intrinsic::frexp: {
    Type *Ty0 = StTy->getContainedType(0);
    Type *Ty1 = StTy->getContainedType(1)->getScalarType();

    if (auto *FVTy0 = dyn_cast<FixedVectorType>(Ty0)) {
      SmallVector<Constant *, 4> Results0(FVTy0->getNumElements());
      SmallVector<Constant *, 4> Results1(FVTy0->getNumElements());

      for (unsigned I = 0, E = FVTy0->getNumElements(); I != E; ++I) {
        Constant *Lane = Operands[0]->getAggregateElement(I);
        std::tie(Results0[I], Results1[I]) =
            ConstantFoldScalarFrexpCall(Lane, Ty1);
        if (!Results0[I])
          return nullptr;
      }

      return ConstantStruct::get(StTy, ConstantVector::get(Results0),
                                 ConstantVector::get(Results1));
    }

    auto [Result0, Result1] = ConstantFoldScalarFrexpCall(Operands[0], Ty1);
    if (!Result0)
      return nullptr;
    return ConstantStruct::get(StTy, Result0, Result1);
  }
  case Intrinsic::sincos: {
    Type *Ty = StTy->getContainedType(0);
    Type *TyScalar = Ty->getScalarType();

    auto ConstantFoldScalarSincosCall =
        [&](Constant *Op) -> std::pair<Constant *, Constant *> {
      Constant *SinResult =
          ConstantFoldScalarCall(Name, Intrinsic::sin, TyScalar, Op, TLI, Call);
      Constant *CosResult =
          ConstantFoldScalarCall(Name, Intrinsic::cos, TyScalar, Op, TLI, Call);
      return std::make_pair(SinResult, CosResult);
    };

    if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) {
      SmallVector<Constant *> SinResults(FVTy->getNumElements());
      SmallVector<Constant *> CosResults(FVTy->getNumElements());

      for (unsigned I = 0, E = FVTy->getNumElements(); I != E; ++I) {
        Constant *Lane = Operands[0]->getAggregateElement(I);
        std::tie(SinResults[I], CosResults[I]) =
            ConstantFoldScalarSincosCall(Lane);
        if (!SinResults[I] || !CosResults[I])
          return nullptr;
      }

      return ConstantStruct::get(StTy, ConstantVector::get(SinResults),
                                 ConstantVector::get(CosResults));
    }

    auto [SinResult, CosResult] = ConstantFoldScalarSincosCall(Operands[0]);
    if (!SinResult || !CosResult)
      return nullptr;
    return ConstantStruct::get(StTy, SinResult, CosResult);
  }
  case Intrinsic::vector_deinterleave2: {
    auto *Vec = Operands[0];
    auto *VecTy = cast<VectorType>(Vec->getType());

    if (auto *EltC = Vec->getSplatValue()) {
      ElementCount HalfEC = VecTy->getElementCount().divideCoefficientBy(2);
      auto *HalfVec = ConstantVector::getSplat(HalfEC, EltC);
      return ConstantStruct::get(StTy, HalfVec, HalfVec);
    }

    if (!isa<FixedVectorType>(Vec->getType()))
      return nullptr;

    unsigned NumElements = VecTy->getElementCount().getFixedValue() / 2;
    SmallVector<Constant *, 4> Res0(NumElements), Res1(NumElements);
    for (unsigned I = 0; I < NumElements; ++I) {
      Constant *Elt0 = Vec->getAggregateElement(2 * I);
      Constant *Elt1 = Vec->getAggregateElement(2 * I + 1);
      if (!Elt0 || !Elt1)
        return nullptr;
      Res0[I] = Elt0;
      Res1[I] = Elt1;
    }
    return ConstantStruct::get(StTy, ConstantVector::get(Res0),
                               ConstantVector::get(Res1));
  }
  default:
    // TODO: Constant folding of vector intrinsics that fall through here does
    // not work (e.g. overflow intrinsics)
    return ConstantFoldScalarCall(Name, IntrinsicID, StTy, Operands, TLI, Call);
  }

  return nullptr;
}

} // end anonymous namespace

Constant *llvm::ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS,
                                            Constant *RHS, Type *Ty,
                                            Instruction *FMFSource) {
  auto *Call = dyn_cast_if_present<CallBase>(FMFSource);
  // Ensure we check flags like StrictFP that might prevent this from getting
  // folded before generating a result.
  if (Call && !canConstantFoldCallTo(Call, Call->getCalledFunction()))
    return nullptr;
  return ConstantFoldIntrinsicCall2(ID, Ty, {LHS, RHS}, Call);
}

Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F,
                                 ArrayRef<Constant *> Operands,
                                 const TargetLibraryInfo *TLI,
                                 bool AllowNonDeterministic) {
  if (Call->isNoBuiltin())
    return nullptr;
  if (!F->hasName())
    return nullptr;

  // If this is not an intrinsic and not recognized as a library call, bail out.
  Intrinsic::ID IID = F->getIntrinsicID();
  if (IID == Intrinsic::not_intrinsic) {
    if (!TLI)
      return nullptr;
    LibFunc LibF;
    if (!TLI->getLibFunc(*F, LibF))
      return nullptr;
  }

  // Conservatively assume that floating-point libcalls may be
  // non-deterministic.
  Type *Ty = F->getReturnType();
  if (!AllowNonDeterministic && Ty->isFPOrFPVectorTy())
    return nullptr;

  StringRef Name = F->getName();
  if (auto *FVTy = dyn_cast<FixedVectorType>(Ty))
    return ConstantFoldFixedVectorCall(
        Name, IID, FVTy, Operands, F->getDataLayout(), TLI, Call);

  if (auto *SVTy = dyn_cast<ScalableVectorType>(Ty))
    return ConstantFoldScalableVectorCall(
        Name, IID, SVTy, Operands, F->getDataLayout(), TLI, Call);

  if (auto *StTy = dyn_cast<StructType>(Ty))
    return ConstantFoldStructCall(Name, IID, StTy, Operands,
                                  F->getDataLayout(), TLI, Call);

  // TODO: If this is a library function, we already discovered that above,
  //       so we should pass the LibFunc, not the name (and it might be better
  //       still to separate intrinsic handling from libcalls).
  return ConstantFoldScalarCall(Name, IID, Ty, Operands, TLI, Call);
}

bool llvm::isMathLibCallNoop(const CallBase *Call,
                             const TargetLibraryInfo *TLI) {
  // FIXME: Refactor this code; this duplicates logic in LibCallsShrinkWrap
  // (and to some extent ConstantFoldScalarCall).
  if (Call->isNoBuiltin() || Call->isStrictFP())
    return false;
  Function *F = Call->getCalledFunction();
  if (!F)
    return false;

  LibFunc Func;
  if (!TLI || !TLI->getLibFunc(*F, Func))
    return false;

  if (Call->arg_size() == 1) {
    if (ConstantFP *OpC = dyn_cast<ConstantFP>(Call->getArgOperand(0))) {
      const APFloat &Op = OpC->getValueAPF();
      switch (Func) {
      case LibFunc_logl:
      case LibFunc_log:
      case LibFunc_logf:
      case LibFunc_log2l:
      case LibFunc_log2:
      case LibFunc_log2f:
      case LibFunc_log10l:
      case LibFunc_log10:
      case LibFunc_log10f:
        return Op.isNaN() || (!Op.isZero() && !Op.isNegative());

      case LibFunc_ilogb:
        return !Op.isNaN() && !Op.isZero() && !Op.isInfinity();

      case LibFunc_expl:
      case LibFunc_exp:
      case LibFunc_expf:
        // FIXME: These boundaries are slightly conservative.
        if (OpC->getType()->isDoubleTy())
          return !(Op < APFloat(-745.0) || Op > APFloat(709.0));
        if (OpC->getType()->isFloatTy())
          return !(Op < APFloat(-103.0f) || Op > APFloat(88.0f));
        break;

      case LibFunc_exp2l:
      case LibFunc_exp2:
      case LibFunc_exp2f:
        // FIXME: These boundaries are slightly conservative.
        if (OpC->getType()->isDoubleTy())
          return !(Op < APFloat(-1074.0) || Op > APFloat(1023.0));
        if (OpC->getType()->isFloatTy())
          return !(Op < APFloat(-149.0f) || Op > APFloat(127.0f));
        break;

      case LibFunc_sinl:
      case LibFunc_sin:
      case LibFunc_sinf:
      case LibFunc_cosl:
      case LibFunc_cos:
      case LibFunc_cosf:
        return !Op.isInfinity();

      case LibFunc_tanl:
      case LibFunc_tan:
      case LibFunc_tanf: {
        // FIXME: Stop using the host math library.
        // FIXME: The computation isn't done in the right precision.
        Type *Ty = OpC->getType();
        if (Ty->isDoubleTy() || Ty->isFloatTy() || Ty->isHalfTy())
          return ConstantFoldFP(tan, OpC->getValueAPF(), Ty) != nullptr;
        break;
      }

      case LibFunc_atan:
      case LibFunc_atanf:
      case LibFunc_atanl:
        // Per POSIX, this MAY fail if Op is denormal. We choose not failing.
        return true;

      case LibFunc_asinl:
      case LibFunc_asin:
      case LibFunc_asinf:
      case LibFunc_acosl:
      case LibFunc_acos:
      case LibFunc_acosf:
        return !(Op < APFloat::getOne(Op.getSemantics(), true) ||
                 Op > APFloat::getOne(Op.getSemantics()));

      case LibFunc_sinh:
      case LibFunc_cosh:
      case LibFunc_sinhf:
      case LibFunc_coshf:
      case LibFunc_sinhl:
      case LibFunc_coshl:
        // FIXME: These boundaries are slightly conservative.
        if (OpC->getType()->isDoubleTy())
          return !(Op < APFloat(-710.0) || Op > APFloat(710.0));
        if (OpC->getType()->isFloatTy())
          return !(Op < APFloat(-89.0f) || Op > APFloat(89.0f));
        break;

      case LibFunc_sqrtl:
      case LibFunc_sqrt:
      case LibFunc_sqrtf:
        return Op.isNaN() || Op.isZero() || !Op.isNegative();

      // FIXME: Add more functions: sqrt_finite, atanh, expm1, log1p,
      // maybe others?
      default:
        break;
      }
    }
  }

  if (Call->arg_size() == 2) {
    ConstantFP *Op0C = dyn_cast<ConstantFP>(Call->getArgOperand(0));
    ConstantFP *Op1C = dyn_cast<ConstantFP>(Call->getArgOperand(1));
    if (Op0C && Op1C) {
      const APFloat &Op0 = Op0C->getValueAPF();
      const APFloat &Op1 = Op1C->getValueAPF();

      switch (Func) {
      case LibFunc_powl:
      case LibFunc_pow:
      case LibFunc_powf: {
        // FIXME: Stop using the host math library.
        // FIXME: The computation isn't done in the right precision.
        Type *Ty = Op0C->getType();
        if (Ty->isDoubleTy() || Ty->isFloatTy() || Ty->isHalfTy()) {
          if (Ty == Op1C->getType())
            return ConstantFoldBinaryFP(pow, Op0, Op1, Ty) != nullptr;
        }
        break;
      }

      case LibFunc_fmodl:
      case LibFunc_fmod:
      case LibFunc_fmodf:
      case LibFunc_remainderl:
      case LibFunc_remainder:
      case LibFunc_remainderf:
        return Op0.isNaN() || Op1.isNaN() ||
               (!Op0.isInfinity() && !Op1.isZero());

      case LibFunc_atan2:
      case LibFunc_atan2f:
      case LibFunc_atan2l:
        // Although IEEE-754 says atan2(+/-0.0, +/-0.0) are well-defined, and
        // GLIBC and MSVC do not appear to raise an error on those, we
        // cannot rely on that behavior. POSIX and C11 say that a domain error
        // may occur, so allow for that possibility.
        return !Op0.isZero() || !Op1.isZero();

      default:
        break;
      }
    }
  }

  return false;
}

void TargetFolder::anchor() {}
