blob: e73a49f7e102d1a1e0903b480d4a069d6be1bff3 [file] [log] [blame]
Chandler Carruth7132e002007-08-04 01:51:18 +00001//===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chandler Carruth7132e002007-08-04 01:51:18 +00007//
8//===----------------------------------------------------------------------===//
9//
Sanjay Patel19792fb2015-03-10 16:08:36 +000010// This file implements the auto-upgrade helper functions.
11// This is where deprecated IR intrinsics and other IR features are updated to
12// current specifications.
Chandler Carruth7132e002007-08-04 01:51:18 +000013//
14//===----------------------------------------------------------------------===//
15
Chandler Carruth91065212014-03-05 10:34:14 +000016#include "llvm/IR/AutoUpgrade.h"
Justin Lebar46624a82017-01-21 01:00:32 +000017#include "llvm/ADT/StringSwitch.h"
Chandler Carruth1305dc32014-03-04 11:45:46 +000018#include "llvm/IR/CFG.h"
Chandler Carruth219b89b2014-03-04 11:01:28 +000019#include "llvm/IR/CallSite.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000020#include "llvm/IR/Constants.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000021#include "llvm/IR/DIBuilder.h"
Chandler Carruth9a4c9e52014-03-06 00:46:21 +000022#include "llvm/IR/DebugInfo.h"
Manman Ren2ebfb422014-01-16 01:51:12 +000023#include "llvm/IR/DiagnosticInfo.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000024#include "llvm/IR/Function.h"
25#include "llvm/IR/IRBuilder.h"
26#include "llvm/IR/Instruction.h"
27#include "llvm/IR/IntrinsicInst.h"
28#include "llvm/IR/LLVMContext.h"
29#include "llvm/IR/Module.h"
Torok Edwin56d06592009-07-11 20:10:48 +000030#include "llvm/Support/ErrorHandling.h"
Jeroen Ketemaab99b592015-09-30 10:56:37 +000031#include "llvm/Support/Regex.h"
Anton Korobeynikov579f0712008-02-20 11:08:44 +000032#include <cstring>
Chandler Carruth7132e002007-08-04 01:51:18 +000033using namespace llvm;
34
Rafael Espindolad7325ee2016-10-03 15:51:42 +000035static void rename(GlobalValue *GV) { GV->setName(GV->getName() + ".old"); }
36
Craig Topper905cc752017-02-17 07:07:21 +000037// Upgrade the declarations of the SSE4.1 ptest intrinsics whose arguments have
Nadav Rotem17ee58a2012-06-10 18:42:51 +000038// changed their type from v4f32 to v2i64.
Craig Topper905cc752017-02-17 07:07:21 +000039static bool UpgradePTESTIntrinsic(Function* F, Intrinsic::ID IID,
40 Function *&NewFn) {
Nadav Rotem17ee58a2012-06-10 18:42:51 +000041 // Check whether this is an old version of the function, which received
42 // v4f32 arguments.
43 Type *Arg0Type = F->getFunctionType()->getParamType(0);
44 if (Arg0Type != VectorType::get(Type::getFloatTy(F->getContext()), 4))
45 return false;
46
47 // Yes, it's old, replace it with new version.
Rafael Espindolad7325ee2016-10-03 15:51:42 +000048 rename(F);
Nadav Rotem17ee58a2012-06-10 18:42:51 +000049 NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
50 return true;
51}
Chandler Carruth7132e002007-08-04 01:51:18 +000052
Chandler Carruth373b2b12014-09-06 10:00:01 +000053// Upgrade the declarations of intrinsic functions whose 8-bit immediate mask
54// arguments have changed their type from i32 to i8.
55static bool UpgradeX86IntrinsicsWith8BitMask(Function *F, Intrinsic::ID IID,
56 Function *&NewFn) {
57 // Check that the last argument is an i32.
58 Type *LastArgType = F->getFunctionType()->getParamType(
59 F->getFunctionType()->getNumParams() - 1);
60 if (!LastArgType->isIntegerTy(32))
61 return false;
62
63 // Move this function aside and map down.
Rafael Espindolad7325ee2016-10-03 15:51:42 +000064 rename(F);
Chandler Carruth373b2b12014-09-06 10:00:01 +000065 NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
66 return true;
67}
68
Craig Topperb9b9cb02017-02-17 07:07:19 +000069static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
70 // All of the intrinsics matches below should be marked with which llvm
71 // version started autoupgrading them. At some point in the future we would
72 // like to use this information to remove upgrade code for some older
73 // intrinsics. It is currently undecided how we will determine that future
74 // point.
75 if (Name.startswith("sse2.pcmpeq.") || // Added in 3.1
76 Name.startswith("sse2.pcmpgt.") || // Added in 3.1
77 Name.startswith("avx2.pcmpeq.") || // Added in 3.1
78 Name.startswith("avx2.pcmpgt.") || // Added in 3.1
79 Name.startswith("avx512.mask.pcmpeq.") || // Added in 3.9
80 Name.startswith("avx512.mask.pcmpgt.") || // Added in 3.9
81 Name == "sse.add.ss" || // Added in 4.0
82 Name == "sse2.add.sd" || // Added in 4.0
83 Name == "sse.sub.ss" || // Added in 4.0
84 Name == "sse2.sub.sd" || // Added in 4.0
85 Name == "sse.mul.ss" || // Added in 4.0
86 Name == "sse2.mul.sd" || // Added in 4.0
87 Name == "sse.div.ss" || // Added in 4.0
88 Name == "sse2.div.sd" || // Added in 4.0
89 Name == "sse41.pmaxsb" || // Added in 3.9
90 Name == "sse2.pmaxs.w" || // Added in 3.9
91 Name == "sse41.pmaxsd" || // Added in 3.9
92 Name == "sse2.pmaxu.b" || // Added in 3.9
93 Name == "sse41.pmaxuw" || // Added in 3.9
94 Name == "sse41.pmaxud" || // Added in 3.9
95 Name == "sse41.pminsb" || // Added in 3.9
96 Name == "sse2.pmins.w" || // Added in 3.9
97 Name == "sse41.pminsd" || // Added in 3.9
98 Name == "sse2.pminu.b" || // Added in 3.9
99 Name == "sse41.pminuw" || // Added in 3.9
100 Name == "sse41.pminud" || // Added in 3.9
101 Name.startswith("avx512.mask.pshuf.b.") || // Added in 4.0
102 Name.startswith("avx2.pmax") || // Added in 3.9
103 Name.startswith("avx2.pmin") || // Added in 3.9
104 Name.startswith("avx512.mask.pmax") || // Added in 4.0
105 Name.startswith("avx512.mask.pmin") || // Added in 4.0
106 Name.startswith("avx2.vbroadcast") || // Added in 3.8
107 Name.startswith("avx2.pbroadcast") || // Added in 3.8
108 Name.startswith("avx.vpermil.") || // Added in 3.1
109 Name.startswith("sse2.pshuf") || // Added in 3.9
110 Name.startswith("avx512.pbroadcast") || // Added in 3.9
111 Name.startswith("avx512.mask.broadcast.s") || // Added in 3.9
112 Name.startswith("avx512.mask.movddup") || // Added in 3.9
113 Name.startswith("avx512.mask.movshdup") || // Added in 3.9
114 Name.startswith("avx512.mask.movsldup") || // Added in 3.9
115 Name.startswith("avx512.mask.pshuf.d.") || // Added in 3.9
116 Name.startswith("avx512.mask.pshufl.w.") || // Added in 3.9
117 Name.startswith("avx512.mask.pshufh.w.") || // Added in 3.9
118 Name.startswith("avx512.mask.shuf.p") || // Added in 4.0
119 Name.startswith("avx512.mask.vpermil.p") || // Added in 3.9
120 Name.startswith("avx512.mask.perm.df.") || // Added in 3.9
121 Name.startswith("avx512.mask.perm.di.") || // Added in 3.9
122 Name.startswith("avx512.mask.punpckl") || // Added in 3.9
123 Name.startswith("avx512.mask.punpckh") || // Added in 3.9
124 Name.startswith("avx512.mask.unpckl.") || // Added in 3.9
125 Name.startswith("avx512.mask.unpckh.") || // Added in 3.9
126 Name.startswith("avx512.mask.pand.") || // Added in 3.9
127 Name.startswith("avx512.mask.pandn.") || // Added in 3.9
128 Name.startswith("avx512.mask.por.") || // Added in 3.9
129 Name.startswith("avx512.mask.pxor.") || // Added in 3.9
130 Name.startswith("avx512.mask.and.") || // Added in 3.9
131 Name.startswith("avx512.mask.andn.") || // Added in 3.9
132 Name.startswith("avx512.mask.or.") || // Added in 3.9
133 Name.startswith("avx512.mask.xor.") || // Added in 3.9
134 Name.startswith("avx512.mask.padd.") || // Added in 4.0
135 Name.startswith("avx512.mask.psub.") || // Added in 4.0
136 Name.startswith("avx512.mask.pmull.") || // Added in 4.0
137 Name.startswith("avx512.mask.cvtdq2pd.") || // Added in 4.0
138 Name.startswith("avx512.mask.cvtudq2pd.") || // Added in 4.0
139 Name.startswith("avx512.mask.pmul.dq.") || // Added in 4.0
140 Name.startswith("avx512.mask.pmulu.dq.") || // Added in 4.0
Craig Topperc43f3f32017-02-24 05:35:07 +0000141 Name.startswith("avx512.mask.packsswb.") || // Added in 5.0
142 Name.startswith("avx512.mask.packssdw.") || // Added in 5.0
143 Name.startswith("avx512.mask.packuswb.") || // Added in 5.0
144 Name.startswith("avx512.mask.packusdw.") || // Added in 5.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000145 Name == "avx512.mask.add.pd.128" || // Added in 4.0
146 Name == "avx512.mask.add.pd.256" || // Added in 4.0
147 Name == "avx512.mask.add.ps.128" || // Added in 4.0
148 Name == "avx512.mask.add.ps.256" || // Added in 4.0
149 Name == "avx512.mask.div.pd.128" || // Added in 4.0
150 Name == "avx512.mask.div.pd.256" || // Added in 4.0
151 Name == "avx512.mask.div.ps.128" || // Added in 4.0
152 Name == "avx512.mask.div.ps.256" || // Added in 4.0
153 Name == "avx512.mask.mul.pd.128" || // Added in 4.0
154 Name == "avx512.mask.mul.pd.256" || // Added in 4.0
155 Name == "avx512.mask.mul.ps.128" || // Added in 4.0
156 Name == "avx512.mask.mul.ps.256" || // Added in 4.0
157 Name == "avx512.mask.sub.pd.128" || // Added in 4.0
158 Name == "avx512.mask.sub.pd.256" || // Added in 4.0
159 Name == "avx512.mask.sub.ps.128" || // Added in 4.0
160 Name == "avx512.mask.sub.ps.256" || // Added in 4.0
Craig Topperc43f3f32017-02-24 05:35:07 +0000161 Name == "avx512.mask.max.pd.128" || // Added in 5.0
162 Name == "avx512.mask.max.pd.256" || // Added in 5.0
163 Name == "avx512.mask.max.ps.128" || // Added in 5.0
164 Name == "avx512.mask.max.ps.256" || // Added in 5.0
165 Name == "avx512.mask.min.pd.128" || // Added in 5.0
166 Name == "avx512.mask.min.pd.256" || // Added in 5.0
167 Name == "avx512.mask.min.ps.128" || // Added in 5.0
168 Name == "avx512.mask.min.ps.256" || // Added in 5.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000169 Name.startswith("avx512.mask.vpermilvar.") || // Added in 4.0
170 Name.startswith("avx512.mask.psll.d") || // Added in 4.0
171 Name.startswith("avx512.mask.psll.q") || // Added in 4.0
172 Name.startswith("avx512.mask.psll.w") || // Added in 4.0
173 Name.startswith("avx512.mask.psra.d") || // Added in 4.0
174 Name.startswith("avx512.mask.psra.q") || // Added in 4.0
175 Name.startswith("avx512.mask.psra.w") || // Added in 4.0
176 Name.startswith("avx512.mask.psrl.d") || // Added in 4.0
177 Name.startswith("avx512.mask.psrl.q") || // Added in 4.0
178 Name.startswith("avx512.mask.psrl.w") || // Added in 4.0
179 Name.startswith("avx512.mask.pslli") || // Added in 4.0
180 Name.startswith("avx512.mask.psrai") || // Added in 4.0
181 Name.startswith("avx512.mask.psrli") || // Added in 4.0
182 Name.startswith("avx512.mask.psllv") || // Added in 4.0
183 Name.startswith("avx512.mask.psrav") || // Added in 4.0
184 Name.startswith("avx512.mask.psrlv") || // Added in 4.0
185 Name.startswith("sse41.pmovsx") || // Added in 3.8
186 Name.startswith("sse41.pmovzx") || // Added in 3.9
187 Name.startswith("avx2.pmovsx") || // Added in 3.9
188 Name.startswith("avx2.pmovzx") || // Added in 3.9
189 Name.startswith("avx512.mask.pmovsx") || // Added in 4.0
190 Name.startswith("avx512.mask.pmovzx") || // Added in 4.0
Craig Topperf2529c12017-02-24 05:35:04 +0000191 Name.startswith("avx512.mask.lzcnt.") || // Added in 5.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000192 Name == "sse2.cvtdq2pd" || // Added in 3.9
193 Name == "sse2.cvtps2pd" || // Added in 3.9
194 Name == "avx.cvtdq2.pd.256" || // Added in 3.9
195 Name == "avx.cvt.ps2.pd.256" || // Added in 3.9
196 Name.startswith("avx.vinsertf128.") || // Added in 3.7
197 Name == "avx2.vinserti128" || // Added in 3.7
198 Name.startswith("avx512.mask.insert") || // Added in 4.0
199 Name.startswith("avx.vextractf128.") || // Added in 3.7
200 Name == "avx2.vextracti128" || // Added in 3.7
201 Name.startswith("avx512.mask.vextract") || // Added in 4.0
202 Name.startswith("sse4a.movnt.") || // Added in 3.9
203 Name.startswith("avx.movnt.") || // Added in 3.2
204 Name.startswith("avx512.storent.") || // Added in 3.9
205 Name == "sse2.storel.dq" || // Added in 3.9
206 Name.startswith("sse.storeu.") || // Added in 3.9
207 Name.startswith("sse2.storeu.") || // Added in 3.9
208 Name.startswith("avx.storeu.") || // Added in 3.9
209 Name.startswith("avx512.mask.storeu.") || // Added in 3.9
210 Name.startswith("avx512.mask.store.p") || // Added in 3.9
211 Name.startswith("avx512.mask.store.b.") || // Added in 3.9
212 Name.startswith("avx512.mask.store.w.") || // Added in 3.9
213 Name.startswith("avx512.mask.store.d.") || // Added in 3.9
214 Name.startswith("avx512.mask.store.q.") || // Added in 3.9
215 Name.startswith("avx512.mask.loadu.") || // Added in 3.9
216 Name.startswith("avx512.mask.load.") || // Added in 3.9
217 Name == "sse42.crc32.64.8" || // Added in 3.4
218 Name.startswith("avx.vbroadcast.s") || // Added in 3.5
219 Name.startswith("avx512.mask.palignr.") || // Added in 3.9
220 Name.startswith("avx512.mask.valign.") || // Added in 4.0
221 Name.startswith("sse2.psll.dq") || // Added in 3.7
222 Name.startswith("sse2.psrl.dq") || // Added in 3.7
223 Name.startswith("avx2.psll.dq") || // Added in 3.7
224 Name.startswith("avx2.psrl.dq") || // Added in 3.7
225 Name.startswith("avx512.psll.dq") || // Added in 3.9
226 Name.startswith("avx512.psrl.dq") || // Added in 3.9
227 Name == "sse41.pblendw" || // Added in 3.7
228 Name.startswith("sse41.blendp") || // Added in 3.7
229 Name.startswith("avx.blend.p") || // Added in 3.7
230 Name == "avx2.pblendw" || // Added in 3.7
231 Name.startswith("avx2.pblendd.") || // Added in 3.7
232 Name.startswith("avx.vbroadcastf128") || // Added in 4.0
233 Name == "avx2.vbroadcasti128" || // Added in 3.7
Craig Topper185ced82017-02-23 03:22:14 +0000234 Name == "xop.vpcmov" || // Added in 3.8
Craig Topperc43f3f32017-02-24 05:35:07 +0000235 Name == "xop.vpcmov.256" || // Added in 5.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000236 Name.startswith("avx512.mask.move.s") || // Added in 4.0
Michael Zuckerman88fb1712017-04-04 13:32:14 +0000237 Name.startswith("avx512.cvtmask2") || // Added in 5.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000238 (Name.startswith("xop.vpcom") && // Added in 3.2
239 F->arg_size() == 2))
240 return true;
241
242 return false;
243}
244
245static bool UpgradeX86IntrinsicFunction(Function *F, StringRef Name,
246 Function *&NewFn) {
247 // Only handle intrinsics that start with "x86.".
248 if (!Name.startswith("x86."))
249 return false;
250 // Remove "x86." prefix.
251 Name = Name.substr(4);
252
253 if (ShouldUpgradeX86Intrinsic(F, Name)) {
254 NewFn = nullptr;
255 return true;
256 }
257
258 // SSE4.1 ptest functions may have an old signature.
259 if (Name.startswith("sse41.ptest")) { // Added in 3.2
260 if (Name.substr(11) == "c")
Craig Topper905cc752017-02-17 07:07:21 +0000261 return UpgradePTESTIntrinsic(F, Intrinsic::x86_sse41_ptestc, NewFn);
Craig Topperb9b9cb02017-02-17 07:07:19 +0000262 if (Name.substr(11) == "z")
Craig Topper905cc752017-02-17 07:07:21 +0000263 return UpgradePTESTIntrinsic(F, Intrinsic::x86_sse41_ptestz, NewFn);
Craig Topperb9b9cb02017-02-17 07:07:19 +0000264 if (Name.substr(11) == "nzc")
Craig Topper905cc752017-02-17 07:07:21 +0000265 return UpgradePTESTIntrinsic(F, Intrinsic::x86_sse41_ptestnzc, NewFn);
Craig Topperb9b9cb02017-02-17 07:07:19 +0000266 }
267 // Several blend and other instructions with masks used the wrong number of
268 // bits.
269 if (Name == "sse41.insertps") // Added in 3.6
270 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_sse41_insertps,
271 NewFn);
272 if (Name == "sse41.dppd") // Added in 3.6
273 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_sse41_dppd,
274 NewFn);
275 if (Name == "sse41.dpps") // Added in 3.6
276 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_sse41_dpps,
277 NewFn);
278 if (Name == "sse41.mpsadbw") // Added in 3.6
279 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_sse41_mpsadbw,
280 NewFn);
281 if (Name == "avx.dp.ps.256") // Added in 3.6
282 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_avx_dp_ps_256,
283 NewFn);
284 if (Name == "avx2.mpsadbw") // Added in 3.6
285 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_avx2_mpsadbw,
286 NewFn);
287
288 // frcz.ss/sd may need to have an argument dropped. Added in 3.2
289 if (Name.startswith("xop.vfrcz.ss") && F->arg_size() == 2) {
290 rename(F);
291 NewFn = Intrinsic::getDeclaration(F->getParent(),
292 Intrinsic::x86_xop_vfrcz_ss);
293 return true;
294 }
295 if (Name.startswith("xop.vfrcz.sd") && F->arg_size() == 2) {
296 rename(F);
297 NewFn = Intrinsic::getDeclaration(F->getParent(),
298 Intrinsic::x86_xop_vfrcz_sd);
299 return true;
300 }
301 // Upgrade any XOP PERMIL2 index operand still using a float/double vector.
302 if (Name.startswith("xop.vpermil2")) { // Added in 3.9
Craig Toppercbd1b602017-02-17 07:07:24 +0000303 auto Idx = F->getFunctionType()->getParamType(2);
304 if (Idx->isFPOrFPVectorTy()) {
Craig Topperb9b9cb02017-02-17 07:07:19 +0000305 rename(F);
306 unsigned IdxSize = Idx->getPrimitiveSizeInBits();
307 unsigned EltSize = Idx->getScalarSizeInBits();
308 Intrinsic::ID Permil2ID;
309 if (EltSize == 64 && IdxSize == 128)
310 Permil2ID = Intrinsic::x86_xop_vpermil2pd;
311 else if (EltSize == 32 && IdxSize == 128)
312 Permil2ID = Intrinsic::x86_xop_vpermil2ps;
313 else if (EltSize == 64 && IdxSize == 256)
314 Permil2ID = Intrinsic::x86_xop_vpermil2pd_256;
315 else
316 Permil2ID = Intrinsic::x86_xop_vpermil2ps_256;
317 NewFn = Intrinsic::getDeclaration(F->getParent(), Permil2ID);
318 return true;
319 }
320 }
321
322 return false;
323}
324
Evan Cheng0e179d02007-12-17 22:33:23 +0000325static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
Chandler Carruth7132e002007-08-04 01:51:18 +0000326 assert(F && "Illegal to upgrade a non-existent Function.");
327
Chandler Carruth7132e002007-08-04 01:51:18 +0000328 // Quickly eliminate it, if it's not a candidate.
Eric Liuc9c68172016-07-08 16:09:51 +0000329 StringRef Name = F->getName();
Chris Lattnerb372f662011-06-18 18:56:39 +0000330 if (Name.size() <= 8 || !Name.startswith("llvm."))
Evan Cheng0e179d02007-12-17 22:33:23 +0000331 return false;
Chris Lattnerb372f662011-06-18 18:56:39 +0000332 Name = Name.substr(5); // Strip off "llvm."
Chris Lattner0bcbde42011-11-27 08:42:07 +0000333
Chris Lattnerb372f662011-06-18 18:56:39 +0000334 switch (Name[0]) {
Chandler Carruth7132e002007-08-04 01:51:18 +0000335 default: break;
Joel Jones43cb8782012-07-13 23:25:25 +0000336 case 'a': {
Chad Rosierd0114fc2017-01-10 19:23:51 +0000337 if (Name.startswith("arm.rbit") || Name.startswith("aarch64.rbit")) {
Chad Rosier3daffbf2017-01-10 17:20:33 +0000338 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::bitreverse,
339 F->arg_begin()->getType());
340 return true;
341 }
Joel Jones43cb8782012-07-13 23:25:25 +0000342 if (Name.startswith("arm.neon.vclz")) {
343 Type* args[2] = {
Matt Arsenaultc4c92262013-07-20 17:46:00 +0000344 F->arg_begin()->getType(),
Joel Jones43cb8782012-07-13 23:25:25 +0000345 Type::getInt1Ty(F->getContext())
346 };
347 // Can't use Intrinsic::getDeclaration here as it adds a ".i1" to
348 // the end of the name. Change name from llvm.arm.neon.vclz.* to
349 // llvm.ctlz.*
350 FunctionType* fType = FunctionType::get(F->getReturnType(), args, false);
Matt Arsenaultc4c92262013-07-20 17:46:00 +0000351 NewFn = Function::Create(fType, F->getLinkage(),
Joel Jones43cb8782012-07-13 23:25:25 +0000352 "llvm.ctlz." + Name.substr(14), F->getParent());
353 return true;
354 }
Joel Jonesb84f7be2012-07-18 00:02:16 +0000355 if (Name.startswith("arm.neon.vcnt")) {
356 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctpop,
357 F->arg_begin()->getType());
358 return true;
359 }
Jeroen Ketemaab99b592015-09-30 10:56:37 +0000360 Regex vldRegex("^arm\\.neon\\.vld([1234]|[234]lane)\\.v[a-z0-9]*$");
361 if (vldRegex.match(Name)) {
362 auto fArgs = F->getFunctionType()->params();
363 SmallVector<Type *, 4> Tys(fArgs.begin(), fArgs.end());
364 // Can't use Intrinsic::getDeclaration here as the return types might
365 // then only be structurally equal.
366 FunctionType* fType = FunctionType::get(F->getReturnType(), Tys, false);
367 NewFn = Function::Create(fType, F->getLinkage(),
368 "llvm." + Name + ".p0i8", F->getParent());
369 return true;
370 }
371 Regex vstRegex("^arm\\.neon\\.vst([1234]|[234]lane)\\.v[a-z0-9]*$");
372 if (vstRegex.match(Name)) {
Craig Topper26260942015-10-18 05:15:34 +0000373 static const Intrinsic::ID StoreInts[] = {Intrinsic::arm_neon_vst1,
374 Intrinsic::arm_neon_vst2,
375 Intrinsic::arm_neon_vst3,
376 Intrinsic::arm_neon_vst4};
Jeroen Ketemaab99b592015-09-30 10:56:37 +0000377
Craig Topper26260942015-10-18 05:15:34 +0000378 static const Intrinsic::ID StoreLaneInts[] = {
379 Intrinsic::arm_neon_vst2lane, Intrinsic::arm_neon_vst3lane,
380 Intrinsic::arm_neon_vst4lane
381 };
Jeroen Ketemaab99b592015-09-30 10:56:37 +0000382
383 auto fArgs = F->getFunctionType()->params();
384 Type *Tys[] = {fArgs[0], fArgs[1]};
385 if (Name.find("lane") == StringRef::npos)
386 NewFn = Intrinsic::getDeclaration(F->getParent(),
387 StoreInts[fArgs.size() - 3], Tys);
388 else
389 NewFn = Intrinsic::getDeclaration(F->getParent(),
390 StoreLaneInts[fArgs.size() - 5], Tys);
391 return true;
392 }
Marcin Koscielnicki3fdc2572016-04-19 20:51:05 +0000393 if (Name == "aarch64.thread.pointer" || Name == "arm.thread.pointer") {
394 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::thread_pointer);
395 return true;
396 }
Joel Jones43cb8782012-07-13 23:25:25 +0000397 break;
398 }
Jeroen Ketemaab99b592015-09-30 10:56:37 +0000399
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000400 case 'c': {
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000401 if (Name.startswith("ctlz.") && F->arg_size() == 1) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000402 rename(F);
Chandler Carruthd4a02402011-12-12 10:57:20 +0000403 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
404 F->arg_begin()->getType());
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000405 return true;
406 }
407 if (Name.startswith("cttz.") && F->arg_size() == 1) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000408 rename(F);
Chandler Carruthd4a02402011-12-12 10:57:20 +0000409 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
410 F->arg_begin()->getType());
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000411 return true;
412 }
413 break;
414 }
Mehdi Amini8c629ec2016-08-13 23:31:24 +0000415 case 'i': {
416 if (Name.startswith("invariant.start")) {
417 auto Args = F->getFunctionType()->params();
418 Type* ObjectPtr[1] = {Args[1]};
419 if (F->getName() !=
420 Intrinsic::getName(Intrinsic::invariant_start, ObjectPtr)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000421 rename(F);
Mehdi Amini8c629ec2016-08-13 23:31:24 +0000422 NewFn = Intrinsic::getDeclaration(
423 F->getParent(), Intrinsic::invariant_start, ObjectPtr);
424 return true;
425 }
426 }
427 if (Name.startswith("invariant.end")) {
428 auto Args = F->getFunctionType()->params();
429 Type* ObjectPtr[1] = {Args[2]};
430 if (F->getName() !=
431 Intrinsic::getName(Intrinsic::invariant_end, ObjectPtr)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000432 rename(F);
Mehdi Amini8c629ec2016-08-13 23:31:24 +0000433 NewFn = Intrinsic::getDeclaration(F->getParent(),
434 Intrinsic::invariant_end, ObjectPtr);
435 return true;
436 }
437 }
438 break;
439 }
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000440 case 'm': {
441 if (Name.startswith("masked.load.")) {
442 Type *Tys[] = { F->getReturnType(), F->arg_begin()->getType() };
443 if (F->getName() != Intrinsic::getName(Intrinsic::masked_load, Tys)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000444 rename(F);
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000445 NewFn = Intrinsic::getDeclaration(F->getParent(),
446 Intrinsic::masked_load,
447 Tys);
448 return true;
449 }
450 }
451 if (Name.startswith("masked.store.")) {
452 auto Args = F->getFunctionType()->params();
453 Type *Tys[] = { Args[0], Args[1] };
454 if (F->getName() != Intrinsic::getName(Intrinsic::masked_store, Tys)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000455 rename(F);
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000456 NewFn = Intrinsic::getDeclaration(F->getParent(),
457 Intrinsic::masked_store,
458 Tys);
459 return true;
460 }
461 }
462 break;
463 }
Justin Lebar46624a82017-01-21 01:00:32 +0000464 case 'n': {
465 if (Name.startswith("nvvm.")) {
466 Name = Name.substr(5);
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000467
Justin Lebar46624a82017-01-21 01:00:32 +0000468 // The following nvvm intrinsics correspond exactly to an LLVM intrinsic.
469 Intrinsic::ID IID = StringSwitch<Intrinsic::ID>(Name)
470 .Cases("brev32", "brev64", Intrinsic::bitreverse)
471 .Case("clz.i", Intrinsic::ctlz)
472 .Case("popc.i", Intrinsic::ctpop)
473 .Default(Intrinsic::not_intrinsic);
474 if (IID != Intrinsic::not_intrinsic && F->arg_size() == 1) {
475 NewFn = Intrinsic::getDeclaration(F->getParent(), IID,
476 {F->getReturnType()});
477 return true;
478 }
479
480 // The following nvvm intrinsics correspond exactly to an LLVM idiom, but
481 // not to an intrinsic alone. We expand them in UpgradeIntrinsicCall.
482 //
483 // TODO: We could add lohi.i2d.
484 bool Expand = StringSwitch<bool>(Name)
485 .Cases("abs.i", "abs.ll", true)
486 .Cases("clz.ll", "popc.ll", "h2f", true)
487 .Cases("max.i", "max.ll", "max.ui", "max.ull", true)
488 .Cases("min.i", "min.ll", "min.ui", "min.ull", true)
489 .Default(false);
490 if (Expand) {
491 NewFn = nullptr;
492 return true;
493 }
494 }
495 }
Matt Arsenaultfbcbce42013-10-07 18:06:48 +0000496 case 'o':
497 // We only need to change the name to match the mangling including the
498 // address space.
George Burgess IV56c7e882017-03-21 20:08:59 +0000499 if (Name.startswith("objectsize.")) {
Matt Arsenaultfbcbce42013-10-07 18:06:48 +0000500 Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() };
George Burgess IV56c7e882017-03-21 20:08:59 +0000501 if (F->arg_size() == 2 ||
502 F->getName() != Intrinsic::getName(Intrinsic::objectsize, Tys)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000503 rename(F);
George Burgess IV56c7e882017-03-21 20:08:59 +0000504 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::objectsize,
505 Tys);
Matt Arsenaultfbcbce42013-10-07 18:06:48 +0000506 return true;
507 }
508 }
509 break;
510
Tim Shen00127562016-04-08 21:26:31 +0000511 case 's':
512 if (Name == "stackprotectorcheck") {
513 NewFn = nullptr;
514 return true;
515 }
George Burgess IV63b06e12016-11-08 04:01:50 +0000516 break;
Tim Shen00127562016-04-08 21:26:31 +0000517
Craig Topperb9b9cb02017-02-17 07:07:19 +0000518 case 'x':
519 if (UpgradeX86IntrinsicFunction(F, Name, NewFn))
Craig Topper3b1817d2012-02-03 06:10:55 +0000520 return true;
Chris Lattnerb372f662011-06-18 18:56:39 +0000521 }
Daniel Berlin3c1432f2017-02-15 23:16:20 +0000522 // Remangle our intrinsic since we upgrade the mangling
523 auto Result = llvm::Intrinsic::remangleIntrinsicFunction(F);
524 if (Result != None) {
525 NewFn = Result.getValue();
526 return true;
527 }
Chandler Carruth7132e002007-08-04 01:51:18 +0000528
Nadav Rotem17ee58a2012-06-10 18:42:51 +0000529 // This may not belong here. This function is effectively being overloaded
530 // to both detect an intrinsic which needs upgrading, and to provide the
531 // upgraded form of the intrinsic. We should perhaps have two separate
Chandler Carruth7132e002007-08-04 01:51:18 +0000532 // functions for this.
Evan Cheng0e179d02007-12-17 22:33:23 +0000533 return false;
Chandler Carruth7132e002007-08-04 01:51:18 +0000534}
535
Evan Cheng0e179d02007-12-17 22:33:23 +0000536bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
Craig Topperc6207612014-04-09 06:08:46 +0000537 NewFn = nullptr;
Evan Cheng0e179d02007-12-17 22:33:23 +0000538 bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
Filipe Cabecinhas0011c582015-07-03 20:12:01 +0000539 assert(F != NewFn && "Intrinsic function upgraded to the same function");
Duncan Sands38ef3a82007-12-03 20:06:50 +0000540
541 // Upgrade intrinsic attributes. This does not change the function.
Evan Cheng0e179d02007-12-17 22:33:23 +0000542 if (NewFn)
543 F = NewFn;
Pete Cooper9e1d3352015-05-20 17:16:39 +0000544 if (Intrinsic::ID id = F->getIntrinsicID())
545 F->setAttributes(Intrinsic::getAttributes(F->getContext(), id));
Duncan Sands38ef3a82007-12-03 20:06:50 +0000546 return Upgraded;
547}
548
Bill Wendlinge26fffc2010-09-10 18:51:56 +0000549bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
Chris Lattner80ed9dc2011-06-18 06:05:24 +0000550 // Nothing to do yet.
Bill Wendlinge26fffc2010-09-10 18:51:56 +0000551 return false;
552}
553
Simon Pilgrimf7186822016-06-09 21:09:03 +0000554// Handles upgrading SSE2/AVX2/AVX512BW PSLLDQ intrinsics by converting them
Craig Topperb324e432015-02-18 06:24:44 +0000555// to byte shuffles.
Craig Topper46b34fe2016-07-12 01:42:33 +0000556static Value *UpgradeX86PSLLDQIntrinsics(IRBuilder<> &Builder,
Craig Topper7355ac32016-05-29 06:37:33 +0000557 Value *Op, unsigned Shift) {
558 Type *ResultTy = Op->getType();
559 unsigned NumElts = ResultTy->getVectorNumElements() * 8;
Craig Topperb324e432015-02-18 06:24:44 +0000560
561 // Bitcast from a 64-bit element type to a byte element type.
Craig Topper46b34fe2016-07-12 01:42:33 +0000562 Type *VecTy = VectorType::get(Builder.getInt8Ty(), NumElts);
Craig Topper7355ac32016-05-29 06:37:33 +0000563 Op = Builder.CreateBitCast(Op, VecTy, "cast");
564
Craig Topperb324e432015-02-18 06:24:44 +0000565 // We'll be shuffling in zeroes.
Craig Topper7355ac32016-05-29 06:37:33 +0000566 Value *Res = Constant::getNullValue(VecTy);
Craig Topperb324e432015-02-18 06:24:44 +0000567
568 // If shift is less than 16, emit a shuffle to move the bytes. Otherwise,
569 // we'll just return the zero vector.
570 if (Shift < 16) {
Craig Topper99d1eab2016-06-12 00:41:19 +0000571 uint32_t Idxs[64];
Simon Pilgrimf7186822016-06-09 21:09:03 +0000572 // 256/512-bit version is split into 2/4 16-byte lanes.
Craig Topperb324e432015-02-18 06:24:44 +0000573 for (unsigned l = 0; l != NumElts; l += 16)
574 for (unsigned i = 0; i != 16; ++i) {
575 unsigned Idx = NumElts + i - Shift;
576 if (Idx < NumElts)
577 Idx -= NumElts - 16; // end of lane, switch operand.
Craig Topper7355ac32016-05-29 06:37:33 +0000578 Idxs[l + i] = Idx + l;
Craig Topperb324e432015-02-18 06:24:44 +0000579 }
580
Craig Topper7355ac32016-05-29 06:37:33 +0000581 Res = Builder.CreateShuffleVector(Res, Op, makeArrayRef(Idxs, NumElts));
Craig Topperb324e432015-02-18 06:24:44 +0000582 }
583
584 // Bitcast back to a 64-bit element type.
Craig Topper7355ac32016-05-29 06:37:33 +0000585 return Builder.CreateBitCast(Res, ResultTy, "cast");
Craig Topperb324e432015-02-18 06:24:44 +0000586}
587
Craig Topperea703ae2016-06-13 02:36:42 +0000588// Handles upgrading SSE2/AVX2/AVX512BW PSRLDQ intrinsics by converting them
589// to byte shuffles.
Craig Topper46b34fe2016-07-12 01:42:33 +0000590static Value *UpgradeX86PSRLDQIntrinsics(IRBuilder<> &Builder, Value *Op,
Craig Topperea703ae2016-06-13 02:36:42 +0000591 unsigned Shift) {
592 Type *ResultTy = Op->getType();
593 unsigned NumElts = ResultTy->getVectorNumElements() * 8;
594
595 // Bitcast from a 64-bit element type to a byte element type.
Craig Topper46b34fe2016-07-12 01:42:33 +0000596 Type *VecTy = VectorType::get(Builder.getInt8Ty(), NumElts);
Craig Topperea703ae2016-06-13 02:36:42 +0000597 Op = Builder.CreateBitCast(Op, VecTy, "cast");
598
599 // We'll be shuffling in zeroes.
600 Value *Res = Constant::getNullValue(VecTy);
601
602 // If shift is less than 16, emit a shuffle to move the bytes. Otherwise,
603 // we'll just return the zero vector.
604 if (Shift < 16) {
605 uint32_t Idxs[64];
606 // 256/512-bit version is split into 2/4 16-byte lanes.
607 for (unsigned l = 0; l != NumElts; l += 16)
608 for (unsigned i = 0; i != 16; ++i) {
609 unsigned Idx = i + Shift;
610 if (Idx >= 16)
611 Idx += NumElts - 16; // end of lane, switch operand.
612 Idxs[l + i] = Idx + l;
613 }
614
615 Res = Builder.CreateShuffleVector(Op, Res, makeArrayRef(Idxs, NumElts));
616 }
617
618 // Bitcast back to a 64-bit element type.
619 return Builder.CreateBitCast(Res, ResultTy, "cast");
620}
621
622static Value *getX86MaskVec(IRBuilder<> &Builder, Value *Mask,
623 unsigned NumElts) {
624 llvm::VectorType *MaskTy = llvm::VectorType::get(Builder.getInt1Ty(),
625 cast<IntegerType>(Mask->getType())->getBitWidth());
626 Mask = Builder.CreateBitCast(Mask, MaskTy);
627
628 // If we have less than 8 elements, then the starting mask was an i8 and
629 // we need to extract down to the right number of elements.
630 if (NumElts < 8) {
631 uint32_t Indices[4];
632 for (unsigned i = 0; i != NumElts; ++i)
633 Indices[i] = i;
634 Mask = Builder.CreateShuffleVector(Mask, Mask,
635 makeArrayRef(Indices, NumElts),
636 "extract");
637 }
638
639 return Mask;
640}
641
642static Value *EmitX86Select(IRBuilder<> &Builder, Value *Mask,
643 Value *Op0, Value *Op1) {
644 // If the mask is all ones just emit the align operation.
645 if (const auto *C = dyn_cast<Constant>(Mask))
646 if (C->isAllOnesValue())
647 return Op0;
648
649 Mask = getX86MaskVec(Builder, Mask, Op0->getType()->getVectorNumElements());
650 return Builder.CreateSelect(Mask, Op0, Op1);
651}
652
Craig Topperf57e17d2016-11-23 06:54:55 +0000653// Handle autoupgrade for masked PALIGNR and VALIGND/Q intrinsics.
654// PALIGNR handles large immediates by shifting while VALIGN masks the immediate
655// so we need to handle both cases. VALIGN also doesn't have 128-bit lanes.
656static Value *UpgradeX86ALIGNIntrinsics(IRBuilder<> &Builder, Value *Op0,
657 Value *Op1, Value *Shift,
658 Value *Passthru, Value *Mask,
659 bool IsVALIGN) {
Craig Topper33350cc2016-06-06 06:12:54 +0000660 unsigned ShiftVal = cast<llvm::ConstantInt>(Shift)->getZExtValue();
661
662 unsigned NumElts = Op0->getType()->getVectorNumElements();
Craig Topperf57e17d2016-11-23 06:54:55 +0000663 assert((IsVALIGN || NumElts % 16 == 0) && "Illegal NumElts for PALIGNR!");
664 assert((!IsVALIGN || NumElts <= 16) && "NumElts too large for VALIGN!");
665 assert(isPowerOf2_32(NumElts) && "NumElts not a power of 2!");
666
667 // Mask the immediate for VALIGN.
668 if (IsVALIGN)
669 ShiftVal &= (NumElts - 1);
Craig Topper33350cc2016-06-06 06:12:54 +0000670
671 // If palignr is shifting the pair of vectors more than the size of two
672 // lanes, emit zero.
673 if (ShiftVal >= 32)
674 return llvm::Constant::getNullValue(Op0->getType());
675
676 // If palignr is shifting the pair of input vectors more than one lane,
677 // but less than two lanes, convert to shifting in zeroes.
678 if (ShiftVal > 16) {
679 ShiftVal -= 16;
680 Op1 = Op0;
681 Op0 = llvm::Constant::getNullValue(Op0->getType());
682 }
683
Craig Topper99d1eab2016-06-12 00:41:19 +0000684 uint32_t Indices[64];
Craig Topper33350cc2016-06-06 06:12:54 +0000685 // 256-bit palignr operates on 128-bit lanes so we need to handle that
Craig Topperf57e17d2016-11-23 06:54:55 +0000686 for (unsigned l = 0; l < NumElts; l += 16) {
Craig Topper33350cc2016-06-06 06:12:54 +0000687 for (unsigned i = 0; i != 16; ++i) {
688 unsigned Idx = ShiftVal + i;
Craig Topperf57e17d2016-11-23 06:54:55 +0000689 if (!IsVALIGN && Idx >= 16) // Disable wrap for VALIGN.
Craig Topper33350cc2016-06-06 06:12:54 +0000690 Idx += NumElts - 16; // End of lane, switch operand.
691 Indices[l + i] = Idx + l;
692 }
693 }
694
695 Value *Align = Builder.CreateShuffleVector(Op1, Op0,
696 makeArrayRef(Indices, NumElts),
697 "palignr");
698
Craig Topperea703ae2016-06-13 02:36:42 +0000699 return EmitX86Select(Builder, Mask, Align, Passthru);
Craig Topperb324e432015-02-18 06:24:44 +0000700}
701
Craig Topper46b34fe2016-07-12 01:42:33 +0000702static Value *UpgradeMaskedStore(IRBuilder<> &Builder,
Craig Topper50f85c22016-05-31 01:50:02 +0000703 Value *Ptr, Value *Data, Value *Mask,
704 bool Aligned) {
705 // Cast the pointer to the right type.
706 Ptr = Builder.CreateBitCast(Ptr,
707 llvm::PointerType::getUnqual(Data->getType()));
708 unsigned Align =
709 Aligned ? cast<VectorType>(Data->getType())->getBitWidth() / 8 : 1;
710
711 // If the mask is all ones just emit a regular store.
712 if (const auto *C = dyn_cast<Constant>(Mask))
713 if (C->isAllOnesValue())
714 return Builder.CreateAlignedStore(Data, Ptr, Align);
715
716 // Convert the mask from an integer type to a vector of i1.
717 unsigned NumElts = Data->getType()->getVectorNumElements();
Craig Topperea703ae2016-06-13 02:36:42 +0000718 Mask = getX86MaskVec(Builder, Mask, NumElts);
Craig Topper50f85c22016-05-31 01:50:02 +0000719 return Builder.CreateMaskedStore(Data, Ptr, Align, Mask);
720}
721
Craig Topper46b34fe2016-07-12 01:42:33 +0000722static Value *UpgradeMaskedLoad(IRBuilder<> &Builder,
Craig Topperf10fbfa2016-06-02 04:19:36 +0000723 Value *Ptr, Value *Passthru, Value *Mask,
724 bool Aligned) {
725 // Cast the pointer to the right type.
726 Ptr = Builder.CreateBitCast(Ptr,
727 llvm::PointerType::getUnqual(Passthru->getType()));
728 unsigned Align =
729 Aligned ? cast<VectorType>(Passthru->getType())->getBitWidth() / 8 : 1;
730
731 // If the mask is all ones just emit a regular store.
732 if (const auto *C = dyn_cast<Constant>(Mask))
733 if (C->isAllOnesValue())
734 return Builder.CreateAlignedLoad(Ptr, Align);
735
736 // Convert the mask from an integer type to a vector of i1.
737 unsigned NumElts = Passthru->getType()->getVectorNumElements();
Craig Topperea703ae2016-06-13 02:36:42 +0000738 Mask = getX86MaskVec(Builder, Mask, NumElts);
Craig Topperf10fbfa2016-06-02 04:19:36 +0000739 return Builder.CreateMaskedLoad(Ptr, Align, Mask, Passthru);
740}
741
Sanjay Patel51ab7572016-06-16 15:48:30 +0000742static Value *upgradeIntMinMax(IRBuilder<> &Builder, CallInst &CI,
743 ICmpInst::Predicate Pred) {
744 Value *Op0 = CI.getArgOperand(0);
745 Value *Op1 = CI.getArgOperand(1);
746 Value *Cmp = Builder.CreateICmp(Pred, Op0, Op1);
Craig Topper8ec5c732016-10-24 04:04:16 +0000747 Value *Res = Builder.CreateSelect(Cmp, Op0, Op1);
748
749 if (CI.getNumArgOperands() == 4)
750 Res = EmitX86Select(Builder, CI.getArgOperand(3), Res, CI.getArgOperand(2));
751
752 return Res;
Sanjay Patel51ab7572016-06-16 15:48:30 +0000753}
754
Craig Topper0a0fb0f2016-06-21 03:53:24 +0000755static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallInst &CI,
756 ICmpInst::Predicate Pred) {
757 Value *Op0 = CI.getArgOperand(0);
758 unsigned NumElts = Op0->getType()->getVectorNumElements();
759 Value *Cmp = Builder.CreateICmp(Pred, Op0, CI.getArgOperand(1));
760
761 Value *Mask = CI.getArgOperand(2);
762 const auto *C = dyn_cast<Constant>(Mask);
763 if (!C || !C->isAllOnesValue())
764 Cmp = Builder.CreateAnd(Cmp, getX86MaskVec(Builder, Mask, NumElts));
765
766 if (NumElts < 8) {
767 uint32_t Indices[8];
768 for (unsigned i = 0; i != NumElts; ++i)
769 Indices[i] = i;
770 for (unsigned i = NumElts; i != 8; ++i)
Craig Topperd5d2a352016-07-07 06:11:07 +0000771 Indices[i] = NumElts + i % NumElts;
772 Cmp = Builder.CreateShuffleVector(Cmp,
773 Constant::getNullValue(Cmp->getType()),
Craig Topper0a0fb0f2016-06-21 03:53:24 +0000774 Indices);
775 }
776 return Builder.CreateBitCast(Cmp, IntegerType::get(CI.getContext(),
777 std::max(NumElts, 8U)));
778}
779
Craig Topperc9467ed2016-11-06 16:29:08 +0000780// Replace a masked intrinsic with an older unmasked intrinsic.
781static Value *UpgradeX86MaskedShift(IRBuilder<> &Builder, CallInst &CI,
782 Intrinsic::ID IID) {
783 Function *F = CI.getCalledFunction();
784 Function *Intrin = Intrinsic::getDeclaration(F->getParent(), IID);
785 Value *Rep = Builder.CreateCall(Intrin,
786 { CI.getArgOperand(0), CI.getArgOperand(1) });
787 return EmitX86Select(Builder, CI.getArgOperand(3), Rep, CI.getArgOperand(2));
788}
789
Ayman Musa4d602432016-11-16 09:00:28 +0000790static Value* upgradeMaskedMove(IRBuilder<> &Builder, CallInst &CI) {
791 Value* A = CI.getArgOperand(0);
792 Value* B = CI.getArgOperand(1);
793 Value* Src = CI.getArgOperand(2);
794 Value* Mask = CI.getArgOperand(3);
795
796 Value* AndNode = Builder.CreateAnd(Mask, APInt(8, 1));
797 Value* Cmp = Builder.CreateIsNotNull(AndNode);
798 Value* Extract1 = Builder.CreateExtractElement(B, (uint64_t)0);
799 Value* Extract2 = Builder.CreateExtractElement(Src, (uint64_t)0);
800 Value* Select = Builder.CreateSelect(Cmp, Extract1, Extract2);
801 return Builder.CreateInsertElement(A, Select, (uint64_t)0);
802}
Craig Topperc9467ed2016-11-06 16:29:08 +0000803
Michael Zuckerman88fb1712017-04-04 13:32:14 +0000804
805static Value* UpgradeMaskToInt(IRBuilder<> &Builder, CallInst &CI) {
806 Value* Op = CI.getArgOperand(0);
807 Type* ReturnOp = CI.getType();
808 unsigned NumElts = CI.getType()->getVectorNumElements();
809 Value *Mask = getX86MaskVec(Builder, Op, NumElts);
810 return Builder.CreateSExt(Mask, ReturnOp, "vpmovm2");
811}
812
Sanjay Patel595098f2016-06-15 22:01:28 +0000813/// Upgrade a call to an old intrinsic. All argument and return casting must be
814/// provided to seamlessly integrate with existing context.
Chandler Carruth7132e002007-08-04 01:51:18 +0000815void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Craig Topper3b1817d2012-02-03 06:10:55 +0000816 Function *F = CI->getCalledFunction();
Nick Lewycky2eb3ade2011-12-12 22:59:34 +0000817 LLVMContext &C = CI->getContext();
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000818 IRBuilder<> Builder(C);
Duncan P. N. Exon Smith52888a62015-10-08 23:49:46 +0000819 Builder.SetInsertPoint(CI->getParent(), CI->getIterator());
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000820
Craig Topper3b1817d2012-02-03 06:10:55 +0000821 assert(F && "Intrinsic call is not direct?");
822
823 if (!NewFn) {
824 // Get the Function's name.
825 StringRef Name = F->getName();
826
Craig Topper5aebb862016-07-04 20:56:38 +0000827 assert(Name.startswith("llvm.") && "Intrinsic doesn't start with 'llvm.'");
828 Name = Name.substr(5);
829
830 bool IsX86 = Name.startswith("x86.");
831 if (IsX86)
832 Name = Name.substr(4);
Justin Lebar46624a82017-01-21 01:00:32 +0000833 bool IsNVVM = Name.startswith("nvvm.");
834 if (IsNVVM)
835 Name = Name.substr(5);
Craig Topper5aebb862016-07-04 20:56:38 +0000836
Craig Toppera4744d12016-12-10 21:15:48 +0000837 if (IsX86 && Name.startswith("sse4a.movnt.")) {
838 Module *M = F->getParent();
839 SmallVector<Metadata *, 1> Elts;
840 Elts.push_back(
841 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1)));
842 MDNode *Node = MDNode::get(C, Elts);
843
844 Value *Arg0 = CI->getArgOperand(0);
845 Value *Arg1 = CI->getArgOperand(1);
846
847 // Nontemporal (unaligned) store of the 0'th element of the float/double
848 // vector.
849 Type *SrcEltTy = cast<VectorType>(Arg1->getType())->getElementType();
850 PointerType *EltPtrTy = PointerType::getUnqual(SrcEltTy);
851 Value *Addr = Builder.CreateBitCast(Arg0, EltPtrTy, "cast");
852 Value *Extract =
853 Builder.CreateExtractElement(Arg1, (uint64_t)0, "extractelement");
854
855 StoreInst *SI = Builder.CreateAlignedStore(Extract, Addr, 1);
856 SI->setMetadata(M->getMDKindID("nontemporal"), Node);
857
858 // Remove intrinsic.
859 CI->eraseFromParent();
860 return;
861 }
862
863 if (IsX86 && (Name.startswith("avx.movnt.") ||
864 Name.startswith("avx512.storent."))) {
865 Module *M = F->getParent();
866 SmallVector<Metadata *, 1> Elts;
867 Elts.push_back(
868 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1)));
869 MDNode *Node = MDNode::get(C, Elts);
870
871 Value *Arg0 = CI->getArgOperand(0);
872 Value *Arg1 = CI->getArgOperand(1);
873
874 // Convert the type of the pointer to a pointer to the stored type.
875 Value *BC = Builder.CreateBitCast(Arg0,
876 PointerType::getUnqual(Arg1->getType()),
877 "cast");
878 VectorType *VTy = cast<VectorType>(Arg1->getType());
879 StoreInst *SI = Builder.CreateAlignedStore(Arg1, BC,
880 VTy->getBitWidth() / 8);
881 SI->setMetadata(M->getMDKindID("nontemporal"), Node);
882
883 // Remove intrinsic.
884 CI->eraseFromParent();
885 return;
886 }
887
888 if (IsX86 && Name == "sse2.storel.dq") {
889 Value *Arg0 = CI->getArgOperand(0);
890 Value *Arg1 = CI->getArgOperand(1);
891
892 Type *NewVecTy = VectorType::get(Type::getInt64Ty(C), 2);
893 Value *BC0 = Builder.CreateBitCast(Arg1, NewVecTy, "cast");
894 Value *Elt = Builder.CreateExtractElement(BC0, (uint64_t)0);
895 Value *BC = Builder.CreateBitCast(Arg0,
896 PointerType::getUnqual(Elt->getType()),
897 "cast");
898 Builder.CreateAlignedStore(Elt, BC, 1);
899
900 // Remove intrinsic.
901 CI->eraseFromParent();
902 return;
903 }
904
905 if (IsX86 && (Name.startswith("sse.storeu.") ||
906 Name.startswith("sse2.storeu.") ||
907 Name.startswith("avx.storeu."))) {
908 Value *Arg0 = CI->getArgOperand(0);
909 Value *Arg1 = CI->getArgOperand(1);
910
911 Arg0 = Builder.CreateBitCast(Arg0,
912 PointerType::getUnqual(Arg1->getType()),
913 "cast");
914 Builder.CreateAlignedStore(Arg1, Arg0, 1);
915
916 // Remove intrinsic.
917 CI->eraseFromParent();
918 return;
919 }
920
Craig Topperaa49f142017-02-18 19:51:14 +0000921 if (IsX86 && (Name.startswith("avx512.mask.store"))) {
922 // "avx512.mask.storeu." or "avx512.mask.store."
923 bool Aligned = Name[17] != 'u'; // "avx512.mask.storeu".
Craig Toppera4744d12016-12-10 21:15:48 +0000924 UpgradeMaskedStore(Builder, CI->getArgOperand(0), CI->getArgOperand(1),
Craig Topperaa49f142017-02-18 19:51:14 +0000925 CI->getArgOperand(2), Aligned);
Craig Toppera4744d12016-12-10 21:15:48 +0000926
927 // Remove intrinsic.
928 CI->eraseFromParent();
929 return;
930 }
931
Craig Topper3b1817d2012-02-03 06:10:55 +0000932 Value *Rep;
Sanjay Patel595098f2016-06-15 22:01:28 +0000933 // Upgrade packed integer vector compare intrinsics to compare instructions.
Craig Topperaa49f142017-02-18 19:51:14 +0000934 if (IsX86 && (Name.startswith("sse2.pcmp") ||
935 Name.startswith("avx2.pcmp"))) {
936 // "sse2.pcpmpeq." "sse2.pcmpgt." "avx2.pcmpeq." or "avx2.pcmpgt."
937 bool CmpEq = Name[9] == 'e';
938 Rep = Builder.CreateICmp(CmpEq ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_SGT,
939 CI->getArgOperand(0), CI->getArgOperand(1));
Craig Topper3b1817d2012-02-03 06:10:55 +0000940 Rep = Builder.CreateSExt(Rep, CI->getType(), "");
Craig Topper6910fa02016-11-16 05:24:10 +0000941 } else if (IsX86 && (Name == "sse.add.ss" || Name == "sse2.add.sd")) {
942 Type *I32Ty = Type::getInt32Ty(C);
943 Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0),
944 ConstantInt::get(I32Ty, 0));
945 Value *Elt1 = Builder.CreateExtractElement(CI->getArgOperand(1),
946 ConstantInt::get(I32Ty, 0));
947 Rep = Builder.CreateInsertElement(CI->getArgOperand(0),
948 Builder.CreateFAdd(Elt0, Elt1),
949 ConstantInt::get(I32Ty, 0));
950 } else if (IsX86 && (Name == "sse.sub.ss" || Name == "sse2.sub.sd")) {
951 Type *I32Ty = Type::getInt32Ty(C);
952 Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0),
953 ConstantInt::get(I32Ty, 0));
954 Value *Elt1 = Builder.CreateExtractElement(CI->getArgOperand(1),
955 ConstantInt::get(I32Ty, 0));
956 Rep = Builder.CreateInsertElement(CI->getArgOperand(0),
957 Builder.CreateFSub(Elt0, Elt1),
958 ConstantInt::get(I32Ty, 0));
959 } else if (IsX86 && (Name == "sse.mul.ss" || Name == "sse2.mul.sd")) {
960 Type *I32Ty = Type::getInt32Ty(C);
961 Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0),
962 ConstantInt::get(I32Ty, 0));
963 Value *Elt1 = Builder.CreateExtractElement(CI->getArgOperand(1),
964 ConstantInt::get(I32Ty, 0));
965 Rep = Builder.CreateInsertElement(CI->getArgOperand(0),
966 Builder.CreateFMul(Elt0, Elt1),
967 ConstantInt::get(I32Ty, 0));
968 } else if (IsX86 && (Name == "sse.div.ss" || Name == "sse2.div.sd")) {
969 Type *I32Ty = Type::getInt32Ty(C);
970 Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0),
971 ConstantInt::get(I32Ty, 0));
972 Value *Elt1 = Builder.CreateExtractElement(CI->getArgOperand(1),
973 ConstantInt::get(I32Ty, 0));
974 Rep = Builder.CreateInsertElement(CI->getArgOperand(0),
975 Builder.CreateFDiv(Elt0, Elt1),
976 ConstantInt::get(I32Ty, 0));
Craig Topperaa49f142017-02-18 19:51:14 +0000977 } else if (IsX86 && Name.startswith("avx512.mask.pcmp")) {
978 // "avx512.mask.pcmpeq." or "avx512.mask.pcmpgt."
979 bool CmpEq = Name[16] == 'e';
980 Rep = upgradeMaskedCompare(Builder, *CI,
981 CmpEq ? ICmpInst::ICMP_EQ
982 : ICmpInst::ICMP_SGT);
Craig Topper5aebb862016-07-04 20:56:38 +0000983 } else if (IsX86 && (Name == "sse41.pmaxsb" ||
984 Name == "sse2.pmaxs.w" ||
985 Name == "sse41.pmaxsd" ||
Craig Topper8ec5c732016-10-24 04:04:16 +0000986 Name.startswith("avx2.pmaxs") ||
987 Name.startswith("avx512.mask.pmaxs"))) {
Sanjay Patel51ab7572016-06-16 15:48:30 +0000988 Rep = upgradeIntMinMax(Builder, *CI, ICmpInst::ICMP_SGT);
Craig Topper5aebb862016-07-04 20:56:38 +0000989 } else if (IsX86 && (Name == "sse2.pmaxu.b" ||
990 Name == "sse41.pmaxuw" ||
991 Name == "sse41.pmaxud" ||
Craig Topper8ec5c732016-10-24 04:04:16 +0000992 Name.startswith("avx2.pmaxu") ||
993 Name.startswith("avx512.mask.pmaxu"))) {
Sanjay Patel51ab7572016-06-16 15:48:30 +0000994 Rep = upgradeIntMinMax(Builder, *CI, ICmpInst::ICMP_UGT);
Craig Topper5aebb862016-07-04 20:56:38 +0000995 } else if (IsX86 && (Name == "sse41.pminsb" ||
996 Name == "sse2.pmins.w" ||
997 Name == "sse41.pminsd" ||
Craig Topper8ec5c732016-10-24 04:04:16 +0000998 Name.startswith("avx2.pmins") ||
999 Name.startswith("avx512.mask.pmins"))) {
Sanjay Patel51ab7572016-06-16 15:48:30 +00001000 Rep = upgradeIntMinMax(Builder, *CI, ICmpInst::ICMP_SLT);
Craig Topper5aebb862016-07-04 20:56:38 +00001001 } else if (IsX86 && (Name == "sse2.pminu.b" ||
1002 Name == "sse41.pminuw" ||
1003 Name == "sse41.pminud" ||
Craig Topper8ec5c732016-10-24 04:04:16 +00001004 Name.startswith("avx2.pminu") ||
1005 Name.startswith("avx512.mask.pminu"))) {
Sanjay Patel51ab7572016-06-16 15:48:30 +00001006 Rep = upgradeIntMinMax(Builder, *CI, ICmpInst::ICMP_ULT);
Craig Topper5aebb862016-07-04 20:56:38 +00001007 } else if (IsX86 && (Name == "sse2.cvtdq2pd" ||
1008 Name == "sse2.cvtps2pd" ||
1009 Name == "avx.cvtdq2.pd.256" ||
Simon Pilgrimb57dd172016-11-16 14:48:32 +00001010 Name == "avx.cvt.ps2.pd.256" ||
1011 Name.startswith("avx512.mask.cvtdq2pd.") ||
1012 Name.startswith("avx512.mask.cvtudq2pd."))) {
Simon Pilgrim4298d062016-05-25 08:59:18 +00001013 // Lossless i32/float to double conversion.
1014 // Extract the bottom elements if necessary and convert to double vector.
1015 Value *Src = CI->getArgOperand(0);
1016 VectorType *SrcTy = cast<VectorType>(Src->getType());
1017 VectorType *DstTy = cast<VectorType>(CI->getType());
1018 Rep = CI->getArgOperand(0);
1019
1020 unsigned NumDstElts = DstTy->getNumElements();
1021 if (NumDstElts < SrcTy->getNumElements()) {
1022 assert(NumDstElts == 2 && "Unexpected vector size");
Craig Topper99d1eab2016-06-12 00:41:19 +00001023 uint32_t ShuffleMask[2] = { 0, 1 };
1024 Rep = Builder.CreateShuffleVector(Rep, UndefValue::get(SrcTy),
1025 ShuffleMask);
Simon Pilgrim4298d062016-05-25 08:59:18 +00001026 }
1027
Simon Pilgrimb57dd172016-11-16 14:48:32 +00001028 bool SInt2Double = (StringRef::npos != Name.find("cvtdq2"));
1029 bool UInt2Double = (StringRef::npos != Name.find("cvtudq2"));
1030 if (SInt2Double)
Simon Pilgrim4298d062016-05-25 08:59:18 +00001031 Rep = Builder.CreateSIToFP(Rep, DstTy, "cvtdq2pd");
Simon Pilgrimb57dd172016-11-16 14:48:32 +00001032 else if (UInt2Double)
1033 Rep = Builder.CreateUIToFP(Rep, DstTy, "cvtudq2pd");
Simon Pilgrim4298d062016-05-25 08:59:18 +00001034 else
1035 Rep = Builder.CreateFPExt(Rep, DstTy, "cvtps2pd");
Simon Pilgrimb57dd172016-11-16 14:48:32 +00001036
1037 if (CI->getNumArgOperands() == 3)
1038 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1039 CI->getArgOperand(1));
Craig Toppera57d2ca2016-09-03 23:55:13 +00001040 } else if (IsX86 && (Name.startswith("avx512.mask.loadu."))) {
Craig Topper46b34fe2016-07-12 01:42:33 +00001041 Rep = UpgradeMaskedLoad(Builder, CI->getArgOperand(0),
Craig Topperf10fbfa2016-06-02 04:19:36 +00001042 CI->getArgOperand(1), CI->getArgOperand(2),
1043 /*Aligned*/false);
Craig Toppera57d2ca2016-09-03 23:55:13 +00001044 } else if (IsX86 && (Name.startswith("avx512.mask.load."))) {
Craig Topper46b34fe2016-07-12 01:42:33 +00001045 Rep = UpgradeMaskedLoad(Builder, CI->getArgOperand(0),
Craig Topperf10fbfa2016-06-02 04:19:36 +00001046 CI->getArgOperand(1),CI->getArgOperand(2),
1047 /*Aligned*/true);
Craig Topper5aebb862016-07-04 20:56:38 +00001048 } else if (IsX86 && Name.startswith("xop.vpcom")) {
Craig Topper3352ba52012-06-09 16:46:13 +00001049 Intrinsic::ID intID;
1050 if (Name.endswith("ub"))
1051 intID = Intrinsic::x86_xop_vpcomub;
1052 else if (Name.endswith("uw"))
1053 intID = Intrinsic::x86_xop_vpcomuw;
1054 else if (Name.endswith("ud"))
1055 intID = Intrinsic::x86_xop_vpcomud;
1056 else if (Name.endswith("uq"))
1057 intID = Intrinsic::x86_xop_vpcomuq;
1058 else if (Name.endswith("b"))
1059 intID = Intrinsic::x86_xop_vpcomb;
1060 else if (Name.endswith("w"))
1061 intID = Intrinsic::x86_xop_vpcomw;
1062 else if (Name.endswith("d"))
1063 intID = Intrinsic::x86_xop_vpcomd;
1064 else if (Name.endswith("q"))
1065 intID = Intrinsic::x86_xop_vpcomq;
1066 else
1067 llvm_unreachable("Unknown suffix");
1068
Craig Topper5aebb862016-07-04 20:56:38 +00001069 Name = Name.substr(9); // strip off "xop.vpcom"
Craig Topper3352ba52012-06-09 16:46:13 +00001070 unsigned Imm;
1071 if (Name.startswith("lt"))
1072 Imm = 0;
1073 else if (Name.startswith("le"))
1074 Imm = 1;
1075 else if (Name.startswith("gt"))
1076 Imm = 2;
1077 else if (Name.startswith("ge"))
1078 Imm = 3;
1079 else if (Name.startswith("eq"))
1080 Imm = 4;
1081 else if (Name.startswith("ne"))
1082 Imm = 5;
Craig Topper3352ba52012-06-09 16:46:13 +00001083 else if (Name.startswith("false"))
Craig Toppere32546d2015-02-13 07:42:15 +00001084 Imm = 6;
1085 else if (Name.startswith("true"))
Craig Topper3352ba52012-06-09 16:46:13 +00001086 Imm = 7;
1087 else
1088 llvm_unreachable("Unknown condition");
1089
1090 Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID);
David Blaikieff6409d2015-05-18 22:13:54 +00001091 Rep =
1092 Builder.CreateCall(VPCOM, {CI->getArgOperand(0), CI->getArgOperand(1),
1093 Builder.getInt8(Imm)});
Craig Topperde103122017-02-18 21:50:58 +00001094 } else if (IsX86 && Name.startswith("xop.vpcmov")) {
Simon Pilgrime88dc042015-11-03 20:27:01 +00001095 Value *Sel = CI->getArgOperand(2);
Craig Topper03a9adc2017-02-18 19:51:19 +00001096 Value *NotSel = Builder.CreateNot(Sel);
1097 Value *Sel0 = Builder.CreateAnd(CI->getArgOperand(0), Sel);
1098 Value *Sel1 = Builder.CreateAnd(CI->getArgOperand(1), NotSel);
Simon Pilgrime88dc042015-11-03 20:27:01 +00001099 Rep = Builder.CreateOr(Sel0, Sel1);
Craig Topper5aebb862016-07-04 20:56:38 +00001100 } else if (IsX86 && Name == "sse42.crc32.64.8") {
Craig Topperef9e9932013-10-15 05:20:47 +00001101 Function *CRC32 = Intrinsic::getDeclaration(F->getParent(),
1102 Intrinsic::x86_sse42_crc32_32_8);
1103 Value *Trunc0 = Builder.CreateTrunc(CI->getArgOperand(0), Type::getInt32Ty(C));
David Blaikieff6409d2015-05-18 22:13:54 +00001104 Rep = Builder.CreateCall(CRC32, {Trunc0, CI->getArgOperand(1)});
Craig Topperef9e9932013-10-15 05:20:47 +00001105 Rep = Builder.CreateZExt(Rep, CI->getType(), "");
Simon Pilgrimea0d4f92016-07-22 13:58:44 +00001106 } else if (IsX86 && Name.startswith("avx.vbroadcast.s")) {
Adam Nemet39066802014-05-29 23:35:33 +00001107 // Replace broadcasts with a series of insertelements.
1108 Type *VecTy = CI->getType();
1109 Type *EltTy = VecTy->getVectorElementType();
1110 unsigned EltNum = VecTy->getVectorNumElements();
1111 Value *Cast = Builder.CreateBitCast(CI->getArgOperand(0),
1112 EltTy->getPointerTo());
David Blaikie0c28fd72015-05-20 21:46:30 +00001113 Value *Load = Builder.CreateLoad(EltTy, Cast);
Adam Nemet39066802014-05-29 23:35:33 +00001114 Type *I32Ty = Type::getInt32Ty(C);
1115 Rep = UndefValue::get(VecTy);
1116 for (unsigned I = 0; I < EltNum; ++I)
1117 Rep = Builder.CreateInsertElement(Rep, Load,
1118 ConstantInt::get(I32Ty, I));
Craig Topper5aebb862016-07-04 20:56:38 +00001119 } else if (IsX86 && (Name.startswith("sse41.pmovsx") ||
1120 Name.startswith("sse41.pmovzx") ||
1121 Name.startswith("avx2.pmovsx") ||
Craig Topperb110e042016-11-07 02:12:57 +00001122 Name.startswith("avx2.pmovzx") ||
1123 Name.startswith("avx512.mask.pmovsx") ||
1124 Name.startswith("avx512.mask.pmovzx"))) {
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001125 VectorType *SrcTy = cast<VectorType>(CI->getArgOperand(0)->getType());
1126 VectorType *DstTy = cast<VectorType>(CI->getType());
1127 unsigned NumDstElts = DstTy->getNumElements();
1128
Simon Pilgrim9602d672016-05-28 18:03:41 +00001129 // Extract a subvector of the first NumDstElts lanes and sign/zero extend.
Craig Topperc0a5fa02016-06-12 04:48:00 +00001130 SmallVector<uint32_t, 8> ShuffleMask(NumDstElts);
Craig Topper99d1eab2016-06-12 00:41:19 +00001131 for (unsigned i = 0; i != NumDstElts; ++i)
Craig Topperc0a5fa02016-06-12 04:48:00 +00001132 ShuffleMask[i] = i;
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001133
1134 Value *SV = Builder.CreateShuffleVector(
1135 CI->getArgOperand(0), UndefValue::get(SrcTy), ShuffleMask);
Simon Pilgrim9602d672016-05-28 18:03:41 +00001136
1137 bool DoSext = (StringRef::npos != Name.find("pmovsx"));
1138 Rep = DoSext ? Builder.CreateSExt(SV, DstTy)
1139 : Builder.CreateZExt(SV, DstTy);
Craig Topperb110e042016-11-07 02:12:57 +00001140 // If there are 3 arguments, it's a masked intrinsic so we need a select.
1141 if (CI->getNumArgOperands() == 3)
1142 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1143 CI->getArgOperand(1));
Simon Pilgrimea0d4f92016-07-22 13:58:44 +00001144 } else if (IsX86 && (Name.startswith("avx.vbroadcastf128") ||
1145 Name == "avx2.vbroadcasti128")) {
1146 // Replace vbroadcastf128/vbroadcasti128 with a vector load+shuffle.
1147 Type *EltTy = CI->getType()->getVectorElementType();
1148 unsigned NumSrcElts = 128 / EltTy->getPrimitiveSizeInBits();
1149 Type *VT = VectorType::get(EltTy, NumSrcElts);
David Blaikie0c28fd72015-05-20 21:46:30 +00001150 Value *Op = Builder.CreatePointerCast(CI->getArgOperand(0),
1151 PointerType::getUnqual(VT));
Chandler Carruth0215e762016-08-10 07:41:26 +00001152 Value *Load = Builder.CreateAlignedLoad(Op, 1);
Simon Pilgrimea0d4f92016-07-22 13:58:44 +00001153 if (NumSrcElts == 2)
1154 Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()),
1155 { 0, 1, 0, 1 });
1156 else
1157 Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()),
1158 { 0, 1, 2, 3, 0, 1, 2, 3 });
Craig Topper5aebb862016-07-04 20:56:38 +00001159 } else if (IsX86 && (Name.startswith("avx2.pbroadcast") ||
Simon Pilgrim4e96fbf2016-07-05 13:58:47 +00001160 Name.startswith("avx2.vbroadcast") ||
1161 Name.startswith("avx512.pbroadcast") ||
1162 Name.startswith("avx512.mask.broadcast.s"))) {
Ahmed Bougacha1a4987052015-08-20 20:36:19 +00001163 // Replace vp?broadcasts with a vector shuffle.
1164 Value *Op = CI->getArgOperand(0);
1165 unsigned NumElts = CI->getType()->getVectorNumElements();
1166 Type *MaskTy = VectorType::get(Type::getInt32Ty(C), NumElts);
1167 Rep = Builder.CreateShuffleVector(Op, UndefValue::get(Op->getType()),
1168 Constant::getNullValue(MaskTy));
Simon Pilgrim4e96fbf2016-07-05 13:58:47 +00001169
1170 if (CI->getNumArgOperands() == 3)
1171 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1172 CI->getArgOperand(1));
Craig Topper5aebb862016-07-04 20:56:38 +00001173 } else if (IsX86 && Name.startswith("avx512.mask.palignr.")) {
Craig Topperf57e17d2016-11-23 06:54:55 +00001174 Rep = UpgradeX86ALIGNIntrinsics(Builder, CI->getArgOperand(0),
1175 CI->getArgOperand(1),
1176 CI->getArgOperand(2),
1177 CI->getArgOperand(3),
1178 CI->getArgOperand(4),
1179 false);
1180 } else if (IsX86 && Name.startswith("avx512.mask.valign.")) {
1181 Rep = UpgradeX86ALIGNIntrinsics(Builder, CI->getArgOperand(0),
1182 CI->getArgOperand(1),
1183 CI->getArgOperand(2),
1184 CI->getArgOperand(3),
1185 CI->getArgOperand(4),
1186 true);
Craig Topper5aebb862016-07-04 20:56:38 +00001187 } else if (IsX86 && (Name == "sse2.psll.dq" ||
1188 Name == "avx2.psll.dq")) {
Craig Topper7355ac32016-05-29 06:37:33 +00001189 // 128/256-bit shift left specified in bits.
Craig Topperb324e432015-02-18 06:24:44 +00001190 unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper46b34fe2016-07-12 01:42:33 +00001191 Rep = UpgradeX86PSLLDQIntrinsics(Builder, CI->getArgOperand(0),
Craig Topperb324e432015-02-18 06:24:44 +00001192 Shift / 8); // Shift is in bits.
Craig Topper5aebb862016-07-04 20:56:38 +00001193 } else if (IsX86 && (Name == "sse2.psrl.dq" ||
1194 Name == "avx2.psrl.dq")) {
Craig Topper7355ac32016-05-29 06:37:33 +00001195 // 128/256-bit shift right specified in bits.
Craig Topperb324e432015-02-18 06:24:44 +00001196 unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper46b34fe2016-07-12 01:42:33 +00001197 Rep = UpgradeX86PSRLDQIntrinsics(Builder, CI->getArgOperand(0),
Craig Topperb324e432015-02-18 06:24:44 +00001198 Shift / 8); // Shift is in bits.
Craig Topper5aebb862016-07-04 20:56:38 +00001199 } else if (IsX86 && (Name == "sse2.psll.dq.bs" ||
1200 Name == "avx2.psll.dq.bs" ||
1201 Name == "avx512.psll.dq.512")) {
Simon Pilgrimf7186822016-06-09 21:09:03 +00001202 // 128/256/512-bit shift left specified in bytes.
Craig Topperb324e432015-02-18 06:24:44 +00001203 unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper46b34fe2016-07-12 01:42:33 +00001204 Rep = UpgradeX86PSLLDQIntrinsics(Builder, CI->getArgOperand(0), Shift);
Craig Topper5aebb862016-07-04 20:56:38 +00001205 } else if (IsX86 && (Name == "sse2.psrl.dq.bs" ||
1206 Name == "avx2.psrl.dq.bs" ||
1207 Name == "avx512.psrl.dq.512")) {
Simon Pilgrimf7186822016-06-09 21:09:03 +00001208 // 128/256/512-bit shift right specified in bytes.
Craig Topperb324e432015-02-18 06:24:44 +00001209 unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper46b34fe2016-07-12 01:42:33 +00001210 Rep = UpgradeX86PSRLDQIntrinsics(Builder, CI->getArgOperand(0), Shift);
Craig Topper5aebb862016-07-04 20:56:38 +00001211 } else if (IsX86 && (Name == "sse41.pblendw" ||
1212 Name.startswith("sse41.blendp") ||
1213 Name.startswith("avx.blend.p") ||
1214 Name == "avx2.pblendw" ||
1215 Name.startswith("avx2.pblendd."))) {
Craig Topper782d6202015-02-28 19:33:17 +00001216 Value *Op0 = CI->getArgOperand(0);
1217 Value *Op1 = CI->getArgOperand(1);
1218 unsigned Imm = cast <ConstantInt>(CI->getArgOperand(2))->getZExtValue();
1219 VectorType *VecTy = cast<VectorType>(CI->getType());
1220 unsigned NumElts = VecTy->getNumElements();
1221
Craig Topperc0a5fa02016-06-12 04:48:00 +00001222 SmallVector<uint32_t, 16> Idxs(NumElts);
1223 for (unsigned i = 0; i != NumElts; ++i)
1224 Idxs[i] = ((Imm >> (i%8)) & 1) ? i + NumElts : i;
Craig Topper782d6202015-02-28 19:33:17 +00001225
Craig Topper2f561822016-06-12 01:05:59 +00001226 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
Craig Topper5aebb862016-07-04 20:56:38 +00001227 } else if (IsX86 && (Name.startswith("avx.vinsertf128.") ||
Craig Topper0cda8bb2017-01-03 05:45:57 +00001228 Name == "avx2.vinserti128" ||
1229 Name.startswith("avx512.mask.insert"))) {
Sanjay Patel19792fb2015-03-10 16:08:36 +00001230 Value *Op0 = CI->getArgOperand(0);
1231 Value *Op1 = CI->getArgOperand(1);
1232 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
Craig Topper0cda8bb2017-01-03 05:45:57 +00001233 unsigned DstNumElts = CI->getType()->getVectorNumElements();
1234 unsigned SrcNumElts = Op1->getType()->getVectorNumElements();
1235 unsigned Scale = DstNumElts / SrcNumElts;
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001236
Sanjay Patel19792fb2015-03-10 16:08:36 +00001237 // Mask off the high bits of the immediate value; hardware ignores those.
Craig Topper0cda8bb2017-01-03 05:45:57 +00001238 Imm = Imm % Scale;
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001239
Craig Topper0cda8bb2017-01-03 05:45:57 +00001240 // Extend the second operand into a vector the size of the destination.
Sanjay Patel19792fb2015-03-10 16:08:36 +00001241 Value *UndefV = UndefValue::get(Op1->getType());
Craig Topper0cda8bb2017-01-03 05:45:57 +00001242 SmallVector<uint32_t, 8> Idxs(DstNumElts);
1243 for (unsigned i = 0; i != SrcNumElts; ++i)
Craig Topperc0a5fa02016-06-12 04:48:00 +00001244 Idxs[i] = i;
Craig Topper0cda8bb2017-01-03 05:45:57 +00001245 for (unsigned i = SrcNumElts; i != DstNumElts; ++i)
1246 Idxs[i] = SrcNumElts;
Craig Topper2f561822016-06-12 01:05:59 +00001247 Rep = Builder.CreateShuffleVector(Op1, UndefV, Idxs);
Sanjay Patel19792fb2015-03-10 16:08:36 +00001248
1249 // Insert the second operand into the first operand.
1250
1251 // Note that there is no guarantee that instruction lowering will actually
1252 // produce a vinsertf128 instruction for the created shuffles. In
1253 // particular, the 0 immediate case involves no lane changes, so it can
1254 // be handled as a blend.
1255
1256 // Example of shuffle mask for 32-bit elements:
1257 // Imm = 1 <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
1258 // Imm = 0 <i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7 >
1259
Craig Topper0cda8bb2017-01-03 05:45:57 +00001260 // First fill with identify mask.
1261 for (unsigned i = 0; i != DstNumElts; ++i)
1262 Idxs[i] = i;
1263 // Then replace the elements where we need to insert.
1264 for (unsigned i = 0; i != SrcNumElts; ++i)
1265 Idxs[i + Imm * SrcNumElts] = i + DstNumElts;
Craig Topper2f561822016-06-12 01:05:59 +00001266 Rep = Builder.CreateShuffleVector(Op0, Rep, Idxs);
Craig Topper0cda8bb2017-01-03 05:45:57 +00001267
1268 // If the intrinsic has a mask operand, handle that.
1269 if (CI->getNumArgOperands() == 5)
1270 Rep = EmitX86Select(Builder, CI->getArgOperand(4), Rep,
1271 CI->getArgOperand(3));
Craig Topper5aebb862016-07-04 20:56:38 +00001272 } else if (IsX86 && (Name.startswith("avx.vextractf128.") ||
Craig Topper4d47c6a2017-01-03 05:45:46 +00001273 Name == "avx2.vextracti128" ||
1274 Name.startswith("avx512.mask.vextract"))) {
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001275 Value *Op0 = CI->getArgOperand(0);
1276 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper4d47c6a2017-01-03 05:45:46 +00001277 unsigned DstNumElts = CI->getType()->getVectorNumElements();
1278 unsigned SrcNumElts = Op0->getType()->getVectorNumElements();
1279 unsigned Scale = SrcNumElts / DstNumElts;
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001280
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001281 // Mask off the high bits of the immediate value; hardware ignores those.
Craig Topper4d47c6a2017-01-03 05:45:46 +00001282 Imm = Imm % Scale;
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001283
Craig Topper4d47c6a2017-01-03 05:45:46 +00001284 // Get indexes for the subvector of the input vector.
1285 SmallVector<uint32_t, 8> Idxs(DstNumElts);
1286 for (unsigned i = 0; i != DstNumElts; ++i) {
1287 Idxs[i] = i + (Imm * DstNumElts);
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001288 }
Craig Topper4d47c6a2017-01-03 05:45:46 +00001289 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001290
Craig Topper4d47c6a2017-01-03 05:45:46 +00001291 // If the intrinsic has a mask operand, handle that.
1292 if (CI->getNumArgOperands() == 4)
1293 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1294 CI->getArgOperand(2));
Craig Topper5aebb862016-07-04 20:56:38 +00001295 } else if (!IsX86 && Name == "stackprotectorcheck") {
Tim Shen00127562016-04-08 21:26:31 +00001296 Rep = nullptr;
Craig Topper5aebb862016-07-04 20:56:38 +00001297 } else if (IsX86 && (Name.startswith("avx512.mask.perm.df.") ||
1298 Name.startswith("avx512.mask.perm.di."))) {
Simon Pilgrim02d435d2016-07-04 14:19:05 +00001299 Value *Op0 = CI->getArgOperand(0);
1300 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
1301 VectorType *VecTy = cast<VectorType>(CI->getType());
1302 unsigned NumElts = VecTy->getNumElements();
1303
1304 SmallVector<uint32_t, 8> Idxs(NumElts);
1305 for (unsigned i = 0; i != NumElts; ++i)
1306 Idxs[i] = (i & ~0x3) + ((Imm >> (2 * (i & 0x3))) & 3);
1307
1308 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
1309
1310 if (CI->getNumArgOperands() == 4)
1311 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1312 CI->getArgOperand(2));
Craig Topper5aebb862016-07-04 20:56:38 +00001313 } else if (IsX86 && (Name.startswith("avx.vpermil.") ||
1314 Name == "sse2.pshuf.d" ||
1315 Name.startswith("avx512.mask.vpermil.p") ||
1316 Name.startswith("avx512.mask.pshuf.d."))) {
Craig Topper8a105052016-06-12 03:10:47 +00001317 Value *Op0 = CI->getArgOperand(0);
1318 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
1319 VectorType *VecTy = cast<VectorType>(CI->getType());
1320 unsigned NumElts = VecTy->getNumElements();
Simon Pilgrim9fca3002016-07-04 12:40:54 +00001321 // Calculate the size of each index in the immediate.
Craig Topper8a105052016-06-12 03:10:47 +00001322 unsigned IdxSize = 64 / VecTy->getScalarSizeInBits();
1323 unsigned IdxMask = ((1 << IdxSize) - 1);
1324
1325 SmallVector<uint32_t, 8> Idxs(NumElts);
1326 // Lookup the bits for this element, wrapping around the immediate every
1327 // 8-bits. Elements are grouped into sets of 2 or 4 elements so we need
1328 // to offset by the first index of each group.
1329 for (unsigned i = 0; i != NumElts; ++i)
1330 Idxs[i] = ((Imm >> ((i * IdxSize) % 8)) & IdxMask) | (i & ~IdxMask);
1331
1332 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
Craig Topper13cf7ca2016-06-13 02:36:48 +00001333
1334 if (CI->getNumArgOperands() == 4)
1335 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1336 CI->getArgOperand(2));
Craig Topper5aebb862016-07-04 20:56:38 +00001337 } else if (IsX86 && (Name == "sse2.pshufl.w" ||
1338 Name.startswith("avx512.mask.pshufl.w."))) {
Craig Topper10679862016-06-12 14:11:32 +00001339 Value *Op0 = CI->getArgOperand(0);
1340 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
1341 unsigned NumElts = CI->getType()->getVectorNumElements();
1342
1343 SmallVector<uint32_t, 16> Idxs(NumElts);
1344 for (unsigned l = 0; l != NumElts; l += 8) {
1345 for (unsigned i = 0; i != 4; ++i)
1346 Idxs[i + l] = ((Imm >> (2 * i)) & 0x3) + l;
1347 for (unsigned i = 4; i != 8; ++i)
1348 Idxs[i + l] = i + l;
1349 }
1350
1351 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
Craig Topper13cf7ca2016-06-13 02:36:48 +00001352
1353 if (CI->getNumArgOperands() == 4)
1354 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1355 CI->getArgOperand(2));
Craig Topper5aebb862016-07-04 20:56:38 +00001356 } else if (IsX86 && (Name == "sse2.pshufh.w" ||
1357 Name.startswith("avx512.mask.pshufh.w."))) {
Craig Topper10679862016-06-12 14:11:32 +00001358 Value *Op0 = CI->getArgOperand(0);
1359 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
1360 unsigned NumElts = CI->getType()->getVectorNumElements();
1361
1362 SmallVector<uint32_t, 16> Idxs(NumElts);
1363 for (unsigned l = 0; l != NumElts; l += 8) {
1364 for (unsigned i = 0; i != 4; ++i)
1365 Idxs[i + l] = i + l;
1366 for (unsigned i = 0; i != 4; ++i)
1367 Idxs[i + l + 4] = ((Imm >> (2 * i)) & 0x3) + 4 + l;
1368 }
1369
1370 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
Craig Topper13cf7ca2016-06-13 02:36:48 +00001371
1372 if (CI->getNumArgOperands() == 4)
1373 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1374 CI->getArgOperand(2));
Craig Topper4619c9e2016-09-13 07:40:53 +00001375 } else if (IsX86 && Name.startswith("avx512.mask.shuf.p")) {
1376 Value *Op0 = CI->getArgOperand(0);
1377 Value *Op1 = CI->getArgOperand(1);
1378 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
1379 unsigned NumElts = CI->getType()->getVectorNumElements();
1380
1381 unsigned NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
1382 unsigned HalfLaneElts = NumLaneElts / 2;
1383
1384 SmallVector<uint32_t, 16> Idxs(NumElts);
1385 for (unsigned i = 0; i != NumElts; ++i) {
1386 // Base index is the starting element of the lane.
1387 Idxs[i] = i - (i % NumLaneElts);
1388 // If we are half way through the lane switch to the other source.
1389 if ((i % NumLaneElts) >= HalfLaneElts)
1390 Idxs[i] += NumElts;
1391 // Now select the specific element. By adding HalfLaneElts bits from
1392 // the immediate. Wrapping around the immediate every 8-bits.
1393 Idxs[i] += (Imm >> ((i * HalfLaneElts) % 8)) & ((1 << HalfLaneElts) - 1);
1394 }
1395
1396 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
1397
1398 Rep = EmitX86Select(Builder, CI->getArgOperand(4), Rep,
1399 CI->getArgOperand(3));
Craig Topper5aebb862016-07-04 20:56:38 +00001400 } else if (IsX86 && (Name.startswith("avx512.mask.movddup") ||
1401 Name.startswith("avx512.mask.movshdup") ||
1402 Name.startswith("avx512.mask.movsldup"))) {
Simon Pilgrim19adee92016-07-02 14:42:35 +00001403 Value *Op0 = CI->getArgOperand(0);
1404 unsigned NumElts = CI->getType()->getVectorNumElements();
1405 unsigned NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
1406
1407 unsigned Offset = 0;
Craig Topper5aebb862016-07-04 20:56:38 +00001408 if (Name.startswith("avx512.mask.movshdup."))
Simon Pilgrim19adee92016-07-02 14:42:35 +00001409 Offset = 1;
1410
1411 SmallVector<uint32_t, 16> Idxs(NumElts);
1412 for (unsigned l = 0; l != NumElts; l += NumLaneElts)
1413 for (unsigned i = 0; i != NumLaneElts; i += 2) {
1414 Idxs[i + l + 0] = i + l + Offset;
1415 Idxs[i + l + 1] = i + l + Offset;
1416 }
1417
1418 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
1419
1420 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1421 CI->getArgOperand(1));
Craig Topper5aebb862016-07-04 20:56:38 +00001422 } else if (IsX86 && (Name.startswith("avx512.mask.punpckl") ||
1423 Name.startswith("avx512.mask.unpckl."))) {
Craig Topper597aa422016-06-23 07:37:33 +00001424 Value *Op0 = CI->getArgOperand(0);
1425 Value *Op1 = CI->getArgOperand(1);
1426 int NumElts = CI->getType()->getVectorNumElements();
1427 int NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
1428
1429 SmallVector<uint32_t, 64> Idxs(NumElts);
1430 for (int l = 0; l != NumElts; l += NumLaneElts)
1431 for (int i = 0; i != NumLaneElts; ++i)
1432 Idxs[i + l] = l + (i / 2) + NumElts * (i % 2);
1433
1434 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
1435
1436 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1437 CI->getArgOperand(2));
Craig Topper5aebb862016-07-04 20:56:38 +00001438 } else if (IsX86 && (Name.startswith("avx512.mask.punpckh") ||
1439 Name.startswith("avx512.mask.unpckh."))) {
Craig Topper597aa422016-06-23 07:37:33 +00001440 Value *Op0 = CI->getArgOperand(0);
1441 Value *Op1 = CI->getArgOperand(1);
1442 int NumElts = CI->getType()->getVectorNumElements();
1443 int NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
1444
1445 SmallVector<uint32_t, 64> Idxs(NumElts);
1446 for (int l = 0; l != NumElts; l += NumLaneElts)
1447 for (int i = 0; i != NumLaneElts; ++i)
1448 Idxs[i + l] = (NumLaneElts / 2) + l + (i / 2) + NumElts * (i % 2);
1449
1450 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
1451
1452 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1453 CI->getArgOperand(2));
Craig Toppera6e6feb2016-07-12 05:27:53 +00001454 } else if (IsX86 && Name.startswith("avx512.mask.pand.")) {
1455 Rep = Builder.CreateAnd(CI->getArgOperand(0), CI->getArgOperand(1));
1456 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1457 CI->getArgOperand(2));
1458 } else if (IsX86 && Name.startswith("avx512.mask.pandn.")) {
1459 Rep = Builder.CreateAnd(Builder.CreateNot(CI->getArgOperand(0)),
1460 CI->getArgOperand(1));
1461 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1462 CI->getArgOperand(2));
1463 } else if (IsX86 && Name.startswith("avx512.mask.por.")) {
1464 Rep = Builder.CreateOr(CI->getArgOperand(0), CI->getArgOperand(1));
1465 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1466 CI->getArgOperand(2));
1467 } else if (IsX86 && Name.startswith("avx512.mask.pxor.")) {
1468 Rep = Builder.CreateXor(CI->getArgOperand(0), CI->getArgOperand(1));
1469 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1470 CI->getArgOperand(2));
Craig Toppere75c4952016-09-02 05:29:17 +00001471 } else if (IsX86 && Name.startswith("avx512.mask.and.")) {
1472 VectorType *FTy = cast<VectorType>(CI->getType());
1473 VectorType *ITy = VectorType::getInteger(FTy);
1474 Rep = Builder.CreateAnd(Builder.CreateBitCast(CI->getArgOperand(0), ITy),
1475 Builder.CreateBitCast(CI->getArgOperand(1), ITy));
1476 Rep = Builder.CreateBitCast(Rep, FTy);
1477 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1478 CI->getArgOperand(2));
1479 } else if (IsX86 && Name.startswith("avx512.mask.andn.")) {
1480 VectorType *FTy = cast<VectorType>(CI->getType());
1481 VectorType *ITy = VectorType::getInteger(FTy);
1482 Rep = Builder.CreateNot(Builder.CreateBitCast(CI->getArgOperand(0), ITy));
1483 Rep = Builder.CreateAnd(Rep,
1484 Builder.CreateBitCast(CI->getArgOperand(1), ITy));
1485 Rep = Builder.CreateBitCast(Rep, FTy);
1486 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1487 CI->getArgOperand(2));
1488 } else if (IsX86 && Name.startswith("avx512.mask.or.")) {
1489 VectorType *FTy = cast<VectorType>(CI->getType());
1490 VectorType *ITy = VectorType::getInteger(FTy);
1491 Rep = Builder.CreateOr(Builder.CreateBitCast(CI->getArgOperand(0), ITy),
1492 Builder.CreateBitCast(CI->getArgOperand(1), ITy));
1493 Rep = Builder.CreateBitCast(Rep, FTy);
1494 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1495 CI->getArgOperand(2));
1496 } else if (IsX86 && Name.startswith("avx512.mask.xor.")) {
1497 VectorType *FTy = cast<VectorType>(CI->getType());
1498 VectorType *ITy = VectorType::getInteger(FTy);
1499 Rep = Builder.CreateXor(Builder.CreateBitCast(CI->getArgOperand(0), ITy),
1500 Builder.CreateBitCast(CI->getArgOperand(1), ITy));
1501 Rep = Builder.CreateBitCast(Rep, FTy);
1502 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1503 CI->getArgOperand(2));
Craig Topperaf0d63d2016-09-04 02:09:53 +00001504 } else if (IsX86 && Name.startswith("avx512.mask.padd.")) {
1505 Rep = Builder.CreateAdd(CI->getArgOperand(0), CI->getArgOperand(1));
1506 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1507 CI->getArgOperand(2));
1508 } else if (IsX86 && Name.startswith("avx512.mask.psub.")) {
1509 Rep = Builder.CreateSub(CI->getArgOperand(0), CI->getArgOperand(1));
1510 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1511 CI->getArgOperand(2));
1512 } else if (IsX86 && Name.startswith("avx512.mask.pmull.")) {
1513 Rep = Builder.CreateMul(CI->getArgOperand(0), CI->getArgOperand(1));
1514 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1515 CI->getArgOperand(2));
Craig Topper8f354a72016-11-05 05:35:23 +00001516 } else if (IsX86 && (Name.startswith("avx512.mask.add.p"))) {
Craig Topper41773452016-09-04 18:13:33 +00001517 Rep = Builder.CreateFAdd(CI->getArgOperand(0), CI->getArgOperand(1));
1518 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1519 CI->getArgOperand(2));
Craig Topper96041c62016-11-07 00:13:42 +00001520 } else if (IsX86 && Name.startswith("avx512.mask.div.p")) {
Craig Topper41773452016-09-04 18:13:33 +00001521 Rep = Builder.CreateFDiv(CI->getArgOperand(0), CI->getArgOperand(1));
1522 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1523 CI->getArgOperand(2));
Craig Topper96041c62016-11-07 00:13:42 +00001524 } else if (IsX86 && Name.startswith("avx512.mask.mul.p")) {
Craig Topper41773452016-09-04 18:13:33 +00001525 Rep = Builder.CreateFMul(CI->getArgOperand(0), CI->getArgOperand(1));
1526 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1527 CI->getArgOperand(2));
Craig Topper96041c62016-11-07 00:13:42 +00001528 } else if (IsX86 && Name.startswith("avx512.mask.sub.p")) {
Craig Topper41773452016-09-04 18:13:33 +00001529 Rep = Builder.CreateFSub(CI->getArgOperand(0), CI->getArgOperand(1));
1530 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1531 CI->getArgOperand(2));
Craig Topperf2529c12017-02-24 05:35:04 +00001532 } else if (IsX86 && Name.startswith("avx512.mask.lzcnt.")) {
1533 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(),
1534 Intrinsic::ctlz,
1535 CI->getType()),
1536 { CI->getArgOperand(0), Builder.getInt1(false) });
1537 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1538 CI->getArgOperand(1));
Craig Toppera5051692017-02-18 07:07:50 +00001539 } else if (IsX86 && (Name.startswith("avx512.mask.max.p") ||
1540 Name.startswith("avx512.mask.min.p"))) {
1541 bool IsMin = Name[13] == 'i';
1542 VectorType *VecTy = cast<VectorType>(CI->getType());
1543 unsigned VecWidth = VecTy->getPrimitiveSizeInBits();
1544 unsigned EltWidth = VecTy->getScalarSizeInBits();
1545 Intrinsic::ID IID;
1546 if (!IsMin && VecWidth == 128 && EltWidth == 32)
1547 IID = Intrinsic::x86_sse_max_ps;
1548 else if (!IsMin && VecWidth == 128 && EltWidth == 64)
1549 IID = Intrinsic::x86_sse2_max_pd;
1550 else if (!IsMin && VecWidth == 256 && EltWidth == 32)
1551 IID = Intrinsic::x86_avx_max_ps_256;
1552 else if (!IsMin && VecWidth == 256 && EltWidth == 64)
1553 IID = Intrinsic::x86_avx_max_pd_256;
1554 else if (IsMin && VecWidth == 128 && EltWidth == 32)
1555 IID = Intrinsic::x86_sse_min_ps;
1556 else if (IsMin && VecWidth == 128 && EltWidth == 64)
1557 IID = Intrinsic::x86_sse2_min_pd;
1558 else if (IsMin && VecWidth == 256 && EltWidth == 32)
1559 IID = Intrinsic::x86_avx_min_ps_256;
1560 else if (IsMin && VecWidth == 256 && EltWidth == 64)
1561 IID = Intrinsic::x86_avx_min_pd_256;
1562 else
1563 llvm_unreachable("Unexpected intrinsic");
1564
1565 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
1566 { CI->getArgOperand(0), CI->getArgOperand(1) });
1567 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1568 CI->getArgOperand(2));
Craig Topper7e545332016-11-07 00:13:39 +00001569 } else if (IsX86 && Name.startswith("avx512.mask.pshuf.b.")) {
1570 VectorType *VecTy = cast<VectorType>(CI->getType());
1571 Intrinsic::ID IID;
1572 if (VecTy->getPrimitiveSizeInBits() == 128)
1573 IID = Intrinsic::x86_ssse3_pshuf_b_128;
1574 else if (VecTy->getPrimitiveSizeInBits() == 256)
1575 IID = Intrinsic::x86_avx2_pshuf_b;
Craig Topperedab02b2016-12-10 23:09:43 +00001576 else if (VecTy->getPrimitiveSizeInBits() == 512)
1577 IID = Intrinsic::x86_avx512_pshuf_b_512;
Craig Topper7e545332016-11-07 00:13:39 +00001578 else
1579 llvm_unreachable("Unexpected intrinsic");
1580
1581 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
1582 { CI->getArgOperand(0), CI->getArgOperand(1) });
1583 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1584 CI->getArgOperand(2));
Craig Topper2da265b2016-12-27 05:30:14 +00001585 } else if (IsX86 && (Name.startswith("avx512.mask.pmul.dq.") ||
1586 Name.startswith("avx512.mask.pmulu.dq."))) {
1587 bool IsUnsigned = Name[16] == 'u';
1588 VectorType *VecTy = cast<VectorType>(CI->getType());
1589 Intrinsic::ID IID;
1590 if (!IsUnsigned && VecTy->getPrimitiveSizeInBits() == 128)
1591 IID = Intrinsic::x86_sse41_pmuldq;
1592 else if (!IsUnsigned && VecTy->getPrimitiveSizeInBits() == 256)
1593 IID = Intrinsic::x86_avx2_pmul_dq;
1594 else if (!IsUnsigned && VecTy->getPrimitiveSizeInBits() == 512)
1595 IID = Intrinsic::x86_avx512_pmul_dq_512;
1596 else if (IsUnsigned && VecTy->getPrimitiveSizeInBits() == 128)
1597 IID = Intrinsic::x86_sse2_pmulu_dq;
1598 else if (IsUnsigned && VecTy->getPrimitiveSizeInBits() == 256)
1599 IID = Intrinsic::x86_avx2_pmulu_dq;
1600 else if (IsUnsigned && VecTy->getPrimitiveSizeInBits() == 512)
1601 IID = Intrinsic::x86_avx512_pmulu_dq_512;
1602 else
1603 llvm_unreachable("Unexpected intrinsic");
1604
1605 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
1606 { CI->getArgOperand(0), CI->getArgOperand(1) });
1607 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1608 CI->getArgOperand(2));
Craig Topper715873e2017-02-16 06:31:54 +00001609 } else if (IsX86 && Name.startswith("avx512.mask.pack")) {
1610 bool IsUnsigned = Name[16] == 'u';
1611 bool IsDW = Name[18] == 'd';
1612 VectorType *VecTy = cast<VectorType>(CI->getType());
1613 Intrinsic::ID IID;
1614 if (!IsUnsigned && !IsDW && VecTy->getPrimitiveSizeInBits() == 128)
1615 IID = Intrinsic::x86_sse2_packsswb_128;
1616 else if (!IsUnsigned && !IsDW && VecTy->getPrimitiveSizeInBits() == 256)
1617 IID = Intrinsic::x86_avx2_packsswb;
1618 else if (!IsUnsigned && !IsDW && VecTy->getPrimitiveSizeInBits() == 512)
1619 IID = Intrinsic::x86_avx512_packsswb_512;
1620 else if (!IsUnsigned && IsDW && VecTy->getPrimitiveSizeInBits() == 128)
1621 IID = Intrinsic::x86_sse2_packssdw_128;
1622 else if (!IsUnsigned && IsDW && VecTy->getPrimitiveSizeInBits() == 256)
1623 IID = Intrinsic::x86_avx2_packssdw;
1624 else if (!IsUnsigned && IsDW && VecTy->getPrimitiveSizeInBits() == 512)
1625 IID = Intrinsic::x86_avx512_packssdw_512;
1626 else if (IsUnsigned && !IsDW && VecTy->getPrimitiveSizeInBits() == 128)
1627 IID = Intrinsic::x86_sse2_packuswb_128;
1628 else if (IsUnsigned && !IsDW && VecTy->getPrimitiveSizeInBits() == 256)
1629 IID = Intrinsic::x86_avx2_packuswb;
1630 else if (IsUnsigned && !IsDW && VecTy->getPrimitiveSizeInBits() == 512)
1631 IID = Intrinsic::x86_avx512_packuswb_512;
1632 else if (IsUnsigned && IsDW && VecTy->getPrimitiveSizeInBits() == 128)
1633 IID = Intrinsic::x86_sse41_packusdw;
1634 else if (IsUnsigned && IsDW && VecTy->getPrimitiveSizeInBits() == 256)
1635 IID = Intrinsic::x86_avx2_packusdw;
1636 else if (IsUnsigned && IsDW && VecTy->getPrimitiveSizeInBits() == 512)
1637 IID = Intrinsic::x86_avx512_packusdw_512;
1638 else
1639 llvm_unreachable("Unexpected intrinsic");
1640
1641 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
1642 { CI->getArgOperand(0), CI->getArgOperand(1) });
1643 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1644 CI->getArgOperand(2));
Craig Topper987dad22016-11-13 19:09:56 +00001645 } else if (IsX86 && Name.startswith("avx512.mask.psll")) {
1646 bool IsImmediate = Name[16] == 'i' ||
1647 (Name.size() > 18 && Name[18] == 'i');
1648 bool IsVariable = Name[16] == 'v';
1649 char Size = Name[16] == '.' ? Name[17] :
1650 Name[17] == '.' ? Name[18] :
Craig Topper02b5a1b2016-11-18 05:04:44 +00001651 Name[18] == '.' ? Name[19] :
1652 Name[20];
Craig Topper987dad22016-11-13 19:09:56 +00001653
1654 Intrinsic::ID IID;
Craig Topper353e59b2016-11-14 01:53:22 +00001655 if (IsVariable && Name[17] != '.') {
Craig Topper987dad22016-11-13 19:09:56 +00001656 if (Size == 'd' && Name[17] == '2') // avx512.mask.psllv2.di
1657 IID = Intrinsic::x86_avx2_psllv_q;
1658 else if (Size == 'd' && Name[17] == '4') // avx512.mask.psllv4.di
1659 IID = Intrinsic::x86_avx2_psllv_q_256;
1660 else if (Size == 's' && Name[17] == '4') // avx512.mask.psllv4.si
1661 IID = Intrinsic::x86_avx2_psllv_d;
1662 else if (Size == 's' && Name[17] == '8') // avx512.mask.psllv8.si
1663 IID = Intrinsic::x86_avx2_psllv_d_256;
Craig Topper02b5a1b2016-11-18 05:04:44 +00001664 else if (Size == 'h' && Name[17] == '8') // avx512.mask.psllv8.hi
1665 IID = Intrinsic::x86_avx512_psllv_w_128;
1666 else if (Size == 'h' && Name[17] == '1') // avx512.mask.psllv16.hi
1667 IID = Intrinsic::x86_avx512_psllv_w_256;
1668 else if (Name[17] == '3' && Name[18] == '2') // avx512.mask.psllv32hi
1669 IID = Intrinsic::x86_avx512_psllv_w_512;
Craig Topper987dad22016-11-13 19:09:56 +00001670 else
1671 llvm_unreachable("Unexpected size");
1672 } else if (Name.endswith(".128")) {
1673 if (Size == 'd') // avx512.mask.psll.d.128, avx512.mask.psll.di.128
1674 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_d
1675 : Intrinsic::x86_sse2_psll_d;
1676 else if (Size == 'q') // avx512.mask.psll.q.128, avx512.mask.psll.qi.128
1677 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_q
1678 : Intrinsic::x86_sse2_psll_q;
1679 else if (Size == 'w') // avx512.mask.psll.w.128, avx512.mask.psll.wi.128
1680 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_w
1681 : Intrinsic::x86_sse2_psll_w;
1682 else
1683 llvm_unreachable("Unexpected size");
1684 } else if (Name.endswith(".256")) {
1685 if (Size == 'd') // avx512.mask.psll.d.256, avx512.mask.psll.di.256
1686 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_d
1687 : Intrinsic::x86_avx2_psll_d;
1688 else if (Size == 'q') // avx512.mask.psll.q.256, avx512.mask.psll.qi.256
1689 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_q
1690 : Intrinsic::x86_avx2_psll_q;
1691 else if (Size == 'w') // avx512.mask.psll.w.256, avx512.mask.psll.wi.256
1692 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_w
1693 : Intrinsic::x86_avx2_psll_w;
1694 else
1695 llvm_unreachable("Unexpected size");
1696 } else {
Craig Topper353e59b2016-11-14 01:53:22 +00001697 if (Size == 'd') // psll.di.512, pslli.d, psll.d, psllv.d.512
1698 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_d_512 :
1699 IsVariable ? Intrinsic::x86_avx512_psllv_d_512 :
1700 Intrinsic::x86_avx512_psll_d_512;
1701 else if (Size == 'q') // psll.qi.512, pslli.q, psll.q, psllv.q.512
1702 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_q_512 :
1703 IsVariable ? Intrinsic::x86_avx512_psllv_q_512 :
1704 Intrinsic::x86_avx512_psll_q_512;
Craig Topper987dad22016-11-13 19:09:56 +00001705 else if (Size == 'w') // psll.wi.512, pslli.w, psll.w
1706 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_w_512
1707 : Intrinsic::x86_avx512_psll_w_512;
1708 else
1709 llvm_unreachable("Unexpected size");
1710 }
1711
1712 Rep = UpgradeX86MaskedShift(Builder, *CI, IID);
1713 } else if (IsX86 && Name.startswith("avx512.mask.psrl")) {
1714 bool IsImmediate = Name[16] == 'i' ||
1715 (Name.size() > 18 && Name[18] == 'i');
1716 bool IsVariable = Name[16] == 'v';
1717 char Size = Name[16] == '.' ? Name[17] :
1718 Name[17] == '.' ? Name[18] :
Craig Topper02b5a1b2016-11-18 05:04:44 +00001719 Name[18] == '.' ? Name[19] :
1720 Name[20];
Craig Topper987dad22016-11-13 19:09:56 +00001721
1722 Intrinsic::ID IID;
Craig Topper353e59b2016-11-14 01:53:22 +00001723 if (IsVariable && Name[17] != '.') {
Craig Topper987dad22016-11-13 19:09:56 +00001724 if (Size == 'd' && Name[17] == '2') // avx512.mask.psrlv2.di
1725 IID = Intrinsic::x86_avx2_psrlv_q;
1726 else if (Size == 'd' && Name[17] == '4') // avx512.mask.psrlv4.di
1727 IID = Intrinsic::x86_avx2_psrlv_q_256;
1728 else if (Size == 's' && Name[17] == '4') // avx512.mask.psrlv4.si
1729 IID = Intrinsic::x86_avx2_psrlv_d;
1730 else if (Size == 's' && Name[17] == '8') // avx512.mask.psrlv8.si
1731 IID = Intrinsic::x86_avx2_psrlv_d_256;
Craig Topper02b5a1b2016-11-18 05:04:44 +00001732 else if (Size == 'h' && Name[17] == '8') // avx512.mask.psrlv8.hi
1733 IID = Intrinsic::x86_avx512_psrlv_w_128;
1734 else if (Size == 'h' && Name[17] == '1') // avx512.mask.psrlv16.hi
1735 IID = Intrinsic::x86_avx512_psrlv_w_256;
1736 else if (Name[17] == '3' && Name[18] == '2') // avx512.mask.psrlv32hi
1737 IID = Intrinsic::x86_avx512_psrlv_w_512;
Craig Topper987dad22016-11-13 19:09:56 +00001738 else
1739 llvm_unreachable("Unexpected size");
1740 } else if (Name.endswith(".128")) {
1741 if (Size == 'd') // avx512.mask.psrl.d.128, avx512.mask.psrl.di.128
1742 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_d
1743 : Intrinsic::x86_sse2_psrl_d;
1744 else if (Size == 'q') // avx512.mask.psrl.q.128, avx512.mask.psrl.qi.128
1745 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_q
1746 : Intrinsic::x86_sse2_psrl_q;
1747 else if (Size == 'w') // avx512.mask.psrl.w.128, avx512.mask.psrl.wi.128
1748 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_w
1749 : Intrinsic::x86_sse2_psrl_w;
1750 else
1751 llvm_unreachable("Unexpected size");
1752 } else if (Name.endswith(".256")) {
1753 if (Size == 'd') // avx512.mask.psrl.d.256, avx512.mask.psrl.di.256
1754 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_d
1755 : Intrinsic::x86_avx2_psrl_d;
1756 else if (Size == 'q') // avx512.mask.psrl.q.256, avx512.mask.psrl.qi.256
1757 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_q
1758 : Intrinsic::x86_avx2_psrl_q;
1759 else if (Size == 'w') // avx512.mask.psrl.w.256, avx512.mask.psrl.wi.256
1760 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_w
1761 : Intrinsic::x86_avx2_psrl_w;
1762 else
1763 llvm_unreachable("Unexpected size");
1764 } else {
Craig Topper353e59b2016-11-14 01:53:22 +00001765 if (Size == 'd') // psrl.di.512, psrli.d, psrl.d, psrl.d.512
1766 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_d_512 :
1767 IsVariable ? Intrinsic::x86_avx512_psrlv_d_512 :
1768 Intrinsic::x86_avx512_psrl_d_512;
1769 else if (Size == 'q') // psrl.qi.512, psrli.q, psrl.q, psrl.q.512
1770 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_q_512 :
1771 IsVariable ? Intrinsic::x86_avx512_psrlv_q_512 :
1772 Intrinsic::x86_avx512_psrl_q_512;
Craig Topper987dad22016-11-13 19:09:56 +00001773 else if (Size == 'w') // psrl.wi.512, psrli.w, psrl.w)
1774 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_w_512
1775 : Intrinsic::x86_avx512_psrl_w_512;
1776 else
1777 llvm_unreachable("Unexpected size");
1778 }
1779
1780 Rep = UpgradeX86MaskedShift(Builder, *CI, IID);
1781 } else if (IsX86 && Name.startswith("avx512.mask.psra")) {
1782 bool IsImmediate = Name[16] == 'i' ||
1783 (Name.size() > 18 && Name[18] == 'i');
1784 bool IsVariable = Name[16] == 'v';
1785 char Size = Name[16] == '.' ? Name[17] :
1786 Name[17] == '.' ? Name[18] :
Craig Topper02b5a1b2016-11-18 05:04:44 +00001787 Name[18] == '.' ? Name[19] :
1788 Name[20];
Craig Topper987dad22016-11-13 19:09:56 +00001789
1790 Intrinsic::ID IID;
Craig Topper353e59b2016-11-14 01:53:22 +00001791 if (IsVariable && Name[17] != '.') {
Craig Topper987dad22016-11-13 19:09:56 +00001792 if (Size == 's' && Name[17] == '4') // avx512.mask.psrav4.si
1793 IID = Intrinsic::x86_avx2_psrav_d;
1794 else if (Size == 's' && Name[17] == '8') // avx512.mask.psrav8.si
1795 IID = Intrinsic::x86_avx2_psrav_d_256;
Craig Topper02b5a1b2016-11-18 05:04:44 +00001796 else if (Size == 'h' && Name[17] == '8') // avx512.mask.psrav8.hi
1797 IID = Intrinsic::x86_avx512_psrav_w_128;
1798 else if (Size == 'h' && Name[17] == '1') // avx512.mask.psrav16.hi
1799 IID = Intrinsic::x86_avx512_psrav_w_256;
1800 else if (Name[17] == '3' && Name[18] == '2') // avx512.mask.psrav32hi
1801 IID = Intrinsic::x86_avx512_psrav_w_512;
Craig Topper987dad22016-11-13 19:09:56 +00001802 else
1803 llvm_unreachable("Unexpected size");
1804 } else if (Name.endswith(".128")) {
1805 if (Size == 'd') // avx512.mask.psra.d.128, avx512.mask.psra.di.128
1806 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_d
1807 : Intrinsic::x86_sse2_psra_d;
1808 else if (Size == 'q') // avx512.mask.psra.q.128, avx512.mask.psra.qi.128
Craig Topper353e59b2016-11-14 01:53:22 +00001809 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_128 :
1810 IsVariable ? Intrinsic::x86_avx512_psrav_q_128 :
1811 Intrinsic::x86_avx512_psra_q_128;
Craig Topper987dad22016-11-13 19:09:56 +00001812 else if (Size == 'w') // avx512.mask.psra.w.128, avx512.mask.psra.wi.128
1813 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_w
1814 : Intrinsic::x86_sse2_psra_w;
1815 else
1816 llvm_unreachable("Unexpected size");
1817 } else if (Name.endswith(".256")) {
1818 if (Size == 'd') // avx512.mask.psra.d.256, avx512.mask.psra.di.256
1819 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_d
1820 : Intrinsic::x86_avx2_psra_d;
1821 else if (Size == 'q') // avx512.mask.psra.q.256, avx512.mask.psra.qi.256
Craig Topper353e59b2016-11-14 01:53:22 +00001822 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_256 :
1823 IsVariable ? Intrinsic::x86_avx512_psrav_q_256 :
1824 Intrinsic::x86_avx512_psra_q_256;
Craig Topper987dad22016-11-13 19:09:56 +00001825 else if (Size == 'w') // avx512.mask.psra.w.256, avx512.mask.psra.wi.256
1826 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_w
1827 : Intrinsic::x86_avx2_psra_w;
1828 else
1829 llvm_unreachable("Unexpected size");
1830 } else {
Craig Topper353e59b2016-11-14 01:53:22 +00001831 if (Size == 'd') // psra.di.512, psrai.d, psra.d, psrav.d.512
1832 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_d_512 :
1833 IsVariable ? Intrinsic::x86_avx512_psrav_d_512 :
1834 Intrinsic::x86_avx512_psra_d_512;
Craig Topper987dad22016-11-13 19:09:56 +00001835 else if (Size == 'q') // psra.qi.512, psrai.q, psra.q
Craig Topper353e59b2016-11-14 01:53:22 +00001836 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_512 :
1837 IsVariable ? Intrinsic::x86_avx512_psrav_q_512 :
1838 Intrinsic::x86_avx512_psra_q_512;
Craig Topper987dad22016-11-13 19:09:56 +00001839 else if (Size == 'w') // psra.wi.512, psrai.w, psra.w
1840 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_w_512
1841 : Intrinsic::x86_avx512_psra_w_512;
1842 else
1843 llvm_unreachable("Unexpected size");
1844 }
1845
1846 Rep = UpgradeX86MaskedShift(Builder, *CI, IID);
Ayman Musa4d602432016-11-16 09:00:28 +00001847 } else if (IsX86 && Name.startswith("avx512.mask.move.s")) {
1848 Rep = upgradeMaskedMove(Builder, *CI);
Michael Zuckerman88fb1712017-04-04 13:32:14 +00001849 } else if (IsX86 && Name.startswith("avx512.cvtmask2")) {
1850 Rep = UpgradeMaskToInt(Builder, *CI);
Craig Topperabe7c5b2016-12-10 21:15:52 +00001851 } else if (IsX86 && Name.startswith("avx512.mask.vpermilvar.")) {
1852 Intrinsic::ID IID;
1853 if (Name.endswith("ps.128"))
1854 IID = Intrinsic::x86_avx_vpermilvar_ps;
1855 else if (Name.endswith("pd.128"))
1856 IID = Intrinsic::x86_avx_vpermilvar_pd;
1857 else if (Name.endswith("ps.256"))
1858 IID = Intrinsic::x86_avx_vpermilvar_ps_256;
1859 else if (Name.endswith("pd.256"))
1860 IID = Intrinsic::x86_avx_vpermilvar_pd_256;
Craig Topper1f1b4412016-12-11 01:26:44 +00001861 else if (Name.endswith("ps.512"))
1862 IID = Intrinsic::x86_avx512_vpermilvar_ps_512;
1863 else if (Name.endswith("pd.512"))
1864 IID = Intrinsic::x86_avx512_vpermilvar_pd_512;
Craig Topperabe7c5b2016-12-10 21:15:52 +00001865 else
1866 llvm_unreachable("Unexpected vpermilvar intrinsic");
1867
1868 Function *Intrin = Intrinsic::getDeclaration(F->getParent(), IID);
1869 Rep = Builder.CreateCall(Intrin,
1870 { CI->getArgOperand(0), CI->getArgOperand(1) });
1871 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1872 CI->getArgOperand(2));
Justin Lebar46624a82017-01-21 01:00:32 +00001873 } else if (IsNVVM && (Name == "abs.i" || Name == "abs.ll")) {
1874 Value *Arg = CI->getArgOperand(0);
1875 Value *Neg = Builder.CreateNeg(Arg, "neg");
1876 Value *Cmp = Builder.CreateICmpSGE(
1877 Arg, llvm::Constant::getNullValue(Arg->getType()), "abs.cond");
1878 Rep = Builder.CreateSelect(Cmp, Arg, Neg, "abs");
1879 } else if (IsNVVM && (Name == "max.i" || Name == "max.ll" ||
1880 Name == "max.ui" || Name == "max.ull")) {
1881 Value *Arg0 = CI->getArgOperand(0);
1882 Value *Arg1 = CI->getArgOperand(1);
1883 Value *Cmp = Name.endswith(".ui") || Name.endswith(".ull")
1884 ? Builder.CreateICmpUGE(Arg0, Arg1, "max.cond")
1885 : Builder.CreateICmpSGE(Arg0, Arg1, "max.cond");
1886 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1, "max");
1887 } else if (IsNVVM && (Name == "min.i" || Name == "min.ll" ||
1888 Name == "min.ui" || Name == "min.ull")) {
1889 Value *Arg0 = CI->getArgOperand(0);
1890 Value *Arg1 = CI->getArgOperand(1);
1891 Value *Cmp = Name.endswith(".ui") || Name.endswith(".ull")
1892 ? Builder.CreateICmpULE(Arg0, Arg1, "min.cond")
1893 : Builder.CreateICmpSLE(Arg0, Arg1, "min.cond");
1894 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1, "min");
1895 } else if (IsNVVM && Name == "clz.ll") {
1896 // llvm.nvvm.clz.ll returns an i32, but llvm.ctlz.i64 and returns an i64.
1897 Value *Arg = CI->getArgOperand(0);
1898 Value *Ctlz = Builder.CreateCall(
1899 Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
1900 {Arg->getType()}),
1901 {Arg, Builder.getFalse()}, "ctlz");
1902 Rep = Builder.CreateTrunc(Ctlz, Builder.getInt32Ty(), "ctlz.trunc");
1903 } else if (IsNVVM && Name == "popc.ll") {
1904 // llvm.nvvm.popc.ll returns an i32, but llvm.ctpop.i64 and returns an
1905 // i64.
1906 Value *Arg = CI->getArgOperand(0);
1907 Value *Popc = Builder.CreateCall(
1908 Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctpop,
1909 {Arg->getType()}),
1910 Arg, "ctpop");
1911 Rep = Builder.CreateTrunc(Popc, Builder.getInt32Ty(), "ctpop.trunc");
1912 } else if (IsNVVM && Name == "h2f") {
1913 Rep = Builder.CreateCall(Intrinsic::getDeclaration(
1914 F->getParent(), Intrinsic::convert_from_fp16,
1915 {Builder.getFloatTy()}),
1916 CI->getArgOperand(0), "h2f");
Craig Topper3b1817d2012-02-03 06:10:55 +00001917 } else {
Craig Topper8a105052016-06-12 03:10:47 +00001918 llvm_unreachable("Unknown function for CallInst upgrade.");
Craig Topper3b1817d2012-02-03 06:10:55 +00001919 }
1920
Tim Shen00127562016-04-08 21:26:31 +00001921 if (Rep)
1922 CI->replaceAllUsesWith(Rep);
Craig Topper3b1817d2012-02-03 06:10:55 +00001923 CI->eraseFromParent();
1924 return;
1925 }
1926
Daniel Berlin3f910042017-03-01 01:49:13 +00001927 CallInst *NewCall = nullptr;
Chandler Carruth58a71ed2011-12-12 04:26:04 +00001928 switch (NewFn->getIntrinsicID()) {
Daniel Berlin3c1432f2017-02-15 23:16:20 +00001929 default: {
1930 // Handle generic mangling change, but nothing else
1931 assert(
1932 (CI->getCalledFunction()->getName() != NewFn->getName()) &&
1933 "Unknown function for CallInst upgrade and isn't just a name change");
Daniel Berlin3f910042017-03-01 01:49:13 +00001934 CI->setCalledFunction(NewFn);
Daniel Berlin3c1432f2017-02-15 23:16:20 +00001935 return;
1936 }
Chandler Carruth58a71ed2011-12-12 04:26:04 +00001937
Jeroen Ketemaab99b592015-09-30 10:56:37 +00001938 case Intrinsic::arm_neon_vld1:
1939 case Intrinsic::arm_neon_vld2:
1940 case Intrinsic::arm_neon_vld3:
1941 case Intrinsic::arm_neon_vld4:
1942 case Intrinsic::arm_neon_vld2lane:
1943 case Intrinsic::arm_neon_vld3lane:
1944 case Intrinsic::arm_neon_vld4lane:
1945 case Intrinsic::arm_neon_vst1:
1946 case Intrinsic::arm_neon_vst2:
1947 case Intrinsic::arm_neon_vst3:
1948 case Intrinsic::arm_neon_vst4:
1949 case Intrinsic::arm_neon_vst2lane:
1950 case Intrinsic::arm_neon_vst3lane:
1951 case Intrinsic::arm_neon_vst4lane: {
1952 SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
1953 CI->arg_operands().end());
Daniel Berlin3f910042017-03-01 01:49:13 +00001954 NewCall = Builder.CreateCall(NewFn, Args);
1955 break;
Jeroen Ketemaab99b592015-09-30 10:56:37 +00001956 }
1957
Chad Rosier3daffbf2017-01-10 17:20:33 +00001958 case Intrinsic::bitreverse:
Daniel Berlin3f910042017-03-01 01:49:13 +00001959 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
1960 break;
Chad Rosier3daffbf2017-01-10 17:20:33 +00001961
Chandler Carruth58a71ed2011-12-12 04:26:04 +00001962 case Intrinsic::ctlz:
Nuno Lopesad40c0a2012-05-22 15:25:31 +00001963 case Intrinsic::cttz:
Chandler Carruth58a71ed2011-12-12 04:26:04 +00001964 assert(CI->getNumArgOperands() == 1 &&
1965 "Mismatch between function args and call args");
Daniel Berlin3f910042017-03-01 01:49:13 +00001966 NewCall =
1967 Builder.CreateCall(NewFn, {CI->getArgOperand(0), Builder.getFalse()});
1968 break;
Nadav Rotem17ee58a2012-06-10 18:42:51 +00001969
George Burgess IV56c7e882017-03-21 20:08:59 +00001970 case Intrinsic::objectsize: {
1971 Value *NullIsUnknownSize = CI->getNumArgOperands() == 2
1972 ? Builder.getFalse()
1973 : CI->getArgOperand(2);
1974 NewCall = Builder.CreateCall(
1975 NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize});
Daniel Berlin3f910042017-03-01 01:49:13 +00001976 break;
George Burgess IV56c7e882017-03-21 20:08:59 +00001977 }
Matt Arsenaultfbcbce42013-10-07 18:06:48 +00001978
Justin Lebar46624a82017-01-21 01:00:32 +00001979 case Intrinsic::ctpop:
Daniel Berlin3f910042017-03-01 01:49:13 +00001980 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
1981 break;
Justin Lebar46624a82017-01-21 01:00:32 +00001982
1983 case Intrinsic::convert_from_fp16:
Daniel Berlin3f910042017-03-01 01:49:13 +00001984 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
1985 break;
Joel Jones43cb8782012-07-13 23:25:25 +00001986
Craig Topper71dc02d2012-06-13 07:18:53 +00001987 case Intrinsic::x86_xop_vfrcz_ss:
1988 case Intrinsic::x86_xop_vfrcz_sd:
Daniel Berlin3f910042017-03-01 01:49:13 +00001989 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(1)});
1990 break;
Craig Topper71dc02d2012-06-13 07:18:53 +00001991
Simon Pilgrime85506b2016-06-03 08:06:03 +00001992 case Intrinsic::x86_xop_vpermil2pd:
1993 case Intrinsic::x86_xop_vpermil2ps:
1994 case Intrinsic::x86_xop_vpermil2pd_256:
1995 case Intrinsic::x86_xop_vpermil2ps_256: {
1996 SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
1997 CI->arg_operands().end());
1998 VectorType *FltIdxTy = cast<VectorType>(Args[2]->getType());
1999 VectorType *IntIdxTy = VectorType::getInteger(FltIdxTy);
2000 Args[2] = Builder.CreateBitCast(Args[2], IntIdxTy);
Daniel Berlin3f910042017-03-01 01:49:13 +00002001 NewCall = Builder.CreateCall(NewFn, Args);
2002 break;
Simon Pilgrime85506b2016-06-03 08:06:03 +00002003 }
2004
Nadav Rotem17ee58a2012-06-10 18:42:51 +00002005 case Intrinsic::x86_sse41_ptestc:
2006 case Intrinsic::x86_sse41_ptestz:
Craig Topper71dc02d2012-06-13 07:18:53 +00002007 case Intrinsic::x86_sse41_ptestnzc: {
Nadav Rotem17ee58a2012-06-10 18:42:51 +00002008 // The arguments for these intrinsics used to be v4f32, and changed
2009 // to v2i64. This is purely a nop, since those are bitwise intrinsics.
2010 // So, the only thing required is a bitcast for both arguments.
2011 // First, check the arguments have the old type.
2012 Value *Arg0 = CI->getArgOperand(0);
2013 if (Arg0->getType() != VectorType::get(Type::getFloatTy(C), 4))
2014 return;
2015
2016 // Old intrinsic, add bitcasts
2017 Value *Arg1 = CI->getArgOperand(1);
2018
David Blaikie5bacf372015-04-24 21:16:07 +00002019 Type *NewVecTy = VectorType::get(Type::getInt64Ty(C), 2);
Nadav Rotem17ee58a2012-06-10 18:42:51 +00002020
David Blaikie5bacf372015-04-24 21:16:07 +00002021 Value *BC0 = Builder.CreateBitCast(Arg0, NewVecTy, "cast");
2022 Value *BC1 = Builder.CreateBitCast(Arg1, NewVecTy, "cast");
2023
Daniel Berlin3f910042017-03-01 01:49:13 +00002024 NewCall = Builder.CreateCall(NewFn, {BC0, BC1});
2025 break;
Evan Cheng0e179d02007-12-17 22:33:23 +00002026 }
Chandler Carruth373b2b12014-09-06 10:00:01 +00002027
Chandler Carruth373b2b12014-09-06 10:00:01 +00002028 case Intrinsic::x86_sse41_insertps:
2029 case Intrinsic::x86_sse41_dppd:
2030 case Intrinsic::x86_sse41_dpps:
2031 case Intrinsic::x86_sse41_mpsadbw:
Chandler Carruth373b2b12014-09-06 10:00:01 +00002032 case Intrinsic::x86_avx_dp_ps_256:
Chandler Carruth373b2b12014-09-06 10:00:01 +00002033 case Intrinsic::x86_avx2_mpsadbw: {
2034 // Need to truncate the last argument from i32 to i8 -- this argument models
2035 // an inherently 8-bit immediate operand to these x86 instructions.
2036 SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
2037 CI->arg_operands().end());
2038
2039 // Replace the last argument with a trunc.
2040 Args.back() = Builder.CreateTrunc(Args.back(), Type::getInt8Ty(C), "trunc");
Daniel Berlin3f910042017-03-01 01:49:13 +00002041 NewCall = Builder.CreateCall(NewFn, Args);
2042 break;
Chandler Carruth373b2b12014-09-06 10:00:01 +00002043 }
Marcin Koscielnicki3fdc2572016-04-19 20:51:05 +00002044
2045 case Intrinsic::thread_pointer: {
Daniel Berlin3f910042017-03-01 01:49:13 +00002046 NewCall = Builder.CreateCall(NewFn, {});
2047 break;
Marcin Koscielnicki3fdc2572016-04-19 20:51:05 +00002048 }
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +00002049
Mehdi Amini8c629ec2016-08-13 23:31:24 +00002050 case Intrinsic::invariant_start:
2051 case Intrinsic::invariant_end:
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +00002052 case Intrinsic::masked_load:
2053 case Intrinsic::masked_store: {
2054 SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
2055 CI->arg_operands().end());
Daniel Berlin3f910042017-03-01 01:49:13 +00002056 NewCall = Builder.CreateCall(NewFn, Args);
2057 break;
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +00002058 }
Craig Topper71dc02d2012-06-13 07:18:53 +00002059 }
Daniel Berlin3f910042017-03-01 01:49:13 +00002060 assert(NewCall && "Should have either set this variable or returned through "
2061 "the default case");
2062 std::string Name = CI->getName();
2063 if (!Name.empty()) {
2064 CI->setName(Name + ".old");
2065 NewCall->setName(Name);
2066 }
2067 CI->replaceAllUsesWith(NewCall);
2068 CI->eraseFromParent();
Chandler Carruth7132e002007-08-04 01:51:18 +00002069}
2070
Sanjay Patelfdf0d5f2016-04-18 19:11:57 +00002071void llvm::UpgradeCallsToIntrinsic(Function *F) {
Chandler Carruth7132e002007-08-04 01:51:18 +00002072 assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
2073
Sanjay Patelfdf0d5f2016-04-18 19:11:57 +00002074 // Check if this function should be upgraded and get the replacement function
2075 // if there is one.
Chris Lattner80ed9dc2011-06-18 06:05:24 +00002076 Function *NewFn;
Evan Cheng0e179d02007-12-17 22:33:23 +00002077 if (UpgradeIntrinsicFunction(F, NewFn)) {
Sanjay Patelfdf0d5f2016-04-18 19:11:57 +00002078 // Replace all users of the old function with the new function or new
2079 // instructions. This is not a range loop because the call is deleted.
2080 for (auto UI = F->user_begin(), UE = F->user_end(); UI != UE; )
Duncan P. N. Exon Smith93f53c42016-04-17 03:59:37 +00002081 if (CallInst *CI = dyn_cast<CallInst>(*UI++))
Filipe Cabecinhas0011c582015-07-03 20:12:01 +00002082 UpgradeIntrinsicCall(CI, NewFn);
Sanjay Patelfdf0d5f2016-04-18 19:11:57 +00002083
Filipe Cabecinhas0011c582015-07-03 20:12:01 +00002084 // Remove old function, no longer used, from the module.
2085 F->eraseFromParent();
Chandler Carruth7132e002007-08-04 01:51:18 +00002086 }
2087}
Devang Patel80ae3492009-08-28 23:24:31 +00002088
Mehdi Aminie4709272016-09-14 22:29:59 +00002089MDNode *llvm::UpgradeTBAANode(MDNode &MD) {
Manman Ren209b17c2013-09-28 00:22:27 +00002090 // Check if the tag uses struct-path aware TBAA format.
Mehdi Aminie4709272016-09-14 22:29:59 +00002091 if (isa<MDNode>(MD.getOperand(0)) && MD.getNumOperands() >= 3)
2092 return &MD;
Manman Ren209b17c2013-09-28 00:22:27 +00002093
Mehdi Aminie4709272016-09-14 22:29:59 +00002094 auto &Context = MD.getContext();
2095 if (MD.getNumOperands() == 3) {
2096 Metadata *Elts[] = {MD.getOperand(0), MD.getOperand(1)};
2097 MDNode *ScalarType = MDNode::get(Context, Elts);
Manman Ren209b17c2013-09-28 00:22:27 +00002098 // Create a MDNode <ScalarType, ScalarType, offset 0, const>
Duncan P. N. Exon Smith5bf8fef2014-12-09 18:38:53 +00002099 Metadata *Elts2[] = {ScalarType, ScalarType,
Mehdi Aminie4709272016-09-14 22:29:59 +00002100 ConstantAsMetadata::get(
2101 Constant::getNullValue(Type::getInt64Ty(Context))),
2102 MD.getOperand(2)};
2103 return MDNode::get(Context, Elts2);
Manman Ren209b17c2013-09-28 00:22:27 +00002104 }
Mehdi Aminie4709272016-09-14 22:29:59 +00002105 // Create a MDNode <MD, MD, offset 0>
2106 Metadata *Elts[] = {&MD, &MD, ConstantAsMetadata::get(Constant::getNullValue(
2107 Type::getInt64Ty(Context)))};
2108 return MDNode::get(Context, Elts);
Manman Ren209b17c2013-09-28 00:22:27 +00002109}
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00002110
2111Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy,
2112 Instruction *&Temp) {
2113 if (Opc != Instruction::BitCast)
Craig Topperc6207612014-04-09 06:08:46 +00002114 return nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00002115
Craig Topperc6207612014-04-09 06:08:46 +00002116 Temp = nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00002117 Type *SrcTy = V->getType();
2118 if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() &&
2119 SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) {
2120 LLVMContext &Context = V->getContext();
2121
2122 // We have no information about target data layout, so we assume that
2123 // the maximum pointer size is 64bit.
2124 Type *MidTy = Type::getInt64Ty(Context);
2125 Temp = CastInst::Create(Instruction::PtrToInt, V, MidTy);
2126
2127 return CastInst::Create(Instruction::IntToPtr, Temp, DestTy);
2128 }
2129
Craig Topperc6207612014-04-09 06:08:46 +00002130 return nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00002131}
2132
2133Value *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) {
2134 if (Opc != Instruction::BitCast)
Craig Topperc6207612014-04-09 06:08:46 +00002135 return nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00002136
2137 Type *SrcTy = C->getType();
2138 if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() &&
2139 SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) {
2140 LLVMContext &Context = C->getContext();
2141
2142 // We have no information about target data layout, so we assume that
2143 // the maximum pointer size is 64bit.
2144 Type *MidTy = Type::getInt64Ty(Context);
2145
2146 return ConstantExpr::getIntToPtr(ConstantExpr::getPtrToInt(C, MidTy),
2147 DestTy);
2148 }
2149
Craig Topperc6207612014-04-09 06:08:46 +00002150 return nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00002151}
Manman Ren8b4306c2013-12-02 21:29:56 +00002152
2153/// Check the debug info version number, if it is out-dated, drop the debug
2154/// info. Return true if module is modified.
2155bool llvm::UpgradeDebugInfo(Module &M) {
Manman Ren2ebfb422014-01-16 01:51:12 +00002156 unsigned Version = getDebugMetadataVersionFromModule(M);
2157 if (Version == DEBUG_METADATA_VERSION)
Manman Ren8b4306c2013-12-02 21:29:56 +00002158 return false;
2159
Manman Ren2ebfb422014-01-16 01:51:12 +00002160 bool RetCode = StripDebugInfo(M);
2161 if (RetCode) {
2162 DiagnosticInfoDebugMetadataVersion DiagVersion(M, Version);
2163 M.getContext().diagnose(DiagVersion);
2164 }
2165 return RetCode;
Manman Ren8b4306c2013-12-02 21:29:56 +00002166}
Eli Bendersky5d5e18d2014-06-25 15:41:00 +00002167
Manman Renb5d7ff42016-05-25 23:14:48 +00002168bool llvm::UpgradeModuleFlags(Module &M) {
2169 const NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
2170 if (!ModFlags)
2171 return false;
2172
2173 bool HasObjCFlag = false, HasClassProperties = false;
2174 for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
2175 MDNode *Op = ModFlags->getOperand(I);
2176 if (Op->getNumOperands() < 2)
2177 continue;
2178 MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1));
2179 if (!ID)
2180 continue;
2181 if (ID->getString() == "Objective-C Image Info Version")
2182 HasObjCFlag = true;
2183 if (ID->getString() == "Objective-C Class Properties")
2184 HasClassProperties = true;
2185 }
2186 // "Objective-C Class Properties" is recently added for Objective-C. We
2187 // upgrade ObjC bitcodes to contain a "Objective-C Class Properties" module
Mehdi Aminib53b62e2016-09-16 00:38:18 +00002188 // flag of value 0, so we can correclty downgrade this flag when trying to
2189 // link an ObjC bitcode without this module flag with an ObjC bitcode with
2190 // this module flag.
Manman Renb5d7ff42016-05-25 23:14:48 +00002191 if (HasObjCFlag && !HasClassProperties) {
Mehdi Aminib53b62e2016-09-16 00:38:18 +00002192 M.addModuleFlag(llvm::Module::Override, "Objective-C Class Properties",
Manman Renb5d7ff42016-05-25 23:14:48 +00002193 (uint32_t)0);
2194 return true;
2195 }
2196 return false;
2197}
2198
Duncan P. N. Exon Smithefe16c82016-03-25 00:56:13 +00002199static bool isOldLoopArgument(Metadata *MD) {
2200 auto *T = dyn_cast_or_null<MDTuple>(MD);
2201 if (!T)
2202 return false;
2203 if (T->getNumOperands() < 1)
2204 return false;
2205 auto *S = dyn_cast_or_null<MDString>(T->getOperand(0));
2206 if (!S)
2207 return false;
2208 return S->getString().startswith("llvm.vectorizer.");
2209}
2210
2211static MDString *upgradeLoopTag(LLVMContext &C, StringRef OldTag) {
2212 StringRef OldPrefix = "llvm.vectorizer.";
2213 assert(OldTag.startswith(OldPrefix) && "Expected old prefix");
2214
2215 if (OldTag == "llvm.vectorizer.unroll")
2216 return MDString::get(C, "llvm.loop.interleave.count");
2217
2218 return MDString::get(
2219 C, (Twine("llvm.loop.vectorize.") + OldTag.drop_front(OldPrefix.size()))
2220 .str());
2221}
2222
2223static Metadata *upgradeLoopArgument(Metadata *MD) {
2224 auto *T = dyn_cast_or_null<MDTuple>(MD);
2225 if (!T)
2226 return MD;
2227 if (T->getNumOperands() < 1)
2228 return MD;
2229 auto *OldTag = dyn_cast_or_null<MDString>(T->getOperand(0));
2230 if (!OldTag)
2231 return MD;
2232 if (!OldTag->getString().startswith("llvm.vectorizer."))
2233 return MD;
2234
2235 // This has an old tag. Upgrade it.
2236 SmallVector<Metadata *, 8> Ops;
2237 Ops.reserve(T->getNumOperands());
2238 Ops.push_back(upgradeLoopTag(T->getContext(), OldTag->getString()));
2239 for (unsigned I = 1, E = T->getNumOperands(); I != E; ++I)
2240 Ops.push_back(T->getOperand(I));
2241
2242 return MDTuple::get(T->getContext(), Ops);
2243}
2244
2245MDNode *llvm::upgradeInstructionLoopAttachment(MDNode &N) {
2246 auto *T = dyn_cast<MDTuple>(&N);
2247 if (!T)
2248 return &N;
2249
David Majnemer0a16c222016-08-11 21:15:00 +00002250 if (none_of(T->operands(), isOldLoopArgument))
Duncan P. N. Exon Smithefe16c82016-03-25 00:56:13 +00002251 return &N;
2252
2253 SmallVector<Metadata *, 8> Ops;
2254 Ops.reserve(T->getNumOperands());
2255 for (Metadata *MD : T->operands())
2256 Ops.push_back(upgradeLoopArgument(MD));
2257
2258 return MDTuple::get(T->getContext(), Ops);
Eli Bendersky5d5e18d2014-06-25 15:41:00 +00002259}