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/IR/Constants.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/IRBuilder.h"
18 #include "llvm/IR/Instruction.h"
19 #include "llvm/IR/IntrinsicInst.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/IR/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());
69 if (Name.startswith("arm.neon.vcnt")) {
70 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctpop,
71 F->arg_begin()->getType());
77 if (Name.startswith("ctlz.") && F->arg_size() == 1) {
78 F->setName(Name + ".old");
79 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
80 F->arg_begin()->getType());
83 if (Name.startswith("cttz.") && F->arg_size() == 1) {
84 F->setName(Name + ".old");
85 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
86 F->arg_begin()->getType());
92 if (Name.startswith("x86.sse2.pcmpeq.") ||
93 Name.startswith("x86.sse2.pcmpgt.") ||
94 Name.startswith("x86.avx2.pcmpeq.") ||
95 Name.startswith("x86.avx2.pcmpgt.") ||
96 Name.startswith("x86.avx.vpermil.") ||
97 Name == "x86.avx.movnt.dq.256" ||
98 Name == "x86.avx.movnt.pd.256" ||
99 Name == "x86.avx.movnt.ps.256" ||
100 (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) {
104 // SSE4.1 ptest functions may have an old signature.
105 if (Name.startswith("x86.sse41.ptest")) {
106 if (Name == "x86.sse41.ptestc")
107 return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestc, NewFn);
108 if (Name == "x86.sse41.ptestz")
109 return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestz, NewFn);
110 if (Name == "x86.sse41.ptestnzc")
111 return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestnzc, NewFn);
113 // frcz.ss/sd may need to have an argument dropped
114 if (Name.startswith("x86.xop.vfrcz.ss") && F->arg_size() == 2) {
115 F->setName(Name + ".old");
116 NewFn = Intrinsic::getDeclaration(F->getParent(),
117 Intrinsic::x86_xop_vfrcz_ss);
120 if (Name.startswith("x86.xop.vfrcz.sd") && F->arg_size() == 2) {
121 F->setName(Name + ".old");
122 NewFn = Intrinsic::getDeclaration(F->getParent(),
123 Intrinsic::x86_xop_vfrcz_sd);
126 // Fix the FMA4 intrinsics to remove the 4
127 if (Name.startswith("x86.fma4.")) {
128 F->setName("llvm.x86.fma" + Name.substr(8));
136 // This may not belong here. This function is effectively being overloaded
137 // to both detect an intrinsic which needs upgrading, and to provide the
138 // upgraded form of the intrinsic. We should perhaps have two separate
139 // functions for this.
143 bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
145 bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
147 // Upgrade intrinsic attributes. This does not change the function.
150 if (unsigned id = F->getIntrinsicID())
151 F->setAttributes(Intrinsic::getAttributes(F->getContext(),
156 bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
157 // Nothing to do yet.
161 // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
162 // upgraded intrinsic. All argument and return casting must be provided in
163 // order to seamlessly integrate with existing context.
164 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
165 Function *F = CI->getCalledFunction();
166 LLVMContext &C = CI->getContext();
167 IRBuilder<> Builder(C);
168 Builder.SetInsertPoint(CI->getParent(), CI);
170 assert(F && "Intrinsic call is not direct?");
173 // Get the Function's name.
174 StringRef Name = F->getName();
177 // Upgrade packed integer vector compares intrinsics to compare instructions
178 if (Name.startswith("llvm.x86.sse2.pcmpeq.") ||
179 Name.startswith("llvm.x86.avx2.pcmpeq.")) {
180 Rep = Builder.CreateICmpEQ(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.startswith("llvm.x86.sse2.pcmpgt.") ||
185 Name.startswith("llvm.x86.avx2.pcmpgt.")) {
186 Rep = Builder.CreateICmpSGT(CI->getArgOperand(0), CI->getArgOperand(1),
188 // need to sign extend since icmp returns vector of i1
189 Rep = Builder.CreateSExt(Rep, CI->getType(), "");
190 } else if (Name == "llvm.x86.avx.movnt.dq.256" ||
191 Name == "llvm.x86.avx.movnt.ps.256" ||
192 Name == "llvm.x86.avx.movnt.pd.256") {
193 IRBuilder<> Builder(C);
194 Builder.SetInsertPoint(CI->getParent(), CI);
196 Module *M = F->getParent();
197 SmallVector<Value *, 1> Elts;
198 Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
199 MDNode *Node = MDNode::get(C, Elts);
201 Value *Arg0 = CI->getArgOperand(0);
202 Value *Arg1 = CI->getArgOperand(1);
204 // Convert the type of the pointer to a pointer to the stored type.
205 Value *BC = Builder.CreateBitCast(Arg0,
206 PointerType::getUnqual(Arg1->getType()),
208 StoreInst *SI = Builder.CreateStore(Arg1, BC);
209 SI->setMetadata(M->getMDKindID("nontemporal"), Node);
210 SI->setAlignment(16);
213 CI->eraseFromParent();
215 } else if (Name.startswith("llvm.x86.xop.vpcom")) {
217 if (Name.endswith("ub"))
218 intID = Intrinsic::x86_xop_vpcomub;
219 else if (Name.endswith("uw"))
220 intID = Intrinsic::x86_xop_vpcomuw;
221 else if (Name.endswith("ud"))
222 intID = Intrinsic::x86_xop_vpcomud;
223 else if (Name.endswith("uq"))
224 intID = Intrinsic::x86_xop_vpcomuq;
225 else if (Name.endswith("b"))
226 intID = Intrinsic::x86_xop_vpcomb;
227 else if (Name.endswith("w"))
228 intID = Intrinsic::x86_xop_vpcomw;
229 else if (Name.endswith("d"))
230 intID = Intrinsic::x86_xop_vpcomd;
231 else if (Name.endswith("q"))
232 intID = Intrinsic::x86_xop_vpcomq;
234 llvm_unreachable("Unknown suffix");
236 Name = Name.substr(18); // strip off "llvm.x86.xop.vpcom"
238 if (Name.startswith("lt"))
240 else if (Name.startswith("le"))
242 else if (Name.startswith("gt"))
244 else if (Name.startswith("ge"))
246 else if (Name.startswith("eq"))
248 else if (Name.startswith("ne"))
250 else if (Name.startswith("true"))
252 else if (Name.startswith("false"))
255 llvm_unreachable("Unknown condition");
257 Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID);
258 Rep = Builder.CreateCall3(VPCOM, CI->getArgOperand(0),
259 CI->getArgOperand(1), Builder.getInt8(Imm));
261 bool PD128 = false, PD256 = false, PS128 = false, PS256 = false;
262 if (Name == "llvm.x86.avx.vpermil.pd.256")
264 else if (Name == "llvm.x86.avx.vpermil.pd")
266 else if (Name == "llvm.x86.avx.vpermil.ps.256")
268 else if (Name == "llvm.x86.avx.vpermil.ps")
271 if (PD256 || PD128 || PS256 || PS128) {
272 Value *Op0 = CI->getArgOperand(0);
273 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
274 SmallVector<Constant*, 8> Idxs;
277 for (unsigned i = 0; i != 2; ++i)
278 Idxs.push_back(Builder.getInt32((Imm >> i) & 0x1));
280 for (unsigned l = 0; l != 4; l+=2)
281 for (unsigned i = 0; i != 2; ++i)
282 Idxs.push_back(Builder.getInt32(((Imm >> (l+i)) & 0x1) + l));
284 for (unsigned i = 0; i != 4; ++i)
285 Idxs.push_back(Builder.getInt32((Imm >> (2 * i)) & 0x3));
287 for (unsigned l = 0; l != 8; l+=4)
288 for (unsigned i = 0; i != 4; ++i)
289 Idxs.push_back(Builder.getInt32(((Imm >> (2 * i)) & 0x3) + l));
291 llvm_unreachable("Unexpected function");
293 Rep = Builder.CreateShuffleVector(Op0, Op0, ConstantVector::get(Idxs));
295 llvm_unreachable("Unknown function for CallInst upgrade.");
299 CI->replaceAllUsesWith(Rep);
300 CI->eraseFromParent();
304 std::string Name = CI->getName().str();
305 CI->setName(Name + ".old");
307 switch (NewFn->getIntrinsicID()) {
309 llvm_unreachable("Unknown function for CallInst upgrade.");
311 case Intrinsic::ctlz:
312 case Intrinsic::cttz:
313 assert(CI->getNumArgOperands() == 1 &&
314 "Mismatch between function args and call args");
315 CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
316 Builder.getFalse(), Name));
317 CI->eraseFromParent();
320 case Intrinsic::arm_neon_vclz: {
321 // Change name from llvm.arm.neon.vclz.* to llvm.ctlz.*
322 CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
324 "llvm.ctlz." + Name.substr(14)));
325 CI->eraseFromParent();
328 case Intrinsic::ctpop: {
329 CI->replaceAllUsesWith(Builder.CreateCall(NewFn, CI->getArgOperand(0)));
330 CI->eraseFromParent();
334 case Intrinsic::x86_xop_vfrcz_ss:
335 case Intrinsic::x86_xop_vfrcz_sd:
336 CI->replaceAllUsesWith(Builder.CreateCall(NewFn, CI->getArgOperand(1),
338 CI->eraseFromParent();
341 case Intrinsic::x86_sse41_ptestc:
342 case Intrinsic::x86_sse41_ptestz:
343 case Intrinsic::x86_sse41_ptestnzc: {
344 // The arguments for these intrinsics used to be v4f32, and changed
345 // to v2i64. This is purely a nop, since those are bitwise intrinsics.
346 // So, the only thing required is a bitcast for both arguments.
347 // First, check the arguments have the old type.
348 Value *Arg0 = CI->getArgOperand(0);
349 if (Arg0->getType() != VectorType::get(Type::getFloatTy(C), 4))
352 // Old intrinsic, add bitcasts
353 Value *Arg1 = CI->getArgOperand(1);
356 Builder.CreateBitCast(Arg0,
357 VectorType::get(Type::getInt64Ty(C), 2),
360 Builder.CreateBitCast(Arg1,
361 VectorType::get(Type::getInt64Ty(C), 2),
364 CallInst* NewCall = Builder.CreateCall2(NewFn, BC0, BC1, Name);
365 CI->replaceAllUsesWith(NewCall);
366 CI->eraseFromParent();
372 // This tests each Function to determine if it needs upgrading. When we find
373 // one we are interested in, we then upgrade all calls to reflect the new
375 void llvm::UpgradeCallsToIntrinsic(Function* F) {
376 assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
378 // Upgrade the function and check if it is a totaly new function.
380 if (UpgradeIntrinsicFunction(F, NewFn)) {
382 // Replace all uses to the old function with the new one if necessary.
383 for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
385 if (CallInst *CI = dyn_cast<CallInst>(*UI++))
386 UpgradeIntrinsicCall(CI, NewFn);
388 // Remove old function, no longer used, from the module.
389 F->eraseFromParent();