1 //===-- PPCLowerMASSVEntries.cpp ------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements lowering of MASSV (SIMD) entries for specific PowerPC
11 // Following is an example of a conversion specific to Power9 subtarget:
12 // __sind2_massv ---> __sind2_P9
14 //===----------------------------------------------------------------------===//
17 #include "PPCSubtarget.h"
18 #include "PPCTargetMachine.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/Analysis/TargetTransformInfo.h"
21 #include "llvm/CodeGen/TargetPassConfig.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/Module.h"
25 #define DEBUG_TYPE "ppc-lower-massv-entries"
31 static StringRef MASSVFuncs
[] = {
32 #define TLI_DEFINE_MASSV_VECFUNCS_NAMES
33 #include "llvm/Analysis/VecFuncs.def"
36 class PPCLowerMASSVEntries
: public ModulePass
{
40 PPCLowerMASSVEntries() : ModulePass(ID
) {}
42 bool runOnModule(Module
&M
) override
;
44 StringRef
getPassName() const override
{ return "PPC Lower MASS Entries"; }
46 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
47 AU
.addRequired
<TargetTransformInfoWrapperPass
>();
51 static bool isMASSVFunc(StringRef Name
);
52 static StringRef
getCPUSuffix(const PPCSubtarget
*Subtarget
);
53 static std::string
createMASSVFuncName(Function
&Func
,
54 const PPCSubtarget
*Subtarget
);
55 bool handlePowSpecialCases(CallInst
*CI
, Function
&Func
, Module
&M
);
56 bool lowerMASSVCall(CallInst
*CI
, Function
&Func
, Module
&M
,
57 const PPCSubtarget
*Subtarget
);
62 /// Checks if the specified function name represents an entry in the MASSV
64 bool PPCLowerMASSVEntries::isMASSVFunc(StringRef Name
) {
65 return llvm::is_contained(MASSVFuncs
, Name
);
69 /// Returns a string corresponding to the specified PowerPC subtarget. e.g.:
70 /// "_P8" for Power8, "_P9" for Power9. The string is used as a suffix while
71 /// generating subtarget-specific MASSV library functions. Current support
72 /// includes minimum subtarget Power8 for Linux and Power7 for AIX.
73 StringRef
PPCLowerMASSVEntries::getCPUSuffix(const PPCSubtarget
*Subtarget
) {
74 // Assume generic when Subtarget is unavailable.
77 // TODO: add _P10 enties to Linux MASS lib and remove the check for AIX
78 if (Subtarget
->isAIXABI() && Subtarget
->hasP10Vector())
80 if (Subtarget
->hasP9Vector())
82 if (Subtarget
->hasP8Vector())
84 if (Subtarget
->isAIXABI())
88 "Mininum subtarget for -vector-library=MASSV option is Power8 on Linux "
89 "and Power7 on AIX when vectorization is not disabled.");
92 /// Creates PowerPC subtarget-specific name corresponding to the specified
93 /// generic MASSV function, and the PowerPC subtarget.
95 PPCLowerMASSVEntries::createMASSVFuncName(Function
&Func
,
96 const PPCSubtarget
*Subtarget
) {
97 StringRef Suffix
= getCPUSuffix(Subtarget
);
98 auto GenericName
= Func
.getName().str();
99 std::string MASSVEntryName
= GenericName
+ Suffix
.str();
100 return MASSVEntryName
;
103 /// If there are proper fast-math flags, this function creates llvm.pow
104 /// intrinsics when the exponent is 0.25 or 0.75.
105 bool PPCLowerMASSVEntries::handlePowSpecialCases(CallInst
*CI
, Function
&Func
,
107 if (Func
.getName() != "__powf4" && Func
.getName() != "__powd2")
110 if (Constant
*Exp
= dyn_cast
<Constant
>(CI
->getArgOperand(1)))
111 if (ConstantFP
*CFP
= dyn_cast_or_null
<ConstantFP
>(Exp
->getSplatValue())) {
112 // If the argument is 0.75 or 0.25 it is cheaper to turn it into pow
113 // intrinsic so that it could be optimzed as sequence of sqrt's.
114 if (!CI
->hasNoInfs() || !CI
->hasApproxFunc())
117 if (!CFP
->isExactlyValue(0.75) && !CFP
->isExactlyValue(0.25))
120 if (CFP
->isExactlyValue(0.25) && !CI
->hasNoSignedZeros())
123 CI
->setCalledFunction(
124 Intrinsic::getDeclaration(&M
, Intrinsic::pow
, CI
->getType()));
131 /// Lowers generic MASSV entries to PowerPC subtarget-specific MASSV entries.
132 /// e.g.: __sind2_massv --> __sind2_P9 for a Power9 subtarget.
133 /// Both function prototypes and their callsites are updated during lowering.
134 bool PPCLowerMASSVEntries::lowerMASSVCall(CallInst
*CI
, Function
&Func
,
136 const PPCSubtarget
*Subtarget
) {
140 // Handling pow(x, 0.25), pow(x, 0.75), powf(x, 0.25), powf(x, 0.75)
141 if (handlePowSpecialCases(CI
, Func
, M
))
144 std::string MASSVEntryName
= createMASSVFuncName(Func
, Subtarget
);
145 FunctionCallee FCache
= M
.getOrInsertFunction(
146 MASSVEntryName
, Func
.getFunctionType(), Func
.getAttributes());
148 CI
->setCalledFunction(FCache
);
153 bool PPCLowerMASSVEntries::runOnModule(Module
&M
) {
154 bool Changed
= false;
156 auto *TPC
= getAnalysisIfAvailable
<TargetPassConfig
>();
160 auto &TM
= TPC
->getTM
<PPCTargetMachine
>();
161 const PPCSubtarget
*Subtarget
;
163 for (Function
&Func
: M
) {
164 if (!Func
.isDeclaration())
167 if (!isMASSVFunc(Func
.getName()))
170 // Call to lowerMASSVCall() invalidates the iterator over users upon
171 // replacing the users. Precomputing the current list of users allows us to
172 // replace all the call sites.
173 SmallVector
<User
*, 4> MASSVUsers(Func
.users());
175 for (auto *User
: MASSVUsers
) {
176 auto *CI
= dyn_cast
<CallInst
>(User
);
180 Subtarget
= &TM
.getSubtarget
<PPCSubtarget
>(*CI
->getParent()->getParent());
181 Changed
|= lowerMASSVCall(CI
, Func
, M
, Subtarget
);
188 char PPCLowerMASSVEntries::ID
= 0;
190 char &llvm::PPCLowerMASSVEntriesID
= PPCLowerMASSVEntries::ID
;
192 INITIALIZE_PASS(PPCLowerMASSVEntries
, DEBUG_TYPE
, "Lower MASSV entries", false,
195 ModulePass
*llvm::createPPCLowerMASSVEntriesPass() {
196 return new PPCLowerMASSVEntries();