//===- LowerVectorIntrinsics.cpp ------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/LowerVectorIntrinsics.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ProfDataUtils.h"

#define DEBUG_TYPE "lower-vector-intrinsics"

using namespace llvm;

bool llvm::lowerUnaryVectorIntrinsicAsLoop(Module &M, CallInst *CI) {
  Type *RetTy = CI->getType();
  auto *StructRetTy = dyn_cast<StructType>(RetTy);
  unsigned NumResults = StructRetTy ? StructRetTy->getNumElements() : 1;
  auto *VecTy =
      cast<VectorType>(StructRetTy ? StructRetTy->getElementType(0) : RetTy);

  BasicBlock *PreLoopBB = CI->getParent();
  BasicBlock *PostLoopBB = nullptr;
  Function *ParentFunc = PreLoopBB->getParent();
  LLVMContext &Ctx = PreLoopBB->getContext();
  Type *IdxTy = M.getDataLayout().getIndexType(Ctx, 0);

  PostLoopBB = PreLoopBB->splitBasicBlock(CI);
  BasicBlock *LoopBB = BasicBlock::Create(Ctx, "", ParentFunc, PostLoopBB);
  PreLoopBB->getTerminator()->setSuccessor(0, LoopBB);

  // Loop preheader
  IRBuilder<> PreLoopBuilder(PreLoopBB->getTerminator());
  Value *LoopEnd =
      PreLoopBuilder.CreateElementCount(IdxTy, VecTy->getElementCount());

  // Loop body
  IRBuilder<> LoopBuilder(LoopBB);

  PHINode *LoopIndex = LoopBuilder.CreatePHI(IdxTy, 2);
  LoopIndex->addIncoming(ConstantInt::get(IdxTy, 0U), PreLoopBB);

  SmallVector<PHINode *, 2> ResultPhis(NumResults);
  for (unsigned I = 0; I != NumResults; ++I) {
    ResultPhis[I] = LoopBuilder.CreatePHI(VecTy, 2);
    ResultPhis[I]->addIncoming(PoisonValue::get(VecTy), PreLoopBB);
  }

  Value *Elem =
      LoopBuilder.CreateExtractElement(CI->getArgOperand(0), LoopIndex);
  Function *Fn = Intrinsic::getOrInsertDeclaration(&M, CI->getIntrinsicID(),
                                                   VecTy->getElementType());

  CallInst *ScalarCall = LoopBuilder.CreateCall(Fn, Elem);
  if (isa<FPMathOperator>(CI))
    ScalarCall->copyFastMathFlags(CI);

  SmallVector<Value *, 2> NewVecs(NumResults);
  for (unsigned I = 0; I != NumResults; ++I) {
    Value *ScalarRes = ScalarCall;
    if (StructRetTy)
      ScalarRes = LoopBuilder.CreateExtractValue(ScalarCall, I);
    NewVecs[I] =
        LoopBuilder.CreateInsertElement(ResultPhis[I], ScalarRes, LoopIndex);
    ResultPhis[I]->addIncoming(NewVecs[I], LoopBB);
  }

  Value *One = ConstantInt::get(IdxTy, 1U);
  Value *NextLoopIndex = LoopBuilder.CreateAdd(LoopIndex, One);
  LoopIndex->addIncoming(NextLoopIndex, LoopBB);

  Value *ExitCond =
      LoopBuilder.CreateICmp(CmpInst::ICMP_EQ, NextLoopIndex, LoopEnd);
  CondBrInst *Br = LoopBuilder.CreateCondBr(ExitCond, PostLoopBB, LoopBB);
  setExplicitlyUnknownBranchWeightsIfProfiled(*Br, DEBUG_TYPE);

  Value *Res = NewVecs[0];
  if (StructRetTy) {
    IRBuilder<> PostLoopBuilder(CI);
    Res = PoisonValue::get(RetTy);
    for (unsigned I = 0; I != NumResults; ++I)
      Res = PostLoopBuilder.CreateInsertValue(Res, NewVecs[I], I);
  }

  CI->replaceAllUsesWith(Res);
  CI->eraseFromParent();
  return true;
}
