LLVM 24.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#include "llvm/IR/Module.h"
12
13#define DEBUG_TYPE "lower-vector-intrinsics"
14
15using namespace llvm;
16
18 Type *RetTy = CI->getType();
19 auto *StructRetTy = dyn_cast<StructType>(RetTy);
20 unsigned NumResults = StructRetTy ? StructRetTy->getNumElements() : 1;
21 auto *VecTy =
22 cast<VectorType>(StructRetTy ? StructRetTy->getElementType(0) : RetTy);
23
24 BasicBlock *PreLoopBB = CI->getParent();
25 BasicBlock *PostLoopBB = nullptr;
26 Function *ParentFunc = PreLoopBB->getParent();
27 LLVMContext &Ctx = PreLoopBB->getContext();
28 Type *IdxTy = M.getDataLayout().getIndexType(Ctx, 0);
29
30 PostLoopBB = PreLoopBB->splitBasicBlock(CI);
31 BasicBlock *LoopBB = BasicBlock::Create(Ctx, "", ParentFunc, PostLoopBB);
32 PreLoopBB->getTerminator()->setSuccessor(0, LoopBB);
33
34 // Loop preheader
35 IRBuilder<> PreLoopBuilder(PreLoopBB->getTerminator());
36 Value *LoopEnd =
37 PreLoopBuilder.CreateElementCount(IdxTy, VecTy->getElementCount());
38
39 // Loop body
40 IRBuilder<> LoopBuilder(LoopBB);
41
42 PHINode *LoopIndex = LoopBuilder.CreatePHI(IdxTy, 2);
43 LoopIndex->addIncoming(ConstantInt::get(IdxTy, 0U), PreLoopBB);
44
45 SmallVector<PHINode *, 2> ResultPhis(NumResults);
46 for (unsigned I = 0; I != NumResults; ++I) {
47 ResultPhis[I] = LoopBuilder.CreatePHI(VecTy, 2);
48 ResultPhis[I]->addIncoming(PoisonValue::get(VecTy), PreLoopBB);
49 }
50
51 Value *Elem =
52 LoopBuilder.CreateExtractElement(CI->getArgOperand(0), LoopIndex);
54 VecTy->getElementType());
55
56 CallInst *ScalarCall = LoopBuilder.CreateCall(Fn, Elem);
57 if (isa<FPMathOperator>(CI))
58 ScalarCall->copyFastMathFlags(CI);
59
60 SmallVector<Value *, 2> NewVecs(NumResults);
61 for (unsigned I = 0; I != NumResults; ++I) {
62 Value *ScalarRes = ScalarCall;
63 if (StructRetTy)
64 ScalarRes = LoopBuilder.CreateExtractValue(ScalarCall, I);
65 NewVecs[I] =
66 LoopBuilder.CreateInsertElement(ResultPhis[I], ScalarRes, LoopIndex);
67 ResultPhis[I]->addIncoming(NewVecs[I], LoopBB);
68 }
69
70 Value *One = ConstantInt::get(IdxTy, 1U);
71 Value *NextLoopIndex = LoopBuilder.CreateAdd(LoopIndex, One);
72 LoopIndex->addIncoming(NextLoopIndex, LoopBB);
73
74 Value *ExitCond =
75 LoopBuilder.CreateICmp(CmpInst::ICMP_EQ, NextLoopIndex, LoopEnd);
76 LoopBuilder.CreateCondBr(ExitCond, PostLoopBB, LoopBB);
77
78 Value *Res = NewVecs[0];
79 if (StructRetTy) {
80 IRBuilder<> PostLoopBuilder(CI);
81 Res = PoisonValue::get(RetTy);
82 for (unsigned I = 0; I != NumResults; ++I)
83 Res = PostLoopBuilder.CreateInsertValue(Res, NewVecs[I], I);
84 }
85
86 CI->replaceAllUsesWith(Res);
87 CI->eraseFromParent();
88 return true;
89}
Module.h This file contains the declarations for the Module class.
#define I(x, y, z)
Definition MD5.cpp:57
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Value * getArgOperand(unsigned i) const
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.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2677
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2731
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2665
CondBrInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
Definition IRBuilder.h:1224
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2724
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2555
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1430
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2569
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2500
LLVM_ABI Value * CreateElementCount(Type *Ty, ElementCount EC)
Create an expression which evaluates to the number of elements in EC at runtime.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2908
LLVM_ABI void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
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.
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:68
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
const ParentTy * getParent() const
Definition ilist_node.h:34
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool lowerUnaryVectorIntrinsicAsLoop(Module &M, CallInst *CI)
Lower CI as a loop.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559