blob: 609048e00ba7ff4388e403df299f874e16f9af4d [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 Carruth9fb823b2013-01-02 11:36:10 +000018#include "llvm/IR/Constants.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000019#include "llvm/IR/DIBuilder.h"
Chandler Carruth9a4c9e52014-03-06 00:46:21 +000020#include "llvm/IR/DebugInfo.h"
Manman Ren2ebfb422014-01-16 01:51:12 +000021#include "llvm/IR/DiagnosticInfo.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000022#include "llvm/IR/Function.h"
23#include "llvm/IR/IRBuilder.h"
24#include "llvm/IR/Instruction.h"
Daniel Neilson1e687242018-01-19 17:13:12 +000025#include "llvm/IR/IntrinsicInst.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000026#include "llvm/IR/LLVMContext.h"
27#include "llvm/IR/Module.h"
Adrian Prantla8b2ddb2017-10-02 18:31:29 +000028#include "llvm/IR/Verifier.h"
Torok Edwin56d06592009-07-11 20:10:48 +000029#include "llvm/Support/ErrorHandling.h"
Jeroen Ketemaab99b592015-09-30 10:56:37 +000030#include "llvm/Support/Regex.h"
Anton Korobeynikov579f0712008-02-20 11:08:44 +000031#include <cstring>
Chandler Carruth7132e002007-08-04 01:51:18 +000032using namespace llvm;
33
Rafael Espindolad7325ee2016-10-03 15:51:42 +000034static void rename(GlobalValue *GV) { GV->setName(GV->getName() + ".old"); }
35
Craig Topper905cc752017-02-17 07:07:21 +000036// Upgrade the declarations of the SSE4.1 ptest intrinsics whose arguments have
Nadav Rotem17ee58a2012-06-10 18:42:51 +000037// changed their type from v4f32 to v2i64.
Craig Topper905cc752017-02-17 07:07:21 +000038static bool UpgradePTESTIntrinsic(Function* F, Intrinsic::ID IID,
39 Function *&NewFn) {
Nadav Rotem17ee58a2012-06-10 18:42:51 +000040 // Check whether this is an old version of the function, which received
41 // v4f32 arguments.
42 Type *Arg0Type = F->getFunctionType()->getParamType(0);
43 if (Arg0Type != VectorType::get(Type::getFloatTy(F->getContext()), 4))
44 return false;
45
46 // Yes, it's old, replace it with new version.
Rafael Espindolad7325ee2016-10-03 15:51:42 +000047 rename(F);
Nadav Rotem17ee58a2012-06-10 18:42:51 +000048 NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
49 return true;
50}
Chandler Carruth7132e002007-08-04 01:51:18 +000051
Chandler Carruth373b2b12014-09-06 10:00:01 +000052// Upgrade the declarations of intrinsic functions whose 8-bit immediate mask
53// arguments have changed their type from i32 to i8.
54static bool UpgradeX86IntrinsicsWith8BitMask(Function *F, Intrinsic::ID IID,
55 Function *&NewFn) {
56 // Check that the last argument is an i32.
57 Type *LastArgType = F->getFunctionType()->getParamType(
58 F->getFunctionType()->getNumParams() - 1);
59 if (!LastArgType->isIntegerTy(32))
60 return false;
61
62 // Move this function aside and map down.
Rafael Espindolad7325ee2016-10-03 15:51:42 +000063 rename(F);
Chandler Carruth373b2b12014-09-06 10:00:01 +000064 NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
65 return true;
66}
67
Craig Topper4dccffc82018-02-10 23:33:55 +000068// Upgrade the declaration of fp compare intrinsics that change return type
69// from scalar to vXi1 mask.
70static bool UpgradeX86MaskedFPCompare(Function *F, Intrinsic::ID IID,
71 Function *&NewFn) {
72 // Check if the return type is a vector.
73 if (F->getReturnType()->isVectorTy())
74 return false;
75
76 rename(F);
77 NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
78 return true;
79}
80
Craig Topperb9b9cb02017-02-17 07:07:19 +000081static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
82 // All of the intrinsics matches below should be marked with which llvm
83 // version started autoupgrading them. At some point in the future we would
84 // like to use this information to remove upgrade code for some older
85 // intrinsics. It is currently undecided how we will determine that future
86 // point.
Chandler Carruth16429ac2018-04-26 21:46:01 +000087 if (Name=="ssse3.pabs.b.128" || // Added in 6.0
Uriel Korach5d5da5f2017-09-13 09:02:36 +000088 Name=="ssse3.pabs.w.128" || // Added in 6.0
89 Name=="ssse3.pabs.d.128" || // Added in 6.0
Craig Toppera17d6272018-05-11 21:59:34 +000090 Name.startswith("fma.vfmsub.") || // Added in 7.0
91 Name.startswith("fma.vfmsubadd.") || // Added in 7.0
92 Name.startswith("fma.vfnmadd.") || // Added in 7.0
93 Name.startswith("fma.vfnmsub.") || // Added in 7.0
Jina Nahias9a7f9f12017-11-13 09:16:39 +000094 Name.startswith("avx512.mask.shuf.i") || // Added in 6.0
95 Name.startswith("avx512.mask.shuf.f") || // Added in 6.0
Jina Nahias51c1a622017-12-05 15:42:56 +000096 Name.startswith("avx512.kunpck") || //added in 6.0
Uriel Korach5d5da5f2017-09-13 09:02:36 +000097 Name.startswith("avx2.pabs.") || // Added in 6.0
98 Name.startswith("avx512.mask.pabs.") || // Added in 6.0
Jina Nahias7b705f12017-11-06 07:09:24 +000099 Name.startswith("avx512.broadcastm") || // Added in 6.0
Jina Nahiasccfb8d42017-09-19 11:03:06 +0000100 Name.startswith("avx512.mask.pbroadcast") || // Added in 6.0
Uriel Korach5d5da5f2017-09-13 09:02:36 +0000101 Name.startswith("sse2.pcmpeq.") || // Added in 3.1
Craig Topperb9b9cb02017-02-17 07:07:19 +0000102 Name.startswith("sse2.pcmpgt.") || // Added in 3.1
103 Name.startswith("avx2.pcmpeq.") || // Added in 3.1
104 Name.startswith("avx2.pcmpgt.") || // Added in 3.1
105 Name.startswith("avx512.mask.pcmpeq.") || // Added in 3.9
106 Name.startswith("avx512.mask.pcmpgt.") || // Added in 3.9
Craig Topperf264fcc2017-09-16 07:36:14 +0000107 Name.startswith("avx.vperm2f128.") || // Added in 6.0
108 Name == "avx2.vperm2i128" || // Added in 6.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000109 Name == "sse.add.ss" || // Added in 4.0
110 Name == "sse2.add.sd" || // Added in 4.0
111 Name == "sse.sub.ss" || // Added in 4.0
112 Name == "sse2.sub.sd" || // Added in 4.0
113 Name == "sse.mul.ss" || // Added in 4.0
114 Name == "sse2.mul.sd" || // Added in 4.0
115 Name == "sse.div.ss" || // Added in 4.0
116 Name == "sse2.div.sd" || // Added in 4.0
117 Name == "sse41.pmaxsb" || // Added in 3.9
118 Name == "sse2.pmaxs.w" || // Added in 3.9
119 Name == "sse41.pmaxsd" || // Added in 3.9
120 Name == "sse2.pmaxu.b" || // Added in 3.9
121 Name == "sse41.pmaxuw" || // Added in 3.9
122 Name == "sse41.pmaxud" || // Added in 3.9
123 Name == "sse41.pminsb" || // Added in 3.9
124 Name == "sse2.pmins.w" || // Added in 3.9
125 Name == "sse41.pminsd" || // Added in 3.9
126 Name == "sse2.pminu.b" || // Added in 3.9
127 Name == "sse41.pminuw" || // Added in 3.9
128 Name == "sse41.pminud" || // Added in 3.9
Craig Topper071ad9c2018-02-03 20:18:25 +0000129 Name == "avx512.kand.w" || // Added in 7.0
130 Name == "avx512.kandn.w" || // Added in 7.0
131 Name == "avx512.knot.w" || // Added in 7.0
132 Name == "avx512.kor.w" || // Added in 7.0
133 Name == "avx512.kxor.w" || // Added in 7.0
134 Name == "avx512.kxnor.w" || // Added in 7.0
Craig Topperdccf72b2018-02-08 20:16:06 +0000135 Name == "avx512.kortestc.w" || // Added in 7.0
136 Name == "avx512.kortestz.w" || // Added in 7.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000137 Name.startswith("avx512.mask.pshuf.b.") || // Added in 4.0
138 Name.startswith("avx2.pmax") || // Added in 3.9
139 Name.startswith("avx2.pmin") || // Added in 3.9
140 Name.startswith("avx512.mask.pmax") || // Added in 4.0
141 Name.startswith("avx512.mask.pmin") || // Added in 4.0
142 Name.startswith("avx2.vbroadcast") || // Added in 3.8
143 Name.startswith("avx2.pbroadcast") || // Added in 3.8
144 Name.startswith("avx.vpermil.") || // Added in 3.1
145 Name.startswith("sse2.pshuf") || // Added in 3.9
146 Name.startswith("avx512.pbroadcast") || // Added in 3.9
147 Name.startswith("avx512.mask.broadcast.s") || // Added in 3.9
148 Name.startswith("avx512.mask.movddup") || // Added in 3.9
149 Name.startswith("avx512.mask.movshdup") || // Added in 3.9
150 Name.startswith("avx512.mask.movsldup") || // Added in 3.9
151 Name.startswith("avx512.mask.pshuf.d.") || // Added in 3.9
152 Name.startswith("avx512.mask.pshufl.w.") || // Added in 3.9
153 Name.startswith("avx512.mask.pshufh.w.") || // Added in 3.9
154 Name.startswith("avx512.mask.shuf.p") || // Added in 4.0
155 Name.startswith("avx512.mask.vpermil.p") || // Added in 3.9
156 Name.startswith("avx512.mask.perm.df.") || // Added in 3.9
157 Name.startswith("avx512.mask.perm.di.") || // Added in 3.9
158 Name.startswith("avx512.mask.punpckl") || // Added in 3.9
159 Name.startswith("avx512.mask.punpckh") || // Added in 3.9
160 Name.startswith("avx512.mask.unpckl.") || // Added in 3.9
161 Name.startswith("avx512.mask.unpckh.") || // Added in 3.9
162 Name.startswith("avx512.mask.pand.") || // Added in 3.9
163 Name.startswith("avx512.mask.pandn.") || // Added in 3.9
164 Name.startswith("avx512.mask.por.") || // Added in 3.9
165 Name.startswith("avx512.mask.pxor.") || // Added in 3.9
166 Name.startswith("avx512.mask.and.") || // Added in 3.9
167 Name.startswith("avx512.mask.andn.") || // Added in 3.9
168 Name.startswith("avx512.mask.or.") || // Added in 3.9
169 Name.startswith("avx512.mask.xor.") || // Added in 3.9
170 Name.startswith("avx512.mask.padd.") || // Added in 4.0
171 Name.startswith("avx512.mask.psub.") || // Added in 4.0
172 Name.startswith("avx512.mask.pmull.") || // Added in 4.0
173 Name.startswith("avx512.mask.cvtdq2pd.") || // Added in 4.0
174 Name.startswith("avx512.mask.cvtudq2pd.") || // Added in 4.0
Craig Topper358b0942018-05-21 23:15:00 +0000175 Name == "avx512.mask.cvtudq2ps.128" || // Added in 7.0
176 Name == "avx512.mask.cvtudq2ps.256" || // Added in 7.0
177 Name == "avx512.mask.cvtqq2pd.128" || // Added in 7.0
178 Name == "avx512.mask.cvtqq2pd.256" || // Added in 7.0
179 Name == "avx512.mask.cvtuqq2pd.128" || // Added in 7.0
180 Name == "avx512.mask.cvtuqq2pd.256" || // Added in 7.0
Craig Toppera288f242018-05-12 02:34:28 +0000181 Name == "avx512.mask.cvtdq2ps.128" || // Added in 7.0
182 Name == "avx512.mask.cvtdq2ps.256" || // Added in 7.0
183 Name == "avx512.mask.cvtpd2dq.256" || // Added in 7.0
184 Name == "avx512.mask.cvtpd2ps.256" || // Added in 7.0
185 Name == "avx512.mask.cvttpd2dq.256" || // Added in 7.0
186 Name == "avx512.mask.cvttps2dq.128" || // Added in 7.0
187 Name == "avx512.mask.cvttps2dq.256" || // Added in 7.0
188 Name == "avx512.mask.cvtps2pd.128" || // Added in 7.0
189 Name == "avx512.mask.cvtps2pd.256" || // Added in 7.0
Craig Topper0e71c6d2018-05-14 00:06:49 +0000190 Name == "avx512.cvtusi2sd" || // Added in 7.0
Craig Toppere4c045b2018-05-20 23:34:04 +0000191 Name.startswith("avx512.mask.permvar.") || // Added in 7.0
192 Name.startswith("avx512.mask.permvar.") || // Added in 7.0
Craig Topper254ed022018-04-13 06:07:18 +0000193 Name == "sse2.pmulu.dq" || // Added in 7.0
194 Name == "sse41.pmuldq" || // Added in 7.0
195 Name == "avx2.pmulu.dq" || // Added in 7.0
196 Name == "avx2.pmul.dq" || // Added in 7.0
197 Name == "avx512.pmulu.dq.512" || // Added in 7.0
198 Name == "avx512.pmul.dq.512" || // Added in 7.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000199 Name.startswith("avx512.mask.pmul.dq.") || // Added in 4.0
200 Name.startswith("avx512.mask.pmulu.dq.") || // Added in 4.0
Craig Topper9256ac12018-02-20 07:28:14 +0000201 Name.startswith("avx512.mask.pmul.hr.sw.") || // Added in 7.0
202 Name.startswith("avx512.mask.pmulh.w.") || // Added in 7.0
203 Name.startswith("avx512.mask.pmulhu.w.") || // Added in 7.0
Craig Topper9507fa32018-04-11 04:55:04 +0000204 Name.startswith("avx512.mask.pmaddw.d.") || // Added in 7.0
205 Name.startswith("avx512.mask.pmaddubs.w.") || // Added in 7.0
Craig Topperc43f3f32017-02-24 05:35:07 +0000206 Name.startswith("avx512.mask.packsswb.") || // Added in 5.0
207 Name.startswith("avx512.mask.packssdw.") || // Added in 5.0
208 Name.startswith("avx512.mask.packuswb.") || // Added in 5.0
209 Name.startswith("avx512.mask.packusdw.") || // Added in 5.0
Craig Topper792fc922017-06-22 20:11:01 +0000210 Name.startswith("avx512.mask.cmp.b") || // Added in 5.0
211 Name.startswith("avx512.mask.cmp.d") || // Added in 5.0
212 Name.startswith("avx512.mask.cmp.q") || // Added in 5.0
213 Name.startswith("avx512.mask.cmp.w") || // Added in 5.0
214 Name.startswith("avx512.mask.ucmp.") || // Added in 5.0
Craig Toppercc342d42018-01-09 00:50:47 +0000215 Name.startswith("avx512.cvtb2mask.") || // Added in 7.0
216 Name.startswith("avx512.cvtw2mask.") || // Added in 7.0
217 Name.startswith("avx512.cvtd2mask.") || // Added in 7.0
218 Name.startswith("avx512.cvtq2mask.") || // Added in 7.0
Craig Topperc43f3f32017-02-24 05:35:07 +0000219 Name == "avx512.mask.max.pd.128" || // Added in 5.0
220 Name == "avx512.mask.max.pd.256" || // Added in 5.0
221 Name == "avx512.mask.max.ps.128" || // Added in 5.0
222 Name == "avx512.mask.max.ps.256" || // Added in 5.0
223 Name == "avx512.mask.min.pd.128" || // Added in 5.0
224 Name == "avx512.mask.min.pd.256" || // Added in 5.0
225 Name == "avx512.mask.min.ps.128" || // Added in 5.0
226 Name == "avx512.mask.min.ps.256" || // Added in 5.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000227 Name.startswith("avx512.mask.vpermilvar.") || // Added in 4.0
228 Name.startswith("avx512.mask.psll.d") || // Added in 4.0
229 Name.startswith("avx512.mask.psll.q") || // Added in 4.0
230 Name.startswith("avx512.mask.psll.w") || // Added in 4.0
231 Name.startswith("avx512.mask.psra.d") || // Added in 4.0
232 Name.startswith("avx512.mask.psra.q") || // Added in 4.0
233 Name.startswith("avx512.mask.psra.w") || // Added in 4.0
234 Name.startswith("avx512.mask.psrl.d") || // Added in 4.0
235 Name.startswith("avx512.mask.psrl.q") || // Added in 4.0
236 Name.startswith("avx512.mask.psrl.w") || // Added in 4.0
237 Name.startswith("avx512.mask.pslli") || // Added in 4.0
238 Name.startswith("avx512.mask.psrai") || // Added in 4.0
239 Name.startswith("avx512.mask.psrli") || // Added in 4.0
240 Name.startswith("avx512.mask.psllv") || // Added in 4.0
241 Name.startswith("avx512.mask.psrav") || // Added in 4.0
242 Name.startswith("avx512.mask.psrlv") || // Added in 4.0
243 Name.startswith("sse41.pmovsx") || // Added in 3.8
244 Name.startswith("sse41.pmovzx") || // Added in 3.9
245 Name.startswith("avx2.pmovsx") || // Added in 3.9
246 Name.startswith("avx2.pmovzx") || // Added in 3.9
247 Name.startswith("avx512.mask.pmovsx") || // Added in 4.0
248 Name.startswith("avx512.mask.pmovzx") || // Added in 4.0
Craig Topperf2529c12017-02-24 05:35:04 +0000249 Name.startswith("avx512.mask.lzcnt.") || // Added in 5.0
Craig Topperaad3aef2018-05-21 20:58:09 +0000250 Name.startswith("avx512.mask.pternlog.") || // Added in 7.0
251 Name.startswith("avx512.maskz.pternlog.") || // Added in 7.0
Craig Topper51eddb82018-05-26 18:55:19 +0000252 Name.startswith("avx512.mask.vpmadd52") || // Added in 7.0
253 Name.startswith("avx512.maskz.vpmadd52") || // Added in 7.0
Craig Topper21aeddc2018-05-29 05:22:05 +0000254 Name.startswith("avx512.mask.vpermi2var.") || // Added in 7.0
255 Name.startswith("avx512.mask.vpermt2var.") || // Added in 7.0
256 Name.startswith("avx512.maskz.vpermt2var.") || // Added in 7.0
Craig Topper9923eac2018-06-03 23:24:17 +0000257 Name.startswith("avx512.mask.vpdpbusd.") || // Added in 7.0
258 Name.startswith("avx512.maskz.vpdpbusd.") || // Added in 7.0
259 Name.startswith("avx512.mask.vpdpbusds.") || // Added in 7.0
260 Name.startswith("avx512.maskz.vpdpbusds.") || // Added in 7.0
261 Name.startswith("avx512.mask.vpdpwssd.") || // Added in 7.0
262 Name.startswith("avx512.maskz.vpdpwssd.") || // Added in 7.0
263 Name.startswith("avx512.mask.vpdpwssds.") || // Added in 7.0
264 Name.startswith("avx512.maskz.vpdpwssds.") || // Added in 7.0
Craig Topper98a79932018-06-10 06:01:36 +0000265 Name.startswith("avx512.mask.add.p") || // Added in 7.0
266 Name.startswith("avx512.mask.sub.p") || // Added in 7.0
267 Name.startswith("avx512.mask.mul.p") || // Added in 7.0
268 Name.startswith("avx512.mask.div.p") || // Added in 7.0
Craig Topper38ad7dd2018-05-12 23:14:39 +0000269 Name == "sse.cvtsi2ss" || // Added in 7.0
270 Name == "sse.cvtsi642ss" || // Added in 7.0
271 Name == "sse2.cvtsi2sd" || // Added in 7.0
272 Name == "sse2.cvtsi642sd" || // Added in 7.0
Craig Topperdf3a9ce2018-05-13 00:29:40 +0000273 Name == "sse2.cvtss2sd" || // Added in 7.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000274 Name == "sse2.cvtdq2pd" || // Added in 3.9
Craig Topper358b0942018-05-21 23:15:00 +0000275 Name == "sse2.cvtdq2ps" || // Added in 7.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000276 Name == "sse2.cvtps2pd" || // Added in 3.9
277 Name == "avx.cvtdq2.pd.256" || // Added in 3.9
Craig Topper358b0942018-05-21 23:15:00 +0000278 Name == "avx.cvtdq2.ps.256" || // Added in 7.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000279 Name == "avx.cvt.ps2.pd.256" || // Added in 3.9
280 Name.startswith("avx.vinsertf128.") || // Added in 3.7
281 Name == "avx2.vinserti128" || // Added in 3.7
282 Name.startswith("avx512.mask.insert") || // Added in 4.0
283 Name.startswith("avx.vextractf128.") || // Added in 3.7
284 Name == "avx2.vextracti128" || // Added in 3.7
285 Name.startswith("avx512.mask.vextract") || // Added in 4.0
286 Name.startswith("sse4a.movnt.") || // Added in 3.9
287 Name.startswith("avx.movnt.") || // Added in 3.2
288 Name.startswith("avx512.storent.") || // Added in 3.9
Simon Pilgrim5a22eaa2017-04-14 15:05:35 +0000289 Name == "sse41.movntdqa" || // Added in 5.0
290 Name == "avx2.movntdqa" || // Added in 5.0
291 Name == "avx512.movntdqa" || // Added in 5.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000292 Name == "sse2.storel.dq" || // Added in 3.9
293 Name.startswith("sse.storeu.") || // Added in 3.9
294 Name.startswith("sse2.storeu.") || // Added in 3.9
295 Name.startswith("avx.storeu.") || // Added in 3.9
296 Name.startswith("avx512.mask.storeu.") || // Added in 3.9
297 Name.startswith("avx512.mask.store.p") || // Added in 3.9
298 Name.startswith("avx512.mask.store.b.") || // Added in 3.9
299 Name.startswith("avx512.mask.store.w.") || // Added in 3.9
300 Name.startswith("avx512.mask.store.d.") || // Added in 3.9
301 Name.startswith("avx512.mask.store.q.") || // Added in 3.9
Craig Topper9968af42018-05-11 04:33:18 +0000302 Name == "avx512.mask.store.ss" || // Added in 7.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000303 Name.startswith("avx512.mask.loadu.") || // Added in 3.9
304 Name.startswith("avx512.mask.load.") || // Added in 3.9
Craig Toppere71ad1f2018-06-11 01:25:22 +0000305 Name.startswith("avx512.mask.expand.load.") || // Added in 7.0
306 Name.startswith("avx512.mask.compress.store.") || // Added in 7.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000307 Name == "sse42.crc32.64.8" || // Added in 3.4
308 Name.startswith("avx.vbroadcast.s") || // Added in 3.5
Craig Topper53ceb482018-05-14 18:21:22 +0000309 Name.startswith("avx512.vbroadcast.s") || // Added in 7.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000310 Name.startswith("avx512.mask.palignr.") || // Added in 3.9
311 Name.startswith("avx512.mask.valign.") || // Added in 4.0
312 Name.startswith("sse2.psll.dq") || // Added in 3.7
313 Name.startswith("sse2.psrl.dq") || // Added in 3.7
314 Name.startswith("avx2.psll.dq") || // Added in 3.7
315 Name.startswith("avx2.psrl.dq") || // Added in 3.7
316 Name.startswith("avx512.psll.dq") || // Added in 3.9
317 Name.startswith("avx512.psrl.dq") || // Added in 3.9
318 Name == "sse41.pblendw" || // Added in 3.7
319 Name.startswith("sse41.blendp") || // Added in 3.7
320 Name.startswith("avx.blend.p") || // Added in 3.7
321 Name == "avx2.pblendw" || // Added in 3.7
322 Name.startswith("avx2.pblendd.") || // Added in 3.7
323 Name.startswith("avx.vbroadcastf128") || // Added in 4.0
324 Name == "avx2.vbroadcasti128" || // Added in 3.7
Uriel Korach0ecc9842017-09-26 07:39:39 +0000325 Name.startswith("avx512.mask.broadcastf") || // Added in 6.0
326 Name.startswith("avx512.mask.broadcasti") || // Added in 6.0
Craig Topper185ced82017-02-23 03:22:14 +0000327 Name == "xop.vpcmov" || // Added in 3.8
Craig Topperc43f3f32017-02-24 05:35:07 +0000328 Name == "xop.vpcmov.256" || // Added in 5.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000329 Name.startswith("avx512.mask.move.s") || // Added in 4.0
Michael Zuckerman88fb1712017-04-04 13:32:14 +0000330 Name.startswith("avx512.cvtmask2") || // Added in 5.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000331 (Name.startswith("xop.vpcom") && // Added in 3.2
Yael Tsafrir47668b52017-09-12 07:50:35 +0000332 F->arg_size() == 2) ||
Uriel Korach2aa707b2017-11-13 12:51:18 +0000333 Name.startswith("avx512.ptestm") || //Added in 6.0
334 Name.startswith("avx512.ptestnm") || //Added in 6.0
Yael Tsafrir47668b52017-09-12 07:50:35 +0000335 Name.startswith("sse2.pavg") || // Added in 6.0
336 Name.startswith("avx2.pavg") || // Added in 6.0
337 Name.startswith("avx512.mask.pavg")) // Added in 6.0
Craig Topperb9b9cb02017-02-17 07:07:19 +0000338 return true;
339
340 return false;
341}
342
343static bool UpgradeX86IntrinsicFunction(Function *F, StringRef Name,
344 Function *&NewFn) {
345 // Only handle intrinsics that start with "x86.".
346 if (!Name.startswith("x86."))
347 return false;
348 // Remove "x86." prefix.
349 Name = Name.substr(4);
350
351 if (ShouldUpgradeX86Intrinsic(F, Name)) {
352 NewFn = nullptr;
353 return true;
354 }
355
356 // SSE4.1 ptest functions may have an old signature.
357 if (Name.startswith("sse41.ptest")) { // Added in 3.2
358 if (Name.substr(11) == "c")
Craig Topper905cc752017-02-17 07:07:21 +0000359 return UpgradePTESTIntrinsic(F, Intrinsic::x86_sse41_ptestc, NewFn);
Craig Topperb9b9cb02017-02-17 07:07:19 +0000360 if (Name.substr(11) == "z")
Craig Topper905cc752017-02-17 07:07:21 +0000361 return UpgradePTESTIntrinsic(F, Intrinsic::x86_sse41_ptestz, NewFn);
Craig Topperb9b9cb02017-02-17 07:07:19 +0000362 if (Name.substr(11) == "nzc")
Craig Topper905cc752017-02-17 07:07:21 +0000363 return UpgradePTESTIntrinsic(F, Intrinsic::x86_sse41_ptestnzc, NewFn);
Craig Topperb9b9cb02017-02-17 07:07:19 +0000364 }
365 // Several blend and other instructions with masks used the wrong number of
366 // bits.
367 if (Name == "sse41.insertps") // Added in 3.6
368 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_sse41_insertps,
369 NewFn);
370 if (Name == "sse41.dppd") // Added in 3.6
371 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_sse41_dppd,
372 NewFn);
373 if (Name == "sse41.dpps") // Added in 3.6
374 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_sse41_dpps,
375 NewFn);
376 if (Name == "sse41.mpsadbw") // Added in 3.6
377 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_sse41_mpsadbw,
378 NewFn);
379 if (Name == "avx.dp.ps.256") // Added in 3.6
380 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_avx_dp_ps_256,
381 NewFn);
382 if (Name == "avx2.mpsadbw") // Added in 3.6
383 return UpgradeX86IntrinsicsWith8BitMask(F, Intrinsic::x86_avx2_mpsadbw,
384 NewFn);
Craig Topper4dccffc82018-02-10 23:33:55 +0000385 if (Name == "avx512.mask.cmp.pd.128") // Added in 7.0
386 return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_pd_128,
387 NewFn);
388 if (Name == "avx512.mask.cmp.pd.256") // Added in 7.0
389 return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_pd_256,
390 NewFn);
391 if (Name == "avx512.mask.cmp.pd.512") // Added in 7.0
392 return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_pd_512,
393 NewFn);
394 if (Name == "avx512.mask.cmp.ps.128") // Added in 7.0
395 return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_128,
396 NewFn);
397 if (Name == "avx512.mask.cmp.ps.256") // Added in 7.0
398 return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_256,
399 NewFn);
400 if (Name == "avx512.mask.cmp.ps.512") // Added in 7.0
401 return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_512,
402 NewFn);
Craig Topperb9b9cb02017-02-17 07:07:19 +0000403
404 // frcz.ss/sd may need to have an argument dropped. Added in 3.2
405 if (Name.startswith("xop.vfrcz.ss") && F->arg_size() == 2) {
406 rename(F);
407 NewFn = Intrinsic::getDeclaration(F->getParent(),
408 Intrinsic::x86_xop_vfrcz_ss);
409 return true;
410 }
411 if (Name.startswith("xop.vfrcz.sd") && F->arg_size() == 2) {
412 rename(F);
413 NewFn = Intrinsic::getDeclaration(F->getParent(),
414 Intrinsic::x86_xop_vfrcz_sd);
415 return true;
416 }
417 // Upgrade any XOP PERMIL2 index operand still using a float/double vector.
418 if (Name.startswith("xop.vpermil2")) { // Added in 3.9
Craig Toppercbd1b602017-02-17 07:07:24 +0000419 auto Idx = F->getFunctionType()->getParamType(2);
420 if (Idx->isFPOrFPVectorTy()) {
Craig Topperb9b9cb02017-02-17 07:07:19 +0000421 rename(F);
422 unsigned IdxSize = Idx->getPrimitiveSizeInBits();
423 unsigned EltSize = Idx->getScalarSizeInBits();
424 Intrinsic::ID Permil2ID;
425 if (EltSize == 64 && IdxSize == 128)
426 Permil2ID = Intrinsic::x86_xop_vpermil2pd;
427 else if (EltSize == 32 && IdxSize == 128)
428 Permil2ID = Intrinsic::x86_xop_vpermil2ps;
429 else if (EltSize == 64 && IdxSize == 256)
430 Permil2ID = Intrinsic::x86_xop_vpermil2pd_256;
431 else
432 Permil2ID = Intrinsic::x86_xop_vpermil2ps_256;
433 NewFn = Intrinsic::getDeclaration(F->getParent(), Permil2ID);
434 return true;
435 }
436 }
437
438 return false;
439}
440
Evan Cheng0e179d02007-12-17 22:33:23 +0000441static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
Chandler Carruth7132e002007-08-04 01:51:18 +0000442 assert(F && "Illegal to upgrade a non-existent Function.");
443
Chandler Carruth7132e002007-08-04 01:51:18 +0000444 // Quickly eliminate it, if it's not a candidate.
Eric Liuc9c68172016-07-08 16:09:51 +0000445 StringRef Name = F->getName();
Chris Lattnerb372f662011-06-18 18:56:39 +0000446 if (Name.size() <= 8 || !Name.startswith("llvm."))
Evan Cheng0e179d02007-12-17 22:33:23 +0000447 return false;
Chris Lattnerb372f662011-06-18 18:56:39 +0000448 Name = Name.substr(5); // Strip off "llvm."
Chris Lattner0bcbde42011-11-27 08:42:07 +0000449
Chris Lattnerb372f662011-06-18 18:56:39 +0000450 switch (Name[0]) {
Chandler Carruth7132e002007-08-04 01:51:18 +0000451 default: break;
Joel Jones43cb8782012-07-13 23:25:25 +0000452 case 'a': {
Chad Rosierd0114fc2017-01-10 19:23:51 +0000453 if (Name.startswith("arm.rbit") || Name.startswith("aarch64.rbit")) {
Chad Rosier3daffbf2017-01-10 17:20:33 +0000454 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::bitreverse,
455 F->arg_begin()->getType());
456 return true;
457 }
Joel Jones43cb8782012-07-13 23:25:25 +0000458 if (Name.startswith("arm.neon.vclz")) {
459 Type* args[2] = {
Matt Arsenaultc4c92262013-07-20 17:46:00 +0000460 F->arg_begin()->getType(),
Joel Jones43cb8782012-07-13 23:25:25 +0000461 Type::getInt1Ty(F->getContext())
462 };
463 // Can't use Intrinsic::getDeclaration here as it adds a ".i1" to
464 // the end of the name. Change name from llvm.arm.neon.vclz.* to
465 // llvm.ctlz.*
466 FunctionType* fType = FunctionType::get(F->getReturnType(), args, false);
Matt Arsenaultc4c92262013-07-20 17:46:00 +0000467 NewFn = Function::Create(fType, F->getLinkage(),
Joel Jones43cb8782012-07-13 23:25:25 +0000468 "llvm.ctlz." + Name.substr(14), F->getParent());
469 return true;
470 }
Joel Jonesb84f7be2012-07-18 00:02:16 +0000471 if (Name.startswith("arm.neon.vcnt")) {
472 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctpop,
473 F->arg_begin()->getType());
474 return true;
475 }
Jeroen Ketemaab99b592015-09-30 10:56:37 +0000476 Regex vldRegex("^arm\\.neon\\.vld([1234]|[234]lane)\\.v[a-z0-9]*$");
477 if (vldRegex.match(Name)) {
478 auto fArgs = F->getFunctionType()->params();
479 SmallVector<Type *, 4> Tys(fArgs.begin(), fArgs.end());
480 // Can't use Intrinsic::getDeclaration here as the return types might
481 // then only be structurally equal.
482 FunctionType* fType = FunctionType::get(F->getReturnType(), Tys, false);
483 NewFn = Function::Create(fType, F->getLinkage(),
484 "llvm." + Name + ".p0i8", F->getParent());
485 return true;
486 }
487 Regex vstRegex("^arm\\.neon\\.vst([1234]|[234]lane)\\.v[a-z0-9]*$");
488 if (vstRegex.match(Name)) {
Craig Topper26260942015-10-18 05:15:34 +0000489 static const Intrinsic::ID StoreInts[] = {Intrinsic::arm_neon_vst1,
490 Intrinsic::arm_neon_vst2,
491 Intrinsic::arm_neon_vst3,
492 Intrinsic::arm_neon_vst4};
Jeroen Ketemaab99b592015-09-30 10:56:37 +0000493
Craig Topper26260942015-10-18 05:15:34 +0000494 static const Intrinsic::ID StoreLaneInts[] = {
495 Intrinsic::arm_neon_vst2lane, Intrinsic::arm_neon_vst3lane,
496 Intrinsic::arm_neon_vst4lane
497 };
Jeroen Ketemaab99b592015-09-30 10:56:37 +0000498
499 auto fArgs = F->getFunctionType()->params();
500 Type *Tys[] = {fArgs[0], fArgs[1]};
501 if (Name.find("lane") == StringRef::npos)
502 NewFn = Intrinsic::getDeclaration(F->getParent(),
503 StoreInts[fArgs.size() - 3], Tys);
504 else
505 NewFn = Intrinsic::getDeclaration(F->getParent(),
506 StoreLaneInts[fArgs.size() - 5], Tys);
507 return true;
508 }
Marcin Koscielnicki3fdc2572016-04-19 20:51:05 +0000509 if (Name == "aarch64.thread.pointer" || Name == "arm.thread.pointer") {
510 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::thread_pointer);
511 return true;
512 }
Joel Jones43cb8782012-07-13 23:25:25 +0000513 break;
514 }
Jeroen Ketemaab99b592015-09-30 10:56:37 +0000515
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000516 case 'c': {
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000517 if (Name.startswith("ctlz.") && F->arg_size() == 1) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000518 rename(F);
Chandler Carruthd4a02402011-12-12 10:57:20 +0000519 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
520 F->arg_begin()->getType());
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000521 return true;
522 }
523 if (Name.startswith("cttz.") && F->arg_size() == 1) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000524 rename(F);
Chandler Carruthd4a02402011-12-12 10:57:20 +0000525 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
526 F->arg_begin()->getType());
Chandler Carruth58a71ed2011-12-12 04:26:04 +0000527 return true;
528 }
529 break;
530 }
Adrian Prantlabe04752017-07-28 20:21:02 +0000531 case 'd': {
532 if (Name == "dbg.value" && F->arg_size() == 4) {
533 rename(F);
534 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value);
535 return true;
536 }
537 break;
538 }
Matt Arsenaultf10061e2017-04-10 20:18:21 +0000539 case 'i':
540 case 'l': {
541 bool IsLifetimeStart = Name.startswith("lifetime.start");
542 if (IsLifetimeStart || Name.startswith("invariant.start")) {
543 Intrinsic::ID ID = IsLifetimeStart ?
544 Intrinsic::lifetime_start : Intrinsic::invariant_start;
Mehdi Amini8c629ec2016-08-13 23:31:24 +0000545 auto Args = F->getFunctionType()->params();
546 Type* ObjectPtr[1] = {Args[1]};
Matt Arsenaultf10061e2017-04-10 20:18:21 +0000547 if (F->getName() != Intrinsic::getName(ID, ObjectPtr)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000548 rename(F);
Matt Arsenaultf10061e2017-04-10 20:18:21 +0000549 NewFn = Intrinsic::getDeclaration(F->getParent(), ID, ObjectPtr);
Mehdi Amini8c629ec2016-08-13 23:31:24 +0000550 return true;
551 }
552 }
Matt Arsenaultf10061e2017-04-10 20:18:21 +0000553
554 bool IsLifetimeEnd = Name.startswith("lifetime.end");
555 if (IsLifetimeEnd || Name.startswith("invariant.end")) {
556 Intrinsic::ID ID = IsLifetimeEnd ?
557 Intrinsic::lifetime_end : Intrinsic::invariant_end;
558
Mehdi Amini8c629ec2016-08-13 23:31:24 +0000559 auto Args = F->getFunctionType()->params();
Matt Arsenaultf10061e2017-04-10 20:18:21 +0000560 Type* ObjectPtr[1] = {Args[IsLifetimeEnd ? 1 : 2]};
561 if (F->getName() != Intrinsic::getName(ID, ObjectPtr)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000562 rename(F);
Matt Arsenaultf10061e2017-04-10 20:18:21 +0000563 NewFn = Intrinsic::getDeclaration(F->getParent(), ID, ObjectPtr);
Mehdi Amini8c629ec2016-08-13 23:31:24 +0000564 return true;
565 }
566 }
Piotr Padlewski5dde8092018-05-03 11:03:01 +0000567 if (Name.startswith("invariant.group.barrier")) {
568 // Rename invariant.group.barrier to launder.invariant.group
569 auto Args = F->getFunctionType()->params();
570 Type* ObjectPtr[1] = {Args[0]};
571 rename(F);
572 NewFn = Intrinsic::getDeclaration(F->getParent(),
573 Intrinsic::launder_invariant_group, ObjectPtr);
574 return true;
575
576 }
577
Mehdi Amini8c629ec2016-08-13 23:31:24 +0000578 break;
579 }
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000580 case 'm': {
581 if (Name.startswith("masked.load.")) {
582 Type *Tys[] = { F->getReturnType(), F->arg_begin()->getType() };
583 if (F->getName() != Intrinsic::getName(Intrinsic::masked_load, Tys)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000584 rename(F);
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000585 NewFn = Intrinsic::getDeclaration(F->getParent(),
586 Intrinsic::masked_load,
587 Tys);
588 return true;
589 }
590 }
591 if (Name.startswith("masked.store.")) {
592 auto Args = F->getFunctionType()->params();
593 Type *Tys[] = { Args[0], Args[1] };
594 if (F->getName() != Intrinsic::getName(Intrinsic::masked_store, Tys)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000595 rename(F);
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000596 NewFn = Intrinsic::getDeclaration(F->getParent(),
597 Intrinsic::masked_store,
598 Tys);
599 return true;
600 }
601 }
Elad Cohenef5798a2017-05-03 12:28:54 +0000602 // Renaming gather/scatter intrinsics with no address space overloading
603 // to the new overload which includes an address space
604 if (Name.startswith("masked.gather.")) {
605 Type *Tys[] = {F->getReturnType(), F->arg_begin()->getType()};
606 if (F->getName() != Intrinsic::getName(Intrinsic::masked_gather, Tys)) {
607 rename(F);
608 NewFn = Intrinsic::getDeclaration(F->getParent(),
609 Intrinsic::masked_gather, Tys);
610 return true;
611 }
612 }
613 if (Name.startswith("masked.scatter.")) {
614 auto Args = F->getFunctionType()->params();
615 Type *Tys[] = {Args[0], Args[1]};
616 if (F->getName() != Intrinsic::getName(Intrinsic::masked_scatter, Tys)) {
617 rename(F);
618 NewFn = Intrinsic::getDeclaration(F->getParent(),
619 Intrinsic::masked_scatter, Tys);
620 return true;
621 }
622 }
Daniel Neilson1e687242018-01-19 17:13:12 +0000623 // Updating the memory intrinsics (memcpy/memmove/memset) that have an
624 // alignment parameter to embedding the alignment as an attribute of
625 // the pointer args.
626 if (Name.startswith("memcpy.") && F->arg_size() == 5) {
627 rename(F);
628 // Get the types of dest, src, and len
629 ArrayRef<Type *> ParamTypes = F->getFunctionType()->params().slice(0, 3);
630 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memcpy,
631 ParamTypes);
632 return true;
633 }
634 if (Name.startswith("memmove.") && F->arg_size() == 5) {
635 rename(F);
636 // Get the types of dest, src, and len
637 ArrayRef<Type *> ParamTypes = F->getFunctionType()->params().slice(0, 3);
638 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memmove,
639 ParamTypes);
640 return true;
641 }
642 if (Name.startswith("memset.") && F->arg_size() == 5) {
643 rename(F);
644 // Get the types of dest, and len
645 const auto *FT = F->getFunctionType();
646 Type *ParamTypes[2] = {
647 FT->getParamType(0), // Dest
648 FT->getParamType(2) // len
649 };
650 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::memset,
651 ParamTypes);
652 return true;
653 }
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000654 break;
655 }
Justin Lebar46624a82017-01-21 01:00:32 +0000656 case 'n': {
657 if (Name.startswith("nvvm.")) {
658 Name = Name.substr(5);
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000659
Justin Lebar46624a82017-01-21 01:00:32 +0000660 // The following nvvm intrinsics correspond exactly to an LLVM intrinsic.
661 Intrinsic::ID IID = StringSwitch<Intrinsic::ID>(Name)
662 .Cases("brev32", "brev64", Intrinsic::bitreverse)
663 .Case("clz.i", Intrinsic::ctlz)
664 .Case("popc.i", Intrinsic::ctpop)
665 .Default(Intrinsic::not_intrinsic);
666 if (IID != Intrinsic::not_intrinsic && F->arg_size() == 1) {
667 NewFn = Intrinsic::getDeclaration(F->getParent(), IID,
668 {F->getReturnType()});
669 return true;
670 }
671
672 // The following nvvm intrinsics correspond exactly to an LLVM idiom, but
673 // not to an intrinsic alone. We expand them in UpgradeIntrinsicCall.
674 //
675 // TODO: We could add lohi.i2d.
676 bool Expand = StringSwitch<bool>(Name)
677 .Cases("abs.i", "abs.ll", true)
678 .Cases("clz.ll", "popc.ll", "h2f", true)
679 .Cases("max.i", "max.ll", "max.ui", "max.ull", true)
680 .Cases("min.i", "min.ll", "min.ui", "min.ull", true)
681 .Default(false);
682 if (Expand) {
683 NewFn = nullptr;
684 return true;
685 }
686 }
Galina Kistanovaf525c762017-05-19 20:31:51 +0000687 break;
Justin Lebar46624a82017-01-21 01:00:32 +0000688 }
Matt Arsenaultfbcbce42013-10-07 18:06:48 +0000689 case 'o':
690 // We only need to change the name to match the mangling including the
691 // address space.
George Burgess IV56c7e882017-03-21 20:08:59 +0000692 if (Name.startswith("objectsize.")) {
Matt Arsenaultfbcbce42013-10-07 18:06:48 +0000693 Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() };
George Burgess IV56c7e882017-03-21 20:08:59 +0000694 if (F->arg_size() == 2 ||
695 F->getName() != Intrinsic::getName(Intrinsic::objectsize, Tys)) {
Rafael Espindolad7325ee2016-10-03 15:51:42 +0000696 rename(F);
George Burgess IV56c7e882017-03-21 20:08:59 +0000697 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::objectsize,
698 Tys);
Matt Arsenaultfbcbce42013-10-07 18:06:48 +0000699 return true;
700 }
701 }
702 break;
703
Tim Shen00127562016-04-08 21:26:31 +0000704 case 's':
705 if (Name == "stackprotectorcheck") {
706 NewFn = nullptr;
707 return true;
708 }
George Burgess IV63b06e12016-11-08 04:01:50 +0000709 break;
Tim Shen00127562016-04-08 21:26:31 +0000710
Craig Topperb9b9cb02017-02-17 07:07:19 +0000711 case 'x':
712 if (UpgradeX86IntrinsicFunction(F, Name, NewFn))
Craig Topper3b1817d2012-02-03 06:10:55 +0000713 return true;
Chris Lattnerb372f662011-06-18 18:56:39 +0000714 }
Daniel Berlin3c1432f2017-02-15 23:16:20 +0000715 // Remangle our intrinsic since we upgrade the mangling
716 auto Result = llvm::Intrinsic::remangleIntrinsicFunction(F);
717 if (Result != None) {
718 NewFn = Result.getValue();
719 return true;
720 }
Chandler Carruth7132e002007-08-04 01:51:18 +0000721
Nadav Rotem17ee58a2012-06-10 18:42:51 +0000722 // This may not belong here. This function is effectively being overloaded
723 // to both detect an intrinsic which needs upgrading, and to provide the
724 // upgraded form of the intrinsic. We should perhaps have two separate
Chandler Carruth7132e002007-08-04 01:51:18 +0000725 // functions for this.
Evan Cheng0e179d02007-12-17 22:33:23 +0000726 return false;
Chandler Carruth7132e002007-08-04 01:51:18 +0000727}
728
Evan Cheng0e179d02007-12-17 22:33:23 +0000729bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
Craig Topperc6207612014-04-09 06:08:46 +0000730 NewFn = nullptr;
Evan Cheng0e179d02007-12-17 22:33:23 +0000731 bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
Filipe Cabecinhas0011c582015-07-03 20:12:01 +0000732 assert(F != NewFn && "Intrinsic function upgraded to the same function");
Duncan Sands38ef3a82007-12-03 20:06:50 +0000733
734 // Upgrade intrinsic attributes. This does not change the function.
Evan Cheng0e179d02007-12-17 22:33:23 +0000735 if (NewFn)
736 F = NewFn;
Pete Cooper9e1d3352015-05-20 17:16:39 +0000737 if (Intrinsic::ID id = F->getIntrinsicID())
738 F->setAttributes(Intrinsic::getAttributes(F->getContext(), id));
Duncan Sands38ef3a82007-12-03 20:06:50 +0000739 return Upgraded;
740}
741
Bill Wendlinge26fffc2010-09-10 18:51:56 +0000742bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
Chris Lattner80ed9dc2011-06-18 06:05:24 +0000743 // Nothing to do yet.
Bill Wendlinge26fffc2010-09-10 18:51:56 +0000744 return false;
745}
746
Simon Pilgrimf7186822016-06-09 21:09:03 +0000747// Handles upgrading SSE2/AVX2/AVX512BW PSLLDQ intrinsics by converting them
Craig Topperb324e432015-02-18 06:24:44 +0000748// to byte shuffles.
Craig Topper46b34fe2016-07-12 01:42:33 +0000749static Value *UpgradeX86PSLLDQIntrinsics(IRBuilder<> &Builder,
Craig Topper7355ac32016-05-29 06:37:33 +0000750 Value *Op, unsigned Shift) {
751 Type *ResultTy = Op->getType();
752 unsigned NumElts = ResultTy->getVectorNumElements() * 8;
Craig Topperb324e432015-02-18 06:24:44 +0000753
754 // Bitcast from a 64-bit element type to a byte element type.
Craig Topper46b34fe2016-07-12 01:42:33 +0000755 Type *VecTy = VectorType::get(Builder.getInt8Ty(), NumElts);
Craig Topper7355ac32016-05-29 06:37:33 +0000756 Op = Builder.CreateBitCast(Op, VecTy, "cast");
757
Craig Topperb324e432015-02-18 06:24:44 +0000758 // We'll be shuffling in zeroes.
Craig Topper7355ac32016-05-29 06:37:33 +0000759 Value *Res = Constant::getNullValue(VecTy);
Craig Topperb324e432015-02-18 06:24:44 +0000760
761 // If shift is less than 16, emit a shuffle to move the bytes. Otherwise,
762 // we'll just return the zero vector.
763 if (Shift < 16) {
Craig Topper99d1eab2016-06-12 00:41:19 +0000764 uint32_t Idxs[64];
Simon Pilgrimf7186822016-06-09 21:09:03 +0000765 // 256/512-bit version is split into 2/4 16-byte lanes.
Craig Topperb324e432015-02-18 06:24:44 +0000766 for (unsigned l = 0; l != NumElts; l += 16)
767 for (unsigned i = 0; i != 16; ++i) {
768 unsigned Idx = NumElts + i - Shift;
769 if (Idx < NumElts)
770 Idx -= NumElts - 16; // end of lane, switch operand.
Craig Topper7355ac32016-05-29 06:37:33 +0000771 Idxs[l + i] = Idx + l;
Craig Topperb324e432015-02-18 06:24:44 +0000772 }
773
Craig Topper7355ac32016-05-29 06:37:33 +0000774 Res = Builder.CreateShuffleVector(Res, Op, makeArrayRef(Idxs, NumElts));
Craig Topperb324e432015-02-18 06:24:44 +0000775 }
776
777 // Bitcast back to a 64-bit element type.
Craig Topper7355ac32016-05-29 06:37:33 +0000778 return Builder.CreateBitCast(Res, ResultTy, "cast");
Craig Topperb324e432015-02-18 06:24:44 +0000779}
780
Craig Topperea703ae2016-06-13 02:36:42 +0000781// Handles upgrading SSE2/AVX2/AVX512BW PSRLDQ intrinsics by converting them
782// to byte shuffles.
Craig Topper46b34fe2016-07-12 01:42:33 +0000783static Value *UpgradeX86PSRLDQIntrinsics(IRBuilder<> &Builder, Value *Op,
Craig Topperea703ae2016-06-13 02:36:42 +0000784 unsigned Shift) {
785 Type *ResultTy = Op->getType();
786 unsigned NumElts = ResultTy->getVectorNumElements() * 8;
787
788 // Bitcast from a 64-bit element type to a byte element type.
Craig Topper46b34fe2016-07-12 01:42:33 +0000789 Type *VecTy = VectorType::get(Builder.getInt8Ty(), NumElts);
Craig Topperea703ae2016-06-13 02:36:42 +0000790 Op = Builder.CreateBitCast(Op, VecTy, "cast");
791
792 // We'll be shuffling in zeroes.
793 Value *Res = Constant::getNullValue(VecTy);
794
795 // If shift is less than 16, emit a shuffle to move the bytes. Otherwise,
796 // we'll just return the zero vector.
797 if (Shift < 16) {
798 uint32_t Idxs[64];
799 // 256/512-bit version is split into 2/4 16-byte lanes.
800 for (unsigned l = 0; l != NumElts; l += 16)
801 for (unsigned i = 0; i != 16; ++i) {
802 unsigned Idx = i + Shift;
803 if (Idx >= 16)
804 Idx += NumElts - 16; // end of lane, switch operand.
805 Idxs[l + i] = Idx + l;
806 }
807
808 Res = Builder.CreateShuffleVector(Op, Res, makeArrayRef(Idxs, NumElts));
809 }
810
811 // Bitcast back to a 64-bit element type.
812 return Builder.CreateBitCast(Res, ResultTy, "cast");
813}
814
815static Value *getX86MaskVec(IRBuilder<> &Builder, Value *Mask,
816 unsigned NumElts) {
817 llvm::VectorType *MaskTy = llvm::VectorType::get(Builder.getInt1Ty(),
818 cast<IntegerType>(Mask->getType())->getBitWidth());
819 Mask = Builder.CreateBitCast(Mask, MaskTy);
820
821 // If we have less than 8 elements, then the starting mask was an i8 and
822 // we need to extract down to the right number of elements.
823 if (NumElts < 8) {
824 uint32_t Indices[4];
825 for (unsigned i = 0; i != NumElts; ++i)
826 Indices[i] = i;
827 Mask = Builder.CreateShuffleVector(Mask, Mask,
828 makeArrayRef(Indices, NumElts),
829 "extract");
830 }
831
832 return Mask;
833}
834
835static Value *EmitX86Select(IRBuilder<> &Builder, Value *Mask,
836 Value *Op0, Value *Op1) {
837 // If the mask is all ones just emit the align operation.
838 if (const auto *C = dyn_cast<Constant>(Mask))
839 if (C->isAllOnesValue())
840 return Op0;
841
842 Mask = getX86MaskVec(Builder, Mask, Op0->getType()->getVectorNumElements());
843 return Builder.CreateSelect(Mask, Op0, Op1);
844}
845
Craig Topperf57e17d2016-11-23 06:54:55 +0000846// Handle autoupgrade for masked PALIGNR and VALIGND/Q intrinsics.
847// PALIGNR handles large immediates by shifting while VALIGN masks the immediate
848// so we need to handle both cases. VALIGN also doesn't have 128-bit lanes.
849static Value *UpgradeX86ALIGNIntrinsics(IRBuilder<> &Builder, Value *Op0,
850 Value *Op1, Value *Shift,
851 Value *Passthru, Value *Mask,
852 bool IsVALIGN) {
Craig Topper33350cc2016-06-06 06:12:54 +0000853 unsigned ShiftVal = cast<llvm::ConstantInt>(Shift)->getZExtValue();
854
855 unsigned NumElts = Op0->getType()->getVectorNumElements();
Craig Topperf57e17d2016-11-23 06:54:55 +0000856 assert((IsVALIGN || NumElts % 16 == 0) && "Illegal NumElts for PALIGNR!");
857 assert((!IsVALIGN || NumElts <= 16) && "NumElts too large for VALIGN!");
858 assert(isPowerOf2_32(NumElts) && "NumElts not a power of 2!");
859
860 // Mask the immediate for VALIGN.
861 if (IsVALIGN)
862 ShiftVal &= (NumElts - 1);
Craig Topper33350cc2016-06-06 06:12:54 +0000863
864 // If palignr is shifting the pair of vectors more than the size of two
865 // lanes, emit zero.
866 if (ShiftVal >= 32)
867 return llvm::Constant::getNullValue(Op0->getType());
868
869 // If palignr is shifting the pair of input vectors more than one lane,
870 // but less than two lanes, convert to shifting in zeroes.
871 if (ShiftVal > 16) {
872 ShiftVal -= 16;
873 Op1 = Op0;
874 Op0 = llvm::Constant::getNullValue(Op0->getType());
875 }
876
Craig Topper99d1eab2016-06-12 00:41:19 +0000877 uint32_t Indices[64];
Craig Topper33350cc2016-06-06 06:12:54 +0000878 // 256-bit palignr operates on 128-bit lanes so we need to handle that
Craig Topperf57e17d2016-11-23 06:54:55 +0000879 for (unsigned l = 0; l < NumElts; l += 16) {
Craig Topper33350cc2016-06-06 06:12:54 +0000880 for (unsigned i = 0; i != 16; ++i) {
881 unsigned Idx = ShiftVal + i;
Craig Topperf57e17d2016-11-23 06:54:55 +0000882 if (!IsVALIGN && Idx >= 16) // Disable wrap for VALIGN.
Craig Topper33350cc2016-06-06 06:12:54 +0000883 Idx += NumElts - 16; // End of lane, switch operand.
884 Indices[l + i] = Idx + l;
885 }
886 }
887
888 Value *Align = Builder.CreateShuffleVector(Op1, Op0,
889 makeArrayRef(Indices, NumElts),
890 "palignr");
891
Craig Topperea703ae2016-06-13 02:36:42 +0000892 return EmitX86Select(Builder, Mask, Align, Passthru);
Craig Topperb324e432015-02-18 06:24:44 +0000893}
894
Craig Topper46b34fe2016-07-12 01:42:33 +0000895static Value *UpgradeMaskedStore(IRBuilder<> &Builder,
Craig Topper50f85c22016-05-31 01:50:02 +0000896 Value *Ptr, Value *Data, Value *Mask,
897 bool Aligned) {
898 // Cast the pointer to the right type.
899 Ptr = Builder.CreateBitCast(Ptr,
900 llvm::PointerType::getUnqual(Data->getType()));
901 unsigned Align =
902 Aligned ? cast<VectorType>(Data->getType())->getBitWidth() / 8 : 1;
903
904 // If the mask is all ones just emit a regular store.
905 if (const auto *C = dyn_cast<Constant>(Mask))
906 if (C->isAllOnesValue())
907 return Builder.CreateAlignedStore(Data, Ptr, Align);
908
909 // Convert the mask from an integer type to a vector of i1.
910 unsigned NumElts = Data->getType()->getVectorNumElements();
Craig Topperea703ae2016-06-13 02:36:42 +0000911 Mask = getX86MaskVec(Builder, Mask, NumElts);
Craig Topper50f85c22016-05-31 01:50:02 +0000912 return Builder.CreateMaskedStore(Data, Ptr, Align, Mask);
913}
914
Craig Topper46b34fe2016-07-12 01:42:33 +0000915static Value *UpgradeMaskedLoad(IRBuilder<> &Builder,
Craig Topperf10fbfa2016-06-02 04:19:36 +0000916 Value *Ptr, Value *Passthru, Value *Mask,
917 bool Aligned) {
918 // Cast the pointer to the right type.
919 Ptr = Builder.CreateBitCast(Ptr,
920 llvm::PointerType::getUnqual(Passthru->getType()));
921 unsigned Align =
922 Aligned ? cast<VectorType>(Passthru->getType())->getBitWidth() / 8 : 1;
923
924 // If the mask is all ones just emit a regular store.
925 if (const auto *C = dyn_cast<Constant>(Mask))
926 if (C->isAllOnesValue())
927 return Builder.CreateAlignedLoad(Ptr, Align);
928
929 // Convert the mask from an integer type to a vector of i1.
930 unsigned NumElts = Passthru->getType()->getVectorNumElements();
Craig Topperea703ae2016-06-13 02:36:42 +0000931 Mask = getX86MaskVec(Builder, Mask, NumElts);
Craig Topperf10fbfa2016-06-02 04:19:36 +0000932 return Builder.CreateMaskedLoad(Ptr, Align, Mask, Passthru);
933}
934
Uriel Korach5d5da5f2017-09-13 09:02:36 +0000935static Value *upgradeAbs(IRBuilder<> &Builder, CallInst &CI) {
936 Value *Op0 = CI.getArgOperand(0);
937 llvm::Type *Ty = Op0->getType();
938 Value *Zero = llvm::Constant::getNullValue(Ty);
939 Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_SGT, Op0, Zero);
940 Value *Neg = Builder.CreateNeg(Op0);
941 Value *Res = Builder.CreateSelect(Cmp, Op0, Neg);
942
943 if (CI.getNumArgOperands() == 3)
944 Res = EmitX86Select(Builder,CI.getArgOperand(2), Res, CI.getArgOperand(1));
945
946 return Res;
947}
948
Sanjay Patel51ab7572016-06-16 15:48:30 +0000949static Value *upgradeIntMinMax(IRBuilder<> &Builder, CallInst &CI,
950 ICmpInst::Predicate Pred) {
951 Value *Op0 = CI.getArgOperand(0);
952 Value *Op1 = CI.getArgOperand(1);
953 Value *Cmp = Builder.CreateICmp(Pred, Op0, Op1);
Craig Topper8ec5c732016-10-24 04:04:16 +0000954 Value *Res = Builder.CreateSelect(Cmp, Op0, Op1);
955
956 if (CI.getNumArgOperands() == 4)
957 Res = EmitX86Select(Builder, CI.getArgOperand(3), Res, CI.getArgOperand(2));
958
959 return Res;
Sanjay Patel51ab7572016-06-16 15:48:30 +0000960}
961
Craig Topper254ed022018-04-13 06:07:18 +0000962static Value *upgradePMULDQ(IRBuilder<> &Builder, CallInst &CI, bool IsSigned) {
963 Type *Ty = CI.getType();
964
965 // Arguments have a vXi32 type so cast to vXi64.
966 Value *LHS = Builder.CreateBitCast(CI.getArgOperand(0), Ty);
967 Value *RHS = Builder.CreateBitCast(CI.getArgOperand(1), Ty);
968
969 if (IsSigned) {
970 // Shift left then arithmetic shift right.
971 Constant *ShiftAmt = ConstantInt::get(Ty, 32);
972 LHS = Builder.CreateShl(LHS, ShiftAmt);
973 LHS = Builder.CreateAShr(LHS, ShiftAmt);
974 RHS = Builder.CreateShl(RHS, ShiftAmt);
975 RHS = Builder.CreateAShr(RHS, ShiftAmt);
976 } else {
977 // Clear the upper bits.
978 Constant *Mask = ConstantInt::get(Ty, 0xffffffff);
979 LHS = Builder.CreateAnd(LHS, Mask);
980 RHS = Builder.CreateAnd(RHS, Mask);
981 }
982
983 Value *Res = Builder.CreateMul(LHS, RHS);
984
985 if (CI.getNumArgOperands() == 4)
986 Res = EmitX86Select(Builder, CI.getArgOperand(3), Res, CI.getArgOperand(2));
987
988 return Res;
989}
990
Uriel Korach2aa707b2017-11-13 12:51:18 +0000991// Applying mask on vector of i1's and make sure result is at least 8 bits wide.
992static Value *ApplyX86MaskOn1BitsVec(IRBuilder<> &Builder,Value *Vec, Value *Mask,
993 unsigned NumElts) {
Craig Toppercc342d42018-01-09 00:50:47 +0000994 if (Mask) {
995 const auto *C = dyn_cast<Constant>(Mask);
996 if (!C || !C->isAllOnesValue())
997 Vec = Builder.CreateAnd(Vec, getX86MaskVec(Builder, Mask, NumElts));
998 }
Uriel Korach2aa707b2017-11-13 12:51:18 +0000999
1000 if (NumElts < 8) {
1001 uint32_t Indices[8];
1002 for (unsigned i = 0; i != NumElts; ++i)
1003 Indices[i] = i;
1004 for (unsigned i = NumElts; i != 8; ++i)
1005 Indices[i] = NumElts + i % NumElts;
1006 Vec = Builder.CreateShuffleVector(Vec,
1007 Constant::getNullValue(Vec->getType()),
1008 Indices);
1009 }
1010 return Builder.CreateBitCast(Vec, Builder.getIntNTy(std::max(NumElts, 8U)));
1011}
1012
Craig Topper0a0fb0f2016-06-21 03:53:24 +00001013static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallInst &CI,
Craig Topper792fc922017-06-22 20:11:01 +00001014 unsigned CC, bool Signed) {
Craig Topper0a0fb0f2016-06-21 03:53:24 +00001015 Value *Op0 = CI.getArgOperand(0);
1016 unsigned NumElts = Op0->getType()->getVectorNumElements();
Craig Topper0a0fb0f2016-06-21 03:53:24 +00001017
Craig Topper792fc922017-06-22 20:11:01 +00001018 Value *Cmp;
1019 if (CC == 3) {
1020 Cmp = Constant::getNullValue(llvm::VectorType::get(Builder.getInt1Ty(), NumElts));
1021 } else if (CC == 7) {
1022 Cmp = Constant::getAllOnesValue(llvm::VectorType::get(Builder.getInt1Ty(), NumElts));
1023 } else {
1024 ICmpInst::Predicate Pred;
1025 switch (CC) {
1026 default: llvm_unreachable("Unknown condition code");
1027 case 0: Pred = ICmpInst::ICMP_EQ; break;
1028 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
1029 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
1030 case 4: Pred = ICmpInst::ICMP_NE; break;
1031 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
1032 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
1033 }
1034 Cmp = Builder.CreateICmp(Pred, Op0, CI.getArgOperand(1));
1035 }
1036
1037 Value *Mask = CI.getArgOperand(CI.getNumArgOperands() - 1);
Craig Topper0a0fb0f2016-06-21 03:53:24 +00001038
Uriel Korach2aa707b2017-11-13 12:51:18 +00001039 return ApplyX86MaskOn1BitsVec(Builder, Cmp, Mask, NumElts);
Craig Topper0a0fb0f2016-06-21 03:53:24 +00001040}
1041
Craig Topperc9467ed2016-11-06 16:29:08 +00001042// Replace a masked intrinsic with an older unmasked intrinsic.
1043static Value *UpgradeX86MaskedShift(IRBuilder<> &Builder, CallInst &CI,
1044 Intrinsic::ID IID) {
Craig Topperc95e1222018-04-09 06:15:09 +00001045 Function *Intrin = Intrinsic::getDeclaration(CI.getModule(), IID);
Craig Topperc9467ed2016-11-06 16:29:08 +00001046 Value *Rep = Builder.CreateCall(Intrin,
1047 { CI.getArgOperand(0), CI.getArgOperand(1) });
1048 return EmitX86Select(Builder, CI.getArgOperand(3), Rep, CI.getArgOperand(2));
1049}
1050
Ayman Musa4d602432016-11-16 09:00:28 +00001051static Value* upgradeMaskedMove(IRBuilder<> &Builder, CallInst &CI) {
1052 Value* A = CI.getArgOperand(0);
1053 Value* B = CI.getArgOperand(1);
1054 Value* Src = CI.getArgOperand(2);
1055 Value* Mask = CI.getArgOperand(3);
1056
1057 Value* AndNode = Builder.CreateAnd(Mask, APInt(8, 1));
1058 Value* Cmp = Builder.CreateIsNotNull(AndNode);
1059 Value* Extract1 = Builder.CreateExtractElement(B, (uint64_t)0);
1060 Value* Extract2 = Builder.CreateExtractElement(Src, (uint64_t)0);
1061 Value* Select = Builder.CreateSelect(Cmp, Extract1, Extract2);
1062 return Builder.CreateInsertElement(A, Select, (uint64_t)0);
1063}
Craig Topperc9467ed2016-11-06 16:29:08 +00001064
Michael Zuckerman88fb1712017-04-04 13:32:14 +00001065
1066static Value* UpgradeMaskToInt(IRBuilder<> &Builder, CallInst &CI) {
1067 Value* Op = CI.getArgOperand(0);
1068 Type* ReturnOp = CI.getType();
1069 unsigned NumElts = CI.getType()->getVectorNumElements();
1070 Value *Mask = getX86MaskVec(Builder, Op, NumElts);
1071 return Builder.CreateSExt(Mask, ReturnOp, "vpmovm2");
1072}
1073
Craig Topperc95e1222018-04-09 06:15:09 +00001074// Replace intrinsic with unmasked version and a select.
1075static bool upgradeAVX512MaskToSelect(StringRef Name, IRBuilder<> &Builder,
1076 CallInst &CI, Value *&Rep) {
1077 Name = Name.substr(12); // Remove avx512.mask.
1078
1079 unsigned VecWidth = CI.getType()->getPrimitiveSizeInBits();
1080 unsigned EltWidth = CI.getType()->getScalarSizeInBits();
1081 Intrinsic::ID IID;
1082 if (Name.startswith("max.p")) {
1083 if (VecWidth == 128 && EltWidth == 32)
1084 IID = Intrinsic::x86_sse_max_ps;
1085 else if (VecWidth == 128 && EltWidth == 64)
1086 IID = Intrinsic::x86_sse2_max_pd;
1087 else if (VecWidth == 256 && EltWidth == 32)
1088 IID = Intrinsic::x86_avx_max_ps_256;
1089 else if (VecWidth == 256 && EltWidth == 64)
1090 IID = Intrinsic::x86_avx_max_pd_256;
1091 else
1092 llvm_unreachable("Unexpected intrinsic");
1093 } else if (Name.startswith("min.p")) {
1094 if (VecWidth == 128 && EltWidth == 32)
1095 IID = Intrinsic::x86_sse_min_ps;
1096 else if (VecWidth == 128 && EltWidth == 64)
1097 IID = Intrinsic::x86_sse2_min_pd;
1098 else if (VecWidth == 256 && EltWidth == 32)
1099 IID = Intrinsic::x86_avx_min_ps_256;
1100 else if (VecWidth == 256 && EltWidth == 64)
1101 IID = Intrinsic::x86_avx_min_pd_256;
1102 else
1103 llvm_unreachable("Unexpected intrinsic");
1104 } else if (Name.startswith("pshuf.b.")) {
1105 if (VecWidth == 128)
1106 IID = Intrinsic::x86_ssse3_pshuf_b_128;
1107 else if (VecWidth == 256)
1108 IID = Intrinsic::x86_avx2_pshuf_b;
1109 else if (VecWidth == 512)
1110 IID = Intrinsic::x86_avx512_pshuf_b_512;
1111 else
1112 llvm_unreachable("Unexpected intrinsic");
Craig Topperc95e1222018-04-09 06:15:09 +00001113 } else if (Name.startswith("pmul.hr.sw.")) {
1114 if (VecWidth == 128)
1115 IID = Intrinsic::x86_ssse3_pmul_hr_sw_128;
1116 else if (VecWidth == 256)
1117 IID = Intrinsic::x86_avx2_pmul_hr_sw;
1118 else if (VecWidth == 512)
1119 IID = Intrinsic::x86_avx512_pmul_hr_sw_512;
1120 else
1121 llvm_unreachable("Unexpected intrinsic");
1122 } else if (Name.startswith("pmulh.w.")) {
1123 if (VecWidth == 128)
1124 IID = Intrinsic::x86_sse2_pmulh_w;
1125 else if (VecWidth == 256)
1126 IID = Intrinsic::x86_avx2_pmulh_w;
1127 else if (VecWidth == 512)
1128 IID = Intrinsic::x86_avx512_pmulh_w_512;
1129 else
1130 llvm_unreachable("Unexpected intrinsic");
1131 } else if (Name.startswith("pmulhu.w.")) {
1132 if (VecWidth == 128)
1133 IID = Intrinsic::x86_sse2_pmulhu_w;
1134 else if (VecWidth == 256)
1135 IID = Intrinsic::x86_avx2_pmulhu_w;
1136 else if (VecWidth == 512)
1137 IID = Intrinsic::x86_avx512_pmulhu_w_512;
1138 else
1139 llvm_unreachable("Unexpected intrinsic");
Craig Topper9507fa32018-04-11 04:55:04 +00001140 } else if (Name.startswith("pmaddw.d.")) {
1141 if (VecWidth == 128)
1142 IID = Intrinsic::x86_sse2_pmadd_wd;
1143 else if (VecWidth == 256)
1144 IID = Intrinsic::x86_avx2_pmadd_wd;
1145 else if (VecWidth == 512)
1146 IID = Intrinsic::x86_avx512_pmaddw_d_512;
1147 else
1148 llvm_unreachable("Unexpected intrinsic");
1149 } else if (Name.startswith("pmaddubs.w.")) {
1150 if (VecWidth == 128)
1151 IID = Intrinsic::x86_ssse3_pmadd_ub_sw_128;
1152 else if (VecWidth == 256)
1153 IID = Intrinsic::x86_avx2_pmadd_ub_sw;
1154 else if (VecWidth == 512)
1155 IID = Intrinsic::x86_avx512_pmaddubs_w_512;
1156 else
1157 llvm_unreachable("Unexpected intrinsic");
Craig Topperc95e1222018-04-09 06:15:09 +00001158 } else if (Name.startswith("packsswb.")) {
1159 if (VecWidth == 128)
1160 IID = Intrinsic::x86_sse2_packsswb_128;
1161 else if (VecWidth == 256)
1162 IID = Intrinsic::x86_avx2_packsswb;
1163 else if (VecWidth == 512)
1164 IID = Intrinsic::x86_avx512_packsswb_512;
1165 else
1166 llvm_unreachable("Unexpected intrinsic");
1167 } else if (Name.startswith("packssdw.")) {
1168 if (VecWidth == 128)
1169 IID = Intrinsic::x86_sse2_packssdw_128;
1170 else if (VecWidth == 256)
1171 IID = Intrinsic::x86_avx2_packssdw;
1172 else if (VecWidth == 512)
1173 IID = Intrinsic::x86_avx512_packssdw_512;
1174 else
1175 llvm_unreachable("Unexpected intrinsic");
1176 } else if (Name.startswith("packuswb.")) {
1177 if (VecWidth == 128)
1178 IID = Intrinsic::x86_sse2_packuswb_128;
1179 else if (VecWidth == 256)
1180 IID = Intrinsic::x86_avx2_packuswb;
1181 else if (VecWidth == 512)
1182 IID = Intrinsic::x86_avx512_packuswb_512;
1183 else
1184 llvm_unreachable("Unexpected intrinsic");
1185 } else if (Name.startswith("packusdw.")) {
1186 if (VecWidth == 128)
1187 IID = Intrinsic::x86_sse41_packusdw;
1188 else if (VecWidth == 256)
1189 IID = Intrinsic::x86_avx2_packusdw;
1190 else if (VecWidth == 512)
1191 IID = Intrinsic::x86_avx512_packusdw_512;
1192 else
1193 llvm_unreachable("Unexpected intrinsic");
1194 } else if (Name.startswith("vpermilvar.")) {
1195 if (VecWidth == 128 && EltWidth == 32)
1196 IID = Intrinsic::x86_avx_vpermilvar_ps;
1197 else if (VecWidth == 128 && EltWidth == 64)
1198 IID = Intrinsic::x86_avx_vpermilvar_pd;
1199 else if (VecWidth == 256 && EltWidth == 32)
1200 IID = Intrinsic::x86_avx_vpermilvar_ps_256;
1201 else if (VecWidth == 256 && EltWidth == 64)
1202 IID = Intrinsic::x86_avx_vpermilvar_pd_256;
1203 else if (VecWidth == 512 && EltWidth == 32)
1204 IID = Intrinsic::x86_avx512_vpermilvar_ps_512;
1205 else if (VecWidth == 512 && EltWidth == 64)
1206 IID = Intrinsic::x86_avx512_vpermilvar_pd_512;
1207 else
1208 llvm_unreachable("Unexpected intrinsic");
Craig Toppera288f242018-05-12 02:34:28 +00001209 } else if (Name == "cvtpd2dq.256") {
Craig Topper85906cf2018-05-13 18:03:59 +00001210 IID = Intrinsic::x86_avx_cvt_pd2dq_256;
Craig Toppera288f242018-05-12 02:34:28 +00001211 } else if (Name == "cvtpd2ps.256") {
Craig Topper85906cf2018-05-13 18:03:59 +00001212 IID = Intrinsic::x86_avx_cvt_pd2_ps_256;
Craig Toppera288f242018-05-12 02:34:28 +00001213 } else if (Name == "cvttpd2dq.256") {
Craig Topper85906cf2018-05-13 18:03:59 +00001214 IID = Intrinsic::x86_avx_cvtt_pd2dq_256;
Craig Toppera288f242018-05-12 02:34:28 +00001215 } else if (Name == "cvttps2dq.128") {
Craig Topper85906cf2018-05-13 18:03:59 +00001216 IID = Intrinsic::x86_sse2_cvttps2dq;
Craig Toppera288f242018-05-12 02:34:28 +00001217 } else if (Name == "cvttps2dq.256") {
Craig Topper85906cf2018-05-13 18:03:59 +00001218 IID = Intrinsic::x86_avx_cvtt_ps2dq_256;
Craig Toppere4c045b2018-05-20 23:34:04 +00001219 } else if (Name.startswith("permvar.")) {
1220 bool IsFloat = CI.getType()->isFPOrFPVectorTy();
1221 if (VecWidth == 256 && EltWidth == 32 && IsFloat)
1222 IID = Intrinsic::x86_avx2_permps;
1223 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
1224 IID = Intrinsic::x86_avx2_permd;
1225 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
1226 IID = Intrinsic::x86_avx512_permvar_df_256;
1227 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
1228 IID = Intrinsic::x86_avx512_permvar_di_256;
1229 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
1230 IID = Intrinsic::x86_avx512_permvar_sf_512;
1231 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
1232 IID = Intrinsic::x86_avx512_permvar_si_512;
1233 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
1234 IID = Intrinsic::x86_avx512_permvar_df_512;
1235 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
1236 IID = Intrinsic::x86_avx512_permvar_di_512;
1237 else if (VecWidth == 128 && EltWidth == 16)
1238 IID = Intrinsic::x86_avx512_permvar_hi_128;
1239 else if (VecWidth == 256 && EltWidth == 16)
1240 IID = Intrinsic::x86_avx512_permvar_hi_256;
1241 else if (VecWidth == 512 && EltWidth == 16)
1242 IID = Intrinsic::x86_avx512_permvar_hi_512;
1243 else if (VecWidth == 128 && EltWidth == 8)
1244 IID = Intrinsic::x86_avx512_permvar_qi_128;
1245 else if (VecWidth == 256 && EltWidth == 8)
1246 IID = Intrinsic::x86_avx512_permvar_qi_256;
1247 else if (VecWidth == 512 && EltWidth == 8)
1248 IID = Intrinsic::x86_avx512_permvar_qi_512;
1249 else
1250 llvm_unreachable("Unexpected intrinsic");
Craig Topperc95e1222018-04-09 06:15:09 +00001251 } else
1252 return false;
1253
Craig Toppera288f242018-05-12 02:34:28 +00001254 SmallVector<Value *, 4> Args(CI.arg_operands().begin(),
1255 CI.arg_operands().end());
1256 Args.pop_back();
1257 Args.pop_back();
Craig Topperc95e1222018-04-09 06:15:09 +00001258 Rep = Builder.CreateCall(Intrinsic::getDeclaration(CI.getModule(), IID),
Craig Toppera288f242018-05-12 02:34:28 +00001259 Args);
1260 unsigned NumArgs = CI.getNumArgOperands();
1261 Rep = EmitX86Select(Builder, CI.getArgOperand(NumArgs - 1), Rep,
1262 CI.getArgOperand(NumArgs - 2));
Craig Topperc95e1222018-04-09 06:15:09 +00001263 return true;
1264}
1265
Gerolf Hoflehner1c3a0782018-04-17 04:02:24 +00001266/// Upgrade comment in call to inline asm that represents an objc retain release
1267/// marker.
1268void llvm::UpgradeInlineAsmString(std::string *AsmStr) {
Reid Klecknere160d512018-04-23 16:47:27 +00001269 size_t Pos;
Gerolf Hoflehner1c3a0782018-04-17 04:02:24 +00001270 if (AsmStr->find("mov\tfp") == 0 &&
1271 AsmStr->find("objc_retainAutoreleaseReturnValue") != std::string::npos &&
1272 (Pos = AsmStr->find("# marker")) != std::string::npos) {
1273 AsmStr->replace(Pos, 1, ";");
1274 }
1275 return;
1276}
1277
Sanjay Patel595098f2016-06-15 22:01:28 +00001278/// Upgrade a call to an old intrinsic. All argument and return casting must be
1279/// provided to seamlessly integrate with existing context.
Chandler Carruth7132e002007-08-04 01:51:18 +00001280void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Craig Topper3b1817d2012-02-03 06:10:55 +00001281 Function *F = CI->getCalledFunction();
Nick Lewycky2eb3ade2011-12-12 22:59:34 +00001282 LLVMContext &C = CI->getContext();
Chandler Carruth58a71ed2011-12-12 04:26:04 +00001283 IRBuilder<> Builder(C);
Duncan P. N. Exon Smith52888a62015-10-08 23:49:46 +00001284 Builder.SetInsertPoint(CI->getParent(), CI->getIterator());
Chandler Carruth58a71ed2011-12-12 04:26:04 +00001285
Craig Topper3b1817d2012-02-03 06:10:55 +00001286 assert(F && "Intrinsic call is not direct?");
1287
1288 if (!NewFn) {
1289 // Get the Function's name.
1290 StringRef Name = F->getName();
1291
Craig Topper5aebb862016-07-04 20:56:38 +00001292 assert(Name.startswith("llvm.") && "Intrinsic doesn't start with 'llvm.'");
1293 Name = Name.substr(5);
1294
1295 bool IsX86 = Name.startswith("x86.");
1296 if (IsX86)
1297 Name = Name.substr(4);
Justin Lebar46624a82017-01-21 01:00:32 +00001298 bool IsNVVM = Name.startswith("nvvm.");
1299 if (IsNVVM)
1300 Name = Name.substr(5);
Craig Topper5aebb862016-07-04 20:56:38 +00001301
Craig Toppera4744d12016-12-10 21:15:48 +00001302 if (IsX86 && Name.startswith("sse4a.movnt.")) {
1303 Module *M = F->getParent();
1304 SmallVector<Metadata *, 1> Elts;
1305 Elts.push_back(
1306 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1)));
1307 MDNode *Node = MDNode::get(C, Elts);
1308
1309 Value *Arg0 = CI->getArgOperand(0);
1310 Value *Arg1 = CI->getArgOperand(1);
1311
1312 // Nontemporal (unaligned) store of the 0'th element of the float/double
1313 // vector.
1314 Type *SrcEltTy = cast<VectorType>(Arg1->getType())->getElementType();
1315 PointerType *EltPtrTy = PointerType::getUnqual(SrcEltTy);
1316 Value *Addr = Builder.CreateBitCast(Arg0, EltPtrTy, "cast");
1317 Value *Extract =
1318 Builder.CreateExtractElement(Arg1, (uint64_t)0, "extractelement");
1319
1320 StoreInst *SI = Builder.CreateAlignedStore(Extract, Addr, 1);
1321 SI->setMetadata(M->getMDKindID("nontemporal"), Node);
1322
1323 // Remove intrinsic.
1324 CI->eraseFromParent();
1325 return;
1326 }
1327
1328 if (IsX86 && (Name.startswith("avx.movnt.") ||
1329 Name.startswith("avx512.storent."))) {
1330 Module *M = F->getParent();
1331 SmallVector<Metadata *, 1> Elts;
1332 Elts.push_back(
1333 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1)));
1334 MDNode *Node = MDNode::get(C, Elts);
1335
1336 Value *Arg0 = CI->getArgOperand(0);
1337 Value *Arg1 = CI->getArgOperand(1);
1338
1339 // Convert the type of the pointer to a pointer to the stored type.
1340 Value *BC = Builder.CreateBitCast(Arg0,
1341 PointerType::getUnqual(Arg1->getType()),
1342 "cast");
1343 VectorType *VTy = cast<VectorType>(Arg1->getType());
1344 StoreInst *SI = Builder.CreateAlignedStore(Arg1, BC,
1345 VTy->getBitWidth() / 8);
1346 SI->setMetadata(M->getMDKindID("nontemporal"), Node);
1347
1348 // Remove intrinsic.
1349 CI->eraseFromParent();
1350 return;
1351 }
1352
1353 if (IsX86 && Name == "sse2.storel.dq") {
1354 Value *Arg0 = CI->getArgOperand(0);
1355 Value *Arg1 = CI->getArgOperand(1);
1356
1357 Type *NewVecTy = VectorType::get(Type::getInt64Ty(C), 2);
1358 Value *BC0 = Builder.CreateBitCast(Arg1, NewVecTy, "cast");
1359 Value *Elt = Builder.CreateExtractElement(BC0, (uint64_t)0);
1360 Value *BC = Builder.CreateBitCast(Arg0,
1361 PointerType::getUnqual(Elt->getType()),
1362 "cast");
1363 Builder.CreateAlignedStore(Elt, BC, 1);
1364
1365 // Remove intrinsic.
1366 CI->eraseFromParent();
1367 return;
1368 }
1369
1370 if (IsX86 && (Name.startswith("sse.storeu.") ||
1371 Name.startswith("sse2.storeu.") ||
1372 Name.startswith("avx.storeu."))) {
1373 Value *Arg0 = CI->getArgOperand(0);
1374 Value *Arg1 = CI->getArgOperand(1);
1375
1376 Arg0 = Builder.CreateBitCast(Arg0,
1377 PointerType::getUnqual(Arg1->getType()),
1378 "cast");
1379 Builder.CreateAlignedStore(Arg1, Arg0, 1);
1380
1381 // Remove intrinsic.
1382 CI->eraseFromParent();
1383 return;
1384 }
1385
Craig Topper9968af42018-05-11 04:33:18 +00001386 if (IsX86 && Name == "avx512.mask.store.ss") {
1387 Value *Mask = Builder.CreateAnd(CI->getArgOperand(2), Builder.getInt8(1));
1388 UpgradeMaskedStore(Builder, CI->getArgOperand(0), CI->getArgOperand(1),
1389 Mask, false);
1390
1391 // Remove intrinsic.
1392 CI->eraseFromParent();
1393 return;
1394 }
1395
Craig Topperaa49f142017-02-18 19:51:14 +00001396 if (IsX86 && (Name.startswith("avx512.mask.store"))) {
1397 // "avx512.mask.storeu." or "avx512.mask.store."
1398 bool Aligned = Name[17] != 'u'; // "avx512.mask.storeu".
Craig Toppera4744d12016-12-10 21:15:48 +00001399 UpgradeMaskedStore(Builder, CI->getArgOperand(0), CI->getArgOperand(1),
Craig Topperaa49f142017-02-18 19:51:14 +00001400 CI->getArgOperand(2), Aligned);
Craig Toppera4744d12016-12-10 21:15:48 +00001401
1402 // Remove intrinsic.
1403 CI->eraseFromParent();
1404 return;
1405 }
1406
Craig Topper3b1817d2012-02-03 06:10:55 +00001407 Value *Rep;
Sanjay Patel595098f2016-06-15 22:01:28 +00001408 // Upgrade packed integer vector compare intrinsics to compare instructions.
Craig Topperaa49f142017-02-18 19:51:14 +00001409 if (IsX86 && (Name.startswith("sse2.pcmp") ||
1410 Name.startswith("avx2.pcmp"))) {
1411 // "sse2.pcpmpeq." "sse2.pcmpgt." "avx2.pcmpeq." or "avx2.pcmpgt."
1412 bool CmpEq = Name[9] == 'e';
1413 Rep = Builder.CreateICmp(CmpEq ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_SGT,
1414 CI->getArgOperand(0), CI->getArgOperand(1));
Craig Topper3b1817d2012-02-03 06:10:55 +00001415 Rep = Builder.CreateSExt(Rep, CI->getType(), "");
Jina Nahias7b705f12017-11-06 07:09:24 +00001416 } else if (IsX86 && (Name.startswith("avx512.broadcastm"))) {
1417 Type *ExtTy = Type::getInt32Ty(C);
1418 if (CI->getOperand(0)->getType()->isIntegerTy(8))
1419 ExtTy = Type::getInt64Ty(C);
1420 unsigned NumElts = CI->getType()->getPrimitiveSizeInBits() /
1421 ExtTy->getPrimitiveSizeInBits();
1422 Rep = Builder.CreateZExt(CI->getArgOperand(0), ExtTy);
1423 Rep = Builder.CreateVectorSplat(NumElts, Rep);
Uriel Korach2aa707b2017-11-13 12:51:18 +00001424 } else if (IsX86 && (Name.startswith("avx512.ptestm") ||
1425 Name.startswith("avx512.ptestnm"))) {
1426 Value *Op0 = CI->getArgOperand(0);
1427 Value *Op1 = CI->getArgOperand(1);
1428 Value *Mask = CI->getArgOperand(2);
1429 Rep = Builder.CreateAnd(Op0, Op1);
1430 llvm::Type *Ty = Op0->getType();
1431 Value *Zero = llvm::Constant::getNullValue(Ty);
1432 ICmpInst::Predicate Pred =
1433 Name.startswith("avx512.ptestm") ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ;
1434 Rep = Builder.CreateICmp(Pred, Rep, Zero);
1435 unsigned NumElts = Op0->getType()->getVectorNumElements();
1436 Rep = ApplyX86MaskOn1BitsVec(Builder, Rep, Mask, NumElts);
1437 } else if (IsX86 && (Name.startswith("avx512.mask.pbroadcast"))){
Jina Nahiasccfb8d42017-09-19 11:03:06 +00001438 unsigned NumElts =
1439 CI->getArgOperand(1)->getType()->getVectorNumElements();
1440 Rep = Builder.CreateVectorSplat(NumElts, CI->getArgOperand(0));
1441 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1442 CI->getArgOperand(1));
Jina Nahias51c1a622017-12-05 15:42:56 +00001443 } else if (IsX86 && (Name.startswith("avx512.kunpck"))) {
Craig Topper7197a452018-01-14 19:24:10 +00001444 unsigned NumElts = CI->getType()->getScalarSizeInBits();
1445 Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), NumElts);
1446 Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), NumElts);
1447 uint32_t Indices[64];
1448 for (unsigned i = 0; i != NumElts; ++i)
1449 Indices[i] = i;
1450
1451 // First extract half of each vector. This gives better codegen than
1452 // doing it in a single shuffle.
1453 LHS = Builder.CreateShuffleVector(LHS, LHS,
1454 makeArrayRef(Indices, NumElts / 2));
1455 RHS = Builder.CreateShuffleVector(RHS, RHS,
1456 makeArrayRef(Indices, NumElts / 2));
1457 // Concat the vectors.
Craig Topper8d19c6f2018-02-12 22:38:34 +00001458 // NOTE: Operands have to be swapped to match intrinsic definition.
1459 Rep = Builder.CreateShuffleVector(RHS, LHS,
Craig Topper7197a452018-01-14 19:24:10 +00001460 makeArrayRef(Indices, NumElts));
1461 Rep = Builder.CreateBitCast(Rep, CI->getType());
Craig Topper071ad9c2018-02-03 20:18:25 +00001462 } else if (IsX86 && Name == "avx512.kand.w") {
1463 Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
1464 Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
1465 Rep = Builder.CreateAnd(LHS, RHS);
1466 Rep = Builder.CreateBitCast(Rep, CI->getType());
1467 } else if (IsX86 && Name == "avx512.kandn.w") {
1468 Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
1469 Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
1470 LHS = Builder.CreateNot(LHS);
1471 Rep = Builder.CreateAnd(LHS, RHS);
1472 Rep = Builder.CreateBitCast(Rep, CI->getType());
1473 } else if (IsX86 && Name == "avx512.kor.w") {
1474 Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
1475 Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
1476 Rep = Builder.CreateOr(LHS, RHS);
1477 Rep = Builder.CreateBitCast(Rep, CI->getType());
1478 } else if (IsX86 && Name == "avx512.kxor.w") {
1479 Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
1480 Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
1481 Rep = Builder.CreateXor(LHS, RHS);
1482 Rep = Builder.CreateBitCast(Rep, CI->getType());
1483 } else if (IsX86 && Name == "avx512.kxnor.w") {
1484 Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
1485 Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
1486 LHS = Builder.CreateNot(LHS);
1487 Rep = Builder.CreateXor(LHS, RHS);
1488 Rep = Builder.CreateBitCast(Rep, CI->getType());
1489 } else if (IsX86 && Name == "avx512.knot.w") {
1490 Rep = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
1491 Rep = Builder.CreateNot(Rep);
1492 Rep = Builder.CreateBitCast(Rep, CI->getType());
Craig Topperdccf72b2018-02-08 20:16:06 +00001493 } else if (IsX86 &&
1494 (Name == "avx512.kortestz.w" || Name == "avx512.kortestc.w")) {
1495 Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16);
1496 Value *RHS = getX86MaskVec(Builder, CI->getArgOperand(1), 16);
1497 Rep = Builder.CreateOr(LHS, RHS);
1498 Rep = Builder.CreateBitCast(Rep, Builder.getInt16Ty());
1499 Value *C;
1500 if (Name[14] == 'c')
1501 C = ConstantInt::getAllOnesValue(Builder.getInt16Ty());
1502 else
1503 C = ConstantInt::getNullValue(Builder.getInt16Ty());
1504 Rep = Builder.CreateICmpEQ(Rep, C);
1505 Rep = Builder.CreateZExt(Rep, Builder.getInt32Ty());
Craig Topper6910fa02016-11-16 05:24:10 +00001506 } else if (IsX86 && (Name == "sse.add.ss" || Name == "sse2.add.sd")) {
1507 Type *I32Ty = Type::getInt32Ty(C);
1508 Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0),
1509 ConstantInt::get(I32Ty, 0));
1510 Value *Elt1 = Builder.CreateExtractElement(CI->getArgOperand(1),
1511 ConstantInt::get(I32Ty, 0));
1512 Rep = Builder.CreateInsertElement(CI->getArgOperand(0),
1513 Builder.CreateFAdd(Elt0, Elt1),
1514 ConstantInt::get(I32Ty, 0));
1515 } else if (IsX86 && (Name == "sse.sub.ss" || Name == "sse2.sub.sd")) {
1516 Type *I32Ty = Type::getInt32Ty(C);
1517 Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0),
1518 ConstantInt::get(I32Ty, 0));
1519 Value *Elt1 = Builder.CreateExtractElement(CI->getArgOperand(1),
1520 ConstantInt::get(I32Ty, 0));
1521 Rep = Builder.CreateInsertElement(CI->getArgOperand(0),
1522 Builder.CreateFSub(Elt0, Elt1),
1523 ConstantInt::get(I32Ty, 0));
1524 } else if (IsX86 && (Name == "sse.mul.ss" || Name == "sse2.mul.sd")) {
1525 Type *I32Ty = Type::getInt32Ty(C);
1526 Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0),
1527 ConstantInt::get(I32Ty, 0));
1528 Value *Elt1 = Builder.CreateExtractElement(CI->getArgOperand(1),
1529 ConstantInt::get(I32Ty, 0));
1530 Rep = Builder.CreateInsertElement(CI->getArgOperand(0),
1531 Builder.CreateFMul(Elt0, Elt1),
1532 ConstantInt::get(I32Ty, 0));
1533 } else if (IsX86 && (Name == "sse.div.ss" || Name == "sse2.div.sd")) {
1534 Type *I32Ty = Type::getInt32Ty(C);
1535 Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0),
1536 ConstantInt::get(I32Ty, 0));
1537 Value *Elt1 = Builder.CreateExtractElement(CI->getArgOperand(1),
1538 ConstantInt::get(I32Ty, 0));
1539 Rep = Builder.CreateInsertElement(CI->getArgOperand(0),
1540 Builder.CreateFDiv(Elt0, Elt1),
1541 ConstantInt::get(I32Ty, 0));
Craig Topperaa49f142017-02-18 19:51:14 +00001542 } else if (IsX86 && Name.startswith("avx512.mask.pcmp")) {
1543 // "avx512.mask.pcmpeq." or "avx512.mask.pcmpgt."
1544 bool CmpEq = Name[16] == 'e';
Craig Topper792fc922017-06-22 20:11:01 +00001545 Rep = upgradeMaskedCompare(Builder, *CI, CmpEq ? 0 : 6, true);
1546 } else if (IsX86 && Name.startswith("avx512.mask.cmp")) {
1547 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
1548 Rep = upgradeMaskedCompare(Builder, *CI, Imm, true);
1549 } else if (IsX86 && Name.startswith("avx512.mask.ucmp")) {
1550 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
1551 Rep = upgradeMaskedCompare(Builder, *CI, Imm, false);
Craig Toppercc342d42018-01-09 00:50:47 +00001552 } else if (IsX86 && (Name.startswith("avx512.cvtb2mask.") ||
1553 Name.startswith("avx512.cvtw2mask.") ||
1554 Name.startswith("avx512.cvtd2mask.") ||
1555 Name.startswith("avx512.cvtq2mask."))) {
1556 Value *Op = CI->getArgOperand(0);
1557 Value *Zero = llvm::Constant::getNullValue(Op->getType());
1558 Rep = Builder.CreateICmp(ICmpInst::ICMP_SLT, Op, Zero);
1559 Rep = ApplyX86MaskOn1BitsVec(Builder, Rep, nullptr,
1560 Op->getType()->getVectorNumElements());
Uriel Korach5d5da5f2017-09-13 09:02:36 +00001561 } else if(IsX86 && (Name == "ssse3.pabs.b.128" ||
1562 Name == "ssse3.pabs.w.128" ||
1563 Name == "ssse3.pabs.d.128" ||
1564 Name.startswith("avx2.pabs") ||
1565 Name.startswith("avx512.mask.pabs"))) {
1566 Rep = upgradeAbs(Builder, *CI);
Craig Topper5aebb862016-07-04 20:56:38 +00001567 } else if (IsX86 && (Name == "sse41.pmaxsb" ||
1568 Name == "sse2.pmaxs.w" ||
1569 Name == "sse41.pmaxsd" ||
Craig Topper8ec5c732016-10-24 04:04:16 +00001570 Name.startswith("avx2.pmaxs") ||
1571 Name.startswith("avx512.mask.pmaxs"))) {
Sanjay Patel51ab7572016-06-16 15:48:30 +00001572 Rep = upgradeIntMinMax(Builder, *CI, ICmpInst::ICMP_SGT);
Craig Topper5aebb862016-07-04 20:56:38 +00001573 } else if (IsX86 && (Name == "sse2.pmaxu.b" ||
1574 Name == "sse41.pmaxuw" ||
1575 Name == "sse41.pmaxud" ||
Craig Topper8ec5c732016-10-24 04:04:16 +00001576 Name.startswith("avx2.pmaxu") ||
1577 Name.startswith("avx512.mask.pmaxu"))) {
Sanjay Patel51ab7572016-06-16 15:48:30 +00001578 Rep = upgradeIntMinMax(Builder, *CI, ICmpInst::ICMP_UGT);
Craig Topper5aebb862016-07-04 20:56:38 +00001579 } else if (IsX86 && (Name == "sse41.pminsb" ||
1580 Name == "sse2.pmins.w" ||
1581 Name == "sse41.pminsd" ||
Craig Topper8ec5c732016-10-24 04:04:16 +00001582 Name.startswith("avx2.pmins") ||
1583 Name.startswith("avx512.mask.pmins"))) {
Sanjay Patel51ab7572016-06-16 15:48:30 +00001584 Rep = upgradeIntMinMax(Builder, *CI, ICmpInst::ICMP_SLT);
Craig Topper5aebb862016-07-04 20:56:38 +00001585 } else if (IsX86 && (Name == "sse2.pminu.b" ||
1586 Name == "sse41.pminuw" ||
1587 Name == "sse41.pminud" ||
Craig Topper8ec5c732016-10-24 04:04:16 +00001588 Name.startswith("avx2.pminu") ||
1589 Name.startswith("avx512.mask.pminu"))) {
Sanjay Patel51ab7572016-06-16 15:48:30 +00001590 Rep = upgradeIntMinMax(Builder, *CI, ICmpInst::ICMP_ULT);
Craig Topper254ed022018-04-13 06:07:18 +00001591 } else if (IsX86 && (Name == "sse2.pmulu.dq" ||
1592 Name == "avx2.pmulu.dq" ||
1593 Name == "avx512.pmulu.dq.512" ||
1594 Name.startswith("avx512.mask.pmulu.dq."))) {
1595 Rep = upgradePMULDQ(Builder, *CI, /*Signed*/false);
1596 } else if (IsX86 && (Name == "sse41.pmuldq" ||
1597 Name == "avx2.pmul.dq" ||
1598 Name == "avx512.pmul.dq.512" ||
1599 Name.startswith("avx512.mask.pmul.dq."))) {
1600 Rep = upgradePMULDQ(Builder, *CI, /*Signed*/true);
Craig Topper38ad7dd2018-05-12 23:14:39 +00001601 } else if (IsX86 && (Name == "sse.cvtsi2ss" ||
1602 Name == "sse2.cvtsi2sd" ||
1603 Name == "sse.cvtsi642ss" ||
1604 Name == "sse2.cvtsi642sd")) {
1605 Rep = Builder.CreateSIToFP(CI->getArgOperand(1),
1606 CI->getType()->getVectorElementType());
1607 Rep = Builder.CreateInsertElement(CI->getArgOperand(0), Rep, (uint64_t)0);
Craig Topper0e71c6d2018-05-14 00:06:49 +00001608 } else if (IsX86 && Name == "avx512.cvtusi2sd") {
1609 Rep = Builder.CreateUIToFP(CI->getArgOperand(1),
1610 CI->getType()->getVectorElementType());
1611 Rep = Builder.CreateInsertElement(CI->getArgOperand(0), Rep, (uint64_t)0);
Craig Topperdf3a9ce2018-05-13 00:29:40 +00001612 } else if (IsX86 && Name == "sse2.cvtss2sd") {
1613 Rep = Builder.CreateExtractElement(CI->getArgOperand(1), (uint64_t)0);
1614 Rep = Builder.CreateFPExt(Rep, CI->getType()->getVectorElementType());
1615 Rep = Builder.CreateInsertElement(CI->getArgOperand(0), Rep, (uint64_t)0);
Craig Topper5aebb862016-07-04 20:56:38 +00001616 } else if (IsX86 && (Name == "sse2.cvtdq2pd" ||
Craig Topper358b0942018-05-21 23:15:00 +00001617 Name == "sse2.cvtdq2ps" ||
Craig Topper5aebb862016-07-04 20:56:38 +00001618 Name == "avx.cvtdq2.pd.256" ||
Craig Topper358b0942018-05-21 23:15:00 +00001619 Name == "avx.cvtdq2.ps.256" ||
1620 Name.startswith("avx512.mask.cvtdq2pd.") ||
1621 Name.startswith("avx512.mask.cvtudq2pd.") ||
1622 Name == "avx512.mask.cvtdq2ps.128" ||
1623 Name == "avx512.mask.cvtdq2ps.256" ||
1624 Name == "avx512.mask.cvtudq2ps.128" ||
1625 Name == "avx512.mask.cvtudq2ps.256" ||
1626 Name == "avx512.mask.cvtqq2pd.128" ||
1627 Name == "avx512.mask.cvtqq2pd.256" ||
1628 Name == "avx512.mask.cvtuqq2pd.128" ||
1629 Name == "avx512.mask.cvtuqq2pd.256" ||
1630 Name == "sse2.cvtps2pd" ||
Simon Pilgrimb57dd172016-11-16 14:48:32 +00001631 Name == "avx.cvt.ps2.pd.256" ||
Craig Toppera288f242018-05-12 02:34:28 +00001632 Name == "avx512.mask.cvtps2pd.128" ||
Craig Topper358b0942018-05-21 23:15:00 +00001633 Name == "avx512.mask.cvtps2pd.256")) {
1634 Type *DstTy = CI->getType();
Simon Pilgrim4298d062016-05-25 08:59:18 +00001635 Rep = CI->getArgOperand(0);
1636
Craig Topper358b0942018-05-21 23:15:00 +00001637 unsigned NumDstElts = DstTy->getVectorNumElements();
1638 if (NumDstElts < Rep->getType()->getVectorNumElements()) {
Simon Pilgrim4298d062016-05-25 08:59:18 +00001639 assert(NumDstElts == 2 && "Unexpected vector size");
Craig Topper99d1eab2016-06-12 00:41:19 +00001640 uint32_t ShuffleMask[2] = { 0, 1 };
Craig Topper358b0942018-05-21 23:15:00 +00001641 Rep = Builder.CreateShuffleVector(Rep, Rep, ShuffleMask);
Simon Pilgrim4298d062016-05-25 08:59:18 +00001642 }
1643
Craig Topper358b0942018-05-21 23:15:00 +00001644 bool IsPS2PD = (StringRef::npos != Name.find("ps2"));
1645 bool IsUnsigned = (StringRef::npos != Name.find("cvtu"));
1646 if (IsPS2PD)
Simon Pilgrim4298d062016-05-25 08:59:18 +00001647 Rep = Builder.CreateFPExt(Rep, DstTy, "cvtps2pd");
Craig Topper358b0942018-05-21 23:15:00 +00001648 else if (IsUnsigned)
1649 Rep = Builder.CreateUIToFP(Rep, DstTy, "cvt");
1650 else
1651 Rep = Builder.CreateSIToFP(Rep, DstTy, "cvt");
Simon Pilgrimb57dd172016-11-16 14:48:32 +00001652
1653 if (CI->getNumArgOperands() == 3)
1654 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1655 CI->getArgOperand(1));
Craig Toppera57d2ca2016-09-03 23:55:13 +00001656 } else if (IsX86 && (Name.startswith("avx512.mask.loadu."))) {
Craig Topper46b34fe2016-07-12 01:42:33 +00001657 Rep = UpgradeMaskedLoad(Builder, CI->getArgOperand(0),
Craig Topperf10fbfa2016-06-02 04:19:36 +00001658 CI->getArgOperand(1), CI->getArgOperand(2),
1659 /*Aligned*/false);
Craig Toppera57d2ca2016-09-03 23:55:13 +00001660 } else if (IsX86 && (Name.startswith("avx512.mask.load."))) {
Craig Topper46b34fe2016-07-12 01:42:33 +00001661 Rep = UpgradeMaskedLoad(Builder, CI->getArgOperand(0),
Craig Topperf10fbfa2016-06-02 04:19:36 +00001662 CI->getArgOperand(1),CI->getArgOperand(2),
1663 /*Aligned*/true);
Craig Toppere71ad1f2018-06-11 01:25:22 +00001664 } else if (IsX86 && Name.startswith("avx512.mask.expand.load.")) {
1665 Type *ResultTy = CI->getType();
1666 Type *PtrTy = ResultTy->getVectorElementType();
1667
1668 // Cast the pointer to element type.
1669 Value *Ptr = Builder.CreateBitCast(CI->getOperand(0),
1670 llvm::PointerType::getUnqual(PtrTy));
1671
1672 Value *MaskVec = getX86MaskVec(Builder, CI->getArgOperand(2),
1673 ResultTy->getVectorNumElements());
1674
1675 Function *ELd = Intrinsic::getDeclaration(F->getParent(),
1676 Intrinsic::masked_expandload,
1677 ResultTy);
1678 Rep = Builder.CreateCall(ELd, { Ptr, MaskVec, CI->getOperand(1) });
1679 } else if (IsX86 && Name.startswith("avx512.mask.compress.store.")) {
1680 Type *ResultTy = CI->getArgOperand(1)->getType();
1681 Type *PtrTy = ResultTy->getVectorElementType();
1682
1683 // Cast the pointer to element type.
1684 Value *Ptr = Builder.CreateBitCast(CI->getOperand(0),
1685 llvm::PointerType::getUnqual(PtrTy));
1686
1687 Value *MaskVec = getX86MaskVec(Builder, CI->getArgOperand(2),
1688 ResultTy->getVectorNumElements());
1689
1690 Function *CSt = Intrinsic::getDeclaration(F->getParent(),
1691 Intrinsic::masked_compressstore,
1692 ResultTy);
1693 Rep = Builder.CreateCall(CSt, { CI->getArgOperand(1), Ptr, MaskVec });
Craig Topper5aebb862016-07-04 20:56:38 +00001694 } else if (IsX86 && Name.startswith("xop.vpcom")) {
Craig Topper3352ba52012-06-09 16:46:13 +00001695 Intrinsic::ID intID;
1696 if (Name.endswith("ub"))
1697 intID = Intrinsic::x86_xop_vpcomub;
1698 else if (Name.endswith("uw"))
1699 intID = Intrinsic::x86_xop_vpcomuw;
1700 else if (Name.endswith("ud"))
1701 intID = Intrinsic::x86_xop_vpcomud;
1702 else if (Name.endswith("uq"))
1703 intID = Intrinsic::x86_xop_vpcomuq;
1704 else if (Name.endswith("b"))
1705 intID = Intrinsic::x86_xop_vpcomb;
1706 else if (Name.endswith("w"))
1707 intID = Intrinsic::x86_xop_vpcomw;
1708 else if (Name.endswith("d"))
1709 intID = Intrinsic::x86_xop_vpcomd;
1710 else if (Name.endswith("q"))
1711 intID = Intrinsic::x86_xop_vpcomq;
1712 else
1713 llvm_unreachable("Unknown suffix");
1714
Craig Topper5aebb862016-07-04 20:56:38 +00001715 Name = Name.substr(9); // strip off "xop.vpcom"
Craig Topper3352ba52012-06-09 16:46:13 +00001716 unsigned Imm;
1717 if (Name.startswith("lt"))
1718 Imm = 0;
1719 else if (Name.startswith("le"))
1720 Imm = 1;
1721 else if (Name.startswith("gt"))
1722 Imm = 2;
1723 else if (Name.startswith("ge"))
1724 Imm = 3;
1725 else if (Name.startswith("eq"))
1726 Imm = 4;
1727 else if (Name.startswith("ne"))
1728 Imm = 5;
Craig Topper3352ba52012-06-09 16:46:13 +00001729 else if (Name.startswith("false"))
Craig Toppere32546d2015-02-13 07:42:15 +00001730 Imm = 6;
1731 else if (Name.startswith("true"))
Craig Topper3352ba52012-06-09 16:46:13 +00001732 Imm = 7;
1733 else
1734 llvm_unreachable("Unknown condition");
1735
1736 Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID);
David Blaikieff6409d2015-05-18 22:13:54 +00001737 Rep =
1738 Builder.CreateCall(VPCOM, {CI->getArgOperand(0), CI->getArgOperand(1),
1739 Builder.getInt8(Imm)});
Craig Topperde103122017-02-18 21:50:58 +00001740 } else if (IsX86 && Name.startswith("xop.vpcmov")) {
Simon Pilgrime88dc042015-11-03 20:27:01 +00001741 Value *Sel = CI->getArgOperand(2);
Craig Topper03a9adc2017-02-18 19:51:19 +00001742 Value *NotSel = Builder.CreateNot(Sel);
1743 Value *Sel0 = Builder.CreateAnd(CI->getArgOperand(0), Sel);
1744 Value *Sel1 = Builder.CreateAnd(CI->getArgOperand(1), NotSel);
Simon Pilgrime88dc042015-11-03 20:27:01 +00001745 Rep = Builder.CreateOr(Sel0, Sel1);
Craig Topper5aebb862016-07-04 20:56:38 +00001746 } else if (IsX86 && Name == "sse42.crc32.64.8") {
Craig Topperef9e9932013-10-15 05:20:47 +00001747 Function *CRC32 = Intrinsic::getDeclaration(F->getParent(),
1748 Intrinsic::x86_sse42_crc32_32_8);
1749 Value *Trunc0 = Builder.CreateTrunc(CI->getArgOperand(0), Type::getInt32Ty(C));
David Blaikieff6409d2015-05-18 22:13:54 +00001750 Rep = Builder.CreateCall(CRC32, {Trunc0, CI->getArgOperand(1)});
Craig Topperef9e9932013-10-15 05:20:47 +00001751 Rep = Builder.CreateZExt(Rep, CI->getType(), "");
Craig Topper53ceb482018-05-14 18:21:22 +00001752 } else if (IsX86 && (Name.startswith("avx.vbroadcast.s") ||
1753 Name.startswith("avx512.vbroadcast.s"))) {
Adam Nemet39066802014-05-29 23:35:33 +00001754 // Replace broadcasts with a series of insertelements.
1755 Type *VecTy = CI->getType();
1756 Type *EltTy = VecTy->getVectorElementType();
1757 unsigned EltNum = VecTy->getVectorNumElements();
1758 Value *Cast = Builder.CreateBitCast(CI->getArgOperand(0),
1759 EltTy->getPointerTo());
David Blaikie0c28fd72015-05-20 21:46:30 +00001760 Value *Load = Builder.CreateLoad(EltTy, Cast);
Adam Nemet39066802014-05-29 23:35:33 +00001761 Type *I32Ty = Type::getInt32Ty(C);
1762 Rep = UndefValue::get(VecTy);
1763 for (unsigned I = 0; I < EltNum; ++I)
1764 Rep = Builder.CreateInsertElement(Rep, Load,
1765 ConstantInt::get(I32Ty, I));
Craig Topper5aebb862016-07-04 20:56:38 +00001766 } else if (IsX86 && (Name.startswith("sse41.pmovsx") ||
1767 Name.startswith("sse41.pmovzx") ||
1768 Name.startswith("avx2.pmovsx") ||
Craig Topperb110e042016-11-07 02:12:57 +00001769 Name.startswith("avx2.pmovzx") ||
1770 Name.startswith("avx512.mask.pmovsx") ||
1771 Name.startswith("avx512.mask.pmovzx"))) {
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001772 VectorType *SrcTy = cast<VectorType>(CI->getArgOperand(0)->getType());
1773 VectorType *DstTy = cast<VectorType>(CI->getType());
1774 unsigned NumDstElts = DstTy->getNumElements();
1775
Simon Pilgrim9602d672016-05-28 18:03:41 +00001776 // Extract a subvector of the first NumDstElts lanes and sign/zero extend.
Craig Topperc0a5fa02016-06-12 04:48:00 +00001777 SmallVector<uint32_t, 8> ShuffleMask(NumDstElts);
Craig Topper99d1eab2016-06-12 00:41:19 +00001778 for (unsigned i = 0; i != NumDstElts; ++i)
Craig Topperc0a5fa02016-06-12 04:48:00 +00001779 ShuffleMask[i] = i;
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001780
1781 Value *SV = Builder.CreateShuffleVector(
1782 CI->getArgOperand(0), UndefValue::get(SrcTy), ShuffleMask);
Simon Pilgrim9602d672016-05-28 18:03:41 +00001783
1784 bool DoSext = (StringRef::npos != Name.find("pmovsx"));
1785 Rep = DoSext ? Builder.CreateSExt(SV, DstTy)
1786 : Builder.CreateZExt(SV, DstTy);
Craig Topperb110e042016-11-07 02:12:57 +00001787 // If there are 3 arguments, it's a masked intrinsic so we need a select.
1788 if (CI->getNumArgOperands() == 3)
1789 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1790 CI->getArgOperand(1));
Simon Pilgrimea0d4f92016-07-22 13:58:44 +00001791 } else if (IsX86 && (Name.startswith("avx.vbroadcastf128") ||
1792 Name == "avx2.vbroadcasti128")) {
1793 // Replace vbroadcastf128/vbroadcasti128 with a vector load+shuffle.
1794 Type *EltTy = CI->getType()->getVectorElementType();
1795 unsigned NumSrcElts = 128 / EltTy->getPrimitiveSizeInBits();
1796 Type *VT = VectorType::get(EltTy, NumSrcElts);
David Blaikie0c28fd72015-05-20 21:46:30 +00001797 Value *Op = Builder.CreatePointerCast(CI->getArgOperand(0),
1798 PointerType::getUnqual(VT));
Chandler Carruth0215e762016-08-10 07:41:26 +00001799 Value *Load = Builder.CreateAlignedLoad(Op, 1);
Simon Pilgrimea0d4f92016-07-22 13:58:44 +00001800 if (NumSrcElts == 2)
1801 Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()),
1802 { 0, 1, 0, 1 });
1803 else
1804 Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()),
1805 { 0, 1, 2, 3, 0, 1, 2, 3 });
Jina Nahias9a7f9f12017-11-13 09:16:39 +00001806 } else if (IsX86 && (Name.startswith("avx512.mask.shuf.i") ||
1807 Name.startswith("avx512.mask.shuf.f"))) {
1808 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
1809 Type *VT = CI->getType();
1810 unsigned NumLanes = VT->getPrimitiveSizeInBits() / 128;
1811 unsigned NumElementsInLane = 128 / VT->getScalarSizeInBits();
1812 unsigned ControlBitsMask = NumLanes - 1;
1813 unsigned NumControlBits = NumLanes / 2;
1814 SmallVector<uint32_t, 8> ShuffleMask(0);
1815
1816 for (unsigned l = 0; l != NumLanes; ++l) {
1817 unsigned LaneMask = (Imm >> (l * NumControlBits)) & ControlBitsMask;
1818 // We actually need the other source.
1819 if (l >= NumLanes / 2)
1820 LaneMask += NumLanes;
1821 for (unsigned i = 0; i != NumElementsInLane; ++i)
1822 ShuffleMask.push_back(LaneMask * NumElementsInLane + i);
1823 }
1824 Rep = Builder.CreateShuffleVector(CI->getArgOperand(0),
1825 CI->getArgOperand(1), ShuffleMask);
1826 Rep = EmitX86Select(Builder, CI->getArgOperand(4), Rep,
1827 CI->getArgOperand(3));
1828 }else if (IsX86 && (Name.startswith("avx512.mask.broadcastf") ||
Craig Topper561092f2017-08-11 16:22:45 +00001829 Name.startswith("avx512.mask.broadcasti"))) {
1830 unsigned NumSrcElts =
1831 CI->getArgOperand(0)->getType()->getVectorNumElements();
1832 unsigned NumDstElts = CI->getType()->getVectorNumElements();
1833
1834 SmallVector<uint32_t, 8> ShuffleMask(NumDstElts);
1835 for (unsigned i = 0; i != NumDstElts; ++i)
1836 ShuffleMask[i] = i % NumSrcElts;
1837
1838 Rep = Builder.CreateShuffleVector(CI->getArgOperand(0),
1839 CI->getArgOperand(0),
1840 ShuffleMask);
1841 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1842 CI->getArgOperand(1));
Craig Topper5aebb862016-07-04 20:56:38 +00001843 } else if (IsX86 && (Name.startswith("avx2.pbroadcast") ||
Simon Pilgrim4e96fbf2016-07-05 13:58:47 +00001844 Name.startswith("avx2.vbroadcast") ||
1845 Name.startswith("avx512.pbroadcast") ||
1846 Name.startswith("avx512.mask.broadcast.s"))) {
Ahmed Bougacha1a4987052015-08-20 20:36:19 +00001847 // Replace vp?broadcasts with a vector shuffle.
1848 Value *Op = CI->getArgOperand(0);
1849 unsigned NumElts = CI->getType()->getVectorNumElements();
1850 Type *MaskTy = VectorType::get(Type::getInt32Ty(C), NumElts);
1851 Rep = Builder.CreateShuffleVector(Op, UndefValue::get(Op->getType()),
1852 Constant::getNullValue(MaskTy));
Chandler Carruth16429ac2018-04-26 21:46:01 +00001853
Simon Pilgrim4e96fbf2016-07-05 13:58:47 +00001854 if (CI->getNumArgOperands() == 3)
1855 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
1856 CI->getArgOperand(1));
Craig Topper5aebb862016-07-04 20:56:38 +00001857 } else if (IsX86 && Name.startswith("avx512.mask.palignr.")) {
Craig Topperf57e17d2016-11-23 06:54:55 +00001858 Rep = UpgradeX86ALIGNIntrinsics(Builder, CI->getArgOperand(0),
1859 CI->getArgOperand(1),
1860 CI->getArgOperand(2),
1861 CI->getArgOperand(3),
1862 CI->getArgOperand(4),
1863 false);
1864 } else if (IsX86 && Name.startswith("avx512.mask.valign.")) {
1865 Rep = UpgradeX86ALIGNIntrinsics(Builder, CI->getArgOperand(0),
1866 CI->getArgOperand(1),
1867 CI->getArgOperand(2),
1868 CI->getArgOperand(3),
1869 CI->getArgOperand(4),
1870 true);
Craig Topper5aebb862016-07-04 20:56:38 +00001871 } else if (IsX86 && (Name == "sse2.psll.dq" ||
1872 Name == "avx2.psll.dq")) {
Craig Topper7355ac32016-05-29 06:37:33 +00001873 // 128/256-bit shift left specified in bits.
Craig Topperb324e432015-02-18 06:24:44 +00001874 unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper46b34fe2016-07-12 01:42:33 +00001875 Rep = UpgradeX86PSLLDQIntrinsics(Builder, CI->getArgOperand(0),
Craig Topperb324e432015-02-18 06:24:44 +00001876 Shift / 8); // Shift is in bits.
Craig Topper5aebb862016-07-04 20:56:38 +00001877 } else if (IsX86 && (Name == "sse2.psrl.dq" ||
1878 Name == "avx2.psrl.dq")) {
Craig Topper7355ac32016-05-29 06:37:33 +00001879 // 128/256-bit shift right specified in bits.
Craig Topperb324e432015-02-18 06:24:44 +00001880 unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper46b34fe2016-07-12 01:42:33 +00001881 Rep = UpgradeX86PSRLDQIntrinsics(Builder, CI->getArgOperand(0),
Craig Topperb324e432015-02-18 06:24:44 +00001882 Shift / 8); // Shift is in bits.
Craig Topper5aebb862016-07-04 20:56:38 +00001883 } else if (IsX86 && (Name == "sse2.psll.dq.bs" ||
1884 Name == "avx2.psll.dq.bs" ||
1885 Name == "avx512.psll.dq.512")) {
Simon Pilgrimf7186822016-06-09 21:09:03 +00001886 // 128/256/512-bit shift left specified in bytes.
Craig Topperb324e432015-02-18 06:24:44 +00001887 unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper46b34fe2016-07-12 01:42:33 +00001888 Rep = UpgradeX86PSLLDQIntrinsics(Builder, CI->getArgOperand(0), Shift);
Craig Topper5aebb862016-07-04 20:56:38 +00001889 } else if (IsX86 && (Name == "sse2.psrl.dq.bs" ||
1890 Name == "avx2.psrl.dq.bs" ||
1891 Name == "avx512.psrl.dq.512")) {
Simon Pilgrimf7186822016-06-09 21:09:03 +00001892 // 128/256/512-bit shift right specified in bytes.
Craig Topperb324e432015-02-18 06:24:44 +00001893 unsigned Shift = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper46b34fe2016-07-12 01:42:33 +00001894 Rep = UpgradeX86PSRLDQIntrinsics(Builder, CI->getArgOperand(0), Shift);
Craig Topper5aebb862016-07-04 20:56:38 +00001895 } else if (IsX86 && (Name == "sse41.pblendw" ||
1896 Name.startswith("sse41.blendp") ||
1897 Name.startswith("avx.blend.p") ||
1898 Name == "avx2.pblendw" ||
1899 Name.startswith("avx2.pblendd."))) {
Craig Topper782d6202015-02-28 19:33:17 +00001900 Value *Op0 = CI->getArgOperand(0);
1901 Value *Op1 = CI->getArgOperand(1);
1902 unsigned Imm = cast <ConstantInt>(CI->getArgOperand(2))->getZExtValue();
1903 VectorType *VecTy = cast<VectorType>(CI->getType());
1904 unsigned NumElts = VecTy->getNumElements();
1905
Craig Topperc0a5fa02016-06-12 04:48:00 +00001906 SmallVector<uint32_t, 16> Idxs(NumElts);
1907 for (unsigned i = 0; i != NumElts; ++i)
1908 Idxs[i] = ((Imm >> (i%8)) & 1) ? i + NumElts : i;
Craig Topper782d6202015-02-28 19:33:17 +00001909
Craig Topper2f561822016-06-12 01:05:59 +00001910 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
Craig Topper5aebb862016-07-04 20:56:38 +00001911 } else if (IsX86 && (Name.startswith("avx.vinsertf128.") ||
Craig Topper0cda8bb2017-01-03 05:45:57 +00001912 Name == "avx2.vinserti128" ||
1913 Name.startswith("avx512.mask.insert"))) {
Sanjay Patel19792fb2015-03-10 16:08:36 +00001914 Value *Op0 = CI->getArgOperand(0);
1915 Value *Op1 = CI->getArgOperand(1);
1916 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
Craig Topper0cda8bb2017-01-03 05:45:57 +00001917 unsigned DstNumElts = CI->getType()->getVectorNumElements();
1918 unsigned SrcNumElts = Op1->getType()->getVectorNumElements();
1919 unsigned Scale = DstNumElts / SrcNumElts;
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001920
Sanjay Patel19792fb2015-03-10 16:08:36 +00001921 // Mask off the high bits of the immediate value; hardware ignores those.
Craig Topper0cda8bb2017-01-03 05:45:57 +00001922 Imm = Imm % Scale;
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001923
Craig Topper0cda8bb2017-01-03 05:45:57 +00001924 // Extend the second operand into a vector the size of the destination.
Sanjay Patel19792fb2015-03-10 16:08:36 +00001925 Value *UndefV = UndefValue::get(Op1->getType());
Craig Topper0cda8bb2017-01-03 05:45:57 +00001926 SmallVector<uint32_t, 8> Idxs(DstNumElts);
1927 for (unsigned i = 0; i != SrcNumElts; ++i)
Craig Topperc0a5fa02016-06-12 04:48:00 +00001928 Idxs[i] = i;
Craig Topper0cda8bb2017-01-03 05:45:57 +00001929 for (unsigned i = SrcNumElts; i != DstNumElts; ++i)
1930 Idxs[i] = SrcNumElts;
Craig Topper2f561822016-06-12 01:05:59 +00001931 Rep = Builder.CreateShuffleVector(Op1, UndefV, Idxs);
Sanjay Patel19792fb2015-03-10 16:08:36 +00001932
1933 // Insert the second operand into the first operand.
1934
1935 // Note that there is no guarantee that instruction lowering will actually
1936 // produce a vinsertf128 instruction for the created shuffles. In
1937 // particular, the 0 immediate case involves no lane changes, so it can
1938 // be handled as a blend.
1939
1940 // Example of shuffle mask for 32-bit elements:
1941 // Imm = 1 <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
1942 // Imm = 0 <i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7 >
1943
Craig Topper0cda8bb2017-01-03 05:45:57 +00001944 // First fill with identify mask.
1945 for (unsigned i = 0; i != DstNumElts; ++i)
1946 Idxs[i] = i;
1947 // Then replace the elements where we need to insert.
1948 for (unsigned i = 0; i != SrcNumElts; ++i)
1949 Idxs[i + Imm * SrcNumElts] = i + DstNumElts;
Craig Topper2f561822016-06-12 01:05:59 +00001950 Rep = Builder.CreateShuffleVector(Op0, Rep, Idxs);
Craig Topper0cda8bb2017-01-03 05:45:57 +00001951
1952 // If the intrinsic has a mask operand, handle that.
1953 if (CI->getNumArgOperands() == 5)
1954 Rep = EmitX86Select(Builder, CI->getArgOperand(4), Rep,
1955 CI->getArgOperand(3));
Craig Topper5aebb862016-07-04 20:56:38 +00001956 } else if (IsX86 && (Name.startswith("avx.vextractf128.") ||
Craig Topper4d47c6a2017-01-03 05:45:46 +00001957 Name == "avx2.vextracti128" ||
1958 Name.startswith("avx512.mask.vextract"))) {
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001959 Value *Op0 = CI->getArgOperand(0);
1960 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
Craig Topper4d47c6a2017-01-03 05:45:46 +00001961 unsigned DstNumElts = CI->getType()->getVectorNumElements();
1962 unsigned SrcNumElts = Op0->getType()->getVectorNumElements();
1963 unsigned Scale = SrcNumElts / DstNumElts;
Simon Pilgrim9cb018b2015-09-23 08:48:33 +00001964
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001965 // Mask off the high bits of the immediate value; hardware ignores those.
Craig Topper4d47c6a2017-01-03 05:45:46 +00001966 Imm = Imm % Scale;
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001967
Craig Topper4d47c6a2017-01-03 05:45:46 +00001968 // Get indexes for the subvector of the input vector.
1969 SmallVector<uint32_t, 8> Idxs(DstNumElts);
1970 for (unsigned i = 0; i != DstNumElts; ++i) {
1971 Idxs[i] = i + (Imm * DstNumElts);
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001972 }
Craig Topper4d47c6a2017-01-03 05:45:46 +00001973 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
Sanjay Patelaf1846c2015-03-12 15:15:19 +00001974
Craig Topper4d47c6a2017-01-03 05:45:46 +00001975 // If the intrinsic has a mask operand, handle that.
1976 if (CI->getNumArgOperands() == 4)
1977 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1978 CI->getArgOperand(2));
Craig Topper5aebb862016-07-04 20:56:38 +00001979 } else if (!IsX86 && Name == "stackprotectorcheck") {
Tim Shen00127562016-04-08 21:26:31 +00001980 Rep = nullptr;
Craig Topper5aebb862016-07-04 20:56:38 +00001981 } else if (IsX86 && (Name.startswith("avx512.mask.perm.df.") ||
1982 Name.startswith("avx512.mask.perm.di."))) {
Simon Pilgrim02d435d2016-07-04 14:19:05 +00001983 Value *Op0 = CI->getArgOperand(0);
1984 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
1985 VectorType *VecTy = cast<VectorType>(CI->getType());
1986 unsigned NumElts = VecTy->getNumElements();
1987
1988 SmallVector<uint32_t, 8> Idxs(NumElts);
1989 for (unsigned i = 0; i != NumElts; ++i)
1990 Idxs[i] = (i & ~0x3) + ((Imm >> (2 * (i & 0x3))) & 3);
1991
1992 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
1993
1994 if (CI->getNumArgOperands() == 4)
1995 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
1996 CI->getArgOperand(2));
Craig Topperf264fcc2017-09-16 07:36:14 +00001997 } else if (IsX86 && (Name.startswith("avx.vperm2f128.") ||
1998 Name == "avx2.vperm2i128")) {
1999 // The immediate permute control byte looks like this:
2000 // [1:0] - select 128 bits from sources for low half of destination
2001 // [2] - ignore
2002 // [3] - zero low half of destination
2003 // [5:4] - select 128 bits from sources for high half of destination
2004 // [6] - ignore
2005 // [7] - zero high half of destination
2006
2007 uint8_t Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
2008
2009 unsigned NumElts = CI->getType()->getVectorNumElements();
2010 unsigned HalfSize = NumElts / 2;
2011 SmallVector<uint32_t, 8> ShuffleMask(NumElts);
2012
2013 // Determine which operand(s) are actually in use for this instruction.
2014 Value *V0 = (Imm & 0x02) ? CI->getArgOperand(1) : CI->getArgOperand(0);
2015 Value *V1 = (Imm & 0x20) ? CI->getArgOperand(1) : CI->getArgOperand(0);
2016
2017 // If needed, replace operands based on zero mask.
2018 V0 = (Imm & 0x08) ? ConstantAggregateZero::get(CI->getType()) : V0;
2019 V1 = (Imm & 0x80) ? ConstantAggregateZero::get(CI->getType()) : V1;
2020
2021 // Permute low half of result.
2022 unsigned StartIndex = (Imm & 0x01) ? HalfSize : 0;
2023 for (unsigned i = 0; i < HalfSize; ++i)
2024 ShuffleMask[i] = StartIndex + i;
2025
2026 // Permute high half of result.
2027 StartIndex = (Imm & 0x10) ? HalfSize : 0;
2028 for (unsigned i = 0; i < HalfSize; ++i)
2029 ShuffleMask[i + HalfSize] = NumElts + StartIndex + i;
2030
2031 Rep = Builder.CreateShuffleVector(V0, V1, ShuffleMask);
2032
Craig Topper5aebb862016-07-04 20:56:38 +00002033 } else if (IsX86 && (Name.startswith("avx.vpermil.") ||
2034 Name == "sse2.pshuf.d" ||
2035 Name.startswith("avx512.mask.vpermil.p") ||
2036 Name.startswith("avx512.mask.pshuf.d."))) {
Craig Topper8a105052016-06-12 03:10:47 +00002037 Value *Op0 = CI->getArgOperand(0);
2038 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
2039 VectorType *VecTy = cast<VectorType>(CI->getType());
2040 unsigned NumElts = VecTy->getNumElements();
Simon Pilgrim9fca3002016-07-04 12:40:54 +00002041 // Calculate the size of each index in the immediate.
Craig Topper8a105052016-06-12 03:10:47 +00002042 unsigned IdxSize = 64 / VecTy->getScalarSizeInBits();
2043 unsigned IdxMask = ((1 << IdxSize) - 1);
2044
2045 SmallVector<uint32_t, 8> Idxs(NumElts);
2046 // Lookup the bits for this element, wrapping around the immediate every
2047 // 8-bits. Elements are grouped into sets of 2 or 4 elements so we need
2048 // to offset by the first index of each group.
2049 for (unsigned i = 0; i != NumElts; ++i)
2050 Idxs[i] = ((Imm >> ((i * IdxSize) % 8)) & IdxMask) | (i & ~IdxMask);
2051
2052 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
Craig Topper13cf7ca2016-06-13 02:36:48 +00002053
2054 if (CI->getNumArgOperands() == 4)
2055 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2056 CI->getArgOperand(2));
Craig Topper5aebb862016-07-04 20:56:38 +00002057 } else if (IsX86 && (Name == "sse2.pshufl.w" ||
2058 Name.startswith("avx512.mask.pshufl.w."))) {
Craig Topper10679862016-06-12 14:11:32 +00002059 Value *Op0 = CI->getArgOperand(0);
2060 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
2061 unsigned NumElts = CI->getType()->getVectorNumElements();
2062
2063 SmallVector<uint32_t, 16> Idxs(NumElts);
2064 for (unsigned l = 0; l != NumElts; l += 8) {
2065 for (unsigned i = 0; i != 4; ++i)
2066 Idxs[i + l] = ((Imm >> (2 * i)) & 0x3) + l;
2067 for (unsigned i = 4; i != 8; ++i)
2068 Idxs[i + l] = i + l;
2069 }
2070
2071 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
Craig Topper13cf7ca2016-06-13 02:36:48 +00002072
2073 if (CI->getNumArgOperands() == 4)
2074 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2075 CI->getArgOperand(2));
Craig Topper5aebb862016-07-04 20:56:38 +00002076 } else if (IsX86 && (Name == "sse2.pshufh.w" ||
2077 Name.startswith("avx512.mask.pshufh.w."))) {
Craig Topper10679862016-06-12 14:11:32 +00002078 Value *Op0 = CI->getArgOperand(0);
2079 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
2080 unsigned NumElts = CI->getType()->getVectorNumElements();
2081
2082 SmallVector<uint32_t, 16> Idxs(NumElts);
2083 for (unsigned l = 0; l != NumElts; l += 8) {
2084 for (unsigned i = 0; i != 4; ++i)
2085 Idxs[i + l] = i + l;
2086 for (unsigned i = 0; i != 4; ++i)
2087 Idxs[i + l + 4] = ((Imm >> (2 * i)) & 0x3) + 4 + l;
2088 }
2089
2090 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
Craig Topper13cf7ca2016-06-13 02:36:48 +00002091
2092 if (CI->getNumArgOperands() == 4)
2093 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2094 CI->getArgOperand(2));
Craig Topper4619c9e2016-09-13 07:40:53 +00002095 } else if (IsX86 && Name.startswith("avx512.mask.shuf.p")) {
2096 Value *Op0 = CI->getArgOperand(0);
2097 Value *Op1 = CI->getArgOperand(1);
2098 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
2099 unsigned NumElts = CI->getType()->getVectorNumElements();
2100
2101 unsigned NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
2102 unsigned HalfLaneElts = NumLaneElts / 2;
2103
2104 SmallVector<uint32_t, 16> Idxs(NumElts);
2105 for (unsigned i = 0; i != NumElts; ++i) {
2106 // Base index is the starting element of the lane.
2107 Idxs[i] = i - (i % NumLaneElts);
2108 // If we are half way through the lane switch to the other source.
2109 if ((i % NumLaneElts) >= HalfLaneElts)
2110 Idxs[i] += NumElts;
2111 // Now select the specific element. By adding HalfLaneElts bits from
2112 // the immediate. Wrapping around the immediate every 8-bits.
2113 Idxs[i] += (Imm >> ((i * HalfLaneElts) % 8)) & ((1 << HalfLaneElts) - 1);
2114 }
2115
2116 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
2117
2118 Rep = EmitX86Select(Builder, CI->getArgOperand(4), Rep,
2119 CI->getArgOperand(3));
Craig Topper5aebb862016-07-04 20:56:38 +00002120 } else if (IsX86 && (Name.startswith("avx512.mask.movddup") ||
2121 Name.startswith("avx512.mask.movshdup") ||
2122 Name.startswith("avx512.mask.movsldup"))) {
Simon Pilgrim19adee92016-07-02 14:42:35 +00002123 Value *Op0 = CI->getArgOperand(0);
2124 unsigned NumElts = CI->getType()->getVectorNumElements();
2125 unsigned NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
2126
2127 unsigned Offset = 0;
Craig Topper5aebb862016-07-04 20:56:38 +00002128 if (Name.startswith("avx512.mask.movshdup."))
Simon Pilgrim19adee92016-07-02 14:42:35 +00002129 Offset = 1;
2130
2131 SmallVector<uint32_t, 16> Idxs(NumElts);
2132 for (unsigned l = 0; l != NumElts; l += NumLaneElts)
2133 for (unsigned i = 0; i != NumLaneElts; i += 2) {
2134 Idxs[i + l + 0] = i + l + Offset;
2135 Idxs[i + l + 1] = i + l + Offset;
2136 }
2137
2138 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
2139
2140 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
2141 CI->getArgOperand(1));
Craig Topper5aebb862016-07-04 20:56:38 +00002142 } else if (IsX86 && (Name.startswith("avx512.mask.punpckl") ||
2143 Name.startswith("avx512.mask.unpckl."))) {
Craig Topper597aa422016-06-23 07:37:33 +00002144 Value *Op0 = CI->getArgOperand(0);
2145 Value *Op1 = CI->getArgOperand(1);
2146 int NumElts = CI->getType()->getVectorNumElements();
2147 int NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
2148
2149 SmallVector<uint32_t, 64> Idxs(NumElts);
2150 for (int l = 0; l != NumElts; l += NumLaneElts)
2151 for (int i = 0; i != NumLaneElts; ++i)
2152 Idxs[i + l] = l + (i / 2) + NumElts * (i % 2);
2153
2154 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
2155
2156 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2157 CI->getArgOperand(2));
Craig Topper5aebb862016-07-04 20:56:38 +00002158 } else if (IsX86 && (Name.startswith("avx512.mask.punpckh") ||
2159 Name.startswith("avx512.mask.unpckh."))) {
Craig Topper597aa422016-06-23 07:37:33 +00002160 Value *Op0 = CI->getArgOperand(0);
2161 Value *Op1 = CI->getArgOperand(1);
2162 int NumElts = CI->getType()->getVectorNumElements();
2163 int NumLaneElts = 128/CI->getType()->getScalarSizeInBits();
2164
2165 SmallVector<uint32_t, 64> Idxs(NumElts);
2166 for (int l = 0; l != NumElts; l += NumLaneElts)
2167 for (int i = 0; i != NumLaneElts; ++i)
2168 Idxs[i + l] = (NumLaneElts / 2) + l + (i / 2) + NumElts * (i % 2);
2169
2170 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
2171
2172 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2173 CI->getArgOperand(2));
Craig Toppera6e6feb2016-07-12 05:27:53 +00002174 } else if (IsX86 && Name.startswith("avx512.mask.pand.")) {
2175 Rep = Builder.CreateAnd(CI->getArgOperand(0), CI->getArgOperand(1));
2176 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2177 CI->getArgOperand(2));
2178 } else if (IsX86 && Name.startswith("avx512.mask.pandn.")) {
2179 Rep = Builder.CreateAnd(Builder.CreateNot(CI->getArgOperand(0)),
2180 CI->getArgOperand(1));
2181 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2182 CI->getArgOperand(2));
2183 } else if (IsX86 && Name.startswith("avx512.mask.por.")) {
2184 Rep = Builder.CreateOr(CI->getArgOperand(0), CI->getArgOperand(1));
2185 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2186 CI->getArgOperand(2));
2187 } else if (IsX86 && Name.startswith("avx512.mask.pxor.")) {
2188 Rep = Builder.CreateXor(CI->getArgOperand(0), CI->getArgOperand(1));
2189 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2190 CI->getArgOperand(2));
Craig Toppere75c4952016-09-02 05:29:17 +00002191 } else if (IsX86 && Name.startswith("avx512.mask.and.")) {
2192 VectorType *FTy = cast<VectorType>(CI->getType());
2193 VectorType *ITy = VectorType::getInteger(FTy);
2194 Rep = Builder.CreateAnd(Builder.CreateBitCast(CI->getArgOperand(0), ITy),
2195 Builder.CreateBitCast(CI->getArgOperand(1), ITy));
2196 Rep = Builder.CreateBitCast(Rep, FTy);
2197 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2198 CI->getArgOperand(2));
2199 } else if (IsX86 && Name.startswith("avx512.mask.andn.")) {
2200 VectorType *FTy = cast<VectorType>(CI->getType());
2201 VectorType *ITy = VectorType::getInteger(FTy);
2202 Rep = Builder.CreateNot(Builder.CreateBitCast(CI->getArgOperand(0), ITy));
2203 Rep = Builder.CreateAnd(Rep,
2204 Builder.CreateBitCast(CI->getArgOperand(1), ITy));
2205 Rep = Builder.CreateBitCast(Rep, FTy);
2206 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2207 CI->getArgOperand(2));
2208 } else if (IsX86 && Name.startswith("avx512.mask.or.")) {
2209 VectorType *FTy = cast<VectorType>(CI->getType());
2210 VectorType *ITy = VectorType::getInteger(FTy);
2211 Rep = Builder.CreateOr(Builder.CreateBitCast(CI->getArgOperand(0), ITy),
2212 Builder.CreateBitCast(CI->getArgOperand(1), ITy));
2213 Rep = Builder.CreateBitCast(Rep, FTy);
2214 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2215 CI->getArgOperand(2));
2216 } else if (IsX86 && Name.startswith("avx512.mask.xor.")) {
2217 VectorType *FTy = cast<VectorType>(CI->getType());
2218 VectorType *ITy = VectorType::getInteger(FTy);
2219 Rep = Builder.CreateXor(Builder.CreateBitCast(CI->getArgOperand(0), ITy),
2220 Builder.CreateBitCast(CI->getArgOperand(1), ITy));
2221 Rep = Builder.CreateBitCast(Rep, FTy);
2222 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2223 CI->getArgOperand(2));
Craig Topperaf0d63d2016-09-04 02:09:53 +00002224 } else if (IsX86 && Name.startswith("avx512.mask.padd.")) {
2225 Rep = Builder.CreateAdd(CI->getArgOperand(0), CI->getArgOperand(1));
2226 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2227 CI->getArgOperand(2));
2228 } else if (IsX86 && Name.startswith("avx512.mask.psub.")) {
2229 Rep = Builder.CreateSub(CI->getArgOperand(0), CI->getArgOperand(1));
2230 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2231 CI->getArgOperand(2));
2232 } else if (IsX86 && Name.startswith("avx512.mask.pmull.")) {
2233 Rep = Builder.CreateMul(CI->getArgOperand(0), CI->getArgOperand(1));
2234 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2235 CI->getArgOperand(2));
Craig Topper98a79932018-06-10 06:01:36 +00002236 } else if (IsX86 && Name.startswith("avx512.mask.add.p")) {
2237 if (Name.endswith(".512")) {
2238 Intrinsic::ID IID;
2239 if (Name[17] == 's')
2240 IID = Intrinsic::x86_avx512_add_ps_512;
2241 else
2242 IID = Intrinsic::x86_avx512_add_pd_512;
2243
2244 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
2245 { CI->getArgOperand(0), CI->getArgOperand(1),
2246 CI->getArgOperand(4) });
2247 } else {
2248 Rep = Builder.CreateFAdd(CI->getArgOperand(0), CI->getArgOperand(1));
2249 }
Craig Topper41773452016-09-04 18:13:33 +00002250 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2251 CI->getArgOperand(2));
Craig Topper96041c62016-11-07 00:13:42 +00002252 } else if (IsX86 && Name.startswith("avx512.mask.div.p")) {
Craig Topper98a79932018-06-10 06:01:36 +00002253 if (Name.endswith(".512")) {
2254 Intrinsic::ID IID;
2255 if (Name[17] == 's')
2256 IID = Intrinsic::x86_avx512_div_ps_512;
2257 else
2258 IID = Intrinsic::x86_avx512_div_pd_512;
2259
2260 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
2261 { CI->getArgOperand(0), CI->getArgOperand(1),
2262 CI->getArgOperand(4) });
2263 } else {
2264 Rep = Builder.CreateFDiv(CI->getArgOperand(0), CI->getArgOperand(1));
2265 }
Craig Topper41773452016-09-04 18:13:33 +00002266 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2267 CI->getArgOperand(2));
Craig Topper96041c62016-11-07 00:13:42 +00002268 } else if (IsX86 && Name.startswith("avx512.mask.mul.p")) {
Craig Topper98a79932018-06-10 06:01:36 +00002269 if (Name.endswith(".512")) {
2270 Intrinsic::ID IID;
2271 if (Name[17] == 's')
2272 IID = Intrinsic::x86_avx512_mul_ps_512;
2273 else
2274 IID = Intrinsic::x86_avx512_mul_pd_512;
2275
2276 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
2277 { CI->getArgOperand(0), CI->getArgOperand(1),
2278 CI->getArgOperand(4) });
2279 } else {
2280 Rep = Builder.CreateFMul(CI->getArgOperand(0), CI->getArgOperand(1));
2281 }
Craig Topper41773452016-09-04 18:13:33 +00002282 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2283 CI->getArgOperand(2));
Craig Topper96041c62016-11-07 00:13:42 +00002284 } else if (IsX86 && Name.startswith("avx512.mask.sub.p")) {
Craig Topper98a79932018-06-10 06:01:36 +00002285 if (Name.endswith(".512")) {
2286 Intrinsic::ID IID;
2287 if (Name[17] == 's')
2288 IID = Intrinsic::x86_avx512_sub_ps_512;
2289 else
2290 IID = Intrinsic::x86_avx512_sub_pd_512;
2291
2292 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(), IID),
2293 { CI->getArgOperand(0), CI->getArgOperand(1),
2294 CI->getArgOperand(4) });
2295 } else {
2296 Rep = Builder.CreateFSub(CI->getArgOperand(0), CI->getArgOperand(1));
2297 }
Craig Topper41773452016-09-04 18:13:33 +00002298 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2299 CI->getArgOperand(2));
Craig Topperf2529c12017-02-24 05:35:04 +00002300 } else if (IsX86 && Name.startswith("avx512.mask.lzcnt.")) {
2301 Rep = Builder.CreateCall(Intrinsic::getDeclaration(F->getParent(),
2302 Intrinsic::ctlz,
2303 CI->getType()),
2304 { CI->getArgOperand(0), Builder.getInt1(false) });
2305 Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
2306 CI->getArgOperand(1));
Craig Topper987dad22016-11-13 19:09:56 +00002307 } else if (IsX86 && Name.startswith("avx512.mask.psll")) {
2308 bool IsImmediate = Name[16] == 'i' ||
2309 (Name.size() > 18 && Name[18] == 'i');
2310 bool IsVariable = Name[16] == 'v';
2311 char Size = Name[16] == '.' ? Name[17] :
2312 Name[17] == '.' ? Name[18] :
Craig Topper02b5a1b2016-11-18 05:04:44 +00002313 Name[18] == '.' ? Name[19] :
2314 Name[20];
Craig Topper987dad22016-11-13 19:09:56 +00002315
2316 Intrinsic::ID IID;
Craig Topper353e59b2016-11-14 01:53:22 +00002317 if (IsVariable && Name[17] != '.') {
Craig Topper987dad22016-11-13 19:09:56 +00002318 if (Size == 'd' && Name[17] == '2') // avx512.mask.psllv2.di
2319 IID = Intrinsic::x86_avx2_psllv_q;
2320 else if (Size == 'd' && Name[17] == '4') // avx512.mask.psllv4.di
2321 IID = Intrinsic::x86_avx2_psllv_q_256;
2322 else if (Size == 's' && Name[17] == '4') // avx512.mask.psllv4.si
2323 IID = Intrinsic::x86_avx2_psllv_d;
2324 else if (Size == 's' && Name[17] == '8') // avx512.mask.psllv8.si
2325 IID = Intrinsic::x86_avx2_psllv_d_256;
Craig Topper02b5a1b2016-11-18 05:04:44 +00002326 else if (Size == 'h' && Name[17] == '8') // avx512.mask.psllv8.hi
2327 IID = Intrinsic::x86_avx512_psllv_w_128;
2328 else if (Size == 'h' && Name[17] == '1') // avx512.mask.psllv16.hi
2329 IID = Intrinsic::x86_avx512_psllv_w_256;
2330 else if (Name[17] == '3' && Name[18] == '2') // avx512.mask.psllv32hi
2331 IID = Intrinsic::x86_avx512_psllv_w_512;
Craig Topper987dad22016-11-13 19:09:56 +00002332 else
2333 llvm_unreachable("Unexpected size");
2334 } else if (Name.endswith(".128")) {
2335 if (Size == 'd') // avx512.mask.psll.d.128, avx512.mask.psll.di.128
2336 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_d
2337 : Intrinsic::x86_sse2_psll_d;
2338 else if (Size == 'q') // avx512.mask.psll.q.128, avx512.mask.psll.qi.128
2339 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_q
2340 : Intrinsic::x86_sse2_psll_q;
2341 else if (Size == 'w') // avx512.mask.psll.w.128, avx512.mask.psll.wi.128
2342 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_w
2343 : Intrinsic::x86_sse2_psll_w;
2344 else
2345 llvm_unreachable("Unexpected size");
2346 } else if (Name.endswith(".256")) {
2347 if (Size == 'd') // avx512.mask.psll.d.256, avx512.mask.psll.di.256
2348 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_d
2349 : Intrinsic::x86_avx2_psll_d;
2350 else if (Size == 'q') // avx512.mask.psll.q.256, avx512.mask.psll.qi.256
2351 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_q
2352 : Intrinsic::x86_avx2_psll_q;
2353 else if (Size == 'w') // avx512.mask.psll.w.256, avx512.mask.psll.wi.256
2354 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_w
2355 : Intrinsic::x86_avx2_psll_w;
2356 else
2357 llvm_unreachable("Unexpected size");
2358 } else {
Craig Topper353e59b2016-11-14 01:53:22 +00002359 if (Size == 'd') // psll.di.512, pslli.d, psll.d, psllv.d.512
2360 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_d_512 :
2361 IsVariable ? Intrinsic::x86_avx512_psllv_d_512 :
2362 Intrinsic::x86_avx512_psll_d_512;
2363 else if (Size == 'q') // psll.qi.512, pslli.q, psll.q, psllv.q.512
2364 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_q_512 :
2365 IsVariable ? Intrinsic::x86_avx512_psllv_q_512 :
2366 Intrinsic::x86_avx512_psll_q_512;
Craig Topper987dad22016-11-13 19:09:56 +00002367 else if (Size == 'w') // psll.wi.512, pslli.w, psll.w
2368 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_w_512
2369 : Intrinsic::x86_avx512_psll_w_512;
2370 else
2371 llvm_unreachable("Unexpected size");
2372 }
2373
2374 Rep = UpgradeX86MaskedShift(Builder, *CI, IID);
2375 } else if (IsX86 && Name.startswith("avx512.mask.psrl")) {
2376 bool IsImmediate = Name[16] == 'i' ||
2377 (Name.size() > 18 && Name[18] == 'i');
2378 bool IsVariable = Name[16] == 'v';
2379 char Size = Name[16] == '.' ? Name[17] :
2380 Name[17] == '.' ? Name[18] :
Craig Topper02b5a1b2016-11-18 05:04:44 +00002381 Name[18] == '.' ? Name[19] :
2382 Name[20];
Craig Topper987dad22016-11-13 19:09:56 +00002383
2384 Intrinsic::ID IID;
Craig Topper353e59b2016-11-14 01:53:22 +00002385 if (IsVariable && Name[17] != '.') {
Craig Topper987dad22016-11-13 19:09:56 +00002386 if (Size == 'd' && Name[17] == '2') // avx512.mask.psrlv2.di
2387 IID = Intrinsic::x86_avx2_psrlv_q;
2388 else if (Size == 'd' && Name[17] == '4') // avx512.mask.psrlv4.di
2389 IID = Intrinsic::x86_avx2_psrlv_q_256;
2390 else if (Size == 's' && Name[17] == '4') // avx512.mask.psrlv4.si
2391 IID = Intrinsic::x86_avx2_psrlv_d;
2392 else if (Size == 's' && Name[17] == '8') // avx512.mask.psrlv8.si
2393 IID = Intrinsic::x86_avx2_psrlv_d_256;
Craig Topper02b5a1b2016-11-18 05:04:44 +00002394 else if (Size == 'h' && Name[17] == '8') // avx512.mask.psrlv8.hi
2395 IID = Intrinsic::x86_avx512_psrlv_w_128;
2396 else if (Size == 'h' && Name[17] == '1') // avx512.mask.psrlv16.hi
2397 IID = Intrinsic::x86_avx512_psrlv_w_256;
2398 else if (Name[17] == '3' && Name[18] == '2') // avx512.mask.psrlv32hi
2399 IID = Intrinsic::x86_avx512_psrlv_w_512;
Craig Topper987dad22016-11-13 19:09:56 +00002400 else
2401 llvm_unreachable("Unexpected size");
2402 } else if (Name.endswith(".128")) {
2403 if (Size == 'd') // avx512.mask.psrl.d.128, avx512.mask.psrl.di.128
2404 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_d
2405 : Intrinsic::x86_sse2_psrl_d;
2406 else if (Size == 'q') // avx512.mask.psrl.q.128, avx512.mask.psrl.qi.128
2407 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_q
2408 : Intrinsic::x86_sse2_psrl_q;
2409 else if (Size == 'w') // avx512.mask.psrl.w.128, avx512.mask.psrl.wi.128
2410 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_w
2411 : Intrinsic::x86_sse2_psrl_w;
2412 else
2413 llvm_unreachable("Unexpected size");
2414 } else if (Name.endswith(".256")) {
2415 if (Size == 'd') // avx512.mask.psrl.d.256, avx512.mask.psrl.di.256
2416 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_d
2417 : Intrinsic::x86_avx2_psrl_d;
2418 else if (Size == 'q') // avx512.mask.psrl.q.256, avx512.mask.psrl.qi.256
2419 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_q
2420 : Intrinsic::x86_avx2_psrl_q;
2421 else if (Size == 'w') // avx512.mask.psrl.w.256, avx512.mask.psrl.wi.256
2422 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_w
2423 : Intrinsic::x86_avx2_psrl_w;
2424 else
2425 llvm_unreachable("Unexpected size");
2426 } else {
Craig Topper353e59b2016-11-14 01:53:22 +00002427 if (Size == 'd') // psrl.di.512, psrli.d, psrl.d, psrl.d.512
2428 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_d_512 :
2429 IsVariable ? Intrinsic::x86_avx512_psrlv_d_512 :
2430 Intrinsic::x86_avx512_psrl_d_512;
2431 else if (Size == 'q') // psrl.qi.512, psrli.q, psrl.q, psrl.q.512
2432 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_q_512 :
2433 IsVariable ? Intrinsic::x86_avx512_psrlv_q_512 :
2434 Intrinsic::x86_avx512_psrl_q_512;
Craig Topper987dad22016-11-13 19:09:56 +00002435 else if (Size == 'w') // psrl.wi.512, psrli.w, psrl.w)
2436 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_w_512
2437 : Intrinsic::x86_avx512_psrl_w_512;
2438 else
2439 llvm_unreachable("Unexpected size");
2440 }
2441
2442 Rep = UpgradeX86MaskedShift(Builder, *CI, IID);
2443 } else if (IsX86 && Name.startswith("avx512.mask.psra")) {
2444 bool IsImmediate = Name[16] == 'i' ||
2445 (Name.size() > 18 && Name[18] == 'i');
2446 bool IsVariable = Name[16] == 'v';
2447 char Size = Name[16] == '.' ? Name[17] :
2448 Name[17] == '.' ? Name[18] :
Craig Topper02b5a1b2016-11-18 05:04:44 +00002449 Name[18] == '.' ? Name[19] :
2450 Name[20];
Craig Topper987dad22016-11-13 19:09:56 +00002451
2452 Intrinsic::ID IID;
Craig Topper353e59b2016-11-14 01:53:22 +00002453 if (IsVariable && Name[17] != '.') {
Craig Topper987dad22016-11-13 19:09:56 +00002454 if (Size == 's' && Name[17] == '4') // avx512.mask.psrav4.si
2455 IID = Intrinsic::x86_avx2_psrav_d;
2456 else if (Size == 's' && Name[17] == '8') // avx512.mask.psrav8.si
2457 IID = Intrinsic::x86_avx2_psrav_d_256;
Craig Topper02b5a1b2016-11-18 05:04:44 +00002458 else if (Size == 'h' && Name[17] == '8') // avx512.mask.psrav8.hi
2459 IID = Intrinsic::x86_avx512_psrav_w_128;
2460 else if (Size == 'h' && Name[17] == '1') // avx512.mask.psrav16.hi
2461 IID = Intrinsic::x86_avx512_psrav_w_256;
2462 else if (Name[17] == '3' && Name[18] == '2') // avx512.mask.psrav32hi
2463 IID = Intrinsic::x86_avx512_psrav_w_512;
Craig Topper987dad22016-11-13 19:09:56 +00002464 else
2465 llvm_unreachable("Unexpected size");
2466 } else if (Name.endswith(".128")) {
2467 if (Size == 'd') // avx512.mask.psra.d.128, avx512.mask.psra.di.128
2468 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_d
2469 : Intrinsic::x86_sse2_psra_d;
2470 else if (Size == 'q') // avx512.mask.psra.q.128, avx512.mask.psra.qi.128
Craig Topper353e59b2016-11-14 01:53:22 +00002471 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_128 :
2472 IsVariable ? Intrinsic::x86_avx512_psrav_q_128 :
2473 Intrinsic::x86_avx512_psra_q_128;
Craig Topper987dad22016-11-13 19:09:56 +00002474 else if (Size == 'w') // avx512.mask.psra.w.128, avx512.mask.psra.wi.128
2475 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_w
2476 : Intrinsic::x86_sse2_psra_w;
2477 else
2478 llvm_unreachable("Unexpected size");
2479 } else if (Name.endswith(".256")) {
2480 if (Size == 'd') // avx512.mask.psra.d.256, avx512.mask.psra.di.256
2481 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_d
2482 : Intrinsic::x86_avx2_psra_d;
2483 else if (Size == 'q') // avx512.mask.psra.q.256, avx512.mask.psra.qi.256
Craig Topper353e59b2016-11-14 01:53:22 +00002484 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_256 :
2485 IsVariable ? Intrinsic::x86_avx512_psrav_q_256 :
2486 Intrinsic::x86_avx512_psra_q_256;
Craig Topper987dad22016-11-13 19:09:56 +00002487 else if (Size == 'w') // avx512.mask.psra.w.256, avx512.mask.psra.wi.256
2488 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_w
2489 : Intrinsic::x86_avx2_psra_w;
2490 else
2491 llvm_unreachable("Unexpected size");
2492 } else {
Craig Topper353e59b2016-11-14 01:53:22 +00002493 if (Size == 'd') // psra.di.512, psrai.d, psra.d, psrav.d.512
2494 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_d_512 :
2495 IsVariable ? Intrinsic::x86_avx512_psrav_d_512 :
2496 Intrinsic::x86_avx512_psra_d_512;
Craig Topper987dad22016-11-13 19:09:56 +00002497 else if (Size == 'q') // psra.qi.512, psrai.q, psra.q
Craig Topper353e59b2016-11-14 01:53:22 +00002498 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_512 :
2499 IsVariable ? Intrinsic::x86_avx512_psrav_q_512 :
2500 Intrinsic::x86_avx512_psra_q_512;
Craig Topper987dad22016-11-13 19:09:56 +00002501 else if (Size == 'w') // psra.wi.512, psrai.w, psra.w
2502 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_w_512
2503 : Intrinsic::x86_avx512_psra_w_512;
2504 else
2505 llvm_unreachable("Unexpected size");
2506 }
2507
2508 Rep = UpgradeX86MaskedShift(Builder, *CI, IID);
Ayman Musa4d602432016-11-16 09:00:28 +00002509 } else if (IsX86 && Name.startswith("avx512.mask.move.s")) {
2510 Rep = upgradeMaskedMove(Builder, *CI);
Michael Zuckerman88fb1712017-04-04 13:32:14 +00002511 } else if (IsX86 && Name.startswith("avx512.cvtmask2")) {
2512 Rep = UpgradeMaskToInt(Builder, *CI);
Simon Pilgrim5a22eaa2017-04-14 15:05:35 +00002513 } else if (IsX86 && Name.endswith(".movntdqa")) {
2514 Module *M = F->getParent();
2515 MDNode *Node = MDNode::get(
2516 C, ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1)));
2517
2518 Value *Ptr = CI->getArgOperand(0);
2519 VectorType *VTy = cast<VectorType>(CI->getType());
2520
2521 // Convert the type of the pointer to a pointer to the stored type.
2522 Value *BC =
2523 Builder.CreateBitCast(Ptr, PointerType::getUnqual(VTy), "cast");
2524 LoadInst *LI = Builder.CreateAlignedLoad(BC, VTy->getBitWidth() / 8);
2525 LI->setMetadata(M->getMDKindID("nontemporal"), Node);
2526 Rep = LI;
Yael Tsafrir47668b52017-09-12 07:50:35 +00002527 } else if (IsX86 &&
2528 (Name.startswith("sse2.pavg") || Name.startswith("avx2.pavg") ||
2529 Name.startswith("avx512.mask.pavg"))) {
2530 // llvm.x86.sse2.pavg.b/w, llvm.x86.avx2.pavg.b/w,
2531 // llvm.x86.avx512.mask.pavg.b/w
2532 Value *A = CI->getArgOperand(0);
2533 Value *B = CI->getArgOperand(1);
2534 VectorType *ZextType = VectorType::getExtendedElementVectorType(
2535 cast<VectorType>(A->getType()));
2536 Value *ExtendedA = Builder.CreateZExt(A, ZextType);
2537 Value *ExtendedB = Builder.CreateZExt(B, ZextType);
2538 Value *Sum = Builder.CreateAdd(ExtendedA, ExtendedB);
2539 Value *AddOne = Builder.CreateAdd(Sum, ConstantInt::get(ZextType, 1));
2540 Value *ShiftR = Builder.CreateLShr(AddOne, ConstantInt::get(ZextType, 1));
2541 Rep = Builder.CreateTrunc(ShiftR, A->getType());
2542 if (CI->getNumArgOperands() > 2) {
2543 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
2544 CI->getArgOperand(2));
2545 }
Craig Toppera17d6272018-05-11 21:59:34 +00002546 } else if (IsX86 && Name.startswith("fma.vfmsub")) {
2547 // Handle FMSUB and FSUBADD.
2548 unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
2549 unsigned EltWidth = CI->getType()->getScalarSizeInBits();
2550 Intrinsic::ID IID;
2551 if (Name[10] == '.' && Name[11] == 'p') {
2552 // Packed FMSUB
2553 if (VecWidth == 128 && EltWidth == 32)
2554 IID = Intrinsic::x86_fma_vfmadd_ps;
2555 else if (VecWidth == 128 && EltWidth == 64)
2556 IID = Intrinsic::x86_fma_vfmadd_pd;
2557 else if (VecWidth == 256 && EltWidth == 32)
2558 IID = Intrinsic::x86_fma_vfmadd_ps_256;
2559 else if (VecWidth == 256 && EltWidth == 64)
2560 IID = Intrinsic::x86_fma_vfmadd_pd_256;
2561 else
2562 llvm_unreachable("Unexpected intrinsic");
2563 } else if (Name[10] == '.' && Name[11] == 's') {
2564 // Scalar FMSUB
2565 if (EltWidth == 32)
2566 IID = Intrinsic::x86_fma_vfmadd_ss;
2567 else if (EltWidth == 64)
2568 IID = Intrinsic::x86_fma_vfmadd_sd;
2569 else
2570 llvm_unreachable("Unexpected intrinsic");
2571 } else {
2572 // FMSUBADD
2573 if (VecWidth == 128 && EltWidth == 32)
2574 IID = Intrinsic::x86_fma_vfmaddsub_ps;
2575 else if (VecWidth == 128 && EltWidth == 64)
2576 IID = Intrinsic::x86_fma_vfmaddsub_pd;
2577 else if (VecWidth == 256 && EltWidth == 32)
2578 IID = Intrinsic::x86_fma_vfmaddsub_ps_256;
2579 else if (VecWidth == 256 && EltWidth == 64)
2580 IID = Intrinsic::x86_fma_vfmaddsub_pd_256;
2581 else
2582 llvm_unreachable("Unexpected intrinsic");
2583 }
2584 Value *Arg2 = Builder.CreateFNeg(CI->getArgOperand(2));
2585 Value *Ops[] = { CI->getArgOperand(0), CI->getArgOperand(1), Arg2 };
2586 Rep = Builder.CreateCall(Intrinsic::getDeclaration(CI->getModule(), IID),
2587 Ops);
2588 } else if (IsX86 && (Name.startswith("fma.vfnmadd.") ||
2589 Name.startswith("fma.vfnmsub."))) {
2590 Value *Arg0 = CI->getArgOperand(0);
2591 Value *Arg1 = CI->getArgOperand(1);
2592 Value *Arg2 = CI->getArgOperand(2);
2593 unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
2594 unsigned EltWidth = CI->getType()->getScalarSizeInBits();
2595 Intrinsic::ID IID;
2596 if (Name[12] == 'p') {
2597 // Packed FNMADD/FNSUB
2598 Arg0 = Builder.CreateFNeg(Arg0);
2599 if (VecWidth == 128 && EltWidth == 32)
2600 IID = Intrinsic::x86_fma_vfmadd_ps;
2601 else if (VecWidth == 128 && EltWidth == 64)
2602 IID = Intrinsic::x86_fma_vfmadd_pd;
2603 else if (VecWidth == 256 && EltWidth == 32)
2604 IID = Intrinsic::x86_fma_vfmadd_ps_256;
2605 else if (VecWidth == 256 && EltWidth == 64)
2606 IID = Intrinsic::x86_fma_vfmadd_pd_256;
2607 else
2608 llvm_unreachable("Unexpected intrinsic");
2609 } else {
2610 // Scalar FNMADD/FNMSUB
2611 Arg1 = Builder.CreateFNeg(Arg1); // Arg0 is passthru so invert Arg1.
2612 if (EltWidth == 32)
2613 IID = Intrinsic::x86_fma_vfmadd_ss;
2614 else if (EltWidth == 64)
2615 IID = Intrinsic::x86_fma_vfmadd_sd;
2616 else
2617 llvm_unreachable("Unexpected intrinsic");
2618 }
2619 // Invert for FNMSUB.
2620 if (Name[8] == 's')
2621 Arg2 = Builder.CreateFNeg(Arg2);
2622 Value *Ops[] = { Arg0, Arg1, Arg2 };
2623 Rep = Builder.CreateCall(Intrinsic::getDeclaration(CI->getModule(), IID),
2624 Ops);
Craig Topperaad3aef2018-05-21 20:58:09 +00002625 } else if (IsX86 && (Name.startswith("avx512.mask.pternlog.") ||
2626 Name.startswith("avx512.maskz.pternlog."))) {
2627 bool ZeroMask = Name[11] == 'z';
2628 unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
2629 unsigned EltWidth = CI->getType()->getScalarSizeInBits();
2630 Intrinsic::ID IID;
2631 if (VecWidth == 128 && EltWidth == 32)
2632 IID = Intrinsic::x86_avx512_pternlog_d_128;
2633 else if (VecWidth == 256 && EltWidth == 32)
2634 IID = Intrinsic::x86_avx512_pternlog_d_256;
2635 else if (VecWidth == 512 && EltWidth == 32)
2636 IID = Intrinsic::x86_avx512_pternlog_d_512;
2637 else if (VecWidth == 128 && EltWidth == 64)
2638 IID = Intrinsic::x86_avx512_pternlog_q_128;
2639 else if (VecWidth == 256 && EltWidth == 64)
2640 IID = Intrinsic::x86_avx512_pternlog_q_256;
2641 else if (VecWidth == 512 && EltWidth == 64)
2642 IID = Intrinsic::x86_avx512_pternlog_q_512;
2643 else
2644 llvm_unreachable("Unexpected intrinsic");
2645
2646 Value *Args[] = { CI->getArgOperand(0) , CI->getArgOperand(1),
2647 CI->getArgOperand(2), CI->getArgOperand(3) };
2648 Rep = Builder.CreateCall(Intrinsic::getDeclaration(CI->getModule(), IID),
2649 Args);
2650 Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())
2651 : CI->getArgOperand(0);
2652 Rep = EmitX86Select(Builder, CI->getArgOperand(4), Rep, PassThru);
Craig Topper51eddb82018-05-26 18:55:19 +00002653 } else if (IsX86 && (Name.startswith("avx512.mask.vpmadd52") ||
2654 Name.startswith("avx512.maskz.vpmadd52"))) {
2655 bool ZeroMask = Name[11] == 'z';
2656 bool High = Name[20] == 'h' || Name[21] == 'h';
2657 unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
2658 Intrinsic::ID IID;
2659 if (VecWidth == 128 && !High)
2660 IID = Intrinsic::x86_avx512_vpmadd52l_uq_128;
2661 else if (VecWidth == 256 && !High)
2662 IID = Intrinsic::x86_avx512_vpmadd52l_uq_256;
2663 else if (VecWidth == 512 && !High)
2664 IID = Intrinsic::x86_avx512_vpmadd52l_uq_512;
2665 else if (VecWidth == 128 && High)
2666 IID = Intrinsic::x86_avx512_vpmadd52h_uq_128;
2667 else if (VecWidth == 256 && High)
2668 IID = Intrinsic::x86_avx512_vpmadd52h_uq_256;
2669 else if (VecWidth == 512 && High)
2670 IID = Intrinsic::x86_avx512_vpmadd52h_uq_512;
2671 else
2672 llvm_unreachable("Unexpected intrinsic");
2673
2674 Value *Args[] = { CI->getArgOperand(0) , CI->getArgOperand(1),
2675 CI->getArgOperand(2) };
2676 Rep = Builder.CreateCall(Intrinsic::getDeclaration(CI->getModule(), IID),
2677 Args);
2678 Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())
2679 : CI->getArgOperand(0);
2680 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru);
Craig Topper21aeddc2018-05-29 05:22:05 +00002681 } else if (IsX86 && (Name.startswith("avx512.mask.vpermi2var.") ||
2682 Name.startswith("avx512.mask.vpermt2var.") ||
2683 Name.startswith("avx512.maskz.vpermt2var."))) {
2684 bool ZeroMask = Name[11] == 'z';
2685 bool IndexForm = Name[17] == 'i';
2686 unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
2687 unsigned EltWidth = CI->getType()->getScalarSizeInBits();
2688 bool IsFloat = CI->getType()->isFPOrFPVectorTy();
2689 Intrinsic::ID IID;
2690 if (VecWidth == 128 && EltWidth == 32 && IsFloat)
2691 IID = Intrinsic::x86_avx512_vpermi2var_ps_128;
2692 else if (VecWidth == 128 && EltWidth == 32 && !IsFloat)
2693 IID = Intrinsic::x86_avx512_vpermi2var_d_128;
2694 else if (VecWidth == 128 && EltWidth == 64 && IsFloat)
2695 IID = Intrinsic::x86_avx512_vpermi2var_pd_128;
2696 else if (VecWidth == 128 && EltWidth == 64 && !IsFloat)
2697 IID = Intrinsic::x86_avx512_vpermi2var_q_128;
2698 else if (VecWidth == 256 && EltWidth == 32 && IsFloat)
2699 IID = Intrinsic::x86_avx512_vpermi2var_ps_256;
2700 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
2701 IID = Intrinsic::x86_avx512_vpermi2var_d_256;
2702 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
2703 IID = Intrinsic::x86_avx512_vpermi2var_pd_256;
2704 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
2705 IID = Intrinsic::x86_avx512_vpermi2var_q_256;
2706 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
2707 IID = Intrinsic::x86_avx512_vpermi2var_ps_512;
2708 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
2709 IID = Intrinsic::x86_avx512_vpermi2var_d_512;
2710 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
2711 IID = Intrinsic::x86_avx512_vpermi2var_pd_512;
2712 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
2713 IID = Intrinsic::x86_avx512_vpermi2var_q_512;
2714 else if (VecWidth == 128 && EltWidth == 16)
2715 IID = Intrinsic::x86_avx512_vpermi2var_hi_128;
2716 else if (VecWidth == 256 && EltWidth == 16)
2717 IID = Intrinsic::x86_avx512_vpermi2var_hi_256;
2718 else if (VecWidth == 512 && EltWidth == 16)
2719 IID = Intrinsic::x86_avx512_vpermi2var_hi_512;
2720 else if (VecWidth == 128 && EltWidth == 8)
2721 IID = Intrinsic::x86_avx512_vpermi2var_qi_128;
2722 else if (VecWidth == 256 && EltWidth == 8)
2723 IID = Intrinsic::x86_avx512_vpermi2var_qi_256;
2724 else if (VecWidth == 512 && EltWidth == 8)
2725 IID = Intrinsic::x86_avx512_vpermi2var_qi_512;
2726 else
2727 llvm_unreachable("Unexpected intrinsic");
2728
2729 Value *Args[] = { CI->getArgOperand(0) , CI->getArgOperand(1),
2730 CI->getArgOperand(2) };
2731
2732 // If this isn't index form we need to swap operand 0 and 1.
2733 if (!IndexForm)
2734 std::swap(Args[0], Args[1]);
2735
2736 Rep = Builder.CreateCall(Intrinsic::getDeclaration(CI->getModule(), IID),
2737 Args);
2738 Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())
2739 : Builder.CreateBitCast(CI->getArgOperand(1),
2740 CI->getType());
2741 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru);
Craig Topper9923eac2018-06-03 23:24:17 +00002742 } else if (IsX86 && (Name.startswith("avx512.mask.vpdpbusd.") ||
2743 Name.startswith("avx512.maskz.vpdpbusd.") ||
2744 Name.startswith("avx512.mask.vpdpbusds.") ||
2745 Name.startswith("avx512.maskz.vpdpbusds."))) {
2746 bool ZeroMask = Name[11] == 'z';
2747 bool IsSaturating = Name[ZeroMask ? 21 : 20] == 's';
2748 unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
2749 Intrinsic::ID IID;
2750 if (VecWidth == 128 && !IsSaturating)
2751 IID = Intrinsic::x86_avx512_vpdpbusd_128;
2752 else if (VecWidth == 256 && !IsSaturating)
2753 IID = Intrinsic::x86_avx512_vpdpbusd_256;
2754 else if (VecWidth == 512 && !IsSaturating)
2755 IID = Intrinsic::x86_avx512_vpdpbusd_512;
2756 else if (VecWidth == 128 && IsSaturating)
2757 IID = Intrinsic::x86_avx512_vpdpbusds_128;
2758 else if (VecWidth == 256 && IsSaturating)
2759 IID = Intrinsic::x86_avx512_vpdpbusds_256;
2760 else if (VecWidth == 512 && IsSaturating)
2761 IID = Intrinsic::x86_avx512_vpdpbusds_512;
2762 else
2763 llvm_unreachable("Unexpected intrinsic");
2764
2765 Value *Args[] = { CI->getArgOperand(0), CI->getArgOperand(1),
2766 CI->getArgOperand(2) };
2767 Rep = Builder.CreateCall(Intrinsic::getDeclaration(CI->getModule(), IID),
2768 Args);
2769 Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())
2770 : CI->getArgOperand(0);
2771 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru);
2772 } else if (IsX86 && (Name.startswith("avx512.mask.vpdpwssd.") ||
2773 Name.startswith("avx512.maskz.vpdpwssd.") ||
2774 Name.startswith("avx512.mask.vpdpwssds.") ||
2775 Name.startswith("avx512.maskz.vpdpwssds."))) {
2776 bool ZeroMask = Name[11] == 'z';
2777 bool IsSaturating = Name[ZeroMask ? 21 : 20] == 's';
2778 unsigned VecWidth = CI->getType()->getPrimitiveSizeInBits();
2779 Intrinsic::ID IID;
2780 if (VecWidth == 128 && !IsSaturating)
2781 IID = Intrinsic::x86_avx512_vpdpwssd_128;
2782 else if (VecWidth == 256 && !IsSaturating)
2783 IID = Intrinsic::x86_avx512_vpdpwssd_256;
2784 else if (VecWidth == 512 && !IsSaturating)
2785 IID = Intrinsic::x86_avx512_vpdpwssd_512;
2786 else if (VecWidth == 128 && IsSaturating)
2787 IID = Intrinsic::x86_avx512_vpdpwssds_128;
2788 else if (VecWidth == 256 && IsSaturating)
2789 IID = Intrinsic::x86_avx512_vpdpwssds_256;
2790 else if (VecWidth == 512 && IsSaturating)
2791 IID = Intrinsic::x86_avx512_vpdpwssds_512;
2792 else
2793 llvm_unreachable("Unexpected intrinsic");
2794
2795 Value *Args[] = { CI->getArgOperand(0), CI->getArgOperand(1),
2796 CI->getArgOperand(2) };
2797 Rep = Builder.CreateCall(Intrinsic::getDeclaration(CI->getModule(), IID),
2798 Args);
2799 Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())
2800 : CI->getArgOperand(0);
2801 Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru);
Craig Topperc95e1222018-04-09 06:15:09 +00002802 } else if (IsX86 && Name.startswith("avx512.mask.") &&
2803 upgradeAVX512MaskToSelect(Name, Builder, *CI, Rep)) {
2804 // Rep will be updated by the call in the condition.
Justin Lebar46624a82017-01-21 01:00:32 +00002805 } else if (IsNVVM && (Name == "abs.i" || Name == "abs.ll")) {
2806 Value *Arg = CI->getArgOperand(0);
2807 Value *Neg = Builder.CreateNeg(Arg, "neg");
2808 Value *Cmp = Builder.CreateICmpSGE(
2809 Arg, llvm::Constant::getNullValue(Arg->getType()), "abs.cond");
2810 Rep = Builder.CreateSelect(Cmp, Arg, Neg, "abs");
2811 } else if (IsNVVM && (Name == "max.i" || Name == "max.ll" ||
2812 Name == "max.ui" || Name == "max.ull")) {
2813 Value *Arg0 = CI->getArgOperand(0);
2814 Value *Arg1 = CI->getArgOperand(1);
2815 Value *Cmp = Name.endswith(".ui") || Name.endswith(".ull")
2816 ? Builder.CreateICmpUGE(Arg0, Arg1, "max.cond")
2817 : Builder.CreateICmpSGE(Arg0, Arg1, "max.cond");
2818 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1, "max");
2819 } else if (IsNVVM && (Name == "min.i" || Name == "min.ll" ||
2820 Name == "min.ui" || Name == "min.ull")) {
2821 Value *Arg0 = CI->getArgOperand(0);
2822 Value *Arg1 = CI->getArgOperand(1);
2823 Value *Cmp = Name.endswith(".ui") || Name.endswith(".ull")
2824 ? Builder.CreateICmpULE(Arg0, Arg1, "min.cond")
2825 : Builder.CreateICmpSLE(Arg0, Arg1, "min.cond");
2826 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1, "min");
2827 } else if (IsNVVM && Name == "clz.ll") {
2828 // llvm.nvvm.clz.ll returns an i32, but llvm.ctlz.i64 and returns an i64.
2829 Value *Arg = CI->getArgOperand(0);
2830 Value *Ctlz = Builder.CreateCall(
2831 Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
2832 {Arg->getType()}),
2833 {Arg, Builder.getFalse()}, "ctlz");
2834 Rep = Builder.CreateTrunc(Ctlz, Builder.getInt32Ty(), "ctlz.trunc");
2835 } else if (IsNVVM && Name == "popc.ll") {
2836 // llvm.nvvm.popc.ll returns an i32, but llvm.ctpop.i64 and returns an
2837 // i64.
2838 Value *Arg = CI->getArgOperand(0);
2839 Value *Popc = Builder.CreateCall(
2840 Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctpop,
2841 {Arg->getType()}),
2842 Arg, "ctpop");
2843 Rep = Builder.CreateTrunc(Popc, Builder.getInt32Ty(), "ctpop.trunc");
2844 } else if (IsNVVM && Name == "h2f") {
2845 Rep = Builder.CreateCall(Intrinsic::getDeclaration(
2846 F->getParent(), Intrinsic::convert_from_fp16,
2847 {Builder.getFloatTy()}),
2848 CI->getArgOperand(0), "h2f");
Craig Topper3b1817d2012-02-03 06:10:55 +00002849 } else {
Craig Topper8a105052016-06-12 03:10:47 +00002850 llvm_unreachable("Unknown function for CallInst upgrade.");
Craig Topper3b1817d2012-02-03 06:10:55 +00002851 }
2852
Tim Shen00127562016-04-08 21:26:31 +00002853 if (Rep)
2854 CI->replaceAllUsesWith(Rep);
Craig Topper3b1817d2012-02-03 06:10:55 +00002855 CI->eraseFromParent();
2856 return;
2857 }
2858
Daniel Neilson1e687242018-01-19 17:13:12 +00002859 const auto &DefaultCase = [&NewFn, &CI]() -> void {
Daniel Berlin3c1432f2017-02-15 23:16:20 +00002860 // Handle generic mangling change, but nothing else
2861 assert(
2862 (CI->getCalledFunction()->getName() != NewFn->getName()) &&
2863 "Unknown function for CallInst upgrade and isn't just a name change");
Daniel Berlin3f910042017-03-01 01:49:13 +00002864 CI->setCalledFunction(NewFn);
Daniel Neilson1e687242018-01-19 17:13:12 +00002865 };
2866 CallInst *NewCall = nullptr;
2867 switch (NewFn->getIntrinsicID()) {
2868 default: {
2869 DefaultCase();
Daniel Berlin3c1432f2017-02-15 23:16:20 +00002870 return;
2871 }
Chandler Carruth58a71ed2011-12-12 04:26:04 +00002872
Jeroen Ketemaab99b592015-09-30 10:56:37 +00002873 case Intrinsic::arm_neon_vld1:
2874 case Intrinsic::arm_neon_vld2:
2875 case Intrinsic::arm_neon_vld3:
2876 case Intrinsic::arm_neon_vld4:
2877 case Intrinsic::arm_neon_vld2lane:
2878 case Intrinsic::arm_neon_vld3lane:
2879 case Intrinsic::arm_neon_vld4lane:
2880 case Intrinsic::arm_neon_vst1:
2881 case Intrinsic::arm_neon_vst2:
2882 case Intrinsic::arm_neon_vst3:
2883 case Intrinsic::arm_neon_vst4:
2884 case Intrinsic::arm_neon_vst2lane:
2885 case Intrinsic::arm_neon_vst3lane:
2886 case Intrinsic::arm_neon_vst4lane: {
2887 SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
2888 CI->arg_operands().end());
Daniel Berlin3f910042017-03-01 01:49:13 +00002889 NewCall = Builder.CreateCall(NewFn, Args);
2890 break;
Jeroen Ketemaab99b592015-09-30 10:56:37 +00002891 }
2892
Chad Rosier3daffbf2017-01-10 17:20:33 +00002893 case Intrinsic::bitreverse:
Daniel Berlin3f910042017-03-01 01:49:13 +00002894 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
2895 break;
Chad Rosier3daffbf2017-01-10 17:20:33 +00002896
Chandler Carruth58a71ed2011-12-12 04:26:04 +00002897 case Intrinsic::ctlz:
Nuno Lopesad40c0a2012-05-22 15:25:31 +00002898 case Intrinsic::cttz:
Chandler Carruth58a71ed2011-12-12 04:26:04 +00002899 assert(CI->getNumArgOperands() == 1 &&
2900 "Mismatch between function args and call args");
Daniel Berlin3f910042017-03-01 01:49:13 +00002901 NewCall =
2902 Builder.CreateCall(NewFn, {CI->getArgOperand(0), Builder.getFalse()});
2903 break;
Nadav Rotem17ee58a2012-06-10 18:42:51 +00002904
George Burgess IV56c7e882017-03-21 20:08:59 +00002905 case Intrinsic::objectsize: {
2906 Value *NullIsUnknownSize = CI->getNumArgOperands() == 2
2907 ? Builder.getFalse()
2908 : CI->getArgOperand(2);
2909 NewCall = Builder.CreateCall(
2910 NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize});
Daniel Berlin3f910042017-03-01 01:49:13 +00002911 break;
George Burgess IV56c7e882017-03-21 20:08:59 +00002912 }
Matt Arsenaultfbcbce42013-10-07 18:06:48 +00002913
Justin Lebar46624a82017-01-21 01:00:32 +00002914 case Intrinsic::ctpop:
Daniel Berlin3f910042017-03-01 01:49:13 +00002915 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
2916 break;
Justin Lebar46624a82017-01-21 01:00:32 +00002917
2918 case Intrinsic::convert_from_fp16:
Daniel Berlin3f910042017-03-01 01:49:13 +00002919 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
2920 break;
Joel Jones43cb8782012-07-13 23:25:25 +00002921
Adrian Prantlabe04752017-07-28 20:21:02 +00002922 case Intrinsic::dbg_value:
2923 // Upgrade from the old version that had an extra offset argument.
2924 assert(CI->getNumArgOperands() == 4);
2925 // Drop nonzero offsets instead of attempting to upgrade them.
2926 if (auto *Offset = dyn_cast_or_null<Constant>(CI->getArgOperand(1)))
2927 if (Offset->isZeroValue()) {
2928 NewCall = Builder.CreateCall(
2929 NewFn,
2930 {CI->getArgOperand(0), CI->getArgOperand(2), CI->getArgOperand(3)});
2931 break;
2932 }
2933 CI->eraseFromParent();
2934 return;
2935
Craig Topper71dc02d2012-06-13 07:18:53 +00002936 case Intrinsic::x86_xop_vfrcz_ss:
2937 case Intrinsic::x86_xop_vfrcz_sd:
Daniel Berlin3f910042017-03-01 01:49:13 +00002938 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(1)});
2939 break;
Craig Topper71dc02d2012-06-13 07:18:53 +00002940
Simon Pilgrime85506b2016-06-03 08:06:03 +00002941 case Intrinsic::x86_xop_vpermil2pd:
2942 case Intrinsic::x86_xop_vpermil2ps:
2943 case Intrinsic::x86_xop_vpermil2pd_256:
2944 case Intrinsic::x86_xop_vpermil2ps_256: {
2945 SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
2946 CI->arg_operands().end());
2947 VectorType *FltIdxTy = cast<VectorType>(Args[2]->getType());
2948 VectorType *IntIdxTy = VectorType::getInteger(FltIdxTy);
2949 Args[2] = Builder.CreateBitCast(Args[2], IntIdxTy);
Daniel Berlin3f910042017-03-01 01:49:13 +00002950 NewCall = Builder.CreateCall(NewFn, Args);
2951 break;
Simon Pilgrime85506b2016-06-03 08:06:03 +00002952 }
2953
Nadav Rotem17ee58a2012-06-10 18:42:51 +00002954 case Intrinsic::x86_sse41_ptestc:
2955 case Intrinsic::x86_sse41_ptestz:
Craig Topper71dc02d2012-06-13 07:18:53 +00002956 case Intrinsic::x86_sse41_ptestnzc: {
Nadav Rotem17ee58a2012-06-10 18:42:51 +00002957 // The arguments for these intrinsics used to be v4f32, and changed
2958 // to v2i64. This is purely a nop, since those are bitwise intrinsics.
2959 // So, the only thing required is a bitcast for both arguments.
2960 // First, check the arguments have the old type.
2961 Value *Arg0 = CI->getArgOperand(0);
2962 if (Arg0->getType() != VectorType::get(Type::getFloatTy(C), 4))
2963 return;
2964
2965 // Old intrinsic, add bitcasts
2966 Value *Arg1 = CI->getArgOperand(1);
2967
David Blaikie5bacf372015-04-24 21:16:07 +00002968 Type *NewVecTy = VectorType::get(Type::getInt64Ty(C), 2);
Nadav Rotem17ee58a2012-06-10 18:42:51 +00002969
David Blaikie5bacf372015-04-24 21:16:07 +00002970 Value *BC0 = Builder.CreateBitCast(Arg0, NewVecTy, "cast");
2971 Value *BC1 = Builder.CreateBitCast(Arg1, NewVecTy, "cast");
2972
Daniel Berlin3f910042017-03-01 01:49:13 +00002973 NewCall = Builder.CreateCall(NewFn, {BC0, BC1});
2974 break;
Evan Cheng0e179d02007-12-17 22:33:23 +00002975 }
Chandler Carruth373b2b12014-09-06 10:00:01 +00002976
Chandler Carruth373b2b12014-09-06 10:00:01 +00002977 case Intrinsic::x86_sse41_insertps:
2978 case Intrinsic::x86_sse41_dppd:
2979 case Intrinsic::x86_sse41_dpps:
2980 case Intrinsic::x86_sse41_mpsadbw:
Chandler Carruth373b2b12014-09-06 10:00:01 +00002981 case Intrinsic::x86_avx_dp_ps_256:
Chandler Carruth373b2b12014-09-06 10:00:01 +00002982 case Intrinsic::x86_avx2_mpsadbw: {
2983 // Need to truncate the last argument from i32 to i8 -- this argument models
2984 // an inherently 8-bit immediate operand to these x86 instructions.
2985 SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
2986 CI->arg_operands().end());
2987
2988 // Replace the last argument with a trunc.
2989 Args.back() = Builder.CreateTrunc(Args.back(), Type::getInt8Ty(C), "trunc");
Daniel Berlin3f910042017-03-01 01:49:13 +00002990 NewCall = Builder.CreateCall(NewFn, Args);
2991 break;
Chandler Carruth373b2b12014-09-06 10:00:01 +00002992 }
Marcin Koscielnicki3fdc2572016-04-19 20:51:05 +00002993
Craig Topper4dccffc82018-02-10 23:33:55 +00002994 case Intrinsic::x86_avx512_mask_cmp_pd_128:
2995 case Intrinsic::x86_avx512_mask_cmp_pd_256:
2996 case Intrinsic::x86_avx512_mask_cmp_pd_512:
2997 case Intrinsic::x86_avx512_mask_cmp_ps_128:
2998 case Intrinsic::x86_avx512_mask_cmp_ps_256:
2999 case Intrinsic::x86_avx512_mask_cmp_ps_512: {
3000 SmallVector<Value *, 4> Args;
3001 Args.push_back(CI->getArgOperand(0));
3002 Args.push_back(CI->getArgOperand(1));
3003 Args.push_back(CI->getArgOperand(2));
3004 if (CI->getNumArgOperands() == 5)
3005 Args.push_back(CI->getArgOperand(4));
3006
3007 NewCall = Builder.CreateCall(NewFn, Args);
3008 unsigned NumElts = Args[0]->getType()->getVectorNumElements();
3009 Value *Res = ApplyX86MaskOn1BitsVec(Builder, NewCall, CI->getArgOperand(3),
3010 NumElts);
3011
3012 std::string Name = CI->getName();
3013 if (!Name.empty()) {
3014 CI->setName(Name + ".old");
3015 NewCall->setName(Name);
3016 }
3017 CI->replaceAllUsesWith(Res);
3018 CI->eraseFromParent();
3019 return;
3020 }
3021
Marcin Koscielnicki3fdc2572016-04-19 20:51:05 +00003022 case Intrinsic::thread_pointer: {
Daniel Berlin3f910042017-03-01 01:49:13 +00003023 NewCall = Builder.CreateCall(NewFn, {});
3024 break;
Marcin Koscielnicki3fdc2572016-04-19 20:51:05 +00003025 }
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +00003026
Mehdi Amini8c629ec2016-08-13 23:31:24 +00003027 case Intrinsic::invariant_start:
3028 case Intrinsic::invariant_end:
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +00003029 case Intrinsic::masked_load:
Elad Cohenef5798a2017-05-03 12:28:54 +00003030 case Intrinsic::masked_store:
3031 case Intrinsic::masked_gather:
3032 case Intrinsic::masked_scatter: {
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +00003033 SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
3034 CI->arg_operands().end());
Daniel Berlin3f910042017-03-01 01:49:13 +00003035 NewCall = Builder.CreateCall(NewFn, Args);
3036 break;
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +00003037 }
Daniel Neilson1e687242018-01-19 17:13:12 +00003038
3039 case Intrinsic::memcpy:
3040 case Intrinsic::memmove:
3041 case Intrinsic::memset: {
3042 // We have to make sure that the call signature is what we're expecting.
3043 // We only want to change the old signatures by removing the alignment arg:
3044 // @llvm.mem[cpy|move]...(i8*, i8*, i[32|i64], i32, i1)
3045 // -> @llvm.mem[cpy|move]...(i8*, i8*, i[32|i64], i1)
3046 // @llvm.memset...(i8*, i8, i[32|64], i32, i1)
3047 // -> @llvm.memset...(i8*, i8, i[32|64], i1)
3048 // Note: i8*'s in the above can be any pointer type
3049 if (CI->getNumArgOperands() != 5) {
3050 DefaultCase();
3051 return;
3052 }
3053 // Remove alignment argument (3), and add alignment attributes to the
3054 // dest/src pointers.
3055 Value *Args[4] = {CI->getArgOperand(0), CI->getArgOperand(1),
3056 CI->getArgOperand(2), CI->getArgOperand(4)};
3057 NewCall = Builder.CreateCall(NewFn, Args);
3058 auto *MemCI = cast<MemIntrinsic>(NewCall);
3059 // All mem intrinsics support dest alignment.
3060 const ConstantInt *Align = cast<ConstantInt>(CI->getArgOperand(3));
3061 MemCI->setDestAlignment(Align->getZExtValue());
3062 // Memcpy/Memmove also support source alignment.
3063 if (auto *MTI = dyn_cast<MemTransferInst>(MemCI))
3064 MTI->setSourceAlignment(Align->getZExtValue());
3065 break;
3066 }
Craig Topper71dc02d2012-06-13 07:18:53 +00003067 }
Daniel Berlin3f910042017-03-01 01:49:13 +00003068 assert(NewCall && "Should have either set this variable or returned through "
3069 "the default case");
3070 std::string Name = CI->getName();
3071 if (!Name.empty()) {
3072 CI->setName(Name + ".old");
3073 NewCall->setName(Name);
3074 }
3075 CI->replaceAllUsesWith(NewCall);
3076 CI->eraseFromParent();
Chandler Carruth7132e002007-08-04 01:51:18 +00003077}
3078
Sanjay Patelfdf0d5f2016-04-18 19:11:57 +00003079void llvm::UpgradeCallsToIntrinsic(Function *F) {
Chandler Carruth7132e002007-08-04 01:51:18 +00003080 assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
3081
Sanjay Patelfdf0d5f2016-04-18 19:11:57 +00003082 // Check if this function should be upgraded and get the replacement function
3083 // if there is one.
Chris Lattner80ed9dc2011-06-18 06:05:24 +00003084 Function *NewFn;
Evan Cheng0e179d02007-12-17 22:33:23 +00003085 if (UpgradeIntrinsicFunction(F, NewFn)) {
Sanjay Patelfdf0d5f2016-04-18 19:11:57 +00003086 // Replace all users of the old function with the new function or new
3087 // instructions. This is not a range loop because the call is deleted.
3088 for (auto UI = F->user_begin(), UE = F->user_end(); UI != UE; )
Duncan P. N. Exon Smith93f53c42016-04-17 03:59:37 +00003089 if (CallInst *CI = dyn_cast<CallInst>(*UI++))
Filipe Cabecinhas0011c582015-07-03 20:12:01 +00003090 UpgradeIntrinsicCall(CI, NewFn);
Sanjay Patelfdf0d5f2016-04-18 19:11:57 +00003091
Filipe Cabecinhas0011c582015-07-03 20:12:01 +00003092 // Remove old function, no longer used, from the module.
3093 F->eraseFromParent();
Chandler Carruth7132e002007-08-04 01:51:18 +00003094 }
3095}
Devang Patel80ae3492009-08-28 23:24:31 +00003096
Mehdi Aminie4709272016-09-14 22:29:59 +00003097MDNode *llvm::UpgradeTBAANode(MDNode &MD) {
Manman Ren209b17c2013-09-28 00:22:27 +00003098 // Check if the tag uses struct-path aware TBAA format.
Mehdi Aminie4709272016-09-14 22:29:59 +00003099 if (isa<MDNode>(MD.getOperand(0)) && MD.getNumOperands() >= 3)
3100 return &MD;
Manman Ren209b17c2013-09-28 00:22:27 +00003101
Mehdi Aminie4709272016-09-14 22:29:59 +00003102 auto &Context = MD.getContext();
3103 if (MD.getNumOperands() == 3) {
3104 Metadata *Elts[] = {MD.getOperand(0), MD.getOperand(1)};
3105 MDNode *ScalarType = MDNode::get(Context, Elts);
Manman Ren209b17c2013-09-28 00:22:27 +00003106 // Create a MDNode <ScalarType, ScalarType, offset 0, const>
Duncan P. N. Exon Smith5bf8fef2014-12-09 18:38:53 +00003107 Metadata *Elts2[] = {ScalarType, ScalarType,
Mehdi Aminie4709272016-09-14 22:29:59 +00003108 ConstantAsMetadata::get(
3109 Constant::getNullValue(Type::getInt64Ty(Context))),
3110 MD.getOperand(2)};
3111 return MDNode::get(Context, Elts2);
Manman Ren209b17c2013-09-28 00:22:27 +00003112 }
Mehdi Aminie4709272016-09-14 22:29:59 +00003113 // Create a MDNode <MD, MD, offset 0>
3114 Metadata *Elts[] = {&MD, &MD, ConstantAsMetadata::get(Constant::getNullValue(
3115 Type::getInt64Ty(Context)))};
3116 return MDNode::get(Context, Elts);
Manman Ren209b17c2013-09-28 00:22:27 +00003117}
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00003118
3119Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy,
3120 Instruction *&Temp) {
3121 if (Opc != Instruction::BitCast)
Craig Topperc6207612014-04-09 06:08:46 +00003122 return nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00003123
Craig Topperc6207612014-04-09 06:08:46 +00003124 Temp = nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00003125 Type *SrcTy = V->getType();
3126 if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() &&
3127 SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) {
3128 LLVMContext &Context = V->getContext();
3129
3130 // We have no information about target data layout, so we assume that
3131 // the maximum pointer size is 64bit.
3132 Type *MidTy = Type::getInt64Ty(Context);
3133 Temp = CastInst::Create(Instruction::PtrToInt, V, MidTy);
3134
3135 return CastInst::Create(Instruction::IntToPtr, Temp, DestTy);
3136 }
3137
Craig Topperc6207612014-04-09 06:08:46 +00003138 return nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00003139}
3140
3141Value *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) {
3142 if (Opc != Instruction::BitCast)
Craig Topperc6207612014-04-09 06:08:46 +00003143 return nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00003144
3145 Type *SrcTy = C->getType();
3146 if (SrcTy->isPtrOrPtrVectorTy() && DestTy->isPtrOrPtrVectorTy() &&
3147 SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace()) {
3148 LLVMContext &Context = C->getContext();
3149
3150 // We have no information about target data layout, so we assume that
3151 // the maximum pointer size is 64bit.
3152 Type *MidTy = Type::getInt64Ty(Context);
3153
3154 return ConstantExpr::getIntToPtr(ConstantExpr::getPtrToInt(C, MidTy),
3155 DestTy);
3156 }
3157
Craig Topperc6207612014-04-09 06:08:46 +00003158 return nullptr;
Matt Arsenaultb03bd4d2013-11-15 01:34:59 +00003159}
Manman Ren8b4306c2013-12-02 21:29:56 +00003160
3161/// Check the debug info version number, if it is out-dated, drop the debug
3162/// info. Return true if module is modified.
3163bool llvm::UpgradeDebugInfo(Module &M) {
Manman Ren2ebfb422014-01-16 01:51:12 +00003164 unsigned Version = getDebugMetadataVersionFromModule(M);
Adrian Prantla8b2ddb2017-10-02 18:31:29 +00003165 if (Version == DEBUG_METADATA_VERSION) {
3166 bool BrokenDebugInfo = false;
3167 if (verifyModule(M, &llvm::errs(), &BrokenDebugInfo))
3168 report_fatal_error("Broken module found, compilation aborted!");
3169 if (!BrokenDebugInfo)
3170 // Everything is ok.
3171 return false;
3172 else {
3173 // Diagnose malformed debug info.
3174 DiagnosticInfoIgnoringInvalidDebugMetadata Diag(M);
3175 M.getContext().diagnose(Diag);
3176 }
3177 }
3178 bool Modified = StripDebugInfo(M);
3179 if (Modified && Version != DEBUG_METADATA_VERSION) {
3180 // Diagnose a version mismatch.
Manman Ren2ebfb422014-01-16 01:51:12 +00003181 DiagnosticInfoDebugMetadataVersion DiagVersion(M, Version);
3182 M.getContext().diagnose(DiagVersion);
3183 }
Adrian Prantla8b2ddb2017-10-02 18:31:29 +00003184 return Modified;
Manman Ren8b4306c2013-12-02 21:29:56 +00003185}
Eli Bendersky5d5e18d2014-06-25 15:41:00 +00003186
Gerolf Hoflehnerf41aa4f2018-04-05 02:44:46 +00003187bool llvm::UpgradeRetainReleaseMarker(Module &M) {
3188 bool Changed = false;
3189 NamedMDNode *ModRetainReleaseMarker =
3190 M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker");
3191 if (ModRetainReleaseMarker) {
3192 MDNode *Op = ModRetainReleaseMarker->getOperand(0);
3193 if (Op) {
3194 MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(0));
3195 if (ID) {
3196 SmallVector<StringRef, 4> ValueComp;
3197 ID->getString().split(ValueComp, "#");
3198 if (ValueComp.size() == 2) {
3199 std::string NewValue = ValueComp[0].str() + ";" + ValueComp[1].str();
3200 Metadata *Ops[1] = {MDString::get(M.getContext(), NewValue)};
3201 ModRetainReleaseMarker->setOperand(0,
3202 MDNode::get(M.getContext(), Ops));
3203 Changed = true;
3204 }
3205 }
3206 }
3207 }
3208 return Changed;
3209}
3210
Manman Renb5d7ff42016-05-25 23:14:48 +00003211bool llvm::UpgradeModuleFlags(Module &M) {
Steven Wu010fc492017-08-21 21:49:13 +00003212 NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
Manman Renb5d7ff42016-05-25 23:14:48 +00003213 if (!ModFlags)
3214 return false;
3215
Steven Wu010fc492017-08-21 21:49:13 +00003216 bool HasObjCFlag = false, HasClassProperties = false, Changed = false;
Manman Renb5d7ff42016-05-25 23:14:48 +00003217 for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
3218 MDNode *Op = ModFlags->getOperand(I);
Steven Wu010fc492017-08-21 21:49:13 +00003219 if (Op->getNumOperands() != 3)
Manman Renb5d7ff42016-05-25 23:14:48 +00003220 continue;
3221 MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1));
3222 if (!ID)
3223 continue;
3224 if (ID->getString() == "Objective-C Image Info Version")
3225 HasObjCFlag = true;
3226 if (ID->getString() == "Objective-C Class Properties")
3227 HasClassProperties = true;
Steven Wu010fc492017-08-21 21:49:13 +00003228 // Upgrade PIC/PIE Module Flags. The module flag behavior for these two
3229 // field was Error and now they are Max.
3230 if (ID->getString() == "PIC Level" || ID->getString() == "PIE Level") {
3231 if (auto *Behavior =
3232 mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0))) {
3233 if (Behavior->getLimitedValue() == Module::Error) {
3234 Type *Int32Ty = Type::getInt32Ty(M.getContext());
3235 Metadata *Ops[3] = {
3236 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Module::Max)),
3237 MDString::get(M.getContext(), ID->getString()),
3238 Op->getOperand(2)};
3239 ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
3240 Changed = true;
3241 }
3242 }
3243 }
Steven Wuab211df2017-09-15 21:12:14 +00003244 // Upgrade Objective-C Image Info Section. Removed the whitespce in the
3245 // section name so that llvm-lto will not complain about mismatching
3246 // module flags that is functionally the same.
3247 if (ID->getString() == "Objective-C Image Info Section") {
3248 if (auto *Value = dyn_cast_or_null<MDString>(Op->getOperand(2))) {
3249 SmallVector<StringRef, 4> ValueComp;
3250 Value->getString().split(ValueComp, " ");
3251 if (ValueComp.size() != 1) {
3252 std::string NewValue;
3253 for (auto &S : ValueComp)
3254 NewValue += S.str();
3255 Metadata *Ops[3] = {Op->getOperand(0), Op->getOperand(1),
3256 MDString::get(M.getContext(), NewValue)};
3257 ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
3258 Changed = true;
3259 }
3260 }
3261 }
Manman Renb5d7ff42016-05-25 23:14:48 +00003262 }
Steven Wu010fc492017-08-21 21:49:13 +00003263
Manman Renb5d7ff42016-05-25 23:14:48 +00003264 // "Objective-C Class Properties" is recently added for Objective-C. We
3265 // upgrade ObjC bitcodes to contain a "Objective-C Class Properties" module
Mehdi Aminib53b62e2016-09-16 00:38:18 +00003266 // flag of value 0, so we can correclty downgrade this flag when trying to
3267 // link an ObjC bitcode without this module flag with an ObjC bitcode with
3268 // this module flag.
Manman Renb5d7ff42016-05-25 23:14:48 +00003269 if (HasObjCFlag && !HasClassProperties) {
Mehdi Aminib53b62e2016-09-16 00:38:18 +00003270 M.addModuleFlag(llvm::Module::Override, "Objective-C Class Properties",
Manman Renb5d7ff42016-05-25 23:14:48 +00003271 (uint32_t)0);
Steven Wu010fc492017-08-21 21:49:13 +00003272 Changed = true;
Manman Renb5d7ff42016-05-25 23:14:48 +00003273 }
Steven Wu010fc492017-08-21 21:49:13 +00003274
3275 return Changed;
Manman Renb5d7ff42016-05-25 23:14:48 +00003276}
3277
Saleem Abdulrasool46a59fd2017-10-06 18:06:59 +00003278void llvm::UpgradeSectionAttributes(Module &M) {
3279 auto TrimSpaces = [](StringRef Section) -> std::string {
3280 SmallVector<StringRef, 5> Components;
3281 Section.split(Components, ',');
3282
3283 SmallString<32> Buffer;
3284 raw_svector_ostream OS(Buffer);
3285
3286 for (auto Component : Components)
3287 OS << ',' << Component.trim();
3288
3289 return OS.str().substr(1);
3290 };
3291
3292 for (auto &GV : M.globals()) {
3293 if (!GV.hasSection())
3294 continue;
3295
3296 StringRef Section = GV.getSection();
3297
3298 if (!Section.startswith("__DATA, __objc_catlist"))
3299 continue;
3300
3301 // __DATA, __objc_catlist, regular, no_dead_strip
3302 // __DATA,__objc_catlist,regular,no_dead_strip
3303 GV.setSection(TrimSpaces(Section));
3304 }
3305}
3306
Duncan P. N. Exon Smithefe16c82016-03-25 00:56:13 +00003307static bool isOldLoopArgument(Metadata *MD) {
3308 auto *T = dyn_cast_or_null<MDTuple>(MD);
3309 if (!T)
3310 return false;
3311 if (T->getNumOperands() < 1)
3312 return false;
3313 auto *S = dyn_cast_or_null<MDString>(T->getOperand(0));
3314 if (!S)
3315 return false;
3316 return S->getString().startswith("llvm.vectorizer.");
3317}
3318
3319static MDString *upgradeLoopTag(LLVMContext &C, StringRef OldTag) {
3320 StringRef OldPrefix = "llvm.vectorizer.";
3321 assert(OldTag.startswith(OldPrefix) && "Expected old prefix");
3322
3323 if (OldTag == "llvm.vectorizer.unroll")
3324 return MDString::get(C, "llvm.loop.interleave.count");
3325
3326 return MDString::get(
3327 C, (Twine("llvm.loop.vectorize.") + OldTag.drop_front(OldPrefix.size()))
3328 .str());
3329}
3330
3331static Metadata *upgradeLoopArgument(Metadata *MD) {
3332 auto *T = dyn_cast_or_null<MDTuple>(MD);
3333 if (!T)
3334 return MD;
3335 if (T->getNumOperands() < 1)
3336 return MD;
3337 auto *OldTag = dyn_cast_or_null<MDString>(T->getOperand(0));
3338 if (!OldTag)
3339 return MD;
3340 if (!OldTag->getString().startswith("llvm.vectorizer."))
3341 return MD;
3342
3343 // This has an old tag. Upgrade it.
3344 SmallVector<Metadata *, 8> Ops;
3345 Ops.reserve(T->getNumOperands());
3346 Ops.push_back(upgradeLoopTag(T->getContext(), OldTag->getString()));
3347 for (unsigned I = 1, E = T->getNumOperands(); I != E; ++I)
3348 Ops.push_back(T->getOperand(I));
3349
3350 return MDTuple::get(T->getContext(), Ops);
3351}
3352
3353MDNode *llvm::upgradeInstructionLoopAttachment(MDNode &N) {
3354 auto *T = dyn_cast<MDTuple>(&N);
3355 if (!T)
3356 return &N;
3357
David Majnemer0a16c222016-08-11 21:15:00 +00003358 if (none_of(T->operands(), isOldLoopArgument))
Duncan P. N. Exon Smithefe16c82016-03-25 00:56:13 +00003359 return &N;
3360
3361 SmallVector<Metadata *, 8> Ops;
3362 Ops.reserve(T->getNumOperands());
3363 for (Metadata *MD : T->operands())
3364 Ops.push_back(upgradeLoopArgument(MD));
3365
3366 return MDTuple::get(T->getContext(), Ops);
Eli Bendersky5d5e18d2014-06-25 15:41:00 +00003367}