LLVM 22.0.0git
LowerVectorIntrinsics.cpp
Go to the documentation of this file.
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
10#include "llvm/IR/IRBuilder.h"
11
12#define DEBUG_TYPE "lower-vector-intrinsics"
13
14using namespace llvm;
15
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);
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}
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:206
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
Definition: BasicBlock.cpp:555
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:213
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition: BasicBlock.cpp:131
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:233
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1292
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
This class represents a function call, abstracting a target machine's calling convention.
@ ICMP_EQ
equal
Definition: InstrTypes.h:699
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2571
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2559
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition: IRBuilder.h:2494
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
Definition: IRBuilder.h:1197
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1403
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2508
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2439
LLVM_ABI Value * CreateElementCount(Type *Ty, ElementCount EC)
Create an expression which evaluates to the number of elements in EC at runtime.
Definition: IRBuilder.cpp:123
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:319
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:546
Base class of all SIMD vector types.
Definition: DerivedTypes.h:430
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Definition: DerivedTypes.h:695
Type * getElementType() const
Definition: DerivedTypes.h:463
const ParentTy * getParent() const
Definition: ilist_node.h:34
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
Definition: Intrinsics.cpp:751
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool lowerUnaryVectorIntrinsicAsLoop(Module &M, CallInst *CI)
Lower CI as a loop.