62 lines · cpp
1//===- LowerVectorIntrinsics.cpp ------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Transforms/Utils/LowerVectorIntrinsics.h"10#include "llvm/IR/IRBuilder.h"11 12#define DEBUG_TYPE "lower-vector-intrinsics"13 14using namespace llvm;15 16bool llvm::lowerUnaryVectorIntrinsicAsLoop(Module &M, CallInst *CI) {17 Type *ArgTy = CI->getArgOperand(0)->getType();18 VectorType *VecTy = cast<VectorType>(ArgTy);19 20 BasicBlock *PreLoopBB = CI->getParent();21 BasicBlock *PostLoopBB = nullptr;22 Function *ParentFunc = PreLoopBB->getParent();23 LLVMContext &Ctx = PreLoopBB->getContext();24 Type *Int64Ty = IntegerType::get(Ctx, 64);25 26 PostLoopBB = PreLoopBB->splitBasicBlock(CI);27 BasicBlock *LoopBB = BasicBlock::Create(Ctx, "", ParentFunc, PostLoopBB);28 PreLoopBB->getTerminator()->setSuccessor(0, LoopBB);29 30 // Loop preheader31 IRBuilder<> PreLoopBuilder(PreLoopBB->getTerminator());32 Value *LoopEnd =33 PreLoopBuilder.CreateElementCount(Int64Ty, VecTy->getElementCount());34 35 // Loop body36 IRBuilder<> LoopBuilder(LoopBB);37 38 PHINode *LoopIndex = LoopBuilder.CreatePHI(Int64Ty, 2);39 LoopIndex->addIncoming(ConstantInt::get(Int64Ty, 0U), PreLoopBB);40 PHINode *Vec = LoopBuilder.CreatePHI(VecTy, 2);41 Vec->addIncoming(CI->getArgOperand(0), PreLoopBB);42 43 Value *Elem = LoopBuilder.CreateExtractElement(Vec, LoopIndex);44 Function *Exp = Intrinsic::getOrInsertDeclaration(&M, CI->getIntrinsicID(),45 VecTy->getElementType());46 Value *Res = LoopBuilder.CreateCall(Exp, Elem);47 Value *NewVec = LoopBuilder.CreateInsertElement(Vec, Res, LoopIndex);48 Vec->addIncoming(NewVec, LoopBB);49 50 Value *One = ConstantInt::get(Int64Ty, 1U);51 Value *NextLoopIndex = LoopBuilder.CreateAdd(LoopIndex, One);52 LoopIndex->addIncoming(NextLoopIndex, LoopBB);53 54 Value *ExitCond =55 LoopBuilder.CreateICmp(CmpInst::ICMP_EQ, NextLoopIndex, LoopEnd);56 LoopBuilder.CreateCondBr(ExitCond, PostLoopBB, LoopBB);57 58 CI->replaceAllUsesWith(NewVec);59 CI->eraseFromParent();60 return true;61}62