blob: b99dc065f305dd8764a00fb8c2aaabe6c245133a [file] [log] [blame]
David Neto22f144c2017-06-12 14:26:21 -04001// Copyright 2017 The Clspv Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
David Neto118188e2018-08-24 11:27:54 -040015#include "llvm/IR/DataLayout.h"
16#include "llvm/IR/IRBuilder.h"
17#include "llvm/IR/Instructions.h"
18#include "llvm/IR/Module.h"
19#include "llvm/Pass.h"
20#include "llvm/Support/raw_ostream.h"
David Neto22f144c2017-06-12 14:26:21 -040021
Diego Novilloa4c44fa2019-04-11 10:56:15 -040022#include "Passes.h"
23
David Neto22f144c2017-06-12 14:26:21 -040024using namespace llvm;
25
26#define DEBUG_TYPE "replacepointerbitcast"
27
28namespace {
29struct ReplacePointerBitcastPass : public ModulePass {
30 static char ID;
31 ReplacePointerBitcastPass() : ModulePass(ID) {}
32
David Neto30ae05e2017-09-06 19:58:36 -040033 // Returns the number of chunks of source data required to exactly
34 // cover the destination data, if the source and destination types are
35 // different sizes. Otherwise returns 0.
David Neto22f144c2017-06-12 14:26:21 -040036 unsigned CalculateNumIter(unsigned SrcTyBitWidth, unsigned DstTyBitWidth);
37 Value *CalculateNewGEPIdx(unsigned SrcTyBitWidth, unsigned DstTyBitWidth,
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040038 GetElementPtrInst *GEP);
David Neto22f144c2017-06-12 14:26:21 -040039
40 bool runOnModule(Module &M) override;
41};
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040042} // namespace
David Neto22f144c2017-06-12 14:26:21 -040043
44char ReplacePointerBitcastPass::ID = 0;
Diego Novilloa4c44fa2019-04-11 10:56:15 -040045INITIALIZE_PASS(ReplacePointerBitcastPass, "ReplacePointerBitcast",
46 "Replace Pointer Bitcast Pass", false, false)
David Neto22f144c2017-06-12 14:26:21 -040047
48namespace clspv {
49ModulePass *createReplacePointerBitcastPass() {
50 return new ReplacePointerBitcastPass();
51}
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040052} // namespace clspv
David Neto22f144c2017-06-12 14:26:21 -040053
alan-baker32014272019-05-22 08:07:18 -040054namespace {
55
56// Gathers the scalar values of |v| into |elements|. Generates new instructions
57// to extract the values.
58void GatherBaseElements(Value *v, SmallVectorImpl<Value *> *elements,
59 IRBuilder<> &builder) {
60 auto *module = builder.GetInsertBlock()->getParent()->getParent();
61 auto &DL = module->getDataLayout();
62 auto *type = v->getType();
63 if (auto *vec_type = dyn_cast<VectorType>(type)) {
64 for (uint64_t i = 0; i != vec_type->getNumElements(); ++i) {
65 elements->push_back(builder.CreateExtractElement(v, i));
66 }
67 } else if (auto *array_type = dyn_cast<ArrayType>(type)) {
68 for (uint64_t i = 0; i != array_type->getNumElements(); ++i) {
69 auto *extract = builder.CreateExtractValue(v, {static_cast<unsigned>(i)});
70 GatherBaseElements(extract, elements, builder);
71 }
72 } else if (auto *struct_type = dyn_cast<StructType>(type)) {
73 const auto *struct_layout = DL.getStructLayout(struct_type);
74 if (struct_layout->hasPadding()) {
75 llvm_unreachable("Unhandled conversion of padded struct");
76 }
77 for (unsigned i = 0; i != struct_type->getNumElements(); ++i) {
78 auto *extract = builder.CreateExtractValue(v, {i});
79 GatherBaseElements(extract, elements, builder);
80 }
81 } else {
82 elements->push_back(v);
83 }
84}
85
86// Returns a value of |dst_type| using the elemental members of |src_elements|.
87Value *BuildFromElements(Type *dst_type, const ArrayRef<Value *> &src_elements,
88 unsigned *used_bits, unsigned *index,
89 IRBuilder<> &builder) {
90 auto *module = builder.GetInsertBlock()->getParent()->getParent();
91 auto &DL = module->getDataLayout();
92 auto &context = dst_type->getContext();
93 Value *dst = nullptr;
94 // Arrays, vectors and structs are annoyingly just different enough to each
95 // require their own cases.
96 if (auto *dst_array_ty = dyn_cast<ArrayType>(dst_type)) {
97 auto *ele_ty = dst_array_ty->getElementType();
98 for (uint64_t i = 0; i != dst_array_ty->getNumElements(); ++i) {
99 auto *tmp_value =
100 BuildFromElements(ele_ty, src_elements, used_bits, index, builder);
101 auto *prev = dst ? dst : UndefValue::get(dst_type);
102 dst = builder.CreateInsertValue(prev, tmp_value,
103 {static_cast<unsigned>(i)});
104 }
105 } else if (auto *dst_struct_ty = dyn_cast<StructType>(dst_type)) {
106 const auto *struct_layout = DL.getStructLayout(dst_struct_ty);
107 if (struct_layout->hasPadding()) {
108 llvm_unreachable("Unhandled padded struct conversion");
109 return nullptr;
110 }
111 for (unsigned i = 0; i != dst_struct_ty->getNumElements(); ++i) {
112 auto *ele_ty = dst_struct_ty->getElementType(i);
113 auto *tmp_value =
114 BuildFromElements(ele_ty, src_elements, used_bits, index, builder);
115 auto *prev = dst ? dst : UndefValue::get(dst_type);
116 dst = builder.CreateInsertValue(prev, tmp_value, {i});
117 }
118 } else if (auto *dst_vec_ty = dyn_cast<VectorType>(dst_type)) {
119 auto *ele_ty = dst_vec_ty->getElementType();
120 for (uint64_t i = 0; i != dst_vec_ty->getNumElements(); ++i) {
121 auto *tmp_value =
122 BuildFromElements(ele_ty, src_elements, used_bits, index, builder);
123 auto *prev = dst ? dst : UndefValue::get(dst_type);
124 dst = builder.CreateInsertElement(prev, tmp_value, i);
125 }
126 } else {
127 // Scalar conversion eats up elements in src_elements.
128 auto dst_width = DL.getTypeStoreSizeInBits(dst_type);
129 uint64_t bits = 0;
130 Value *tmp_value = nullptr;
131 auto prev_bits = 0;
132 Value *ele_int_cast = nullptr;
133 while (bits < dst_width) {
134 prev_bits = bits;
135 auto *ele = src_elements[*index];
136 auto *ele_ty = ele->getType();
137 auto ele_width = DL.getTypeStoreSizeInBits(ele_ty);
138 auto remaining_bits = ele_width - *used_bits;
139 auto needed_bits = dst_width - bits;
140 // Create a reusable cast to an integer type for this element.
141 if (!ele_int_cast || cast<User>(ele_int_cast)->getOperand(0) != ele) {
142 ele_int_cast =
143 builder.CreateBitCast(ele, IntegerType::get(context, ele_width));
144 }
145 tmp_value = ele_int_cast;
146 // Some of the bits of this element were previously used, so shift the
147 // value that many bits.
148 if (*used_bits != 0) {
149 tmp_value = builder.CreateLShr(tmp_value, *used_bits);
150 }
151 if (needed_bits < remaining_bits) {
152 // Ensure only the needed bits are used.
153 uint64_t mask = (1ull << needed_bits) - 1;
154 tmp_value =
155 builder.CreateAnd(tmp_value, builder.getIntN(dst_width, mask));
156 }
157 // Cast to tbe destination bit width, but stay as a integer type.
158 if (ele_width != dst_width) {
159 tmp_value = builder.CreateIntCast(
160 tmp_value, IntegerType::get(context, dst_width), false);
161 }
162
163 if (remaining_bits <= needed_bits) {
164 // Used the rest of the element.
165 *used_bits = 0;
166 ++(*index);
167 bits += remaining_bits;
168 } else {
169 // Only need part of this element.
170 *used_bits += needed_bits;
171 bits += needed_bits;
172 }
173
174 if (dst) {
175 // Previous iteration generated an integer of the right size. That needs
176 // to be combined with the value generated this iteration.
177 tmp_value = builder.CreateShl(tmp_value, prev_bits);
178 dst = builder.CreateOr(dst, tmp_value);
179 } else {
180 dst = tmp_value;
181 }
182 }
183
184 assert(bits <= dst_width);
185 if (bits == dst_width && dst_type != dst->getType()) {
186 // Finally, cast away from the working integer type if necessary.
187 dst = builder.CreateBitCast(dst, dst_type);
188 }
189 }
190
191 return dst;
192}
193
194// Returns an equivalent value of |src| as |dst_type|.
195//
196// This function requires |src|'s and |dst_type|'s bit widths match. Does not
197// introduce new integer sizes, but generates multiple instructions to mimic a
198// generic bitcast (unless a bitcast is sufficient).
199Value *ConvertValue(Value *src, Type *dst_type, IRBuilder<> &builder) {
200 auto *src_type = src->getType();
201 auto *module = builder.GetInsertBlock()->getParent()->getParent();
202 auto &DL = module->getDataLayout();
203 if (!src_type->isFirstClassType() || !dst_type->isFirstClassType() ||
204 src_type->isAggregateType() || dst_type->isAggregateType()) {
205 SmallVector<Value *, 8> src_elements;
206 if (src_type->isAggregateType()) {
207 GatherBaseElements(src, &src_elements, builder);
208 } else {
209 src_elements.push_back(src);
210 }
211
212 // Check that overall sizes make sense.
213 uint64_t element_sum = 0;
214 // Can only successfully convert unpadded structs.
215 for (auto element : src_elements) {
216 element_sum += DL.getTypeStoreSizeInBits(element->getType());
217 }
218 if (DL.getTypeStoreSizeInBits(dst_type) != element_sum) {
219 llvm_unreachable("Elements do not sum to overall size");
220 return nullptr;
221 }
222
223 unsigned used_bits = 0;
224 unsigned index = 0;
225 return BuildFromElements(dst_type, src_elements, &used_bits, &index,
226 builder);
227 } else {
228 return builder.CreateBitCast(src, dst_type);
229 }
230
231 return nullptr;
232}
233
234} // namespace
235
David Neto22f144c2017-06-12 14:26:21 -0400236unsigned ReplacePointerBitcastPass::CalculateNumIter(unsigned SrcTyBitWidth,
237 unsigned DstTyBitWidth) {
238 unsigned NumIter = 0;
239 if (SrcTyBitWidth > DstTyBitWidth) {
240 if (SrcTyBitWidth % DstTyBitWidth) {
241 llvm_unreachable(
242 "Src type bitwidth should be multiple of Dest type bitwidth");
243 }
244 NumIter = 1;
245 } else if (SrcTyBitWidth < DstTyBitWidth) {
246 if (DstTyBitWidth % SrcTyBitWidth) {
247 llvm_unreachable(
248 "Dest type bitwidth should be multiple of Src type bitwidth");
249 }
250 NumIter = DstTyBitWidth / SrcTyBitWidth;
251 } else {
252 NumIter = 0;
253 }
254
255 return NumIter;
256}
257
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400258Value *ReplacePointerBitcastPass::CalculateNewGEPIdx(unsigned SrcTyBitWidth,
259 unsigned DstTyBitWidth,
260 GetElementPtrInst *GEP) {
David Neto22f144c2017-06-12 14:26:21 -0400261 Value *NewGEPIdx = GEP->getOperand(1);
262 IRBuilder<> Builder(GEP);
263
264 if (SrcTyBitWidth > DstTyBitWidth) {
265 if (GEP->getNumOperands() > 2) {
266 GEP->print(errs());
267 llvm_unreachable("Support above GEP on PointerBitcastPass");
268 }
269
270 NewGEPIdx = Builder.CreateLShr(
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400271 NewGEPIdx, Builder.getInt32(std::log2(SrcTyBitWidth / DstTyBitWidth)));
David Neto22f144c2017-06-12 14:26:21 -0400272 } else if (DstTyBitWidth > SrcTyBitWidth) {
273 if (GEP->getNumOperands() > 2) {
274 GEP->print(errs());
275 llvm_unreachable("Support above GEP on PointerBitcastPass");
276 }
277
278 NewGEPIdx = Builder.CreateShl(
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400279 NewGEPIdx, Builder.getInt32(std::log2(DstTyBitWidth / SrcTyBitWidth)));
David Neto22f144c2017-06-12 14:26:21 -0400280 }
281
282 return NewGEPIdx;
283}
284
285bool ReplacePointerBitcastPass::runOnModule(Module &M) {
286 bool Changed = false;
287
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400288 const DataLayout &DL = M.getDataLayout();
David Neto8e138142018-05-29 10:19:21 -0400289
alan-bakerad1a12f2020-08-25 09:18:38 -0400290 SmallVector<Instruction *, 16> ToBeDeleted;
David Neto22f144c2017-06-12 14:26:21 -0400291 SmallVector<Instruction *, 16> VectorWorkList;
292 SmallVector<Instruction *, 16> ScalarWorkList;
alan-baker1b13e8f2019-08-08 17:56:51 -0400293 SmallVector<User *, 16> UserWorkList;
David Neto22f144c2017-06-12 14:26:21 -0400294 for (Function &F : M) {
295 for (BasicBlock &BB : F) {
296 for (Instruction &I : BB) {
297 // Find pointer bitcast instruction.
298 if (isa<BitCastInst>(&I) && isa<PointerType>(I.getType())) {
299 Value *Src = I.getOperand(0);
300 if (isa<PointerType>(Src->getType())) {
alan-baker1b13e8f2019-08-08 17:56:51 -0400301 // Check if this bitcast is one that can be handled during this run
302 // of the pass. If not, just skip it and don't make changes to the
303 // module. These checks are coarse level checks that only the right
304 // instructions appear. Rejected bitcasts might be able to be
305 // handled later in the flow after further optimization.
306 UserWorkList.clear();
307 for (auto User : I.users()) {
308 UserWorkList.push_back(User);
309 }
310 bool ok = true;
311 while (!UserWorkList.empty()) {
312 auto User = UserWorkList.back();
313 UserWorkList.pop_back();
314
315 if (isa<GetElementPtrInst>(User)) {
316 for (auto GEPUser : User->users()) {
317 UserWorkList.push_back(GEPUser);
318 }
319 } else if (!isa<StoreInst>(User) && !isa<LoadInst>(User)) {
320 // Cannot handle this bitcast.
321 ok = false;
322 break;
323 }
324 }
325 if (!ok) {
326 continue;
327 }
328
alan-bakerad1a12f2020-08-25 09:18:38 -0400329 auto inst = &I;
David Neto22f144c2017-06-12 14:26:21 -0400330 Type *SrcEleTy =
alan-bakerad1a12f2020-08-25 09:18:38 -0400331 inst->getOperand(0)->getType()->getPointerElementType();
332
333 // De-"canonicalize" the input pointer.
334 // If Src is an array, LLVM has likely canonicalized all GEPs to
335 // the first element away as the following addresses are all
336 // equivalent:
337 // * %in = alloca [4 x [4 x float]]
338 // * %gep0 = getelementptr [4 x [4 x float]]*, [4 x [4 x [float]]*
339 // %in
340 // * %gep1 = getelementptr [4 x [4 x float]]*, [4 x [4 x [float]]*
341 // %in, i32 0
342 // * %gep2 = getelementptr [4 x [4 x float]]*, [4 x [4 x [float]]*
343 // %in, i32 0, i32 0
344 // * %gep3 = getelementptr [4 x [4 x float]]*, [4 x [4 x [float]]*
345 // %in, i32 0, i32 0, i32 0
346 //
347 // Note: count initialized to 1 to account for the first gep index.
348 uint32_t count = 1;
349 while (auto ArrayTy = dyn_cast<ArrayType>(SrcEleTy)) {
350 ++count;
351 SrcEleTy = ArrayTy->getElementType();
352 }
353
354 if (count > 1) {
355 // Create a cast of the pointer. Replace the original cast with
356 // it and mark the original cast for deletion.
357 SmallVector<Value *, 4> indices(
358 count,
359 ConstantInt::get(IntegerType::get(M.getContext(), 32), 0));
360 auto gep = GetElementPtrInst::CreateInBounds(inst->getOperand(0),
361 indices, "", inst);
362 ToBeDeleted.push_back(&I);
363 auto cast = new BitCastInst(gep, inst->getType(), "", inst);
364 inst->replaceAllUsesWith(cast);
365 inst = cast;
366 }
367
368 Type *DstEleTy = inst->getType()->getPointerElementType();
David Neto22f144c2017-06-12 14:26:21 -0400369 if (SrcEleTy->isVectorTy() || DstEleTy->isVectorTy()) {
370 // Handle case either operand is vector type like char4* -> int4*.
alan-bakerad1a12f2020-08-25 09:18:38 -0400371 VectorWorkList.push_back(inst);
David Neto22f144c2017-06-12 14:26:21 -0400372 } else {
373 // Handle case all operands are scalar type like char* -> int*.
alan-bakerad1a12f2020-08-25 09:18:38 -0400374 ScalarWorkList.push_back(inst);
David Neto22f144c2017-06-12 14:26:21 -0400375 }
376
377 Changed = true;
378 } else {
379 llvm_unreachable("Unsupported bitcast");
380 }
381 }
382 }
383 }
384 }
385
David Neto22f144c2017-06-12 14:26:21 -0400386 for (Instruction *Inst : VectorWorkList) {
387 Value *Src = Inst->getOperand(0);
388 Type *SrcTy = Src->getType()->getPointerElementType();
389 Type *DstTy = Inst->getType()->getPointerElementType();
James Pricecf53df42020-04-20 14:41:24 -0400390 VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy);
391 VectorType *DstVecTy = dyn_cast<VectorType>(DstTy);
392 Type *SrcEleTy = SrcTy->isVectorTy() ? SrcVecTy->getElementType() : SrcTy;
393 Type *DstEleTy = DstTy->isVectorTy() ? DstVecTy->getElementType() : DstTy;
David Neto30ae05e2017-09-06 19:58:36 -0400394 // These are bit widths of the source and destination types, even
alan-bakerad1a12f2020-08-25 09:18:38 -0400395 // if they are vector types. E.g. bit width of float4 is 128.
David Neto8e138142018-05-29 10:19:21 -0400396 unsigned SrcTyBitWidth = DL.getTypeStoreSizeInBits(SrcTy);
397 unsigned DstTyBitWidth = DL.getTypeStoreSizeInBits(DstTy);
398 unsigned SrcEleTyBitWidth = DL.getTypeStoreSizeInBits(SrcEleTy);
399 unsigned DstEleTyBitWidth = DL.getTypeStoreSizeInBits(DstEleTy);
David Neto22f144c2017-06-12 14:26:21 -0400400 unsigned NumIter = CalculateNumIter(SrcTyBitWidth, DstTyBitWidth);
401
402 // Investigate pointer bitcast's users.
403 for (User *BitCastUser : Inst->users()) {
404 Value *BitCastSrc = Inst->getOperand(0);
405 Value *NewAddrIdx = ConstantInt::get(Type::getInt32Ty(M.getContext()), 0);
406
407 // It consist of User* and bool whether user is gep or not.
408 SmallVector<std::pair<User *, bool>, 32> Users;
409
410 GetElementPtrInst *GEP = nullptr;
411 Value *OrgGEPIdx = nullptr;
Jason Gavrise44af072018-08-14 20:44:50 -0400412 if ((GEP = dyn_cast<GetElementPtrInst>(BitCastUser))) {
David Neto22f144c2017-06-12 14:26:21 -0400413 OrgGEPIdx = GEP->getOperand(1);
414
415 // Build new src/dst address index.
416 NewAddrIdx = CalculateNewGEPIdx(SrcTyBitWidth, DstTyBitWidth, GEP);
417
418 // Record gep's users.
419 for (User *GEPUser : GEP->users()) {
420 Users.push_back(std::make_pair(GEPUser, true));
421 }
422 } else {
423 // Record bitcast's users.
424 Users.push_back(std::make_pair(BitCastUser, false));
425 }
426
427 // Handle users.
428 bool IsGEPUser = false;
429 for (auto UserIter : Users) {
430 User *U = UserIter.first;
431 IsGEPUser = UserIter.second;
432
433 IRBuilder<> Builder(cast<Instruction>(U));
434
435 if (StoreInst *ST = dyn_cast<StoreInst>(U)) {
436 if (SrcTyBitWidth < DstTyBitWidth) {
437 //
438 // Consider below case.
439 //
440 // Original IR (float2* --> float4*)
441 // 1. val = load (float4*) src_addr
442 // 2. dst_addr = bitcast float2*, float4*
443 // 3. dst_addr = gep (float4*) dst_addr, idx
444 // 4. store (float4*) dst_addr
445 //
446 // Transformed IR
447 // 1. val(float4) = load (float4*) src_addr
448 // 2. val1(float2) = shufflevector (float4)val, (float4)undef,
449 // (float2)<0, 1>
450 // 3. val2(float2) = shufflevector (float4)val, (float4)undef,
451 // (float2)<2, 3>
452 // 4. dst_addr1(float2*) = gep (float2*)dst_addr, idx * 2
453 // 5. dst_addr2(float2*) = gep (float2*)dst_addr, idx * 2 + 1
454 // 6. store (float2)val1, (float2*)dst_addr1
455 // 7. store (float2)val2, (float2*)dst_addr2
456 //
457
458 unsigned NumElement = DstTyBitWidth / SrcTyBitWidth;
459 unsigned NumVector = 1;
460 // Vulkan SPIR-V does not support over 4 components for
461 // TypeVector.
462 if (NumElement > 4) {
463 NumVector = NumElement >> 2;
464 NumElement = 4;
465 }
466
467 // Create store values.
468 Type *TmpValTy = SrcTy;
469 if (DstTy->isVectorTy()) {
470 if (SrcEleTyBitWidth == DstEleTyBitWidth) {
471 TmpValTy =
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400472 FixedVectorType::get(SrcEleTy, DstVecTy->getNumElements());
David Neto22f144c2017-06-12 14:26:21 -0400473 } else {
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400474 TmpValTy = FixedVectorType::get(SrcEleTy, NumElement);
David Neto22f144c2017-06-12 14:26:21 -0400475 }
476 }
477
478 Value *STVal = ST->getValueOperand();
479 for (unsigned VIdx = 0; VIdx < NumVector; VIdx++) {
480 Value *TmpSTVal = nullptr;
481 if (NumVector == 1) {
482 TmpSTVal = Builder.CreateBitCast(STVal, TmpValTy);
483 } else {
484 unsigned DstVecTyNumElement =
James Pricecf53df42020-04-20 14:41:24 -0400485 DstVecTy->getNumElements() / NumVector;
alan-baker4a757f62020-04-22 08:17:49 -0400486 SmallVector<int32_t, 4> Idxs;
487 for (int i = 0; i < DstVecTyNumElement; i++) {
David Neto22f144c2017-06-12 14:26:21 -0400488 Idxs.push_back(i + (DstVecTyNumElement * VIdx));
489 }
490 Value *UndefVal = UndefValue::get(DstTy);
491 TmpSTVal = Builder.CreateShuffleVector(STVal, UndefVal, Idxs);
492 TmpSTVal = Builder.CreateBitCast(TmpSTVal, TmpValTy);
493 }
494
495 SmallVector<Value *, 8> STValues;
496 if (!SrcTy->isVectorTy()) {
497 // Handle scalar type.
498 for (unsigned i = 0; i < NumElement; i++) {
499 Value *TmpVal = Builder.CreateExtractElement(
500 TmpSTVal, Builder.getInt32(i));
501 STValues.push_back(TmpVal);
502 }
503 } else {
504 // Handle vector type.
James Pricecf53df42020-04-20 14:41:24 -0400505 unsigned SrcNumElement = SrcVecTy->getNumElements();
506 unsigned DstNumElement = DstVecTy->getNumElements();
David Neto22f144c2017-06-12 14:26:21 -0400507 for (unsigned i = 0; i < NumElement; i++) {
alan-baker4a757f62020-04-22 08:17:49 -0400508 SmallVector<int32_t, 4> Idxs;
509 for (int j = 0; j < SrcNumElement; j++) {
David Neto22f144c2017-06-12 14:26:21 -0400510 Idxs.push_back(i * SrcNumElement + j);
511 }
512
513 VectorType *TmpVecTy =
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400514 FixedVectorType::get(SrcEleTy, DstNumElement);
David Neto22f144c2017-06-12 14:26:21 -0400515 Value *UndefVal = UndefValue::get(TmpVecTy);
516 Value *TmpVal =
517 Builder.CreateShuffleVector(TmpSTVal, UndefVal, Idxs);
518 STValues.push_back(TmpVal);
519 }
520 }
521
522 // Generate stores.
523 Value *SrcAddrIdx = NewAddrIdx;
524 Value *BaseAddr = BitCastSrc;
525 for (unsigned i = 0; i < NumElement; i++) {
526 // Calculate store address.
527 Value *DstAddr = Builder.CreateGEP(BaseAddr, SrcAddrIdx);
528 Builder.CreateStore(STValues[i], DstAddr);
529
530 if (i + 1 < NumElement) {
531 // Calculate next store address
532 SrcAddrIdx =
533 Builder.CreateAdd(SrcAddrIdx, Builder.getInt32(1));
534 }
535 }
536 }
537 } else if (SrcTyBitWidth > DstTyBitWidth) {
538 //
539 // Consider below case.
540 //
541 // Original IR (float4* --> float2*)
542 // 1. val = load (float2*) src_addr
543 // 2. dst_addr = bitcast float4*, float2*
544 // 3. dst_addr = gep (float2*) dst_addr, idx
545 // 4. store (float2) val, (float2*) dst_addr
546 //
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400547 // Transformed IR: Decompose the source vector into elements, then
548 // write them one at a time.
David Neto22f144c2017-06-12 14:26:21 -0400549 // 1. val = load (float2*) src_addr
550 // 2. val1 = (float)extract_element val, 0
551 // 3. val2 = (float)extract_element val, 1
David Neto30ae05e2017-09-06 19:58:36 -0400552 // // Source component k maps to destination component k * idxscale
553 // 3a. idxscale = sizeof(float4)/sizeof(float2)
554 // 3b. idxbase = idx / idxscale
555 // 3c. newarrayidx = idxbase * idxscale
556 // 4. dst_addr1 = gep (float4*) dst, newarrayidx
557 // 5. dst_addr2 = gep (float4*) dst, newarrayidx + 1
David Neto22f144c2017-06-12 14:26:21 -0400558 // 6. store (float)val1, (float*) dst_addr1
559 // 7. store (float)val2, (float*) dst_addr2
560 //
561
562 if (SrcTyBitWidth <= DstEleTyBitWidth) {
563 SrcTy->print(errs());
564 DstTy->print(errs());
565 llvm_unreachable("Handle above src/dst type.");
566 }
567
568 // Create store values.
569 Value *STVal = ST->getValueOperand();
570
571 if (DstTy->isVectorTy() && (SrcEleTyBitWidth != DstTyBitWidth)) {
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400572 VectorType *TmpVecTy = FixedVectorType::get(
573 SrcEleTy, DstTyBitWidth / SrcEleTyBitWidth);
David Neto22f144c2017-06-12 14:26:21 -0400574 STVal = Builder.CreateBitCast(STVal, TmpVecTy);
575 }
576
577 SmallVector<Value *, 8> STValues;
David Neto30ae05e2017-09-06 19:58:36 -0400578 // How many destination writes are required?
David Neto22f144c2017-06-12 14:26:21 -0400579 unsigned DstNumElement = 1;
580 if (!DstTy->isVectorTy() || SrcEleTyBitWidth == DstTyBitWidth) {
581 // Handle scalar type.
582 STValues.push_back(STVal);
583 } else {
584 // Handle vector type.
James Pricecf53df42020-04-20 14:41:24 -0400585 DstNumElement = DstVecTy->getNumElements();
David Neto22f144c2017-06-12 14:26:21 -0400586 for (unsigned i = 0; i < DstNumElement; i++) {
587 Value *Idx = Builder.getInt32(i);
588 Value *TmpVal = Builder.CreateExtractElement(STVal, Idx);
589 STValues.push_back(TmpVal);
590 }
591 }
592
593 // Generate stores.
594 Value *BaseAddr = BitCastSrc;
595 Value *SubEleIdx = Builder.getInt32(0);
596 if (IsGEPUser) {
David Neto30ae05e2017-09-06 19:58:36 -0400597 // Compute SubNumElement = idxscale
James Pricecf53df42020-04-20 14:41:24 -0400598 unsigned SubNumElement = SrcVecTy->getNumElements();
David Neto22f144c2017-06-12 14:26:21 -0400599 if (DstTy->isVectorTy() && (SrcEleTyBitWidth != DstTyBitWidth)) {
David Neto30ae05e2017-09-06 19:58:36 -0400600 // Same condition under which DstNumElements > 1
James Pricecf53df42020-04-20 14:41:24 -0400601 SubNumElement =
602 SrcVecTy->getNumElements() / DstVecTy->getNumElements();
David Neto22f144c2017-06-12 14:26:21 -0400603 }
604
David Neto30ae05e2017-09-06 19:58:36 -0400605 // Compute SubEleIdx = idxbase * idxscale
David Neto22f144c2017-06-12 14:26:21 -0400606 SubEleIdx = Builder.CreateAnd(
607 OrgGEPIdx, Builder.getInt32(SubNumElement - 1));
David Neto30ae05e2017-09-06 19:58:36 -0400608 if (DstTy->isVectorTy() && (SrcEleTyBitWidth != DstTyBitWidth)) {
609 SubEleIdx = Builder.CreateShl(
610 SubEleIdx, Builder.getInt32(std::log2(SubNumElement)));
611 }
David Neto22f144c2017-06-12 14:26:21 -0400612 }
613
614 for (unsigned i = 0; i < DstNumElement; i++) {
615 // Calculate address.
616 if (i > 0) {
617 SubEleIdx = Builder.CreateAdd(SubEleIdx, Builder.getInt32(i));
618 }
619
620 Value *Idxs[] = {NewAddrIdx, SubEleIdx};
621 Value *DstAddr = Builder.CreateGEP(BaseAddr, Idxs);
622 Type *TmpSrcTy = SrcEleTy;
James Pricecf53df42020-04-20 14:41:24 -0400623 if (auto TmpSrcVecTy = dyn_cast<VectorType>(TmpSrcTy)) {
624 TmpSrcTy = TmpSrcVecTy->getElementType();
David Neto22f144c2017-06-12 14:26:21 -0400625 }
626 Value *TmpVal = Builder.CreateBitCast(STValues[i], TmpSrcTy);
627
628 Builder.CreateStore(TmpVal, DstAddr);
629 }
630 } else {
631 // if SrcTyBitWidth == DstTyBitWidth
632 Type *TmpSrcTy = SrcTy;
633 Value *DstAddr = Src;
634
635 if (IsGEPUser) {
636 SmallVector<Value *, 4> Idxs;
637 for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
638 Idxs.push_back(GEP->getOperand(i));
639 }
640 DstAddr = Builder.CreateGEP(BitCastSrc, Idxs);
641
642 if (GEP->getNumOperands() > 2) {
643 TmpSrcTy = SrcEleTy;
644 }
645 }
646
647 Value *TmpVal =
648 Builder.CreateBitCast(ST->getValueOperand(), TmpSrcTy);
649 Builder.CreateStore(TmpVal, DstAddr);
650 }
651 } else if (LoadInst *LD = dyn_cast<LoadInst>(U)) {
652 Value *SrcAddrIdx = Builder.getInt32(0);
653 if (IsGEPUser) {
654 SrcAddrIdx = NewAddrIdx;
655 }
656
657 // Load value from src.
658 SmallVector<Value *, 8> LDValues;
659
660 for (unsigned i = 1; i <= NumIter; i++) {
661 Value *SrcAddr = Builder.CreateGEP(Src, SrcAddrIdx);
662 LoadInst *SrcVal = Builder.CreateLoad(SrcAddr, "src_val");
663 LDValues.push_back(SrcVal);
664
665 if (i + 1 <= NumIter) {
666 // Calculate next SrcAddrIdx.
667 SrcAddrIdx = Builder.CreateAdd(SrcAddrIdx, Builder.getInt32(1));
668 }
669 }
670
671 Value *DstVal = nullptr;
672 if (SrcTyBitWidth > DstTyBitWidth) {
673 unsigned NumElement = SrcTyBitWidth / DstTyBitWidth;
674
675 if (SrcEleTyBitWidth == DstTyBitWidth) {
676 //
677 // Consider below case.
678 //
679 // Original IR (int4* --> char4*)
680 // 1. src_addr = bitcast int4*, char4*
681 // 2. element_addr = gep (char4*) src_addr, idx
682 // 3. load (char4*) element_addr
683 //
684 // Transformed IR
685 // 1. src_addr = gep (int4*) src, idx / 4
686 // 2. src_val(int4) = load (int4*) src_addr
687 // 3. tmp_val(int4) = extractelement src_val, idx % 4
688 // 4. dst_val(char4) = bitcast tmp_val, (char4)
689 //
690 Value *EleIdx = Builder.getInt32(0);
691 if (IsGEPUser) {
692 EleIdx = Builder.CreateAnd(OrgGEPIdx,
693 Builder.getInt32(NumElement - 1));
694 }
695 Value *TmpVal =
696 Builder.CreateExtractElement(LDValues[0], EleIdx, "tmp_val");
697 DstVal = Builder.CreateBitCast(TmpVal, DstTy);
698 } else if (SrcEleTyBitWidth < DstTyBitWidth) {
699 if (IsGEPUser) {
700 //
701 // Consider below case.
702 //
703 // Original IR (float4* --> float2*)
704 // 1. src_addr = bitcast float4*, float2*
705 // 2. element_addr = gep (float2*) src_addr, idx
706 // 3. load (float2*) element_addr
707 //
708 // Transformed IR
709 // 1. src_addr = gep (float4*) src, idx / 2
710 // 2. src_val(float4) = load (float4*) src_addr
711 // 3. tmp_val1(float) = extractelement (idx % 2) * 2
712 // 4. tmp_val2(float) = extractelement (idx % 2) * 2 + 1
713 // 5. dst_val(float2) = insertelement undef(float2), tmp_val1, 0
714 // 6. dst_val(float2) = insertelement undef(float2), tmp_val2, 1
715 // 7. dst_val(float2) = bitcast dst_val, (float2)
716 // ==> if types are same between src and dst, it will be
717 // igonored
718 //
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400719 VectorType *TmpVecTy = FixedVectorType::get(
720 SrcEleTy, DstTyBitWidth / SrcEleTyBitWidth);
David Neto22f144c2017-06-12 14:26:21 -0400721 DstVal = UndefValue::get(TmpVecTy);
722 Value *EleIdx = Builder.CreateAnd(
723 OrgGEPIdx, Builder.getInt32(NumElement - 1));
724 EleIdx = Builder.CreateShl(
725 EleIdx, Builder.getInt32(
726 std::log2(DstTyBitWidth / SrcEleTyBitWidth)));
727 Value *TmpOrgGEPIdx = EleIdx;
728 for (unsigned i = 0; i < NumElement; i++) {
729 Value *TmpVal = Builder.CreateExtractElement(
730 LDValues[0], TmpOrgGEPIdx, "tmp_val");
731 DstVal = Builder.CreateInsertElement(DstVal, TmpVal,
732 Builder.getInt32(i));
733
734 if (i + 1 < NumElement) {
735 TmpOrgGEPIdx =
736 Builder.CreateAdd(TmpOrgGEPIdx, Builder.getInt32(1));
737 }
738 }
739 } else {
740 //
741 // Consider below case.
742 //
743 // Original IR (float4* --> int2*)
744 // 1. src_addr = bitcast float4*, int2*
745 // 2. load (int2*) src_addr
746 //
747 // Transformed IR
748 // 1. src_val(float4) = load (float4*) src_addr
749 // 2. tmp_val(float2) = shufflevector (float4)src_val,
750 // (float4)undef,
751 // (float2)<0, 1>
752 // 3. dst_val(int2) = bitcast (float2)tmp_val, (int2)
753 //
754 unsigned NumElement = DstTyBitWidth / SrcEleTyBitWidth;
755 Value *Undef = UndefValue::get(SrcTy);
756
alan-baker4a757f62020-04-22 08:17:49 -0400757 SmallVector<int32_t, 4> Idxs;
758 for (int i = 0; i < NumElement; i++) {
David Neto22f144c2017-06-12 14:26:21 -0400759 Idxs.push_back(i);
760 }
761 DstVal = Builder.CreateShuffleVector(LDValues[0], Undef, Idxs);
762
763 DstVal = Builder.CreateBitCast(DstVal, DstTy);
764 }
765
766 DstVal = Builder.CreateBitCast(DstVal, DstTy);
767 } else {
768 if (IsGEPUser) {
769 //
770 // Consider below case.
771 //
772 // Original IR (int4* --> char2*)
773 // 1. src_addr = bitcast int4*, char2*
774 // 2. element_addr = gep (char2*) src_addr, idx
775 // 3. load (char2*) element_addr
776 //
777 // Transformed IR
778 // 1. src_addr = gep (int4*) src, idx / 8
779 // 2. src_val(int4) = load (int4*) src_addr
780 // 3. tmp_val(int) = extractelement idx / 2
781 // 4. tmp_val(<i16 x 2>) = bitcast tmp_val(int), (<i16 x 2>)
782 // 5. tmp_val(i16) = extractelement idx % 2
783 // 6. dst_val(char2) = bitcast tmp_val, (char2)
784 // ==> if types are same between src and dst, it will be
785 // igonored
786 //
David Neto22f144c2017-06-12 14:26:21 -0400787 unsigned SubNumElement = SrcEleTyBitWidth / DstTyBitWidth;
788 if (SubNumElement != 2 && SubNumElement != 4) {
789 llvm_unreachable("Unsupported SubNumElement");
790 }
791
792 Value *TmpOrgGEPIdx = Builder.CreateLShr(
793 OrgGEPIdx, Builder.getInt32(std::log2(SubNumElement)));
794 Value *TmpVal = Builder.CreateExtractElement(
795 LDValues[0], TmpOrgGEPIdx, "tmp_val");
796 TmpVal = Builder.CreateBitCast(
797 TmpVal,
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400798 FixedVectorType::get(
David Neto22f144c2017-06-12 14:26:21 -0400799 IntegerType::get(DstTy->getContext(), DstTyBitWidth),
800 SubNumElement));
801 TmpOrgGEPIdx = Builder.CreateAnd(
802 OrgGEPIdx, Builder.getInt32(SubNumElement - 1));
803 TmpVal = Builder.CreateExtractElement(TmpVal, TmpOrgGEPIdx,
804 "tmp_val");
805 DstVal = Builder.CreateBitCast(TmpVal, DstTy);
806 } else {
807 Inst->print(errs());
808 llvm_unreachable("Handle this bitcast");
809 }
810 }
811 } else if (SrcTyBitWidth < DstTyBitWidth) {
812 //
813 // Consider below case.
814 //
815 // Original IR (float2* --> float4*)
816 // 1. src_addr = bitcast float2*, float4*
817 // 2. element_addr = gep (float4*) src_addr, idx
818 // 3. load (float4*) element_addr
819 //
820 // Transformed IR
821 // 1. src_addr = gep (float2*) src, idx * 2
822 // 2. src_val1(float2) = load (float2*) src_addr
823 // 3. src_addr2 = gep (float2*) src_addr, 1
824 // 4. src_val2(float2) = load (float2*) src_addr2
825 // 5. dst_val(float4) = shufflevector src_val1, src_val2, <0, 1>
826 // 6. dst_val(float4) = bitcast dst_val, (float4)
827 // ==> if types are same between src and dst, it will be igonored
828 //
829 unsigned NumElement = 1;
830 if (SrcTy->isVectorTy()) {
James Pricecf53df42020-04-20 14:41:24 -0400831 NumElement = SrcVecTy->getNumElements() * 2;
David Neto22f144c2017-06-12 14:26:21 -0400832 }
833
834 // Handle scalar type.
835 if (NumElement == 1) {
836 if (SrcTyBitWidth * 4 <= DstTyBitWidth) {
837 unsigned NumVecElement = DstTyBitWidth / SrcTyBitWidth;
838 unsigned NumVector = 1;
839 if (NumVecElement > 4) {
840 NumVector = NumVecElement >> 2;
841 NumVecElement = 4;
842 }
843
844 SmallVector<Value *, 4> Values;
845 for (unsigned VIdx = 0; VIdx < NumVector; VIdx++) {
846 // In this case, generate only insert element. It generates
847 // less instructions than using shuffle vector.
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400848 VectorType *TmpVecTy =
849 FixedVectorType::get(SrcTy, NumVecElement);
David Neto22f144c2017-06-12 14:26:21 -0400850 Value *TmpVal = UndefValue::get(TmpVecTy);
851 for (unsigned i = 0; i < NumVecElement; i++) {
852 TmpVal = Builder.CreateInsertElement(
853 TmpVal, LDValues[i + (VIdx * 4)], Builder.getInt32(i));
854 }
855 Values.push_back(TmpVal);
856 }
857
858 if (Values.size() > 2) {
859 Inst->print(errs());
860 llvm_unreachable("Support above bitcast");
861 }
862
863 if (Values.size() > 1) {
864 Type *TmpEleTy =
865 Type::getIntNTy(M.getContext(), SrcEleTyBitWidth * 2);
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400866 VectorType *TmpVecTy =
867 FixedVectorType::get(TmpEleTy, NumVector);
David Neto22f144c2017-06-12 14:26:21 -0400868 for (unsigned i = 0; i < Values.size(); i++) {
869 Values[i] = Builder.CreateBitCast(Values[i], TmpVecTy);
870 }
alan-baker4a757f62020-04-22 08:17:49 -0400871 SmallVector<int32_t, 4> Idxs;
872 for (int i = 0; i < (NumVector * 2); i++) {
David Neto22f144c2017-06-12 14:26:21 -0400873 Idxs.push_back(i);
874 }
875 for (unsigned i = 0; i < Values.size(); i = i + 2) {
876 Values[i] = Builder.CreateShuffleVector(
877 Values[i], Values[i + 1], Idxs);
878 }
879 }
880
881 LDValues.clear();
882 LDValues.push_back(Values[0]);
883 } else {
884 SmallVector<Value *, 4> TmpLDValues;
885 for (unsigned i = 0; i < LDValues.size(); i = i + 2) {
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400886 VectorType *TmpVecTy = FixedVectorType::get(SrcTy, 2);
David Neto22f144c2017-06-12 14:26:21 -0400887 Value *TmpVal = UndefValue::get(TmpVecTy);
888 TmpVal = Builder.CreateInsertElement(TmpVal, LDValues[i],
889 Builder.getInt32(0));
890 TmpVal = Builder.CreateInsertElement(TmpVal, LDValues[i + 1],
891 Builder.getInt32(1));
892 TmpLDValues.push_back(TmpVal);
893 }
894 LDValues.clear();
895 LDValues = std::move(TmpLDValues);
896 NumElement = 4;
897 }
898 }
899
900 // Handle vector type.
901 while (LDValues.size() != 1) {
902 SmallVector<Value *, 4> TmpLDValues;
903 for (unsigned i = 0; i < LDValues.size(); i = i + 2) {
alan-baker4a757f62020-04-22 08:17:49 -0400904 SmallVector<int32_t, 4> Idxs;
905 for (int j = 0; j < NumElement; j++) {
David Neto22f144c2017-06-12 14:26:21 -0400906 Idxs.push_back(j);
907 }
908 Value *TmpVal = Builder.CreateShuffleVector(
909 LDValues[i], LDValues[i + 1], Idxs);
910 TmpLDValues.push_back(TmpVal);
911 }
912 LDValues.clear();
913 LDValues = std::move(TmpLDValues);
914 NumElement *= 2;
915 }
916
917 DstVal = Builder.CreateBitCast(LDValues[0], DstTy);
918 } else {
919 //
920 // Consider below case.
921 //
922 // Original IR (float4* --> int4*)
923 // 1. src_addr = bitcast float4*, int4*
924 // 2. element_addr = gep (int4*) src_addr, idx, 0
925 // 3. load (int) element_addr
926 //
927 // Transformed IR
928 // 1. element_addr = gep (float4*) src_addr, idx, 0
929 // 2. src_val = load (float*) element_addr
930 // 3. val = bitcast (float) src_val to (int)
931 //
932 Value *SrcAddr = Src;
933 if (IsGEPUser) {
934 SmallVector<Value *, 4> Idxs;
935 for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
936 Idxs.push_back(GEP->getOperand(i));
937 }
938 SrcAddr = Builder.CreateGEP(Src, Idxs);
939 }
940 LoadInst *SrcVal = Builder.CreateLoad(SrcAddr, "src_val");
941
942 Type *TmpDstTy = DstTy;
943 if (IsGEPUser) {
944 if (GEP->getNumOperands() > 2) {
945 TmpDstTy = DstEleTy;
946 }
947 }
948 DstVal = Builder.CreateBitCast(SrcVal, TmpDstTy);
949 }
950
951 // Update LD's users with DstVal.
952 LD->replaceAllUsesWith(DstVal);
953 } else {
954 U->print(errs());
955 llvm_unreachable(
956 "Handle above user of gep on ReplacePointerBitcastPass");
957 }
958
959 ToBeDeleted.push_back(cast<Instruction>(U));
960 }
961
962 if (IsGEPUser) {
963 ToBeDeleted.push_back(GEP);
964 }
965 }
966
967 ToBeDeleted.push_back(Inst);
968 }
969
970 for (Instruction *Inst : ScalarWorkList) {
David Neto8e138142018-05-29 10:19:21 -0400971 // Some tests have a stray bitcast from pointer-to-array to
972 // pointer to i8*, but the bitcast has no uses. Exit early
973 // but be sure to delete it later.
974 //
975 // Example:
976 // %1 = bitcast [25 x float]* %dst to i8*
977
978 // errs () << " Scalar bitcast is " << *Inst << "\n";
979
980 if (!Inst->hasNUsesOrMore(1)) {
981 ToBeDeleted.push_back(Inst);
982 continue;
983 }
984
David Neto22f144c2017-06-12 14:26:21 -0400985 Value *Src = Inst->getOperand(0);
David Neto8e138142018-05-29 10:19:21 -0400986 Type *SrcTy; // Original type
987 Type *DstTy; // Type that SrcTy is cast to.
988 unsigned SrcTyBitWidth;
989 unsigned DstTyBitWidth;
990
alan-baker1b13e8f2019-08-08 17:56:51 -0400991 bool BailOut = false;
David Neto8e138142018-05-29 10:19:21 -0400992 SrcTy = Src->getType()->getPointerElementType();
993 DstTy = Inst->getType()->getPointerElementType();
994 int iter_count = 0;
995 while (++iter_count) {
996 SrcTyBitWidth = unsigned(DL.getTypeStoreSizeInBits(SrcTy));
997 DstTyBitWidth = unsigned(DL.getTypeStoreSizeInBits(DstTy));
998#if 0
999 errs() << " Try Src " << *Src << "\n";
1000 errs() << " SrcTy elem " << *SrcTy << " bit width " << SrcTyBitWidth
1001 << "\n";
1002 errs() << " DstTy elem " << *DstTy << " bit width " << DstTyBitWidth
1003 << "\n";
1004#endif
1005
1006 // The normal case that we can handle is source type is smaller than
1007 // the dest type.
1008 if (SrcTyBitWidth <= DstTyBitWidth)
1009 break;
1010
1011 // The Source type is bigger than the destination type.
1012 // Walk into the source type to break it down.
1013 if (SrcTy->isArrayTy()) {
1014 // If it's an array, consider only the first element.
1015 Value *Zero = ConstantInt::get(Type::getInt32Ty(M.getContext()), 0);
Diego Novillo3cc8d7a2019-04-10 13:30:34 -04001016 Instruction *NewSrc =
1017 GetElementPtrInst::CreateInBounds(Src, {Zero, Zero});
alan-baker1b13e8f2019-08-08 17:56:51 -04001018 Changed = true;
David Neto8e138142018-05-29 10:19:21 -04001019 // errs() << "NewSrc is " << *NewSrc << "\n";
1020 if (auto *SrcInst = dyn_cast<Instruction>(Src)) {
1021 // errs() << " instruction case\n";
1022 NewSrc->insertAfter(SrcInst);
1023 } else {
1024 // Could be a parameter.
1025 auto where = Inst->getParent()
1026 ->getParent()
1027 ->getEntryBlock()
1028 .getFirstInsertionPt();
Diego Novillo3cc8d7a2019-04-10 13:30:34 -04001029 Instruction &whereInst = *where;
David Neto8e138142018-05-29 10:19:21 -04001030 // errs() << "insert " << *NewSrc << " before " << whereInst << "\n";
1031 NewSrc->insertBefore(&whereInst);
1032 }
1033 Src = NewSrc;
1034 SrcTy = Src->getType()->getPointerElementType();
1035 } else {
alan-baker1b13e8f2019-08-08 17:56:51 -04001036 BailOut = true;
1037 break;
David Neto8e138142018-05-29 10:19:21 -04001038 }
1039 if (iter_count > 1000) {
1040 llvm_unreachable("ReplacePointerBitcastPass: Too many iterations!");
1041 }
1042 };
1043#if 0
1044 errs() << " Src is " << *Src << "\n";
1045 errs() << " Dst is " << *Inst << "\n";
1046 errs() << " SrcTy elem " << *SrcTy << " bit width " << SrcTyBitWidth
1047 << "\n";
1048 errs() << " DstTy elem " << *DstTy << " bit width " << DstTyBitWidth
1049 << "\n";
1050#endif
David Neto22f144c2017-06-12 14:26:21 -04001051
alan-baker1b13e8f2019-08-08 17:56:51 -04001052 // Only dead code has been generated up to this point so it is safe to bail
1053 // out.
1054 if (BailOut) {
1055 continue;
1056 }
1057
David Neto22f144c2017-06-12 14:26:21 -04001058 for (User *BitCastUser : Inst->users()) {
1059 Value *NewAddrIdx = ConstantInt::get(Type::getInt32Ty(M.getContext()), 0);
1060 // It consist of User* and bool whether user is gep or not.
1061 SmallVector<std::pair<User *, bool>, 32> Users;
1062
1063 GetElementPtrInst *GEP = nullptr;
1064 Value *OrgGEPIdx = nullptr;
Jason Gavrise44af072018-08-14 20:44:50 -04001065 if ((GEP = dyn_cast<GetElementPtrInst>(BitCastUser))) {
David Neto22f144c2017-06-12 14:26:21 -04001066 IRBuilder<> Builder(GEP);
1067
1068 // Build new src/dst address.
1069 OrgGEPIdx = GEP->getOperand(1);
1070 NewAddrIdx = CalculateNewGEPIdx(SrcTyBitWidth, DstTyBitWidth, GEP);
1071
1072 // If bitcast's user is gep, investigate gep's users too.
1073 for (User *GEPUser : GEP->users()) {
1074 Users.push_back(std::make_pair(GEPUser, true));
1075 }
1076 } else {
1077 Users.push_back(std::make_pair(BitCastUser, false));
1078 }
1079
1080 // Handle users.
1081 bool IsGEPUser = false;
1082 for (auto UserIter : Users) {
1083 User *U = UserIter.first;
1084 IsGEPUser = UserIter.second;
1085
1086 IRBuilder<> Builder(cast<Instruction>(U));
1087
1088 // Handle store instruction with gep.
1089 if (StoreInst *ST = dyn_cast<StoreInst>(U)) {
Diego Novillo3cc8d7a2019-04-10 13:30:34 -04001090 // errs() << " store is " << *ST << "\n";
David Neto22f144c2017-06-12 14:26:21 -04001091 if (SrcTyBitWidth == DstTyBitWidth) {
alan-baker32014272019-05-22 08:07:18 -04001092 auto STVal = ConvertValue(ST->getValueOperand(), SrcTy, Builder);
David Neto22f144c2017-06-12 14:26:21 -04001093 Value *DstAddr = Builder.CreateGEP(Src, NewAddrIdx);
1094 Builder.CreateStore(STVal, DstAddr);
1095 } else if (SrcTyBitWidth < DstTyBitWidth) {
1096 unsigned NumElement = DstTyBitWidth / SrcTyBitWidth;
1097
David Neto22f144c2017-06-12 14:26:21 -04001098 // Create store values.
1099 Value *STVal = ST->getValueOperand();
1100 SmallVector<Value *, 8> STValues;
1101 for (unsigned i = 0; i < NumElement; i++) {
1102 Type *TmpTy = Type::getIntNTy(M.getContext(), DstTyBitWidth);
1103 Value *TmpVal = Builder.CreateBitCast(STVal, TmpTy);
James Price51952282020-02-14 09:41:11 -05001104 TmpVal = Builder.CreateLShr(
1105 TmpVal, Builder.getIntN(DstTyBitWidth, i * SrcTyBitWidth));
David Neto22f144c2017-06-12 14:26:21 -04001106 TmpVal = Builder.CreateTrunc(TmpVal, SrcTy);
1107 STValues.push_back(TmpVal);
1108 }
1109
1110 // Generate stores.
1111 Value *SrcAddrIdx = NewAddrIdx;
1112 Value *BaseAddr = Src;
1113 for (unsigned i = 0; i < NumElement; i++) {
1114 // Calculate store address.
1115 Value *DstAddr = Builder.CreateGEP(BaseAddr, SrcAddrIdx);
1116 Builder.CreateStore(STValues[i], DstAddr);
1117
1118 if (i + 1 < NumElement) {
1119 // Calculate next store address
1120 SrcAddrIdx = Builder.CreateAdd(SrcAddrIdx, Builder.getInt32(1));
1121 }
1122 }
1123
1124 } else {
1125 Inst->print(errs());
1126 llvm_unreachable("Handle different size store with scalar "
1127 "bitcast on ReplacePointerBitcastPass");
1128 }
1129 } else if (LoadInst *LD = dyn_cast<LoadInst>(U)) {
1130 if (SrcTyBitWidth == DstTyBitWidth) {
1131 Value *SrcAddr = Builder.CreateGEP(Src, NewAddrIdx);
1132 LoadInst *SrcVal = Builder.CreateLoad(SrcAddr, "src_val");
alan-baker32014272019-05-22 08:07:18 -04001133 LD->replaceAllUsesWith(ConvertValue(SrcVal, DstTy, Builder));
David Neto22f144c2017-06-12 14:26:21 -04001134 } else if (SrcTyBitWidth < DstTyBitWidth) {
1135 Value *SrcAddrIdx = NewAddrIdx;
1136
1137 // Load value from src.
1138 unsigned NumIter = CalculateNumIter(SrcTyBitWidth, DstTyBitWidth);
1139 SmallVector<Value *, 8> LDValues;
1140 for (unsigned i = 1; i <= NumIter; i++) {
1141 Value *SrcAddr = Builder.CreateGEP(Src, SrcAddrIdx);
1142 LoadInst *SrcVal = Builder.CreateLoad(SrcAddr, "src_val");
1143 LDValues.push_back(SrcVal);
1144
1145 if (i + 1 <= NumIter) {
1146 // Calculate next SrcAddrIdx.
1147 SrcAddrIdx = Builder.CreateAdd(SrcAddrIdx, Builder.getInt32(1));
1148 }
1149 }
1150
1151 // Merge Load.
1152 Type *TmpSrcTy = Type::getIntNTy(M.getContext(), SrcTyBitWidth);
1153 Value *DstVal = Builder.CreateBitCast(LDValues[0], TmpSrcTy);
1154 Type *TmpDstTy = Type::getIntNTy(M.getContext(), DstTyBitWidth);
1155 DstVal = Builder.CreateZExt(DstVal, TmpDstTy);
1156 for (unsigned i = 1; i < LDValues.size(); i++) {
1157 Value *TmpVal = Builder.CreateBitCast(LDValues[i], TmpSrcTy);
1158 TmpVal = Builder.CreateZExt(TmpVal, TmpDstTy);
Kévin Petit0c9cd042020-04-06 17:32:41 +01001159 TmpVal = Builder.CreateShl(
1160 TmpVal, Builder.getIntN(DstTyBitWidth, i * SrcTyBitWidth));
David Neto22f144c2017-06-12 14:26:21 -04001161 DstVal = Builder.CreateOr(DstVal, TmpVal);
1162 }
1163
1164 DstVal = Builder.CreateBitCast(DstVal, DstTy);
1165 LD->replaceAllUsesWith(DstVal);
1166
1167 } else {
1168 Inst->print(errs());
1169 llvm_unreachable("Handle different size load with scalar "
1170 "bitcast on ReplacePointerBitcastPass");
1171 }
1172 } else {
David Neto22f144c2017-06-12 14:26:21 -04001173 Inst->print(errs());
1174 llvm_unreachable("Handle above user of scalar bitcast with gep on "
1175 "ReplacePointerBitcastPass");
1176 }
1177
1178 ToBeDeleted.push_back(cast<Instruction>(U));
1179 }
1180
1181 if (IsGEPUser) {
1182 ToBeDeleted.push_back(GEP);
1183 }
1184 }
1185
1186 ToBeDeleted.push_back(Inst);
1187 }
1188
1189 for (Instruction *Inst : ToBeDeleted) {
1190 Inst->eraseFromParent();
1191 }
1192
1193 return Changed;
1194}