// Copyright 2022 The Clspv Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "BitcastUtils.h"
#include "Builtins.h"
#include "Types.h"
#include "clspv/AddressSpace.h"
#include "clspv/Option.h"
#include <cmath>
#include <llvm/IR/Instructions.h>
#include <llvm/Support/Debug.h>

#define DEBUG_TYPE "bitcastutils"

#define DEBUG_FCT_TY_VALUES(Ty, Values)                                        \
  do {                                                                         \
    LLVM_DEBUG(fprintf(stderr, "%s: ", __func__); Ty->dump();                  \
               fprintf(stderr, "\tValues[0/%lu] = ", Values.size());           \
               Values[0]->dump());                                             \
  } while (0)
#define DEBUG_FCT_VALUES(Values)                                               \
  do {                                                                         \
    LLVM_DEBUG(                                                                \
        fprintf(stderr, "%s: Values[0/%lu] = ", __func__, Values.size());      \
        Values[0]->dump());                                                    \
  } while (0)

namespace BitcastUtils {

bool IsUnsizedType(const DataLayout &DL, Type *Ty) {
  return SizeInBits(DL, Ty) == 0;
}

// Interface types are often something like: { [ 0 x Ty ] }.
// SizeInBits returns zero for such types. Try to avoid it by go through the
// type as long as SizeInBits returns zero to get the real type size for it.
Type *reworkUnsizedType(const DataLayout &DL, Type *Ty, unsigned *steps) {
  unsigned s = 0;
  auto size = SizeInBits(DL, Ty);
  auto Ele = GetEleType(Ty);
  while (size == 0 && Ty != Ele) {
    s++;
    Ty = Ele;
    Ele = GetEleType(Ty);
    size = SizeInBits(DL, Ty);
  }
  if (steps != nullptr) {
    *steps = s;
  }
  return Ty;
}

void GroupScalarValuesIntoVector(IRBuilder<> &Builder,
                                 SmallVector<Value *, 8> &Values,
                                 unsigned NumElePerVec);
// Returns the size in bits of 'Ty'
size_t SizeInBits(const DataLayout &DL, Type *Ty) {
  if (Ty->isVoidTy()) {
    return 0;
  }
  return DL.getTypeAllocSizeInBits(Ty);
}

// Same as above with different arguments
size_t SizeInBits(IRBuilder<> &builder, Type *Ty) {
  return SizeInBits(
      builder.GetInsertBlock()->getParent()->getParent()->getDataLayout(), Ty);
}

// Returns the element type when 'Ty' is a vector, an array, or a packed struct
// with only one type, otherwise returns 'Ty'.
Type *GetEleType(Type *Ty) {
  if (auto VecTy = dyn_cast<VectorType>(Ty)) {
    return VecTy->getElementType();
  } else if (auto ArrTy = dyn_cast<ArrayType>(Ty)) {
    return ArrTy->getElementType();
  } else if (auto StructTy = dyn_cast<StructType>(Ty)) {
    if (!StructTy->isOpaque() && StructTy->getNumElements() == 1) {
      return StructTy->getContainedType(0);
    }
    return Ty;
  } else {
    return Ty;
  }
}

// Returns the number of elements when 'Ty' is a vector or an array, otherwise
// returns 1.
unsigned GetNumEle(Type *Ty) {
  if (auto VecTy = dyn_cast<FixedVectorType>(Ty)) {
    return VecTy->getNumElements();
  } else if (auto ArrTy = dyn_cast<ArrayType>(Ty)) {
    return ArrTy->getNumElements();
  } else {
    return 1;
  }
}

// Gathers the scalar values of |v| into |elements|. Generates new instructions
// to extract the values.
void GatherBaseElements(Value *v, SmallVectorImpl<Value *> *elements,
                        IRBuilder<> &builder) {
  auto *module = builder.GetInsertBlock()->getParent()->getParent();
  auto &DL = module->getDataLayout();
  auto *type = v->getType();
  if (auto *vec_type = dyn_cast<VectorType>(type)) {
    for (uint64_t i = 0; i != vec_type->getElementCount().getKnownMinValue();
         ++i) {
      elements->push_back(builder.CreateExtractElement(v, i));
    }
  } else if (auto *array_type = dyn_cast<ArrayType>(type)) {
    for (uint64_t i = 0; i != array_type->getNumElements(); ++i) {
      auto *extract = builder.CreateExtractValue(v, {static_cast<unsigned>(i)});
      GatherBaseElements(extract, elements, builder);
    }
  } else if (auto *struct_type = dyn_cast<StructType>(type)) {
    const auto *struct_layout = DL.getStructLayout(struct_type);
    if (struct_layout->hasPadding()) {
      llvm_unreachable("Unhandled conversion of padded struct");
    }
    for (unsigned i = 0; i != struct_type->getNumElements(); ++i) {
      auto *extract = builder.CreateExtractValue(v, {i});
      GatherBaseElements(extract, elements, builder);
    }
  } else {
    elements->push_back(v);
  }
}

// Returns a value of |dst_type| using the elemental members of |src_elements|.
Value *BuildFromElements(Type *dst_type, const ArrayRef<Value *> &src_elements,
                         unsigned *used_bits, unsigned *index,
                         IRBuilder<> &builder) {
  auto *module = builder.GetInsertBlock()->getParent()->getParent();
  auto &DL = module->getDataLayout();
  auto &context = dst_type->getContext();
  Value *dst = nullptr;
  // Arrays, vectors and structs are annoyingly just different enough to each
  // require their own cases.
  if (auto *dst_array_ty = dyn_cast<ArrayType>(dst_type)) {
    auto *ele_ty = dst_array_ty->getElementType();
    for (uint64_t i = 0; i != dst_array_ty->getNumElements(); ++i) {
      auto *tmp_value =
          BuildFromElements(ele_ty, src_elements, used_bits, index, builder);
      auto *prev = dst ? dst : PoisonValue::get(dst_type);
      dst = builder.CreateInsertValue(prev, tmp_value,
                                      {static_cast<unsigned>(i)});
    }
  } else if (auto *dst_struct_ty = dyn_cast<StructType>(dst_type)) {
    const auto *struct_layout = DL.getStructLayout(dst_struct_ty);
    if (struct_layout->hasPadding()) {
      llvm_unreachable("Unhandled padded struct conversion");
      return nullptr;
    }
    for (unsigned i = 0; i != dst_struct_ty->getNumElements(); ++i) {
      auto *ele_ty = dst_struct_ty->getElementType(i);
      auto *tmp_value =
          BuildFromElements(ele_ty, src_elements, used_bits, index, builder);
      auto *prev = dst ? dst : PoisonValue::get(dst_type);
      dst = builder.CreateInsertValue(prev, tmp_value, {i});
    }
  } else if (auto *dst_vec_ty = dyn_cast<VectorType>(dst_type)) {
    auto *ele_ty = dst_vec_ty->getElementType();
    for (uint64_t i = 0; i != dst_vec_ty->getElementCount().getKnownMinValue();
         ++i) {
      auto *tmp_value =
          BuildFromElements(ele_ty, src_elements, used_bits, index, builder);
      auto *prev = dst ? dst : PoisonValue::get(dst_type);
      dst = builder.CreateInsertElement(prev, tmp_value, i);
    }
  } else {
    // Scalar conversion eats up elements in src_elements.
    auto dst_width = DL.getTypeStoreSizeInBits(dst_type);
    uint64_t bits = 0;
    Value *tmp_value = nullptr;
    auto prev_bits = 0;
    Value *ele_int_cast = nullptr;
    while (bits < dst_width) {
      prev_bits = bits;
      auto *ele = src_elements[*index];
      auto *ele_ty = ele->getType();
      auto ele_width = DL.getTypeStoreSizeInBits(ele_ty);
      auto remaining_bits = ele_width - *used_bits;
      auto needed_bits = dst_width - bits;
      // Create a reusable cast to an integer type for this element.
      if (!ele_int_cast || cast<User>(ele_int_cast)->getOperand(0) != ele) {
        ele_int_cast =
            builder.CreateBitCast(ele, IntegerType::get(context, ele_width));
      }
      tmp_value = ele_int_cast;
      // Some of the bits of this element were previously used, so shift the
      // value that many bits.
      if (*used_bits != 0) {
        tmp_value = builder.CreateLShr(tmp_value, *used_bits);
      }
      if (needed_bits < remaining_bits && needed_bits < dst_width) {
        // Ensure only the needed bits are used.
        uint64_t mask = (1ull << needed_bits) - 1;
        tmp_value =
            builder.CreateAnd(tmp_value, builder.getIntN(ele_width, mask));
      }
      // Cast to tbe destination bit width, but stay as a integer type.
      if (ele_width != dst_width) {
        tmp_value = builder.CreateIntCast(
            tmp_value, IntegerType::get(context, dst_width), false);
      }

      if (remaining_bits <= needed_bits) {
        // Used the rest of the element.
        *used_bits = 0;
        ++(*index);
        bits += remaining_bits;
      } else {
        // Only need part of this element.
        *used_bits += needed_bits;
        bits += needed_bits;
      }

      if (dst) {
        // Previous iteration generated an integer of the right size. That needs
        // to be combined with the value generated this iteration.
        tmp_value = builder.CreateShl(tmp_value, prev_bits);
        dst = builder.CreateOr(dst, tmp_value);
      } else {
        dst = tmp_value;
      }
    }

    assert(bits <= dst_width);
    if (bits == dst_width && dst_type != dst->getType()) {
      // Finally, cast away from the working integer type if necessary.
      dst = builder.CreateBitCast(dst, dst_type);
    }
  }

  return dst;
}

// Returns an equivalent value of |src| as |dst_type|.
//
// This function requires |src|'s and |dst_type|'s bit widths match. Does not
// introduce new integer sizes, but generates multiple instructions to mimic a
// generic bitcast (unless a bitcast is sufficient).
Value *ConvertValue(Value *src, Type *dst_type, IRBuilder<> &builder) {
  auto *src_type = src->getType();
  auto *module = builder.GetInsertBlock()->getParent()->getParent();
  auto &DL = module->getDataLayout();
  if (!src_type->isFirstClassType() || !dst_type->isFirstClassType() ||
      src_type->isAggregateType() || dst_type->isAggregateType()) {
    SmallVector<Value *, 8> src_elements;
    if (src_type->isAggregateType()) {
      GatherBaseElements(src, &src_elements, builder);
    } else {
      src_elements.push_back(src);
    }

    // Check that overall sizes make sense.
    uint64_t element_sum = 0;
    // Can only successfully convert unpadded structs.
    for (auto element : src_elements) {
      element_sum += DL.getTypeStoreSizeInBits(element->getType());
    }
    if (DL.getTypeStoreSizeInBits(dst_type) != element_sum) {
      llvm_unreachable("Elements do not sum to overall size");
      return nullptr;
    }

    unsigned used_bits = 0;
    unsigned index = 0;
    return BuildFromElements(dst_type, src_elements, &used_bits, &index,
                             builder);
  } else {
    return builder.CreateBitCast(src, dst_type);
  }

  return nullptr;
}

// 'Values' is expected to contain elements that will compose struct of type
// 'Ty'.
// 'Values' is also the output of this function, containing arrays of type 'Ty'.
void InsertInArrayLikeStruct(IRBuilder<> &Builder, StructType *Ty,
                             SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  unsigned StructNumEles = Ty->getNumElements();
  assert(Ty->getElementType(0) == Values[0]->getType());
  assert(Values.size() % StructNumEles == 0);
  unsigned NumArrays = Values.size() / StructNumEles;
  for (unsigned i = 0; i < NumArrays; i++) {
    Value *Ret = PoisonValue::get(Ty);
    for (unsigned j = 0; j < StructNumEles; j++) {
      Ret = Builder.CreateInsertValue(Ret, Values[i * StructNumEles + j], {j});
    }
    Values[i] = Ret;
  }
  Values.resize(NumArrays);
}

// 'Values' is expected to contain elements that will compose arrays of type
// 'Ty'.
// 'Values' is also the output of this function, containing arrays of type 'Ty'.
void InsertInArray(IRBuilder<> &Builder, ArrayType *Ty,
                   SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  unsigned ArrayNumEles = Ty->getNumElements();
  assert(Ty->getElementType() == Values[0]->getType());
  assert(Values.size() % ArrayNumEles == 0);
  unsigned NumArrays = Values.size() / ArrayNumEles;
  for (unsigned i = 0; i < NumArrays; i++) {
    Value *Ret = PoisonValue::get(Ty);
    for (unsigned j = 0; j < ArrayNumEles; j++) {
      Ret = Builder.CreateInsertValue(Ret, Values[i * ArrayNumEles + j], {j});
    }
    Values[i] = Ret;
  }
  Values.resize(NumArrays);
}

// 'Values' is expected to contain vectors.
// 'Values is also the output of this function, containing all the elements of
// the input vectors.
void ExtractFromVector(IRBuilder<> &Builder, SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_VALUES(Values);
  SmallVector<Value *, 8> ScalarValues;
  Type *ValueTy = Values[0]->getType();
  assert(ValueTy->isVectorTy());
  for (unsigned i = 0; i < Values.size(); i++) {
    for (unsigned j = 0; j < GetNumEle(ValueTy); j++) {
      ScalarValues.push_back(Builder.CreateExtractElement(Values[i], j));
    }
  }
  Values.clear();
  Values = std::move(ScalarValues);
}

// 'Values' is expected to contain arrays.
// 'Values is also the output of this function, containing all the elements of
// the input arrays.
void ExtractFromArray(IRBuilder<> &Builder, SmallVector<Value *, 8> &Values,
                      bool isPackedStructSrc, unsigned DstTySize) {
  DEBUG_FCT_VALUES(Values);
  SmallVector<Value *, 8> ScalarValues;
  Type *ValueTy = Values[0]->getType();
  unsigned CharSize = CHAR_BIT;
  unsigned NumElements =
      isPackedStructSrc ? DstTySize / CharSize : GetNumEle(ValueTy);
  assert(NumElements != 0);
  assert(ValueTy->isArrayTy());
  for (unsigned i = 0; i < Values.size(); i++) {
    for (unsigned j = 0; j < NumElements; j++) {
      ScalarValues.push_back(Builder.CreateExtractValue(Values[i], j));
    }
  }
  Values.clear();
  Values = std::move(ScalarValues);
}

// Return a scalar type of size 'N' matching the 'TargetTy' if possible.
Type *getNTy(IRBuilder<> &Builder, unsigned N, Type *TargetTy) {
  if (GetEleType(TargetTy)->isFloatTy() && N == 32) {
    return Builder.getFloatTy();
  } else if (GetEleType(TargetTy)->isHalfTy() && N == 16) {
    return Builder.getHalfTy();
  } else {
    return Builder.getIntNTy(N);
  }
}

// Convert all elements of 'Values' into 'Ty' using 'ConvertValue'.
// Expect all values to have the same type;
// 'Values' is also the output of this function, containing all bitcasted
// values.
void BitcastValues(IRBuilder<> &Builder, Type *Ty,
                   SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  Type *ValueTy = Values[0]->getType();
  assert(SizeInBits(Builder, ValueTy) == SizeInBits(Builder, Ty));

  if (Ty == ValueTy) {
    return;
  }

  for (unsigned i = 0; i < Values.size(); i++) {
    Values[i] = ConvertValue(Values[i], Ty, Builder);
  }
}

// Bitcast 'Values' into a vector type with 'NumElePerVec' elements, but with
// the same global size as before.
// 'Values' is also the output of this function, containing all bitcasted
// values.
void BitcastIntoVector(IRBuilder<> &Builder, SmallVector<Value *, 8> &Values,
                       unsigned NumElePerVec, Type *Ty) {
  DEBUG_FCT_VALUES(Values);
  Type *SrcTy = Values[0]->getType();
  unsigned SrcSize = SizeInBits(Builder, SrcTy);
  assert(SrcSize % NumElePerVec == 0);
  unsigned SrcEleSize = SrcSize / NumElePerVec;
  VectorType *DstTy =
      FixedVectorType::get(getNTy(Builder, SrcEleSize, Ty), NumElePerVec);

  // As vec3 has the size of a vec4, size of SrcTy can be different than DstTy.
  // Deal with this case by going through an intermediate array type.
  if (SizeInBits(Builder, SrcTy) != SizeInBits(Builder, DstTy)) {
    ArrayType *ArrTy = ArrayType::get(Ty, SizeInBits(Builder, SrcTy) /
                                              SizeInBits(Builder, Ty));
    BitcastValues(Builder, ArrTy, Values);
    ExtractFromArray(Builder, Values);
    GroupScalarValuesIntoVector(Builder, Values, NumElePerVec);
  } else {
    BitcastValues(Builder, DstTy, Values);
  }
}

// 'Values' is expected to contain scalar values.
// Group those values in vector of size 'NumElePerVec'.
// Return the vectors into 'Values'.
void GroupScalarValuesIntoVector(IRBuilder<> &Builder,
                                 SmallVector<Value *, 8> &Values,
                                 unsigned NumElePerVec) {
  DEBUG_FCT_VALUES(Values);
  Type *SrcTy = Values[0]->getType();
  assert(!SrcTy->isVectorTy() && !SrcTy->isArrayTy());
  VectorType *DstTy = FixedVectorType::get(SrcTy, NumElePerVec);
  unsigned int NumVector = Values.size() / NumElePerVec;
  if (Values.size() > NumElePerVec && Values.size() % NumElePerVec != 0) {
    Values.resize(NumVector * NumElePerVec);
  }
  for (unsigned i = 0; i < NumVector; i++) {
    unsigned idx = i * NumElePerVec;
    Value *Vec = PoisonValue::get(DstTy);
    for (unsigned j = 0; j < NumElePerVec; j++) {
      Vec = Builder.CreateInsertElement(Vec, Values[idx + j],
                                        Builder.getInt32(j));
    }
    Values[i] = Vec;
  }
  Values.resize(NumVector);
}

// 'Values' is expected to contain an even number of vectors of 2 elements.
// Group them into vectors of 4 elements using shuffles.
// Return the vectors into 'Values'.
void GroupVectorValuesInPair(IRBuilder<> &Builder,
                             SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_VALUES(Values);
  assert(Values[0]->getType()->isVectorTy() &&
         GetNumEle(Values[0]->getType()) == 2);
  assert(Values.size() % 2 == 0);
  unsigned NewValuesSize = Values.size() / 2;

  for (unsigned i = 0; i < NewValuesSize; i++) {
    unsigned idx = 2 * i;
    Values[i] =
        Builder.CreateShuffleVector(Values[idx], Values[idx + 1], {0, 1, 2, 3});
  }
  Values.resize(NewValuesSize);
}

// 'Values' is expected to contain vectors of 4 elements.
// Split them into vectors of 2 elements using shuffles.
// Return the splitted values into 'Values'.
void SplitVectorValuesInPair(IRBuilder<> &Builder,
                             SmallVector<Value *, 8> &Values, Type *Ty) {
  DEBUG_FCT_VALUES(Values);
  assert(Values[0]->getType()->isVectorTy());
  assert(GetNumEle(Values[0]->getType()) == 4);

  // Bitcast before splitting to have less bitcast
  BitcastIntoVector(Builder, Values, 4, Ty);

  SmallVector<Value *, 8> DstValues;
  for (unsigned i = 0; i < Values.size(); i++) {
    DstValues.push_back(Builder.CreateShuffleVector(Values[i], {0, 1}));
    DstValues.push_back(Builder.CreateShuffleVector(Values[i], {2, 3}));
  }
  Values.clear();
  Values = std::move(DstValues);
}

// Split 'Values' until the element size of the vector is equal to the size of
// 'Ty'.
// 'Values' is expected to contain vectors.
// Return the splitted values into 'Values'.
void SplitVectorUntilEleSizeEquals(Type *Ty, IRBuilder<> &Builder,
                                   SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  Type *ValueTy = Values[0]->getType();
  assert(ValueTy->isVectorTy());

  unsigned ValueEleSize = SizeInBits(Builder, GetEleType(ValueTy));
  unsigned ValueNumEle = GetNumEle(ValueTy);
  unsigned TySize = SizeInBits(Builder, Ty);
  while (ValueEleSize > TySize) {
    if (TySize * 4 == ValueEleSize) {
      // Ty: i8 - ValueTy: <4 x i32>
      // <4 x i32> -> i32 -> <4 x i8>
      ExtractFromVector(Builder, Values);
      BitcastIntoVector(Builder, Values, 4, Ty);
    } else if (ValueNumEle == 2) {
      // <2 x i32> -> <4 x i16>
      BitcastIntoVector(Builder, Values, 4, Ty);
    } else if (ValueNumEle == 4) {
      // <4 x i32> -> <2 x i32>
      SplitVectorValuesInPair(Builder, Values, Ty);
    } else {
      llvm_unreachable("ConvertVectorIntoVector internal error");
    }
    Type *Tmp = Values[0]->getType();
    ValueEleSize = SizeInBits(Builder, GetEleType(Tmp));
    ValueNumEle = GetNumEle(Tmp);
  }
}

// Split 'Values' until the size of the vector is equal to the size of 'Ty'.
// 'Values' is expected to contain vectors.
// Return the splitted values into 'Values'.
void SplitVectorUntilSizeEquals(Type *Ty, IRBuilder<> &Builder,
                                SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  Type *ValueTy = Values[0]->getType();
  assert(ValueTy->isVectorTy());

  unsigned ValueEleSize = SizeInBits(Builder, GetEleType(ValueTy));
  unsigned ValueNumEle = GetNumEle(ValueTy);
  unsigned TySize = SizeInBits(Builder, Ty);

  while ((ValueEleSize * ValueNumEle) > TySize) {
    if (ValueNumEle == 2) {
      // <2 x i32> -> <4 x i16>
      BitcastIntoVector(Builder, Values, 4, Ty);
    } else if (ValueNumEle == 4) {
      // <4 x i32> -> <2 x i32>
      SplitVectorValuesInPair(Builder, Values, Ty);
    } else {
      llvm_unreachable("ConvertVectorIntoVector internal error");
    }
    Type *Tmp = Values[0]->getType();
    ValueEleSize = SizeInBits(Builder, GetEleType(Tmp));
    ValueNumEle = GetNumEle(Tmp);
  }
}

// Group 'Values' until the element size of the vector is equal to the size of
// 'Ty'.
// 'Values' is expected to contain vectors.
// Return the grouped values into 'Values'.
void GroupVectorUntilEleSizeEquals(Type *Ty, IRBuilder<> &Builder,
                                   SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_VALUES(Values);
  Type *ValueTy = Values[0]->getType();
  assert(ValueTy->isVectorTy());

  unsigned ValueEleSize = SizeInBits(Builder, GetEleType(ValueTy));
  unsigned ValueNumEle = GetNumEle(ValueTy);
  unsigned TySize = SizeInBits(Builder, Ty);
  while (ValueEleSize < TySize) {
    if (ValueNumEle == 2) {
      // <2 x i16> -> <4 x i16>
      GroupVectorValuesInPair(Builder, Values);
    } else if (ValueNumEle == 4) {
      // <4 x i16> -> <2 x i32>
      BitcastIntoVector(Builder, Values, 2, Ty);
    } else {
      llvm_unreachable("ConvertVectorIntoVector internal error");
    }
    Type *Tmp = Values[0]->getType();
    ValueEleSize = SizeInBits(Builder, GetEleType(Tmp));
    ValueNumEle = GetNumEle(Tmp);
  }
}

// Group 'Values' until the size of the vector is equal to the size of 'Ty'.
// 'Values' is expected to contain vectors.
// Return the grouped values into 'Values'.
void GroupVectorUntilSizeEquals(Type *Ty, IRBuilder<> &Builder,
                                SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_VALUES(Values);
  Type *ValueTy = Values[0]->getType();
  assert(ValueTy->isVectorTy());

  unsigned ValueEleSize = SizeInBits(Builder, GetEleType(ValueTy));
  unsigned ValueNumEle = GetNumEle(ValueTy);
  unsigned TySize = SizeInBits(Builder, Ty);
  while ((ValueEleSize * ValueNumEle) < TySize) {
    if (ValueNumEle == 2) {
      // <2 x i16> -> <4 x i16>
      GroupVectorValuesInPair(Builder, Values);
    } else if (ValueNumEle == 4) {
      // <4 x i16> -> <2 x i32>
      BitcastIntoVector(Builder, Values, 2, Ty);
    } else {
      llvm_unreachable("ConvertVectorIntoVector internal error");
    }
    Type *Tmp = Values[0]->getType();
    ValueEleSize = SizeInBits(Builder, GetEleType(Tmp));
    ValueNumEle = GetNumEle(Tmp);
  }
}

void ConvertScalarIntoVector(FixedVectorType *Ty, IRBuilder<> &Builder,
                             SmallVector<Value *, 8> &Values);
// 'Values' is expected to contain vectors.
// Return the converted vectors of type 'Ty' into 'Values'.
void ConvertVectorIntoVector(FixedVectorType *Ty, IRBuilder<> &Builder,
                             SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  Type *ValueTy = Values[0]->getType();
  assert(ValueTy->isVectorTy());
  if (Ty == ValueTy) {
    return;
  }

  Type *TyEle = GetEleType(Ty);

  unsigned ValueEleSize = SizeInBits(Builder, GetEleType(ValueTy));
  unsigned TyEleSize = SizeInBits(Builder, GetEleType(Ty));

  // Adjust the size of the vector element
  if (ValueEleSize < TyEleSize) {
    GroupVectorUntilEleSizeEquals(TyEle, Builder, Values);
  } else if (ValueEleSize > TyEleSize) {
    SplitVectorUntilEleSizeEquals(TyEle, Builder, Values);
  }

  ValueTy = Values[0]->getType();
  assert(ValueTy->isVectorTy());

  // Adjust the number of element per vector
  unsigned ValueNumEle = GetNumEle(ValueTy);
  unsigned TyNumEle = GetNumEle(Ty);
  if (ValueNumEle == 4 && TyNumEle == 3) {
    // This case can happen since opaque pointers are used.
    // We can now have packed structure having their vec3 implicitly casted to
    // vec4 that needs to be handled by replacepointercast pass. For this very
    // case, just drop the 4th value as it should be poisoned.
    SmallVector<Value *, 8> scalarValues;
    ExtractFromVector(Builder, Values);
    for (unsigned i = 0; i < Values.size(); i++) {
      if (i % 4 != 3) {
        scalarValues.push_back(Values[i]);
      }
    }
    Values = scalarValues;
    ConvertScalarIntoVector(Ty, Builder, Values);
  } else if (ValueNumEle == 3 && TyNumEle == 4) {
    // This case can happen since opaque pointers are used.
    // We can now have packed structure having their vec3 implicitly casted to
    // vec4 that needs to be handled by replacepointercast pass. For this very
    // case, just add in 4th place a poison value that should never be used.
    SmallVector<Value *, 8> scalarValues;
    ExtractFromVector(Builder, Values);
    for (unsigned i = 0; i < Values.size(); i++) {
      scalarValues.push_back(Values[i]);
      if (i % 3 == 2) {
        scalarValues.push_back(PoisonValue::get(GetEleType(ValueTy)));
      }
    }
    Values = scalarValues;
    ConvertScalarIntoVector(Ty, Builder, Values);
  } else if (ValueNumEle > TyNumEle) {
    assert(ValueNumEle == 4 && TyNumEle == 2);
    SplitVectorValuesInPair(Builder, Values, TyEle);
  } else if (ValueNumEle < TyNumEle) {
    assert(ValueNumEle == 2 && TyNumEle == 4);
    GroupVectorValuesInPair(Builder, Values);
  }

  BitcastValues(Builder, Ty, Values);
}

// 'Values' is expected to contain vectors.
// Return the scalar values of type 'Ty' into 'Values'.
void ConvertVectorIntoScalar(Type *Ty, IRBuilder<> &Builder,
                             SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  Type *ValueTy = Values[0]->getType();
  assert(!Ty->isVectorTy() && !Ty->isArrayTy() && ValueTy->isVectorTy());

  if (Ty == ValueTy) {
    return;
  }

  unsigned TySize = SizeInBits(Builder, Ty);
  unsigned ValueEleSize = SizeInBits(Builder, GetEleType(ValueTy));
  unsigned ValueNumEle = GetNumEle(ValueTy);
  unsigned ValueSize = SizeInBits(Builder, ValueTy);

  if (ValueEleSize > TySize) {
    SplitVectorUntilEleSizeEquals(Ty, Builder, Values);
    // Bitcasting before the extraction reduces the number of bitcast
    BitcastIntoVector(Builder, Values, GetNumEle(Values[0]->getType()), Ty);
    ExtractFromVector(Builder, Values);
  } else if (ValueEleSize == TySize) {
    // Bitcasting before the extraction reduces the number of bitcast
    BitcastIntoVector(Builder, Values, ValueNumEle, Ty);
    ExtractFromVector(Builder, Values);
  } else {
    // ValueEleSize < TySize
    if (ValueSize > TySize) {
      assert(ValueNumEle == 4 && ValueEleSize * 2 == TySize);
      SplitVectorValuesInPair(Builder, Values, Ty);
    } else if (ValueSize < TySize) {
      GroupVectorUntilSizeEquals(Ty, Builder, Values);
    }
  }

  BitcastValues(Builder, Ty, Values);
}

// 'Values' is expected to contain scalar elements.
// Return the vectors values of type 'Ty' into 'Values'.
void ConvertScalarIntoVector(FixedVectorType *Ty, IRBuilder<> &Builder,
                             SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  Type *ValueTy = Values[0]->getType();
  assert(!ValueTy->isVectorTy() && !ValueTy->isArrayTy());

  if (Ty == ValueTy) {
    return;
  }

  unsigned TySize = SizeInBits(Builder, Ty);
  unsigned ValueSize = SizeInBits(Builder, ValueTy);
  if (SizeInBits(Builder, GetEleType(Ty)) == ValueSize) {
    GroupScalarValuesIntoVector(Builder, Values, GetNumEle(Ty));
  } else if (TySize > ValueSize) {
    assert(TySize % ValueSize == 0);
    unsigned NumElements = std::min(TySize / ValueSize, (unsigned)4);
    GroupScalarValuesIntoVector(Builder, Values, NumElements);
    GroupVectorUntilSizeEquals(Ty, Builder, Values);
  } else if (TySize < ValueSize) {
    assert(ValueSize % TySize == 0);
    unsigned NumElements = std::min(ValueSize / TySize, (unsigned)4);
    // Bitcasting before splitting reduces the number of bitcast
    BitcastIntoVector(Builder, Values, NumElements, Ty);
    SplitVectorUntilSizeEquals(Ty, Builder, Values);
  }

  BitcastValues(Builder, Ty, Values);
}

// Return the scalar values of type 'Ty' into 'Values'.
void ConvertScalarIntoScalar(Type *Ty, IRBuilder<> &Builder,
                             SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  Type *ValueTy = Values[0]->getType();

  if (Ty == ValueTy) {
    return;
  }

  unsigned ValueSize = SizeInBits(Builder, ValueTy);
  unsigned TySize = SizeInBits(Builder, Ty);
  if (ValueSize > TySize) {
    assert(ValueSize % TySize == 0);
    unsigned NumElements = std::min(ValueSize / TySize, (unsigned)4);
    BitcastIntoVector(Builder, Values, NumElements, Ty);
    SplitVectorUntilEleSizeEquals(Ty, Builder, Values);
    ExtractFromVector(Builder, Values);
  } else if (ValueSize < TySize) {
    assert(TySize % ValueSize == 0);
    if (IsComplexStruct(
            Builder.GetInsertBlock()->getParent()->getParent()->getDataLayout(),
            Ty)) {
      unsigned ValuePerTy = TySize / ValueSize;
      assert(Values.size() % ValuePerTy == 0);
      InsertInArray(Builder, ArrayType::get(ValueTy, ValuePerTy), Values);
    } else {
      unsigned NumElements = std::min(TySize / ValueSize, (unsigned)4);
      GroupScalarValuesIntoVector(Builder, Values, NumElements);
      GroupVectorUntilSizeEquals(Ty, Builder, Values);
    }
  }

  BitcastValues(Builder, Ty, Values);
}

// Convert values contained in 'Values' into values of type 'Ty'.
// Input values are expected to be either vectors or scalars.
// 'Ty' is expected to be either a vector, an array, a struct or a scalar type.
// Return the converted values into 'Values'.
void ConvertInto(Type *Ty, IRBuilder<> &Builder,
                 SmallVector<Value *, 8> &Values) {
  DEBUG_FCT_TY_VALUES(Ty, Values);
  Type *ValueTy = Values[0]->getType();

  if (Ty == ValueTy) {
    return;
  }
  if (auto VecTy = dyn_cast<FixedVectorType>(Ty)) {
    if (ValueTy->isVectorTy()) {
      ConvertVectorIntoVector(VecTy, Builder, Values);
    } else {
      ConvertScalarIntoVector(VecTy, Builder, Values);
    }
  } else if (auto StructTy = dyn_cast<StructType>(Ty)) {
    if (IsArrayLike(StructTy)) {
      ConvertScalarIntoScalar(StructTy->getElementType(0), Builder, Values);
      InsertInArrayLikeStruct(Builder, StructTy, Values);
    } else {
      ConvertScalarIntoScalar(StructTy, Builder, Values);
    }
  } else {
    Type *EleTy = GetEleType(Ty);
    if (ValueTy->isVectorTy()) {
      ConvertVectorIntoScalar(EleTy, Builder, Values);
    } else {
      ConvertScalarIntoScalar(EleTy, Builder, Values);
    }
    if (auto DstArrTy = dyn_cast<ArrayType>(Ty)) {
      InsertInArray(Builder, DstArrTy, Values);
    }
  }
}

bool RemoveCstExprFromFunction(Function *F) {
  SmallVector<std::pair<Instruction *, unsigned>, 16> WorkList;

  auto CheckInstruction = [&WorkList](Instruction *I) {
    for (unsigned OperandId = 0; OperandId < I->getNumOperands(); OperandId++) {
      if (dyn_cast<ConstantExpr>(I->getOperand(OperandId)) ||
          dyn_cast<ConstantVector>(I->getOperand(OperandId)) ||
          dyn_cast<ConstantArray>(I->getOperand(OperandId))) {
        WorkList.push_back(std::make_pair(I, OperandId));
      }
    }
  };

  for (BasicBlock &BB : *F) {
    for (Instruction &I : BB) {
      CheckInstruction(&I);
    }
  }

  bool Changed = !WorkList.empty();

  while (!WorkList.empty()) {
    auto *I = WorkList.back().first;
    auto OperandId = WorkList.back().second;
    WorkList.pop_back();

    IRBuilder<> B(I);
    auto InsertBefore = I->getIterator();
    if (auto phi = dyn_cast<PHINode>(I)) {
      InsertBefore =
          phi->getIncomingBlock(phi->getIncomingValueNumForOperand(OperandId))
              ->getFirstNonPHIIt();
    }

    if (auto CstArray = dyn_cast<ConstantArray>(I->getOperand(OperandId))) {
      unsigned numEle = CstArray->getType()->getArrayNumElements();
      Value *ArrayNew = UndefValue::get(CstArray->getType());
      for (unsigned i = 0; i < numEle; ++i) {
        Value *Scalar = B.CreateExtractValue(CstArray, i);
        auto *ScalarCst = dyn_cast<ConstantExpr>(Scalar);
        if (ScalarCst) {
          auto *ScalarInst = ScalarCst->getAsInstruction();
          ScalarInst->insertBefore(InsertBefore);
          ArrayNew = B.CreateInsertValue(ArrayNew, ScalarInst, i);
          WorkList.push_back(std::make_pair(ScalarInst, OperandId));
        } else {
          ArrayNew = B.CreateInsertValue(ArrayNew, Scalar, i);
        }
      }
      I->setOperand(OperandId, ArrayNew);
    } else if (auto CstVector =
                   dyn_cast<ConstantVector>(I->getOperand(OperandId))) {
      unsigned numEle = (CstVector->getType())->getNumElements();
      Value *VecNew = UndefValue::get(CstVector->getType());
      for (unsigned i = 0; i < numEle; ++i) {
        Value *Scalar = B.CreateExtractElement(CstVector, i);
        if (auto *CstScalar = dyn_cast<ConstantExpr>(Scalar)) {
          auto ScalarInst = CstScalar->getAsInstruction();
          ScalarInst->insertBefore(InsertBefore);
          VecNew = B.CreateInsertElement(VecNew, ScalarInst, i);
          WorkList.push_back(std::make_pair(ScalarInst, OperandId));
        } else {
          VecNew = B.CreateInsertElement(VecNew, Scalar, i);
        }
      }
      I->setOperand(OperandId, VecNew);
    } else if (auto CstExpr =
                   dyn_cast<ConstantExpr>(I->getOperand(OperandId))) {
      auto Operand = CstExpr->getAsInstruction();
      Operand->insertBefore(InsertBefore);
      CheckInstruction(Operand);
      I->setOperand(OperandId, Operand);
    }
  }

  return Changed;
}

unsigned PointerOperandNum(Instruction *inst) {
  if (isa<StoreInst>(inst)) {
    return 1;
  } else if (auto *call = dyn_cast<CallInst>(inst)) {
    auto &info = clspv::Builtins::Lookup(call->getCalledFunction());
    if (BUILTIN_IN_GROUP(info.getType(), Atomic)) {
      return 0;
    } else if (info.getType() == clspv::Builtins::kSpirvOp) {
      auto opcode_op = call->getArgOperand(0);
      auto opcode = cast<ConstantInt>(opcode_op)->getZExtValue();
      const bool atomic =
          static_cast<uint64_t>(spv::Op::OpAtomicLoad) <= opcode &&
          opcode <= static_cast<uint64_t>(spv::Op::OpAtomicXor);
      if (atomic) {
        return 1;
      }
    }
    llvm::errs() << "Instruction: " << *inst << "\n";
    llvm_unreachable("Unexpected instruction");
  }

  return 0;
}

bool IsImplicitCasts(Module &M, DenseMap<Value *, Type *> &type_cache,
                     Instruction &I, Value *&source, Type *&source_ty,
                     Type *&dest_ty, bool ReplacePhysicalPointerBitcasts,
                     bool reworkUnsizedTy) {
  // The following checks use InferType to distinguish when a pointer's
  // interpretation changes between instructions. This requires the input
  // to be an instruction whose result provides a clear type for a
  // pointer (e.g. gep, alloca, or global variable).
  if (auto *gep = dyn_cast<GetElementPtrInst>(&I)) {
    source = gep->getPointerOperand();
    if (clspv::Option::UntypedPointerAddressSpace(
            source->getType()->getPointerAddressSpace())) {
      return false;
    }
    source_ty = clspv::InferType(source, M.getContext(), &type_cache);
    dest_ty = gep->getSourceElementType();
  } else if (auto *ld = dyn_cast<LoadInst>(&I)) {
    source = ld->getPointerOperand();
    if (clspv::Option::UntypedPointerAddressSpace(
            source->getType()->getPointerAddressSpace())) {
      return false;
    }
    source_ty = clspv::InferType(source, M.getContext(), &type_cache);
    dest_ty = ld->getType();
  } else if (auto *st = dyn_cast<StoreInst>(&I)) {
    source = st->getPointerOperand();
    if (clspv::Option::UntypedPointerAddressSpace(
            source->getType()->getPointerAddressSpace())) {
      return false;
    }
    source_ty = clspv::InferType(source, M.getContext(), &type_cache);
    dest_ty = st->getValueOperand()->getType();
  } else if (auto *phi = dyn_cast<PHINode>(&I)) {
    if (phi->getType()->isPointerTy() &&
        clspv::Option::UntypedPointerAddressSpace(
            phi->getType()->getPointerAddressSpace())) {
      return false;
    }
    auto RefTy = clspv::InferType(phi, M.getContext(), &type_cache);
    if (RefTy) {
      for (unsigned i = 0; i < phi->getNumIncomingValues(); i++) {
        auto Op = phi->getIncomingValue(i);
        auto OpTy = clspv::InferType(Op, M.getContext(), &type_cache);
        if (OpTy != RefTy) {
          source = Op;
          source_ty = OpTy;
          dest_ty = RefTy;
          break;
        }
      }
    }
  } else if (auto *atomic = dyn_cast<AtomicRMWInst>(&I)) {
    source = atomic->getPointerOperand();
    if (clspv::Option::UntypedPointerAddressSpace(
            source->getType()->getPointerAddressSpace())) {
      return false;
    }
    source_ty = clspv::InferType(source, M.getContext(), &type_cache);
    dest_ty = atomic->getType();
  } else if (auto *call = dyn_cast<CallInst>(&I)) {
    auto &info = clspv::Builtins::Lookup(call->getCalledFunction());
    if (BUILTIN_IN_GROUP(info.getType(), Atomic)) {
      source = call->getArgOperand(0);
      if (source->getType()->isPointerTy() &&
          clspv::Option::UntypedPointerAddressSpace(
              source->getType()->getPointerAddressSpace())) {
        return false;
      }
      source_ty = clspv::InferType(source, M.getContext(), &type_cache);
      if (info.getType() == clspv::Builtins::kAtomicStore ||
          info.getType() == clspv::Builtins::kAtomicStoreExplicit) {
        dest_ty = call->getArgOperand(1)->getType();
      } else {
        dest_ty = call->getType();
      }
    } else if (info.getType() == clspv::Builtins::kSpirvOp) {
      auto opcode_op = call->getArgOperand(0);
      auto opcode = cast<ConstantInt>(opcode_op)->getZExtValue();
      const bool atomic =
          static_cast<uint64_t>(spv::Op::OpAtomicLoad) <= opcode &&
          opcode <= static_cast<uint64_t>(spv::Op::OpAtomicXor);
      if (atomic) {
        source = call->getArgOperand(1);
        if (clspv::Option::UntypedPointerAddressSpace(
                source->getType()->getPointerAddressSpace())) {
          return false;
        }
        source_ty = clspv::InferType(source, M.getContext(), &type_cache);
        if (opcode == static_cast<uint64_t>(spv::Op::OpAtomicStore)) {
          dest_ty = call->getArgOperand(4)->getType();
        } else {
          dest_ty = call->getType();
        }
      }
    } else if (call->getCalledFunction()->getName().starts_with(
                   "llvm.memcpy")) {
      // To help lower memcpy, try to rework memcpy inputs to have the same type
      // with the samer of them. It avoids upgrading a type which can lead to
      // complicated issues.
      auto Dst = call->getArgOperand(0);
      auto Src = call->getArgOperand(1);
      if (clspv::Option::UntypedPointerAddressSpace(
              Dst->getType()->getPointerAddressSpace()) &&
          clspv::Option::UntypedPointerAddressSpace(
              Src->getType()->getPointerAddressSpace())) {
        return false;
      }
      auto DstTy = clspv::InferType(Dst, M.getContext(), &type_cache);
      auto SrcTy = clspv::InferType(Src, M.getContext(), &type_cache);
      if (DstTy && SrcTy && DstTy != SrcTy) {
        if (SizeInBits(M.getDataLayout(), DstTy) >=
            SizeInBits(M.getDataLayout(), SrcTy)) {
          source = Src;
          source_ty = SrcTy;
          dest_ty = DstTy;
        } else {
          source = Dst;
          source_ty = DstTy;
          dest_ty = SrcTy;
        }
      }
    }
  }

  // Skip pointer transforms when physical addressing will be used
  if (source && !ReplacePhysicalPointerBitcasts &&
      clspv::Option::PhysicalStorageBuffers()) {
    if (auto *source_ptr_ty = dyn_cast<PointerType>(source->getType())) {
      if (source_ptr_ty->getAddressSpace() == clspv::AddressSpace::Global ||
          source_ptr_ty->getAddressSpace() == clspv::AddressSpace::Constant) {
        return false;
      }
    }
  }
  if (source_ty && reworkUnsizedTy) {
    source_ty = reworkUnsizedType(M.getDataLayout(), source_ty);
  }
  if (dest_ty && reworkUnsizedTy) {
    dest_ty = reworkUnsizedType(M.getDataLayout(), dest_ty);
  }
  return source_ty && dest_ty && source_ty != dest_ty;
}

SmallVector<size_t, 4> getEleTypesBitWidths(Type *Ty, const DataLayout &DL,
                                            Type *BaseTy) {
  SmallVector<size_t, 4> TyBitWidths;
  TyBitWidths.push_back(SizeInBits(DL, Ty));
  Type *EleTy = GetEleType(Ty);
  while (EleTy != Ty && Ty != BaseTy) {
    Ty = EleTy;
    EleTy = GetEleType(Ty);
    TyBitWidths.push_back(SizeInBits(DL, Ty));
  }
  return TyBitWidths;
}

bool IsPowerOfTwo(unsigned x) { return (x & (x - 1)) == 0; }

Type *GetIndexTy(IRBuilder<> &Builder) {
  auto *M = Builder.GetInsertBlock()->getParent()->getParent();
  return clspv::PointersAre64Bit(*M) ? Builder.getInt64Ty()
                                     : Builder.getInt32Ty();
}

ConstantInt *GetIndexTyConst(IRBuilder<> &Builder, uint64_t C) {
  auto *M = Builder.GetInsertBlock()->getParent()->getParent();
  return clspv::PointersAre64Bit(*M) ? Builder.getInt64(C)
                                     : Builder.getInt32(C);
}

Value *CreateDiv(IRBuilder<> &Builder, unsigned div, Value *Val) {
  if (div == 1) {
    return Val;
  }
  auto *IndexTy = GetIndexTy(Builder);
  if (Val->getType() != IndexTy) {
    Val = Builder.CreateZExtOrTrunc(Val, IndexTy);
  }
  if (IsPowerOfTwo(div)) {
    return Builder.CreateLShr(Val, GetIndexTyConst(Builder, std::log2(div)));
  } else {
    return Builder.CreateUDiv(Val, GetIndexTyConst(Builder, div));
  }
}

Value *CreateMul(IRBuilder<> &Builder, unsigned mul, Value *Val) {
  if (mul == 1) {
    return Val;
  }
  auto *IndexTy = GetIndexTy(Builder);
  if (Val->getType() != IndexTy) {
    Val = Builder.CreateZExtOrTrunc(Val, IndexTy);
  }
  if (IsPowerOfTwo(mul)) {
    return Builder.CreateShl(Val, GetIndexTyConst(Builder, std::log2(mul)));
  } else {
    return Builder.CreateMul(Val, GetIndexTyConst(Builder, mul));
  }
}

Value *CreateRem(IRBuilder<> &Builder, unsigned rem, Value *Val) {
  if (rem == 1) {
    return GetIndexTyConst(Builder, 0);
  }
  auto *IndexTy = GetIndexTy(Builder);
  if (Val->getType() != IndexTy) {
    Val = Builder.CreateZExtOrTrunc(Val, IndexTy);
  }
  if (IsPowerOfTwo(rem)) {
    return Builder.CreateAnd(Val, GetIndexTyConst(Builder, rem - 1));
  } else {
    return Builder.CreateURem(Val, GetIndexTyConst(Builder, rem));
  }
}

Value *CreateAdd(IRBuilder<> &Builder, Value *LHS, Value *RHS) {
  auto LHSTy = LHS->getType();
  auto RHSTy = RHS->getType();
  if (LHSTy != RHSTy && LHSTy->isIntegerTy() && RHSTy->isIntegerTy()) {
    if (SizeInBits(Builder, RHSTy) > SizeInBits(Builder, LHSTy)) {
      LHS = Builder.CreateZExtOrTrunc(LHS, RHSTy);
    } else {
      RHS = Builder.CreateZExtOrTrunc(RHS, LHSTy);
    }
  }
  return Builder.CreateAdd(LHS, RHS);
}

bool IsArrayLike(StructType *Ty) {
  if (Ty->getNumElements() == 0)
    return false;
  Type *ElemTy = Ty->getStructElementType(0);
  for (unsigned i = 0; i < Ty->getNumElements(); i++) {
    if (ElemTy != Ty->getStructElementType(i)) {
      return false;
    }
  }
  return true;
}

bool IsComplexStruct(const DataLayout &DL, Type *Ty) {
  if (auto STy = dyn_cast<StructType>(Ty)) {
    auto vec4u64 = FixedVectorType::get(Type::getInt64Ty(Ty->getContext()), 4);
    return !IsArrayLike(STy) && SizeInBits(DL, Ty) > SizeInBits(DL, vec4u64);
  }
  return false;
}

// Check whether a pointer to the type `ContainingTy` is also usable as a
// pointer to the type `TargetTy` due to the layout of the vector or aggregrate
// type. Descends through the first element of the `ContainingTy` until it is
// found or it cannot descend any further. Writes out levels of indirection to
// `Steps`.
bool FindAliasingContainedType(Type *ContainingTy, Type *TargetTy, int &Steps,
                               bool &PerfectMatch, const DataLayout &DL,
                               bool StrictStruct) {
  int StepCount = 0;

  auto IsIntegerOrFloatTy = [](Type *Ty) {
    return Ty->isIntegerTy() || Ty->isFloatTy();
  };
  auto SimilarType = [&DL, &IsIntegerOrFloatTy](Type *Ty1, Type *Ty2) {
    return Ty1 == Ty2 || (SizeInBits(DL, Ty1) == SizeInBits(DL, Ty2) &&
                          IsIntegerOrFloatTy(Ty1) && IsIntegerOrFloatTy(Ty2));
  };

  do {
    if (SimilarType(ContainingTy, TargetTy)) {
      Steps = StepCount;
      PerfectMatch = ContainingTy == TargetTy;
      return true;
    }
    StepCount++;

    if (auto *VectorTy = dyn_cast<VectorType>(ContainingTy)) {
      ContainingTy = VectorTy->getElementType();
    } else if (auto *ArrayTy = dyn_cast<ArrayType>(ContainingTy)) {
      ContainingTy = ArrayTy->getArrayElementType();
    } else if (auto *StructTy = dyn_cast<StructType>(ContainingTy)) {
      if (StructTy->isOpaque() ||
          (StructTy->getStructNumElements() > 1 && StrictStruct))
        break;
      ContainingTy = StructTy->getStructElementType(0);
    } else {
      break;
    }
  } while (ContainingTy->isAggregateType() || ContainingTy->isVectorTy() ||
           SimilarType(ContainingTy, TargetTy));

  return false;
}

void ExtractOffsetFromStruct(const DataLayout &DataLayout, ConstantInt *Cst,
                             StructType *STy, int64_t &CstVal,
                             size_t &SmallerBitWidths) {
  auto offset = DataLayout.getStructLayout(STy)->getElementOffsetInBits(
      Cst->getZExtValue());
  if (offset % SmallerBitWidths != 0) {
    CstVal = (CstVal * (int64_t)SmallerBitWidths + offset) / CHAR_BIT;
    SmallerBitWidths = CHAR_BIT;
  } else {
    CstVal += offset / SmallerBitWidths;
  }
}

void ExtractOffsetFromGEP(const DataLayout &DataLayout, IRBuilder<> &Builder,
                          GetElementPtrInst *GEP, int64_t &CstVal,
                          Value *&DynVal, size_t &SmallerBitWidths) {
  CstVal = 0;
  DynVal = nullptr;

  unsigned NbIdx = GEP->getNumOperands() - 1;
  SmallerBitWidths = SizeInBits(
      DataLayout, reworkUnsizedType(DataLayout, GEP->getResultElementType()));
  SmallVector<Value *, 8> Idxs;

  Type *PrevTy = GEP->getSourceElementType();
  for (unsigned i = 0; i < NbIdx; i++) {
    Value *Op = GEP->getOperand(i + 1);
    Idxs.push_back(Op);
    Type *NextTy =
        GetElementPtrInst::getIndexedType(GEP->getSourceElementType(), Idxs);
    auto STy = dyn_cast<StructType>(PrevTy);
    if (STy && i != 0) {
      auto Cst = dyn_cast<ConstantInt>(Op);
      assert(Cst);
      ExtractOffsetFromStruct(DataLayout, Cst, STy, CstVal, SmallerBitWidths);
    } else {
      auto size =
          SizeInBits(DataLayout, reworkUnsizedType(DataLayout, NextTy)) /
          SmallerBitWidths;
      if (auto Cst = dyn_cast<ConstantInt>(Op)) {
        CstVal += Cst->getSExtValue() * size;
      } else {
        Value *Mul = CreateMul(Builder, size, Op);
        if (DynVal) {
          DynVal = Builder.CreateAdd(DynVal, Mul);
        } else {
          DynVal = Mul;
        }
      }
    }
    PrevTy = NextTy;
  }
}

int64_t GoThroughTypeAtOffset(const DataLayout &DataLayout,
                              IRBuilder<> &Builder, Type *InitialTy, Type *Ty,
                              Type *TargetTy, int64_t Offset,
                              SmallVector<Value *, 2> *Idxs) {
  if (!(Ty->isVectorTy() || Ty->isArrayTy() || Ty->isStructTy())) {
    auto size = SizeInBits(DataLayout, Ty);
    if (Idxs) {
      auto val = Offset / (int64_t)size;
      if (Idxs->size() > 0) {
        if (auto lastIdxCst = dyn_cast<ConstantInt>(Idxs->back())) {
          val += lastIdxCst->getSExtValue();
          Idxs->pop_back();
        }
      }
      Idxs->push_back(Builder.getInt32(val));
    }
    Offset %= (int64_t)size;
    return Offset;
  }
  while ((Ty->isVectorTy() || Ty->isArrayTy() || Ty->isStructTy()) &&
         (TargetTy == nullptr ||
          SizeInBits(DataLayout, Ty) > SizeInBits(DataLayout, TargetTy) ||
          (Ty != TargetTy &&
           SizeInBits(DataLayout, Ty) == SizeInBits(DataLayout, TargetTy)))) {
    if (auto STy = dyn_cast<StructType>(Ty)) {
      auto SLayout = DataLayout.getStructLayout(STy);
      auto SId = SLayout->getElementContainingOffset(Offset / CHAR_BIT);
      auto off = SLayout->getElementOffsetInBits(SId);
      Ty = STy->getElementType(SId);
      if (Idxs) {
        Idxs->push_back(Builder.getInt32(SId));
      }
      Offset -= off;
    } else {
      auto NextTy = GetEleType(Ty);
      assert(NextTy != Ty);
      Ty = NextTy;
      auto size = SizeInBits(DataLayout, Ty);
      if (Idxs) {
        Idxs->push_back(Builder.getInt32(Offset / (int64_t)size));
      }
      Offset %= (int64_t)size;
    }
    assert(Idxs == nullptr ||
           GetElementPtrInst::getIndexedType(InitialTy, *Idxs) == Ty);
  }
  return Offset;
}

bool IsClspvResourceOrLocal(Value *val) {
  if (auto call = dyn_cast<CallInst>(val)) {
    auto builtin_type =
        clspv::Builtins::Lookup(call->getCalledFunction()).getType();
    return builtin_type == clspv::Builtins::kClspvResource ||
           builtin_type == clspv::Builtins::kClspvLocal;
  }
  return false;
}

SmallVector<Value *, 2>
GetIdxsForTyFromOffset(const DataLayout &DataLayout, IRBuilder<> &Builder,
                       Type *SrcTy, Type *DstTy, int64_t CstVal, Value *DynVal,
                       size_t SmallerBitWidths, Value *Src) {
  SmallVector<Value *, 2> Idxs;

  assert(Src->getType()->isPointerTy());
  bool clspv_resource = IsClspvResourceOrLocal(Src);

  unsigned startIdx = 0;
  if ((isa<GlobalVariable>(Src) || clspv_resource || isa<AllocaInst>(Src)) &&
      SrcTy != DstTy &&
      (DstTy == nullptr ||
       SizeInBits(DataLayout, DstTy) <= SizeInBits(DataLayout, SrcTy))) {
    Idxs.push_back(ConstantInt::get(Builder.getInt32Ty(), 0));
    // Unsized types will be removed in `reworkUnsizedType`, no need to bump
    // startIdx for them.
    if (!IsUnsizedType(DataLayout, SrcTy)) {
      startIdx = 1;
    }
  }

  if (DstTy == nullptr || DstTy->isVoidTy()) {
    DstTy = Builder.getInt8Ty();
  }

  unsigned steps;
  Type *InitialSrcTy = SrcTy;
  SrcTy = reworkUnsizedType(DataLayout, SrcTy, &steps);
  DstTy = reworkUnsizedType(DataLayout, DstTy);
  for (unsigned i = Idxs.size(); i < steps; i++) {
    Idxs.push_back(ConstantInt::get(Builder.getInt32Ty(), 0));
  }

  if (SizeInBits(DataLayout, DstTy) >= SizeInBits(DataLayout, SrcTy) &&
      DstTy != SrcTy && DstTy != GetEleType(SrcTy)) {
    DstTy = SrcTy;
    auto ElDstTy = GetEleType(DstTy);
    while (DstTy != ElDstTy) {
      DstTy = ElDstTy;
      ElDstTy = GetEleType(DstTy);
    }
  }

  if (DynVal == nullptr) {
    Type *Ty = SrcTy;
    CstVal *= (int64_t)SmallerBitWidths;
    if (startIdx == 0) {
      auto size = SizeInBits(DataLayout, Ty);
      Idxs.push_back(Builder.getInt32(CstVal / (int64_t)size));
      CstVal %= (int64_t)size;
    }
    CstVal = GoThroughTypeAtOffset(DataLayout, Builder, InitialSrcTy, SrcTy,
                                   DstTy, CstVal, &Idxs);
    if (CstVal != 0) {
      errs() << "Err: SrcTy = ";
      SrcTy->print(errs());
      errs() << " - DstTy = ";
      DstTy->print(errs());
      errs() << " - Ty = ";
      Ty->print(errs());
      errs() << " - CstVal = " << CstVal << "\n";
      llvm_unreachable("Unexpected offset for type in GetIdxsForTyFromOffset");
    }
  } else {
    auto TyBitWidths =
        BitcastUtils::getEleTypesBitWidths(SrcTy, DataLayout, DstTy);
    size_t NewSmallerBitWidths = TyBitWidths[TyBitWidths.size() - 1];
    if (NewSmallerBitWidths <= SmallerBitWidths) {
      CstVal *= (int64_t)SmallerBitWidths / (int64_t)NewSmallerBitWidths;
      DynVal =
          CreateMul(Builder, SmallerBitWidths / NewSmallerBitWidths, DynVal);
    } else {
      CstVal /= (int64_t)NewSmallerBitWidths / (int64_t)SmallerBitWidths;
      DynVal =
          CreateDiv(Builder, NewSmallerBitWidths / SmallerBitWidths, DynVal);
    }
    if (CstVal != 0) {
      DynVal = Builder.CreateAdd(DynVal,
                                 ConstantInt::get(DynVal->getType(), CstVal));
    }
    for (unsigned i = startIdx; i < TyBitWidths.size(); i++) {
      size_t size = TyBitWidths[i] / NewSmallerBitWidths;
      auto IndexedType = GetElementPtrInst::getIndexedType(SrcTy, Idxs);
      auto STy =
          IndexedType != nullptr ? dyn_cast<StructType>(IndexedType) : nullptr;
      if (i != 0 && STy) {
        if (STy->getNumElements() > 1) {
          llvm_unreachable("Cannot create gep with dynamic indices for this "
                           "multi-element struct");
        }
        Idxs.push_back(Builder.getInt32(0));
      } else {
        Idxs.push_back(CreateDiv(Builder, size, DynVal));
        if (i != TyBitWidths.size() - 1)
          DynVal = CreateRem(Builder, size, DynVal);
      }
    }
  }
  return Idxs;
}

bool IsGVConstantGEP(GetElementPtrInst *GEP) {
  assert(GEP != nullptr);
  return isa<GlobalVariable>(GEP->getPointerOperand()) &&
         GEP->hasAllConstantIndices();
}

} // namespace BitcastUtils
