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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Transforms/Utils/LowerVectorIntrinsics.h" 10 #include "llvm/IR/IRBuilder.h" 11 12 #define DEBUG_TYPE "lower-vector-intrinsics" 13 14 using namespace llvm; 15 16 bool 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 preheader 31 IRBuilder<> PreLoopBuilder(PreLoopBB->getTerminator()); 32 Value *LoopEnd = 33 PreLoopBuilder.CreateElementCount(Int64Ty, VecTy->getElementCount()); 34 35 // Loop body 36 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