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("ctlz.") && F->arg_size() == 1) {
57 F->setName(Name + ".old");
58 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
59 F->arg_begin()->getType());
62 if (Name.startswith("cttz.") && F->arg_size() == 1) {
63 F->setName(Name + ".old");
64 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
65 F->arg_begin()->getType());
71 if (Name.startswith("x86.sse2.pcmpeq.") ||
72 Name.startswith("x86.sse2.pcmpgt.") ||
73 Name.startswith("x86.avx2.pcmpeq.") ||
74 Name.startswith("x86.avx2.pcmpgt.") ||
75 Name.startswith("x86.avx.vpermil.") ||
76 Name == "x86.avx.movnt.dq.256" ||
77 Name == "x86.avx.movnt.pd.256" ||
78 Name == "x86.avx.movnt.ps.256" ||
79 (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) {
83 // SSE4.1 ptest functions may have an old signature.
84 if (Name.startswith("x86.sse41.ptest")) {
85 if (Name == "x86.sse41.ptestc")
86 return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestc, NewFn);
87 if (Name == "x86.sse41.ptestz")
88 return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestz, NewFn);
89 if (Name == "x86.sse41.ptestnzc")
90 return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestnzc, NewFn);
92 // frcz.ss/sd may need to have an argument dropped
93 if (Name.startswith("x86.xop.vfrcz.ss") && F->arg_size() == 2) {
94 F->setName(Name + ".old");
95 NewFn = Intrinsic::getDeclaration(F->getParent(),
96 Intrinsic::x86_xop_vfrcz_ss);
99 if (Name.startswith("x86.xop.vfrcz.sd") && F->arg_size() == 2) {
100 F->setName(Name + ".old");
101 NewFn = Intrinsic::getDeclaration(F->getParent(),
102 Intrinsic::x86_xop_vfrcz_sd);
105 // Fix the FMA4 intrinsics to remove the 4
106 if (Name.startswith("x86.fma4.")) {
107 F->setName("llvm.x86.fma" + Name.substr(8));
115 // This may not belong here. This function is effectively being overloaded
116 // to both detect an intrinsic which needs upgrading, and to provide the
117 // upgraded form of the intrinsic. We should perhaps have two separate
118 // functions for this.
122 bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
124 bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
126 // Upgrade intrinsic attributes. This does not change the function.
129 if (unsigned id = F->getIntrinsicID())
130 F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id));
134 bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
135 // Nothing to do yet.
139 // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
140 // upgraded intrinsic. All argument and return casting must be provided in
141 // order to seamlessly integrate with existing context.
142 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
143 Function *F = CI->getCalledFunction();
144 LLVMContext &C = CI->getContext();
145 IRBuilder<> Builder(C);
146 Builder.SetInsertPoint(CI->getParent(), CI);
148 assert(F && "Intrinsic call is not direct?");
151 // Get the Function's name.
152 StringRef Name = F->getName();
155 // Upgrade packed integer vector compares intrinsics to compare instructions
156 if (Name.startswith("llvm.x86.sse2.pcmpeq.") ||
157 Name.startswith("llvm.x86.avx2.pcmpeq.")) {
158 Rep = Builder.CreateICmpEQ(CI->getArgOperand(0), CI->getArgOperand(1),
160 // need to sign extend since icmp returns vector of i1
161 Rep = Builder.CreateSExt(Rep, CI->getType(), "");
162 } else if (Name.startswith("llvm.x86.sse2.pcmpgt.") ||
163 Name.startswith("llvm.x86.avx2.pcmpgt.")) {
164 Rep = Builder.CreateICmpSGT(CI->getArgOperand(0), CI->getArgOperand(1),
166 // need to sign extend since icmp returns vector of i1
167 Rep = Builder.CreateSExt(Rep, CI->getType(), "");
168 } else if (Name == "llvm.x86.avx.movnt.dq.256" ||
169 Name == "llvm.x86.avx.movnt.ps.256" ||
170 Name == "llvm.x86.avx.movnt.pd.256") {
171 IRBuilder<> Builder(C);
172 Builder.SetInsertPoint(CI->getParent(), CI);
174 Module *M = F->getParent();
175 SmallVector<Value *, 1> Elts;
176 Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
177 MDNode *Node = MDNode::get(C, Elts);
179 Value *Arg0 = CI->getArgOperand(0);
180 Value *Arg1 = CI->getArgOperand(1);
182 // Convert the type of the pointer to a pointer to the stored type.
183 Value *BC = Builder.CreateBitCast(Arg0,
184 PointerType::getUnqual(Arg1->getType()),
186 StoreInst *SI = Builder.CreateStore(Arg1, BC);
187 SI->setMetadata(M->getMDKindID("nontemporal"), Node);
188 SI->setAlignment(16);
191 CI->eraseFromParent();
193 } else if (Name.startswith("llvm.x86.xop.vpcom")) {
195 if (Name.endswith("ub"))
196 intID = Intrinsic::x86_xop_vpcomub;
197 else if (Name.endswith("uw"))
198 intID = Intrinsic::x86_xop_vpcomuw;
199 else if (Name.endswith("ud"))
200 intID = Intrinsic::x86_xop_vpcomud;
201 else if (Name.endswith("uq"))
202 intID = Intrinsic::x86_xop_vpcomuq;
203 else if (Name.endswith("b"))
204 intID = Intrinsic::x86_xop_vpcomb;
205 else if (Name.endswith("w"))
206 intID = Intrinsic::x86_xop_vpcomw;
207 else if (Name.endswith("d"))
208 intID = Intrinsic::x86_xop_vpcomd;
209 else if (Name.endswith("q"))
210 intID = Intrinsic::x86_xop_vpcomq;
212 llvm_unreachable("Unknown suffix");
214 Name = Name.substr(18); // strip off "llvm.x86.xop.vpcom"
216 if (Name.startswith("lt"))
218 else if (Name.startswith("le"))
220 else if (Name.startswith("gt"))
222 else if (Name.startswith("ge"))
224 else if (Name.startswith("eq"))
226 else if (Name.startswith("ne"))
228 else if (Name.startswith("true"))
230 else if (Name.startswith("false"))
233 llvm_unreachable("Unknown condition");
235 Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID);
236 Rep = Builder.CreateCall3(VPCOM, CI->getArgOperand(0),
237 CI->getArgOperand(1), Builder.getInt8(Imm));
239 bool PD128 = false, PD256 = false, PS128 = false, PS256 = false;
240 if (Name == "llvm.x86.avx.vpermil.pd.256")
242 else if (Name == "llvm.x86.avx.vpermil.pd")
244 else if (Name == "llvm.x86.avx.vpermil.ps.256")
246 else if (Name == "llvm.x86.avx.vpermil.ps")
249 if (PD256 || PD128 || PS256 || PS128) {
250 Value *Op0 = CI->getArgOperand(0);
251 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
252 SmallVector<Constant*, 8> Idxs;
255 for (unsigned i = 0; i != 2; ++i)
256 Idxs.push_back(Builder.getInt32((Imm >> i) & 0x1));
258 for (unsigned l = 0; l != 4; l+=2)
259 for (unsigned i = 0; i != 2; ++i)
260 Idxs.push_back(Builder.getInt32(((Imm >> (l+i)) & 0x1) + l));
262 for (unsigned i = 0; i != 4; ++i)
263 Idxs.push_back(Builder.getInt32((Imm >> (2 * i)) & 0x3));
265 for (unsigned l = 0; l != 8; l+=4)
266 for (unsigned i = 0; i != 4; ++i)
267 Idxs.push_back(Builder.getInt32(((Imm >> (2 * i)) & 0x3) + l));
269 llvm_unreachable("Unexpected function");
271 Rep = Builder.CreateShuffleVector(Op0, Op0, ConstantVector::get(Idxs));
273 llvm_unreachable("Unknown function for CallInst upgrade.");
277 CI->replaceAllUsesWith(Rep);
278 CI->eraseFromParent();
282 StringRef Name = CI->getName();
284 switch (NewFn->getIntrinsicID()) {
286 llvm_unreachable("Unknown function for CallInst upgrade.");
288 case Intrinsic::ctlz:
289 case Intrinsic::cttz:
290 assert(CI->getNumArgOperands() == 1 &&
291 "Mismatch between function args and call args");
292 CI->setName(Name + ".old");
293 CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
294 Builder.getFalse(), Name));
295 CI->eraseFromParent();
298 case Intrinsic::x86_xop_vfrcz_ss:
299 case Intrinsic::x86_xop_vfrcz_sd:
300 CI->replaceAllUsesWith(Builder.CreateCall(NewFn, CI->getArgOperand(1),
302 CI->eraseFromParent();
305 case Intrinsic::x86_sse41_ptestc:
306 case Intrinsic::x86_sse41_ptestz:
307 case Intrinsic::x86_sse41_ptestnzc: {
308 // The arguments for these intrinsics used to be v4f32, and changed
309 // to v2i64. This is purely a nop, since those are bitwise intrinsics.
310 // So, the only thing required is a bitcast for both arguments.
311 // First, check the arguments have the old type.
312 Value *Arg0 = CI->getArgOperand(0);
313 if (Arg0->getType() != VectorType::get(Type::getFloatTy(C), 4))
316 // Old intrinsic, add bitcasts
317 Value *Arg1 = CI->getArgOperand(1);
320 Builder.CreateBitCast(Arg0,
321 VectorType::get(Type::getInt64Ty(C), 2),
324 Builder.CreateBitCast(Arg1,
325 VectorType::get(Type::getInt64Ty(C), 2),
328 CallInst* NewCall = Builder.CreateCall2(NewFn, BC0, BC1, Name);
329 CI->replaceAllUsesWith(NewCall);
330 CI->eraseFromParent();
336 // This tests each Function to determine if it needs upgrading. When we find
337 // one we are interested in, we then upgrade all calls to reflect the new
339 void llvm::UpgradeCallsToIntrinsic(Function* F) {
340 assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
342 // Upgrade the function and check if it is a totaly new function.
344 if (UpgradeIntrinsicFunction(F, NewFn)) {
346 // Replace all uses to the old function with the new one if necessary.
347 for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
349 if (CallInst *CI = dyn_cast<CallInst>(*UI++))
350 UpgradeIntrinsicCall(CI, NewFn);
352 // Remove old function, no longer used, from the module.
353 F->eraseFromParent();