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/IRBuilder.h"
18 #include "llvm/Instruction.h"
19 #include "llvm/IntrinsicInst.h"
20 #include "llvm/LLVMContext.h"
21 #include "llvm/Module.h"
22 #include "llvm/Support/CFG.h"
23 #include "llvm/Support/CallSite.h"
24 #include "llvm/Support/ErrorHandling.h"
28 // Upgrade the declarations of the SSE4.1 functions whose arguments have
29 // changed their type from v4f32 to v2i64.
30 static bool UpgradeSSE41Function(Function* F, Intrinsic::ID IID,
32 // Check whether this is an old version of the function, which received
34 Type *Arg0Type = F->getFunctionType()->getParamType(0);
35 if (Arg0Type != VectorType::get(Type::getFloatTy(F->getContext()), 4))
38 // Yes, it's old, replace it with new version.
39 F->setName(F->getName() + ".old");
40 NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
44 static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
45 assert(F && "Illegal to upgrade a non-existent Function.");
47 // Quickly eliminate it, if it's not a candidate.
48 StringRef Name = F->getName();
49 if (Name.size() <= 8 || !Name.startswith("llvm."))
51 Name = Name.substr(5); // Strip off "llvm."
56 if (Name.startswith("arm.neon.vclz")) {
58 F->arg_begin()->getType(),
59 Type::getInt1Ty(F->getContext())
61 // Can't use Intrinsic::getDeclaration here as it adds a ".i1" to
62 // the end of the name. Change name from llvm.arm.neon.vclz.* to
64 FunctionType* fType = FunctionType::get(F->getReturnType(), args, false);
65 NewFn = Function::Create(fType, F->getLinkage(),
66 "llvm.ctlz." + Name.substr(14), F->getParent());
72 if (Name.startswith("ctlz.") && F->arg_size() == 1) {
73 F->setName(Name + ".old");
74 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
75 F->arg_begin()->getType());
78 if (Name.startswith("cttz.") && F->arg_size() == 1) {
79 F->setName(Name + ".old");
80 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
81 F->arg_begin()->getType());
87 if (Name.startswith("x86.sse2.pcmpeq.") ||
88 Name.startswith("x86.sse2.pcmpgt.") ||
89 Name.startswith("x86.avx2.pcmpeq.") ||
90 Name.startswith("x86.avx2.pcmpgt.") ||
91 Name.startswith("x86.avx.vpermil.") ||
92 Name == "x86.avx.movnt.dq.256" ||
93 Name == "x86.avx.movnt.pd.256" ||
94 Name == "x86.avx.movnt.ps.256" ||
95 (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) {
99 // SSE4.1 ptest functions may have an old signature.
100 if (Name.startswith("x86.sse41.ptest")) {
101 if (Name == "x86.sse41.ptestc")
102 return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestc, NewFn);
103 if (Name == "x86.sse41.ptestz")
104 return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestz, NewFn);
105 if (Name == "x86.sse41.ptestnzc")
106 return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestnzc, NewFn);
108 // frcz.ss/sd may need to have an argument dropped
109 if (Name.startswith("x86.xop.vfrcz.ss") && F->arg_size() == 2) {
110 F->setName(Name + ".old");
111 NewFn = Intrinsic::getDeclaration(F->getParent(),
112 Intrinsic::x86_xop_vfrcz_ss);
115 if (Name.startswith("x86.xop.vfrcz.sd") && F->arg_size() == 2) {
116 F->setName(Name + ".old");
117 NewFn = Intrinsic::getDeclaration(F->getParent(),
118 Intrinsic::x86_xop_vfrcz_sd);
121 // Fix the FMA4 intrinsics to remove the 4
122 if (Name.startswith("x86.fma4.")) {
123 F->setName("llvm.x86.fma" + Name.substr(8));
131 // This may not belong here. This function is effectively being overloaded
132 // to both detect an intrinsic which needs upgrading, and to provide the
133 // upgraded form of the intrinsic. We should perhaps have two separate
134 // functions for this.
138 bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
140 bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
142 // Upgrade intrinsic attributes. This does not change the function.
145 if (unsigned id = F->getIntrinsicID())
146 F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id));
150 bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
151 // Nothing to do yet.
155 // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
156 // upgraded intrinsic. All argument and return casting must be provided in
157 // order to seamlessly integrate with existing context.
158 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
159 Function *F = CI->getCalledFunction();
160 LLVMContext &C = CI->getContext();
161 IRBuilder<> Builder(C);
162 Builder.SetInsertPoint(CI->getParent(), CI);
164 assert(F && "Intrinsic call is not direct?");
167 // Get the Function's name.
168 StringRef Name = F->getName();
171 // Upgrade packed integer vector compares intrinsics to compare instructions
172 if (Name.startswith("llvm.x86.sse2.pcmpeq.") ||
173 Name.startswith("llvm.x86.avx2.pcmpeq.")) {
174 Rep = Builder.CreateICmpEQ(CI->getArgOperand(0), CI->getArgOperand(1),
176 // need to sign extend since icmp returns vector of i1
177 Rep = Builder.CreateSExt(Rep, CI->getType(), "");
178 } else if (Name.startswith("llvm.x86.sse2.pcmpgt.") ||
179 Name.startswith("llvm.x86.avx2.pcmpgt.")) {
180 Rep = Builder.CreateICmpSGT(CI->getArgOperand(0), CI->getArgOperand(1),
182 // need to sign extend since icmp returns vector of i1
183 Rep = Builder.CreateSExt(Rep, CI->getType(), "");
184 } else if (Name == "llvm.x86.avx.movnt.dq.256" ||
185 Name == "llvm.x86.avx.movnt.ps.256" ||
186 Name == "llvm.x86.avx.movnt.pd.256") {
187 IRBuilder<> Builder(C);
188 Builder.SetInsertPoint(CI->getParent(), CI);
190 Module *M = F->getParent();
191 SmallVector<Value *, 1> Elts;
192 Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
193 MDNode *Node = MDNode::get(C, Elts);
195 Value *Arg0 = CI->getArgOperand(0);
196 Value *Arg1 = CI->getArgOperand(1);
198 // Convert the type of the pointer to a pointer to the stored type.
199 Value *BC = Builder.CreateBitCast(Arg0,
200 PointerType::getUnqual(Arg1->getType()),
202 StoreInst *SI = Builder.CreateStore(Arg1, BC);
203 SI->setMetadata(M->getMDKindID("nontemporal"), Node);
204 SI->setAlignment(16);
207 CI->eraseFromParent();
209 } else if (Name.startswith("llvm.x86.xop.vpcom")) {
211 if (Name.endswith("ub"))
212 intID = Intrinsic::x86_xop_vpcomub;
213 else if (Name.endswith("uw"))
214 intID = Intrinsic::x86_xop_vpcomuw;
215 else if (Name.endswith("ud"))
216 intID = Intrinsic::x86_xop_vpcomud;
217 else if (Name.endswith("uq"))
218 intID = Intrinsic::x86_xop_vpcomuq;
219 else if (Name.endswith("b"))
220 intID = Intrinsic::x86_xop_vpcomb;
221 else if (Name.endswith("w"))
222 intID = Intrinsic::x86_xop_vpcomw;
223 else if (Name.endswith("d"))
224 intID = Intrinsic::x86_xop_vpcomd;
225 else if (Name.endswith("q"))
226 intID = Intrinsic::x86_xop_vpcomq;
228 llvm_unreachable("Unknown suffix");
230 Name = Name.substr(18); // strip off "llvm.x86.xop.vpcom"
232 if (Name.startswith("lt"))
234 else if (Name.startswith("le"))
236 else if (Name.startswith("gt"))
238 else if (Name.startswith("ge"))
240 else if (Name.startswith("eq"))
242 else if (Name.startswith("ne"))
244 else if (Name.startswith("true"))
246 else if (Name.startswith("false"))
249 llvm_unreachable("Unknown condition");
251 Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID);
252 Rep = Builder.CreateCall3(VPCOM, CI->getArgOperand(0),
253 CI->getArgOperand(1), Builder.getInt8(Imm));
255 bool PD128 = false, PD256 = false, PS128 = false, PS256 = false;
256 if (Name == "llvm.x86.avx.vpermil.pd.256")
258 else if (Name == "llvm.x86.avx.vpermil.pd")
260 else if (Name == "llvm.x86.avx.vpermil.ps.256")
262 else if (Name == "llvm.x86.avx.vpermil.ps")
265 if (PD256 || PD128 || PS256 || PS128) {
266 Value *Op0 = CI->getArgOperand(0);
267 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
268 SmallVector<Constant*, 8> Idxs;
271 for (unsigned i = 0; i != 2; ++i)
272 Idxs.push_back(Builder.getInt32((Imm >> i) & 0x1));
274 for (unsigned l = 0; l != 4; l+=2)
275 for (unsigned i = 0; i != 2; ++i)
276 Idxs.push_back(Builder.getInt32(((Imm >> (l+i)) & 0x1) + l));
278 for (unsigned i = 0; i != 4; ++i)
279 Idxs.push_back(Builder.getInt32((Imm >> (2 * i)) & 0x3));
281 for (unsigned l = 0; l != 8; l+=4)
282 for (unsigned i = 0; i != 4; ++i)
283 Idxs.push_back(Builder.getInt32(((Imm >> (2 * i)) & 0x3) + l));
285 llvm_unreachable("Unexpected function");
287 Rep = Builder.CreateShuffleVector(Op0, Op0, ConstantVector::get(Idxs));
289 llvm_unreachable("Unknown function for CallInst upgrade.");
293 CI->replaceAllUsesWith(Rep);
294 CI->eraseFromParent();
298 StringRef Name = CI->getName();
300 switch (NewFn->getIntrinsicID()) {
302 llvm_unreachable("Unknown function for CallInst upgrade.");
304 case Intrinsic::ctlz:
305 case Intrinsic::cttz:
306 assert(CI->getNumArgOperands() == 1 &&
307 "Mismatch between function args and call args");
308 CI->setName(Name + ".old");
309 CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
310 Builder.getFalse(), Name));
311 CI->eraseFromParent();
314 case Intrinsic::arm_neon_vclz: {
315 // Change name from llvm.arm.neon.vclz.* to llvm.ctlz.*
316 CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
318 "llvm.ctlz." + Name.substr(14)));
319 CI->eraseFromParent();
323 case Intrinsic::x86_xop_vfrcz_ss:
324 case Intrinsic::x86_xop_vfrcz_sd:
325 CI->replaceAllUsesWith(Builder.CreateCall(NewFn, CI->getArgOperand(1),
327 CI->eraseFromParent();
330 case Intrinsic::x86_sse41_ptestc:
331 case Intrinsic::x86_sse41_ptestz:
332 case Intrinsic::x86_sse41_ptestnzc: {
333 // The arguments for these intrinsics used to be v4f32, and changed
334 // to v2i64. This is purely a nop, since those are bitwise intrinsics.
335 // So, the only thing required is a bitcast for both arguments.
336 // First, check the arguments have the old type.
337 Value *Arg0 = CI->getArgOperand(0);
338 if (Arg0->getType() != VectorType::get(Type::getFloatTy(C), 4))
341 // Old intrinsic, add bitcasts
342 Value *Arg1 = CI->getArgOperand(1);
345 Builder.CreateBitCast(Arg0,
346 VectorType::get(Type::getInt64Ty(C), 2),
349 Builder.CreateBitCast(Arg1,
350 VectorType::get(Type::getInt64Ty(C), 2),
353 CallInst* NewCall = Builder.CreateCall2(NewFn, BC0, BC1, Name);
354 CI->replaceAllUsesWith(NewCall);
355 CI->eraseFromParent();
361 // This tests each Function to determine if it needs upgrading. When we find
362 // one we are interested in, we then upgrade all calls to reflect the new
364 void llvm::UpgradeCallsToIntrinsic(Function* F) {
365 assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
367 // Upgrade the function and check if it is a totaly new function.
369 if (UpgradeIntrinsicFunction(F, NewFn)) {
371 // Replace all uses to the old function with the new one if necessary.
372 for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
374 if (CallInst *CI = dyn_cast<CallInst>(*UI++))
375 UpgradeIntrinsicCall(CI, NewFn);
377 // Remove old function, no longer used, from the module.
378 F->eraseFromParent();