1 //===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the auto-upgrade helper functions
12 //===----------------------------------------------------------------------===//
14 #include "llvm/AutoUpgrade.h"
15 #include "llvm/Constants.h"
16 #include "llvm/Function.h"
17 #include "llvm/Instruction.h"
18 #include "llvm/LLVMContext.h"
19 #include "llvm/Module.h"
20 #include "llvm/IntrinsicInst.h"
21 #include "llvm/Support/CallSite.h"
22 #include "llvm/Support/CFG.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/IRBuilder.h"
29 static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
30 assert(F && "Illegal to upgrade a non-existent Function.");
32 // Quickly eliminate it, if it's not a candidate.
33 StringRef Name = F->getName();
34 if (Name.size() <= 8 || !Name.startswith("llvm."))
36 Name = Name.substr(5); // Strip off "llvm."
41 if (Name.startswith("ctlz.") && F->arg_size() == 1) {
42 F->setName(Name + ".old");
43 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
44 F->arg_begin()->getType());
47 if (Name.startswith("cttz.") && F->arg_size() == 1) {
48 F->setName(Name + ".old");
49 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
50 F->arg_begin()->getType());
56 if (Name.startswith("x86.sse2.pcmpeq.") ||
57 Name.startswith("x86.sse2.pcmpgt.") ||
58 Name.startswith("x86.avx2.pcmpeq.") ||
59 Name.startswith("x86.avx2.pcmpgt.") ||
60 Name.startswith("x86.avx.vpermil.") ||
61 Name == "x86.avx.movnt.dq.256" ||
62 Name == "x86.avx.movnt.pd.256" ||
63 Name == "x86.avx.movnt.ps.256" ||
64 (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) {
68 // Fix the FMA4 intrinsics to remove the 4
69 if (Name.startswith("x86.fma4.")) {
70 F->setName("llvm.x86.fma" + Name.substr(8));
78 // This may not belong here. This function is effectively being overloaded
79 // to both detect an intrinsic which needs upgrading, and to provide the
80 // upgraded form of the intrinsic. We should perhaps have two separate
81 // functions for this.
85 bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
87 bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
89 // Upgrade intrinsic attributes. This does not change the function.
92 if (unsigned id = F->getIntrinsicID())
93 F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id));
97 bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
102 // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
103 // upgraded intrinsic. All argument and return casting must be provided in
104 // order to seamlessly integrate with existing context.
105 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
106 Function *F = CI->getCalledFunction();
107 LLVMContext &C = CI->getContext();
108 IRBuilder<> Builder(C);
109 Builder.SetInsertPoint(CI->getParent(), CI);
111 assert(F && "Intrinsic call is not direct?");
114 // Get the Function's name.
115 StringRef Name = F->getName();
118 // Upgrade packed integer vector compares intrinsics to compare instructions
119 if (Name.startswith("llvm.x86.sse2.pcmpeq.") ||
120 Name.startswith("llvm.x86.avx2.pcmpeq.")) {
121 Rep = Builder.CreateICmpEQ(CI->getArgOperand(0), CI->getArgOperand(1),
123 // need to sign extend since icmp returns vector of i1
124 Rep = Builder.CreateSExt(Rep, CI->getType(), "");
125 } else if (Name.startswith("llvm.x86.sse2.pcmpgt.") ||
126 Name.startswith("llvm.x86.avx2.pcmpgt.")) {
127 Rep = Builder.CreateICmpSGT(CI->getArgOperand(0), CI->getArgOperand(1),
129 // need to sign extend since icmp returns vector of i1
130 Rep = Builder.CreateSExt(Rep, CI->getType(), "");
131 } else if (Name == "llvm.x86.avx.movnt.dq.256" ||
132 Name == "llvm.x86.avx.movnt.ps.256" ||
133 Name == "llvm.x86.avx.movnt.pd.256") {
134 IRBuilder<> Builder(C);
135 Builder.SetInsertPoint(CI->getParent(), CI);
137 Module *M = F->getParent();
138 SmallVector<Value *, 1> Elts;
139 Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
140 MDNode *Node = MDNode::get(C, Elts);
142 Value *Arg0 = CI->getArgOperand(0);
143 Value *Arg1 = CI->getArgOperand(1);
145 // Convert the type of the pointer to a pointer to the stored type.
146 Value *BC = Builder.CreateBitCast(Arg0,
147 PointerType::getUnqual(Arg1->getType()),
149 StoreInst *SI = Builder.CreateStore(Arg1, BC);
150 SI->setMetadata(M->getMDKindID("nontemporal"), Node);
151 SI->setAlignment(16);
154 CI->eraseFromParent();
156 } else if (Name.startswith("llvm.x86.xop.vpcom")) {
158 if (Name.endswith("ub"))
159 intID = Intrinsic::x86_xop_vpcomub;
160 else if (Name.endswith("uw"))
161 intID = Intrinsic::x86_xop_vpcomuw;
162 else if (Name.endswith("ud"))
163 intID = Intrinsic::x86_xop_vpcomud;
164 else if (Name.endswith("uq"))
165 intID = Intrinsic::x86_xop_vpcomuq;
166 else if (Name.endswith("b"))
167 intID = Intrinsic::x86_xop_vpcomb;
168 else if (Name.endswith("w"))
169 intID = Intrinsic::x86_xop_vpcomw;
170 else if (Name.endswith("d"))
171 intID = Intrinsic::x86_xop_vpcomd;
172 else if (Name.endswith("q"))
173 intID = Intrinsic::x86_xop_vpcomq;
175 llvm_unreachable("Unknown suffix");
177 Name = Name.substr(18); // strip off "llvm.x86.xop.vpcom"
179 if (Name.startswith("lt"))
181 else if (Name.startswith("le"))
183 else if (Name.startswith("gt"))
185 else if (Name.startswith("ge"))
187 else if (Name.startswith("eq"))
189 else if (Name.startswith("ne"))
191 else if (Name.startswith("true"))
193 else if (Name.startswith("false"))
196 llvm_unreachable("Unknown condition");
198 Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID);
199 Rep = Builder.CreateCall3(VPCOM, CI->getArgOperand(0),
200 CI->getArgOperand(1), Builder.getInt8(Imm));
202 bool PD128 = false, PD256 = false, PS128 = false, PS256 = false;
203 if (Name == "llvm.x86.avx.vpermil.pd.256")
205 else if (Name == "llvm.x86.avx.vpermil.pd")
207 else if (Name == "llvm.x86.avx.vpermil.ps.256")
209 else if (Name == "llvm.x86.avx.vpermil.ps")
212 if (PD256 || PD128 || PS256 || PS128) {
213 Value *Op0 = CI->getArgOperand(0);
214 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
215 SmallVector<Constant*, 8> Idxs;
218 for (unsigned i = 0; i != 2; ++i)
219 Idxs.push_back(Builder.getInt32((Imm >> i) & 0x1));
221 for (unsigned l = 0; l != 4; l+=2)
222 for (unsigned i = 0; i != 2; ++i)
223 Idxs.push_back(Builder.getInt32(((Imm >> (l+i)) & 0x1) + l));
225 for (unsigned i = 0; i != 4; ++i)
226 Idxs.push_back(Builder.getInt32((Imm >> (2 * i)) & 0x3));
228 for (unsigned l = 0; l != 8; l+=4)
229 for (unsigned i = 0; i != 4; ++i)
230 Idxs.push_back(Builder.getInt32(((Imm >> (2 * i)) & 0x3) + l));
232 llvm_unreachable("Unexpected function");
234 Rep = Builder.CreateShuffleVector(Op0, Op0, ConstantVector::get(Idxs));
236 llvm_unreachable("Unknown function for CallInst upgrade.");
240 CI->replaceAllUsesWith(Rep);
241 CI->eraseFromParent();
245 switch (NewFn->getIntrinsicID()) {
247 llvm_unreachable("Unknown function for CallInst upgrade.");
249 case Intrinsic::ctlz:
250 case Intrinsic::cttz:
251 assert(CI->getNumArgOperands() == 1 &&
252 "Mismatch between function args and call args");
253 StringRef Name = CI->getName();
254 CI->setName(Name + ".old");
255 CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
256 Builder.getFalse(), Name));
257 CI->eraseFromParent();
262 // This tests each Function to determine if it needs upgrading. When we find
263 // one we are interested in, we then upgrade all calls to reflect the new
265 void llvm::UpgradeCallsToIntrinsic(Function* F) {
266 assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
268 // Upgrade the function and check if it is a totaly new function.
270 if (UpgradeIntrinsicFunction(F, NewFn)) {
272 // Replace all uses to the old function with the new one if necessary.
273 for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
275 if (CallInst *CI = dyn_cast<CallInst>(*UI++))
276 UpgradeIntrinsicCall(CI, NewFn);
278 // Remove old function, no longer used, from the module.
279 F->eraseFromParent();