blob: 6ec17354a75aad15991df1a8f7a76cf49bc2bb35 [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)) {
alan-baker5a8c3be2020-09-09 13:44:26 -040064 for (uint64_t i = 0; i != vec_type->getElementCount().getKnownMinValue();
65 ++i) {
alan-baker32014272019-05-22 08:07:18 -040066 elements->push_back(builder.CreateExtractElement(v, i));
67 }
68 } else if (auto *array_type = dyn_cast<ArrayType>(type)) {
69 for (uint64_t i = 0; i != array_type->getNumElements(); ++i) {
70 auto *extract = builder.CreateExtractValue(v, {static_cast<unsigned>(i)});
71 GatherBaseElements(extract, elements, builder);
72 }
73 } else if (auto *struct_type = dyn_cast<StructType>(type)) {
74 const auto *struct_layout = DL.getStructLayout(struct_type);
75 if (struct_layout->hasPadding()) {
76 llvm_unreachable("Unhandled conversion of padded struct");
77 }
78 for (unsigned i = 0; i != struct_type->getNumElements(); ++i) {
79 auto *extract = builder.CreateExtractValue(v, {i});
80 GatherBaseElements(extract, elements, builder);
81 }
82 } else {
83 elements->push_back(v);
84 }
85}
86
87// Returns a value of |dst_type| using the elemental members of |src_elements|.
88Value *BuildFromElements(Type *dst_type, const ArrayRef<Value *> &src_elements,
89 unsigned *used_bits, unsigned *index,
90 IRBuilder<> &builder) {
91 auto *module = builder.GetInsertBlock()->getParent()->getParent();
92 auto &DL = module->getDataLayout();
93 auto &context = dst_type->getContext();
94 Value *dst = nullptr;
95 // Arrays, vectors and structs are annoyingly just different enough to each
96 // require their own cases.
97 if (auto *dst_array_ty = dyn_cast<ArrayType>(dst_type)) {
98 auto *ele_ty = dst_array_ty->getElementType();
99 for (uint64_t i = 0; i != dst_array_ty->getNumElements(); ++i) {
100 auto *tmp_value =
101 BuildFromElements(ele_ty, src_elements, used_bits, index, builder);
102 auto *prev = dst ? dst : UndefValue::get(dst_type);
103 dst = builder.CreateInsertValue(prev, tmp_value,
104 {static_cast<unsigned>(i)});
105 }
106 } else if (auto *dst_struct_ty = dyn_cast<StructType>(dst_type)) {
107 const auto *struct_layout = DL.getStructLayout(dst_struct_ty);
108 if (struct_layout->hasPadding()) {
109 llvm_unreachable("Unhandled padded struct conversion");
110 return nullptr;
111 }
112 for (unsigned i = 0; i != dst_struct_ty->getNumElements(); ++i) {
113 auto *ele_ty = dst_struct_ty->getElementType(i);
114 auto *tmp_value =
115 BuildFromElements(ele_ty, src_elements, used_bits, index, builder);
116 auto *prev = dst ? dst : UndefValue::get(dst_type);
117 dst = builder.CreateInsertValue(prev, tmp_value, {i});
118 }
119 } else if (auto *dst_vec_ty = dyn_cast<VectorType>(dst_type)) {
120 auto *ele_ty = dst_vec_ty->getElementType();
alan-baker5a8c3be2020-09-09 13:44:26 -0400121 for (uint64_t i = 0; i != dst_vec_ty->getElementCount().getKnownMinValue();
122 ++i) {
alan-baker32014272019-05-22 08:07:18 -0400123 auto *tmp_value =
124 BuildFromElements(ele_ty, src_elements, used_bits, index, builder);
125 auto *prev = dst ? dst : UndefValue::get(dst_type);
126 dst = builder.CreateInsertElement(prev, tmp_value, i);
127 }
128 } else {
129 // Scalar conversion eats up elements in src_elements.
130 auto dst_width = DL.getTypeStoreSizeInBits(dst_type);
131 uint64_t bits = 0;
132 Value *tmp_value = nullptr;
133 auto prev_bits = 0;
134 Value *ele_int_cast = nullptr;
135 while (bits < dst_width) {
136 prev_bits = bits;
137 auto *ele = src_elements[*index];
138 auto *ele_ty = ele->getType();
139 auto ele_width = DL.getTypeStoreSizeInBits(ele_ty);
140 auto remaining_bits = ele_width - *used_bits;
141 auto needed_bits = dst_width - bits;
142 // Create a reusable cast to an integer type for this element.
143 if (!ele_int_cast || cast<User>(ele_int_cast)->getOperand(0) != ele) {
144 ele_int_cast =
145 builder.CreateBitCast(ele, IntegerType::get(context, ele_width));
146 }
147 tmp_value = ele_int_cast;
148 // Some of the bits of this element were previously used, so shift the
149 // value that many bits.
150 if (*used_bits != 0) {
151 tmp_value = builder.CreateLShr(tmp_value, *used_bits);
152 }
153 if (needed_bits < remaining_bits) {
154 // Ensure only the needed bits are used.
155 uint64_t mask = (1ull << needed_bits) - 1;
156 tmp_value =
157 builder.CreateAnd(tmp_value, builder.getIntN(dst_width, mask));
158 }
159 // Cast to tbe destination bit width, but stay as a integer type.
160 if (ele_width != dst_width) {
161 tmp_value = builder.CreateIntCast(
162 tmp_value, IntegerType::get(context, dst_width), false);
163 }
164
165 if (remaining_bits <= needed_bits) {
166 // Used the rest of the element.
167 *used_bits = 0;
168 ++(*index);
169 bits += remaining_bits;
170 } else {
171 // Only need part of this element.
172 *used_bits += needed_bits;
173 bits += needed_bits;
174 }
175
176 if (dst) {
177 // Previous iteration generated an integer of the right size. That needs
178 // to be combined with the value generated this iteration.
179 tmp_value = builder.CreateShl(tmp_value, prev_bits);
180 dst = builder.CreateOr(dst, tmp_value);
181 } else {
182 dst = tmp_value;
183 }
184 }
185
186 assert(bits <= dst_width);
187 if (bits == dst_width && dst_type != dst->getType()) {
188 // Finally, cast away from the working integer type if necessary.
189 dst = builder.CreateBitCast(dst, dst_type);
190 }
191 }
192
193 return dst;
194}
195
196// Returns an equivalent value of |src| as |dst_type|.
197//
198// This function requires |src|'s and |dst_type|'s bit widths match. Does not
199// introduce new integer sizes, but generates multiple instructions to mimic a
200// generic bitcast (unless a bitcast is sufficient).
201Value *ConvertValue(Value *src, Type *dst_type, IRBuilder<> &builder) {
202 auto *src_type = src->getType();
203 auto *module = builder.GetInsertBlock()->getParent()->getParent();
204 auto &DL = module->getDataLayout();
205 if (!src_type->isFirstClassType() || !dst_type->isFirstClassType() ||
206 src_type->isAggregateType() || dst_type->isAggregateType()) {
207 SmallVector<Value *, 8> src_elements;
208 if (src_type->isAggregateType()) {
209 GatherBaseElements(src, &src_elements, builder);
210 } else {
211 src_elements.push_back(src);
212 }
213
214 // Check that overall sizes make sense.
215 uint64_t element_sum = 0;
216 // Can only successfully convert unpadded structs.
217 for (auto element : src_elements) {
218 element_sum += DL.getTypeStoreSizeInBits(element->getType());
219 }
220 if (DL.getTypeStoreSizeInBits(dst_type) != element_sum) {
221 llvm_unreachable("Elements do not sum to overall size");
222 return nullptr;
223 }
224
225 unsigned used_bits = 0;
226 unsigned index = 0;
227 return BuildFromElements(dst_type, src_elements, &used_bits, &index,
228 builder);
229 } else {
230 return builder.CreateBitCast(src, dst_type);
231 }
232
233 return nullptr;
234}
235
236} // namespace
237
David Neto22f144c2017-06-12 14:26:21 -0400238unsigned ReplacePointerBitcastPass::CalculateNumIter(unsigned SrcTyBitWidth,
239 unsigned DstTyBitWidth) {
240 unsigned NumIter = 0;
241 if (SrcTyBitWidth > DstTyBitWidth) {
242 if (SrcTyBitWidth % DstTyBitWidth) {
243 llvm_unreachable(
244 "Src type bitwidth should be multiple of Dest type bitwidth");
245 }
246 NumIter = 1;
247 } else if (SrcTyBitWidth < DstTyBitWidth) {
248 if (DstTyBitWidth % SrcTyBitWidth) {
249 llvm_unreachable(
250 "Dest type bitwidth should be multiple of Src type bitwidth");
251 }
252 NumIter = DstTyBitWidth / SrcTyBitWidth;
253 } else {
254 NumIter = 0;
255 }
256
257 return NumIter;
258}
259
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400260Value *ReplacePointerBitcastPass::CalculateNewGEPIdx(unsigned SrcTyBitWidth,
261 unsigned DstTyBitWidth,
262 GetElementPtrInst *GEP) {
David Neto22f144c2017-06-12 14:26:21 -0400263 Value *NewGEPIdx = GEP->getOperand(1);
264 IRBuilder<> Builder(GEP);
265
266 if (SrcTyBitWidth > DstTyBitWidth) {
267 if (GEP->getNumOperands() > 2) {
268 GEP->print(errs());
269 llvm_unreachable("Support above GEP on PointerBitcastPass");
270 }
271
272 NewGEPIdx = Builder.CreateLShr(
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400273 NewGEPIdx, Builder.getInt32(std::log2(SrcTyBitWidth / DstTyBitWidth)));
David Neto22f144c2017-06-12 14:26:21 -0400274 } else if (DstTyBitWidth > SrcTyBitWidth) {
275 if (GEP->getNumOperands() > 2) {
276 GEP->print(errs());
277 llvm_unreachable("Support above GEP on PointerBitcastPass");
278 }
279
280 NewGEPIdx = Builder.CreateShl(
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400281 NewGEPIdx, Builder.getInt32(std::log2(DstTyBitWidth / SrcTyBitWidth)));
David Neto22f144c2017-06-12 14:26:21 -0400282 }
283
284 return NewGEPIdx;
285}
286
287bool ReplacePointerBitcastPass::runOnModule(Module &M) {
288 bool Changed = false;
289
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400290 const DataLayout &DL = M.getDataLayout();
David Neto8e138142018-05-29 10:19:21 -0400291
alan-bakerad1a12f2020-08-25 09:18:38 -0400292 SmallVector<Instruction *, 16> ToBeDeleted;
David Neto22f144c2017-06-12 14:26:21 -0400293 SmallVector<Instruction *, 16> VectorWorkList;
294 SmallVector<Instruction *, 16> ScalarWorkList;
alan-baker1b13e8f2019-08-08 17:56:51 -0400295 SmallVector<User *, 16> UserWorkList;
David Neto22f144c2017-06-12 14:26:21 -0400296 for (Function &F : M) {
297 for (BasicBlock &BB : F) {
298 for (Instruction &I : BB) {
299 // Find pointer bitcast instruction.
300 if (isa<BitCastInst>(&I) && isa<PointerType>(I.getType())) {
301 Value *Src = I.getOperand(0);
302 if (isa<PointerType>(Src->getType())) {
alan-baker1b13e8f2019-08-08 17:56:51 -0400303 // Check if this bitcast is one that can be handled during this run
304 // of the pass. If not, just skip it and don't make changes to the
305 // module. These checks are coarse level checks that only the right
306 // instructions appear. Rejected bitcasts might be able to be
307 // handled later in the flow after further optimization.
308 UserWorkList.clear();
309 for (auto User : I.users()) {
310 UserWorkList.push_back(User);
311 }
312 bool ok = true;
313 while (!UserWorkList.empty()) {
314 auto User = UserWorkList.back();
315 UserWorkList.pop_back();
316
317 if (isa<GetElementPtrInst>(User)) {
318 for (auto GEPUser : User->users()) {
319 UserWorkList.push_back(GEPUser);
320 }
321 } else if (!isa<StoreInst>(User) && !isa<LoadInst>(User)) {
322 // Cannot handle this bitcast.
323 ok = false;
324 break;
325 }
326 }
327 if (!ok) {
328 continue;
329 }
330
alan-bakerad1a12f2020-08-25 09:18:38 -0400331 auto inst = &I;
David Neto22f144c2017-06-12 14:26:21 -0400332 Type *SrcEleTy =
alan-bakerad1a12f2020-08-25 09:18:38 -0400333 inst->getOperand(0)->getType()->getPointerElementType();
334
335 // De-"canonicalize" the input pointer.
336 // If Src is an array, LLVM has likely canonicalized all GEPs to
337 // the first element away as the following addresses are all
338 // equivalent:
339 // * %in = alloca [4 x [4 x float]]
340 // * %gep0 = getelementptr [4 x [4 x float]]*, [4 x [4 x [float]]*
341 // %in
342 // * %gep1 = getelementptr [4 x [4 x float]]*, [4 x [4 x [float]]*
343 // %in, i32 0
344 // * %gep2 = getelementptr [4 x [4 x float]]*, [4 x [4 x [float]]*
345 // %in, i32 0, i32 0
346 // * %gep3 = getelementptr [4 x [4 x float]]*, [4 x [4 x [float]]*
347 // %in, i32 0, i32 0, i32 0
348 //
349 // Note: count initialized to 1 to account for the first gep index.
350 uint32_t count = 1;
351 while (auto ArrayTy = dyn_cast<ArrayType>(SrcEleTy)) {
352 ++count;
353 SrcEleTy = ArrayTy->getElementType();
354 }
355
356 if (count > 1) {
357 // Create a cast of the pointer. Replace the original cast with
358 // it and mark the original cast for deletion.
359 SmallVector<Value *, 4> indices(
360 count,
361 ConstantInt::get(IntegerType::get(M.getContext(), 32), 0));
362 auto gep = GetElementPtrInst::CreateInBounds(inst->getOperand(0),
363 indices, "", inst);
364 ToBeDeleted.push_back(&I);
365 auto cast = new BitCastInst(gep, inst->getType(), "", inst);
366 inst->replaceAllUsesWith(cast);
367 inst = cast;
368 }
369
370 Type *DstEleTy = inst->getType()->getPointerElementType();
David Neto22f144c2017-06-12 14:26:21 -0400371 if (SrcEleTy->isVectorTy() || DstEleTy->isVectorTy()) {
372 // Handle case either operand is vector type like char4* -> int4*.
alan-bakerad1a12f2020-08-25 09:18:38 -0400373 VectorWorkList.push_back(inst);
David Neto22f144c2017-06-12 14:26:21 -0400374 } else {
375 // Handle case all operands are scalar type like char* -> int*.
alan-bakerad1a12f2020-08-25 09:18:38 -0400376 ScalarWorkList.push_back(inst);
David Neto22f144c2017-06-12 14:26:21 -0400377 }
378
379 Changed = true;
380 } else {
381 llvm_unreachable("Unsupported bitcast");
382 }
383 }
384 }
385 }
386 }
387
David Neto22f144c2017-06-12 14:26:21 -0400388 for (Instruction *Inst : VectorWorkList) {
389 Value *Src = Inst->getOperand(0);
390 Type *SrcTy = Src->getType()->getPointerElementType();
391 Type *DstTy = Inst->getType()->getPointerElementType();
James Pricecf53df42020-04-20 14:41:24 -0400392 VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy);
393 VectorType *DstVecTy = dyn_cast<VectorType>(DstTy);
394 Type *SrcEleTy = SrcTy->isVectorTy() ? SrcVecTy->getElementType() : SrcTy;
395 Type *DstEleTy = DstTy->isVectorTy() ? DstVecTy->getElementType() : DstTy;
David Neto30ae05e2017-09-06 19:58:36 -0400396 // These are bit widths of the source and destination types, even
alan-bakerad1a12f2020-08-25 09:18:38 -0400397 // if they are vector types. E.g. bit width of float4 is 128.
David Neto8e138142018-05-29 10:19:21 -0400398 unsigned SrcTyBitWidth = DL.getTypeStoreSizeInBits(SrcTy);
399 unsigned DstTyBitWidth = DL.getTypeStoreSizeInBits(DstTy);
400 unsigned SrcEleTyBitWidth = DL.getTypeStoreSizeInBits(SrcEleTy);
401 unsigned DstEleTyBitWidth = DL.getTypeStoreSizeInBits(DstEleTy);
David Neto22f144c2017-06-12 14:26:21 -0400402 unsigned NumIter = CalculateNumIter(SrcTyBitWidth, DstTyBitWidth);
403
404 // Investigate pointer bitcast's users.
405 for (User *BitCastUser : Inst->users()) {
406 Value *BitCastSrc = Inst->getOperand(0);
407 Value *NewAddrIdx = ConstantInt::get(Type::getInt32Ty(M.getContext()), 0);
408
409 // It consist of User* and bool whether user is gep or not.
410 SmallVector<std::pair<User *, bool>, 32> Users;
411
412 GetElementPtrInst *GEP = nullptr;
413 Value *OrgGEPIdx = nullptr;
Jason Gavrise44af072018-08-14 20:44:50 -0400414 if ((GEP = dyn_cast<GetElementPtrInst>(BitCastUser))) {
David Neto22f144c2017-06-12 14:26:21 -0400415 OrgGEPIdx = GEP->getOperand(1);
416
417 // Build new src/dst address index.
418 NewAddrIdx = CalculateNewGEPIdx(SrcTyBitWidth, DstTyBitWidth, GEP);
419
420 // Record gep's users.
421 for (User *GEPUser : GEP->users()) {
422 Users.push_back(std::make_pair(GEPUser, true));
423 }
424 } else {
425 // Record bitcast's users.
426 Users.push_back(std::make_pair(BitCastUser, false));
427 }
428
429 // Handle users.
430 bool IsGEPUser = false;
431 for (auto UserIter : Users) {
432 User *U = UserIter.first;
433 IsGEPUser = UserIter.second;
434
435 IRBuilder<> Builder(cast<Instruction>(U));
436
437 if (StoreInst *ST = dyn_cast<StoreInst>(U)) {
438 if (SrcTyBitWidth < DstTyBitWidth) {
439 //
440 // Consider below case.
441 //
442 // Original IR (float2* --> float4*)
443 // 1. val = load (float4*) src_addr
444 // 2. dst_addr = bitcast float2*, float4*
445 // 3. dst_addr = gep (float4*) dst_addr, idx
446 // 4. store (float4*) dst_addr
447 //
448 // Transformed IR
449 // 1. val(float4) = load (float4*) src_addr
450 // 2. val1(float2) = shufflevector (float4)val, (float4)undef,
451 // (float2)<0, 1>
452 // 3. val2(float2) = shufflevector (float4)val, (float4)undef,
453 // (float2)<2, 3>
454 // 4. dst_addr1(float2*) = gep (float2*)dst_addr, idx * 2
455 // 5. dst_addr2(float2*) = gep (float2*)dst_addr, idx * 2 + 1
456 // 6. store (float2)val1, (float2*)dst_addr1
457 // 7. store (float2)val2, (float2*)dst_addr2
458 //
459
460 unsigned NumElement = DstTyBitWidth / SrcTyBitWidth;
461 unsigned NumVector = 1;
462 // Vulkan SPIR-V does not support over 4 components for
463 // TypeVector.
464 if (NumElement > 4) {
465 NumVector = NumElement >> 2;
466 NumElement = 4;
467 }
468
469 // Create store values.
470 Type *TmpValTy = SrcTy;
471 if (DstTy->isVectorTy()) {
472 if (SrcEleTyBitWidth == DstEleTyBitWidth) {
alan-baker5a8c3be2020-09-09 13:44:26 -0400473 TmpValTy = FixedVectorType::get(
474 SrcEleTy, DstVecTy->getElementCount().getKnownMinValue());
David Neto22f144c2017-06-12 14:26:21 -0400475 } else {
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400476 TmpValTy = FixedVectorType::get(SrcEleTy, NumElement);
David Neto22f144c2017-06-12 14:26:21 -0400477 }
478 }
479
480 Value *STVal = ST->getValueOperand();
481 for (unsigned VIdx = 0; VIdx < NumVector; VIdx++) {
482 Value *TmpSTVal = nullptr;
483 if (NumVector == 1) {
484 TmpSTVal = Builder.CreateBitCast(STVal, TmpValTy);
485 } else {
486 unsigned DstVecTyNumElement =
alan-baker5a8c3be2020-09-09 13:44:26 -0400487 DstVecTy->getElementCount().getKnownMinValue() / NumVector;
alan-baker4a757f62020-04-22 08:17:49 -0400488 SmallVector<int32_t, 4> Idxs;
489 for (int i = 0; i < DstVecTyNumElement; i++) {
David Neto22f144c2017-06-12 14:26:21 -0400490 Idxs.push_back(i + (DstVecTyNumElement * VIdx));
491 }
492 Value *UndefVal = UndefValue::get(DstTy);
493 TmpSTVal = Builder.CreateShuffleVector(STVal, UndefVal, Idxs);
494 TmpSTVal = Builder.CreateBitCast(TmpSTVal, TmpValTy);
495 }
496
497 SmallVector<Value *, 8> STValues;
498 if (!SrcTy->isVectorTy()) {
499 // Handle scalar type.
500 for (unsigned i = 0; i < NumElement; i++) {
501 Value *TmpVal = Builder.CreateExtractElement(
502 TmpSTVal, Builder.getInt32(i));
503 STValues.push_back(TmpVal);
504 }
505 } else {
506 // Handle vector type.
alan-baker5a8c3be2020-09-09 13:44:26 -0400507 unsigned SrcNumElement =
508 SrcVecTy->getElementCount().getKnownMinValue();
509 unsigned DstNumElement =
510 DstVecTy->getElementCount().getKnownMinValue();
David Neto22f144c2017-06-12 14:26:21 -0400511 for (unsigned i = 0; i < NumElement; i++) {
alan-baker4a757f62020-04-22 08:17:49 -0400512 SmallVector<int32_t, 4> Idxs;
513 for (int j = 0; j < SrcNumElement; j++) {
David Neto22f144c2017-06-12 14:26:21 -0400514 Idxs.push_back(i * SrcNumElement + j);
515 }
516
517 VectorType *TmpVecTy =
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400518 FixedVectorType::get(SrcEleTy, DstNumElement);
David Neto22f144c2017-06-12 14:26:21 -0400519 Value *UndefVal = UndefValue::get(TmpVecTy);
520 Value *TmpVal =
521 Builder.CreateShuffleVector(TmpSTVal, UndefVal, Idxs);
522 STValues.push_back(TmpVal);
523 }
524 }
525
526 // Generate stores.
527 Value *SrcAddrIdx = NewAddrIdx;
528 Value *BaseAddr = BitCastSrc;
529 for (unsigned i = 0; i < NumElement; i++) {
530 // Calculate store address.
531 Value *DstAddr = Builder.CreateGEP(BaseAddr, SrcAddrIdx);
532 Builder.CreateStore(STValues[i], DstAddr);
533
534 if (i + 1 < NumElement) {
535 // Calculate next store address
536 SrcAddrIdx =
537 Builder.CreateAdd(SrcAddrIdx, Builder.getInt32(1));
538 }
539 }
540 }
541 } else if (SrcTyBitWidth > DstTyBitWidth) {
542 //
543 // Consider below case.
544 //
545 // Original IR (float4* --> float2*)
546 // 1. val = load (float2*) src_addr
547 // 2. dst_addr = bitcast float4*, float2*
548 // 3. dst_addr = gep (float2*) dst_addr, idx
549 // 4. store (float2) val, (float2*) dst_addr
550 //
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400551 // Transformed IR: Decompose the source vector into elements, then
552 // write them one at a time.
David Neto22f144c2017-06-12 14:26:21 -0400553 // 1. val = load (float2*) src_addr
554 // 2. val1 = (float)extract_element val, 0
555 // 3. val2 = (float)extract_element val, 1
David Neto30ae05e2017-09-06 19:58:36 -0400556 // // Source component k maps to destination component k * idxscale
557 // 3a. idxscale = sizeof(float4)/sizeof(float2)
558 // 3b. idxbase = idx / idxscale
559 // 3c. newarrayidx = idxbase * idxscale
560 // 4. dst_addr1 = gep (float4*) dst, newarrayidx
561 // 5. dst_addr2 = gep (float4*) dst, newarrayidx + 1
David Neto22f144c2017-06-12 14:26:21 -0400562 // 6. store (float)val1, (float*) dst_addr1
563 // 7. store (float)val2, (float*) dst_addr2
564 //
565
566 if (SrcTyBitWidth <= DstEleTyBitWidth) {
567 SrcTy->print(errs());
568 DstTy->print(errs());
569 llvm_unreachable("Handle above src/dst type.");
570 }
571
572 // Create store values.
573 Value *STVal = ST->getValueOperand();
574
575 if (DstTy->isVectorTy() && (SrcEleTyBitWidth != DstTyBitWidth)) {
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400576 VectorType *TmpVecTy = FixedVectorType::get(
577 SrcEleTy, DstTyBitWidth / SrcEleTyBitWidth);
David Neto22f144c2017-06-12 14:26:21 -0400578 STVal = Builder.CreateBitCast(STVal, TmpVecTy);
579 }
580
581 SmallVector<Value *, 8> STValues;
David Neto30ae05e2017-09-06 19:58:36 -0400582 // How many destination writes are required?
David Neto22f144c2017-06-12 14:26:21 -0400583 unsigned DstNumElement = 1;
584 if (!DstTy->isVectorTy() || SrcEleTyBitWidth == DstTyBitWidth) {
585 // Handle scalar type.
586 STValues.push_back(STVal);
587 } else {
588 // Handle vector type.
alan-baker5a8c3be2020-09-09 13:44:26 -0400589 DstNumElement = DstVecTy->getElementCount().getKnownMinValue();
David Neto22f144c2017-06-12 14:26:21 -0400590 for (unsigned i = 0; i < DstNumElement; i++) {
591 Value *Idx = Builder.getInt32(i);
592 Value *TmpVal = Builder.CreateExtractElement(STVal, Idx);
593 STValues.push_back(TmpVal);
594 }
595 }
596
597 // Generate stores.
598 Value *BaseAddr = BitCastSrc;
599 Value *SubEleIdx = Builder.getInt32(0);
600 if (IsGEPUser) {
David Neto30ae05e2017-09-06 19:58:36 -0400601 // Compute SubNumElement = idxscale
alan-baker5a8c3be2020-09-09 13:44:26 -0400602 unsigned SubNumElement =
603 SrcVecTy->getElementCount().getKnownMinValue();
David Neto22f144c2017-06-12 14:26:21 -0400604 if (DstTy->isVectorTy() && (SrcEleTyBitWidth != DstTyBitWidth)) {
David Neto30ae05e2017-09-06 19:58:36 -0400605 // Same condition under which DstNumElements > 1
alan-baker5a8c3be2020-09-09 13:44:26 -0400606 SubNumElement = SrcVecTy->getElementCount().getKnownMinValue() /
607 DstVecTy->getElementCount().getKnownMinValue();
David Neto22f144c2017-06-12 14:26:21 -0400608 }
609
David Neto30ae05e2017-09-06 19:58:36 -0400610 // Compute SubEleIdx = idxbase * idxscale
David Neto22f144c2017-06-12 14:26:21 -0400611 SubEleIdx = Builder.CreateAnd(
612 OrgGEPIdx, Builder.getInt32(SubNumElement - 1));
David Neto30ae05e2017-09-06 19:58:36 -0400613 if (DstTy->isVectorTy() && (SrcEleTyBitWidth != DstTyBitWidth)) {
614 SubEleIdx = Builder.CreateShl(
615 SubEleIdx, Builder.getInt32(std::log2(SubNumElement)));
616 }
David Neto22f144c2017-06-12 14:26:21 -0400617 }
618
619 for (unsigned i = 0; i < DstNumElement; i++) {
620 // Calculate address.
621 if (i > 0) {
622 SubEleIdx = Builder.CreateAdd(SubEleIdx, Builder.getInt32(i));
623 }
624
625 Value *Idxs[] = {NewAddrIdx, SubEleIdx};
626 Value *DstAddr = Builder.CreateGEP(BaseAddr, Idxs);
627 Type *TmpSrcTy = SrcEleTy;
James Pricecf53df42020-04-20 14:41:24 -0400628 if (auto TmpSrcVecTy = dyn_cast<VectorType>(TmpSrcTy)) {
629 TmpSrcTy = TmpSrcVecTy->getElementType();
David Neto22f144c2017-06-12 14:26:21 -0400630 }
631 Value *TmpVal = Builder.CreateBitCast(STValues[i], TmpSrcTy);
632
633 Builder.CreateStore(TmpVal, DstAddr);
634 }
635 } else {
636 // if SrcTyBitWidth == DstTyBitWidth
637 Type *TmpSrcTy = SrcTy;
638 Value *DstAddr = Src;
639
640 if (IsGEPUser) {
641 SmallVector<Value *, 4> Idxs;
642 for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
643 Idxs.push_back(GEP->getOperand(i));
644 }
645 DstAddr = Builder.CreateGEP(BitCastSrc, Idxs);
646
647 if (GEP->getNumOperands() > 2) {
648 TmpSrcTy = SrcEleTy;
649 }
650 }
651
652 Value *TmpVal =
653 Builder.CreateBitCast(ST->getValueOperand(), TmpSrcTy);
654 Builder.CreateStore(TmpVal, DstAddr);
655 }
656 } else if (LoadInst *LD = dyn_cast<LoadInst>(U)) {
657 Value *SrcAddrIdx = Builder.getInt32(0);
658 if (IsGEPUser) {
659 SrcAddrIdx = NewAddrIdx;
660 }
661
662 // Load value from src.
663 SmallVector<Value *, 8> LDValues;
664
665 for (unsigned i = 1; i <= NumIter; i++) {
666 Value *SrcAddr = Builder.CreateGEP(Src, SrcAddrIdx);
667 LoadInst *SrcVal = Builder.CreateLoad(SrcAddr, "src_val");
668 LDValues.push_back(SrcVal);
669
670 if (i + 1 <= NumIter) {
671 // Calculate next SrcAddrIdx.
672 SrcAddrIdx = Builder.CreateAdd(SrcAddrIdx, Builder.getInt32(1));
673 }
674 }
675
676 Value *DstVal = nullptr;
677 if (SrcTyBitWidth > DstTyBitWidth) {
678 unsigned NumElement = SrcTyBitWidth / DstTyBitWidth;
679
680 if (SrcEleTyBitWidth == DstTyBitWidth) {
681 //
682 // Consider below case.
683 //
684 // Original IR (int4* --> char4*)
685 // 1. src_addr = bitcast int4*, char4*
686 // 2. element_addr = gep (char4*) src_addr, idx
687 // 3. load (char4*) element_addr
688 //
689 // Transformed IR
690 // 1. src_addr = gep (int4*) src, idx / 4
691 // 2. src_val(int4) = load (int4*) src_addr
692 // 3. tmp_val(int4) = extractelement src_val, idx % 4
693 // 4. dst_val(char4) = bitcast tmp_val, (char4)
694 //
695 Value *EleIdx = Builder.getInt32(0);
696 if (IsGEPUser) {
697 EleIdx = Builder.CreateAnd(OrgGEPIdx,
698 Builder.getInt32(NumElement - 1));
699 }
700 Value *TmpVal =
701 Builder.CreateExtractElement(LDValues[0], EleIdx, "tmp_val");
702 DstVal = Builder.CreateBitCast(TmpVal, DstTy);
703 } else if (SrcEleTyBitWidth < DstTyBitWidth) {
704 if (IsGEPUser) {
705 //
706 // Consider below case.
707 //
708 // Original IR (float4* --> float2*)
709 // 1. src_addr = bitcast float4*, float2*
710 // 2. element_addr = gep (float2*) src_addr, idx
711 // 3. load (float2*) element_addr
712 //
713 // Transformed IR
714 // 1. src_addr = gep (float4*) src, idx / 2
715 // 2. src_val(float4) = load (float4*) src_addr
716 // 3. tmp_val1(float) = extractelement (idx % 2) * 2
717 // 4. tmp_val2(float) = extractelement (idx % 2) * 2 + 1
718 // 5. dst_val(float2) = insertelement undef(float2), tmp_val1, 0
719 // 6. dst_val(float2) = insertelement undef(float2), tmp_val2, 1
720 // 7. dst_val(float2) = bitcast dst_val, (float2)
721 // ==> if types are same between src and dst, it will be
722 // igonored
723 //
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400724 VectorType *TmpVecTy = FixedVectorType::get(
725 SrcEleTy, DstTyBitWidth / SrcEleTyBitWidth);
David Neto22f144c2017-06-12 14:26:21 -0400726 DstVal = UndefValue::get(TmpVecTy);
727 Value *EleIdx = Builder.CreateAnd(
728 OrgGEPIdx, Builder.getInt32(NumElement - 1));
729 EleIdx = Builder.CreateShl(
730 EleIdx, Builder.getInt32(
731 std::log2(DstTyBitWidth / SrcEleTyBitWidth)));
732 Value *TmpOrgGEPIdx = EleIdx;
733 for (unsigned i = 0; i < NumElement; i++) {
734 Value *TmpVal = Builder.CreateExtractElement(
735 LDValues[0], TmpOrgGEPIdx, "tmp_val");
736 DstVal = Builder.CreateInsertElement(DstVal, TmpVal,
737 Builder.getInt32(i));
738
739 if (i + 1 < NumElement) {
740 TmpOrgGEPIdx =
741 Builder.CreateAdd(TmpOrgGEPIdx, Builder.getInt32(1));
742 }
743 }
744 } else {
745 //
746 // Consider below case.
747 //
748 // Original IR (float4* --> int2*)
749 // 1. src_addr = bitcast float4*, int2*
750 // 2. load (int2*) src_addr
751 //
752 // Transformed IR
753 // 1. src_val(float4) = load (float4*) src_addr
754 // 2. tmp_val(float2) = shufflevector (float4)src_val,
755 // (float4)undef,
756 // (float2)<0, 1>
757 // 3. dst_val(int2) = bitcast (float2)tmp_val, (int2)
758 //
759 unsigned NumElement = DstTyBitWidth / SrcEleTyBitWidth;
760 Value *Undef = UndefValue::get(SrcTy);
761
alan-baker4a757f62020-04-22 08:17:49 -0400762 SmallVector<int32_t, 4> Idxs;
763 for (int i = 0; i < NumElement; i++) {
David Neto22f144c2017-06-12 14:26:21 -0400764 Idxs.push_back(i);
765 }
766 DstVal = Builder.CreateShuffleVector(LDValues[0], Undef, Idxs);
767
768 DstVal = Builder.CreateBitCast(DstVal, DstTy);
769 }
770
771 DstVal = Builder.CreateBitCast(DstVal, DstTy);
772 } else {
773 if (IsGEPUser) {
774 //
775 // Consider below case.
776 //
777 // Original IR (int4* --> char2*)
778 // 1. src_addr = bitcast int4*, char2*
779 // 2. element_addr = gep (char2*) src_addr, idx
780 // 3. load (char2*) element_addr
781 //
782 // Transformed IR
783 // 1. src_addr = gep (int4*) src, idx / 8
784 // 2. src_val(int4) = load (int4*) src_addr
785 // 3. tmp_val(int) = extractelement idx / 2
786 // 4. tmp_val(<i16 x 2>) = bitcast tmp_val(int), (<i16 x 2>)
787 // 5. tmp_val(i16) = extractelement idx % 2
788 // 6. dst_val(char2) = bitcast tmp_val, (char2)
789 // ==> if types are same between src and dst, it will be
790 // igonored
791 //
David Neto22f144c2017-06-12 14:26:21 -0400792 unsigned SubNumElement = SrcEleTyBitWidth / DstTyBitWidth;
793 if (SubNumElement != 2 && SubNumElement != 4) {
794 llvm_unreachable("Unsupported SubNumElement");
795 }
796
797 Value *TmpOrgGEPIdx = Builder.CreateLShr(
798 OrgGEPIdx, Builder.getInt32(std::log2(SubNumElement)));
799 Value *TmpVal = Builder.CreateExtractElement(
800 LDValues[0], TmpOrgGEPIdx, "tmp_val");
801 TmpVal = Builder.CreateBitCast(
802 TmpVal,
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400803 FixedVectorType::get(
David Neto22f144c2017-06-12 14:26:21 -0400804 IntegerType::get(DstTy->getContext(), DstTyBitWidth),
805 SubNumElement));
806 TmpOrgGEPIdx = Builder.CreateAnd(
807 OrgGEPIdx, Builder.getInt32(SubNumElement - 1));
808 TmpVal = Builder.CreateExtractElement(TmpVal, TmpOrgGEPIdx,
809 "tmp_val");
810 DstVal = Builder.CreateBitCast(TmpVal, DstTy);
811 } else {
812 Inst->print(errs());
813 llvm_unreachable("Handle this bitcast");
814 }
815 }
816 } else if (SrcTyBitWidth < DstTyBitWidth) {
817 //
818 // Consider below case.
819 //
820 // Original IR (float2* --> float4*)
821 // 1. src_addr = bitcast float2*, float4*
822 // 2. element_addr = gep (float4*) src_addr, idx
823 // 3. load (float4*) element_addr
824 //
825 // Transformed IR
826 // 1. src_addr = gep (float2*) src, idx * 2
827 // 2. src_val1(float2) = load (float2*) src_addr
828 // 3. src_addr2 = gep (float2*) src_addr, 1
829 // 4. src_val2(float2) = load (float2*) src_addr2
830 // 5. dst_val(float4) = shufflevector src_val1, src_val2, <0, 1>
831 // 6. dst_val(float4) = bitcast dst_val, (float4)
832 // ==> if types are same between src and dst, it will be igonored
833 //
834 unsigned NumElement = 1;
835 if (SrcTy->isVectorTy()) {
alan-baker5a8c3be2020-09-09 13:44:26 -0400836 NumElement = SrcVecTy->getElementCount().getKnownMinValue() * 2;
David Neto22f144c2017-06-12 14:26:21 -0400837 }
838
839 // Handle scalar type.
840 if (NumElement == 1) {
841 if (SrcTyBitWidth * 4 <= DstTyBitWidth) {
842 unsigned NumVecElement = DstTyBitWidth / SrcTyBitWidth;
843 unsigned NumVector = 1;
844 if (NumVecElement > 4) {
845 NumVector = NumVecElement >> 2;
846 NumVecElement = 4;
847 }
848
849 SmallVector<Value *, 4> Values;
850 for (unsigned VIdx = 0; VIdx < NumVector; VIdx++) {
851 // In this case, generate only insert element. It generates
852 // less instructions than using shuffle vector.
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400853 VectorType *TmpVecTy =
854 FixedVectorType::get(SrcTy, NumVecElement);
David Neto22f144c2017-06-12 14:26:21 -0400855 Value *TmpVal = UndefValue::get(TmpVecTy);
856 for (unsigned i = 0; i < NumVecElement; i++) {
857 TmpVal = Builder.CreateInsertElement(
858 TmpVal, LDValues[i + (VIdx * 4)], Builder.getInt32(i));
859 }
860 Values.push_back(TmpVal);
861 }
862
863 if (Values.size() > 2) {
864 Inst->print(errs());
865 llvm_unreachable("Support above bitcast");
866 }
867
868 if (Values.size() > 1) {
869 Type *TmpEleTy =
870 Type::getIntNTy(M.getContext(), SrcEleTyBitWidth * 2);
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400871 VectorType *TmpVecTy =
872 FixedVectorType::get(TmpEleTy, NumVector);
David Neto22f144c2017-06-12 14:26:21 -0400873 for (unsigned i = 0; i < Values.size(); i++) {
874 Values[i] = Builder.CreateBitCast(Values[i], TmpVecTy);
875 }
alan-baker4a757f62020-04-22 08:17:49 -0400876 SmallVector<int32_t, 4> Idxs;
877 for (int i = 0; i < (NumVector * 2); i++) {
David Neto22f144c2017-06-12 14:26:21 -0400878 Idxs.push_back(i);
879 }
880 for (unsigned i = 0; i < Values.size(); i = i + 2) {
881 Values[i] = Builder.CreateShuffleVector(
882 Values[i], Values[i + 1], Idxs);
883 }
884 }
885
886 LDValues.clear();
887 LDValues.push_back(Values[0]);
888 } else {
889 SmallVector<Value *, 4> TmpLDValues;
890 for (unsigned i = 0; i < LDValues.size(); i = i + 2) {
alan-bakerb3e2b6d2020-06-24 23:59:57 -0400891 VectorType *TmpVecTy = FixedVectorType::get(SrcTy, 2);
David Neto22f144c2017-06-12 14:26:21 -0400892 Value *TmpVal = UndefValue::get(TmpVecTy);
893 TmpVal = Builder.CreateInsertElement(TmpVal, LDValues[i],
894 Builder.getInt32(0));
895 TmpVal = Builder.CreateInsertElement(TmpVal, LDValues[i + 1],
896 Builder.getInt32(1));
897 TmpLDValues.push_back(TmpVal);
898 }
899 LDValues.clear();
900 LDValues = std::move(TmpLDValues);
901 NumElement = 4;
902 }
903 }
904
905 // Handle vector type.
906 while (LDValues.size() != 1) {
907 SmallVector<Value *, 4> TmpLDValues;
908 for (unsigned i = 0; i < LDValues.size(); i = i + 2) {
alan-baker4a757f62020-04-22 08:17:49 -0400909 SmallVector<int32_t, 4> Idxs;
910 for (int j = 0; j < NumElement; j++) {
David Neto22f144c2017-06-12 14:26:21 -0400911 Idxs.push_back(j);
912 }
913 Value *TmpVal = Builder.CreateShuffleVector(
914 LDValues[i], LDValues[i + 1], Idxs);
915 TmpLDValues.push_back(TmpVal);
916 }
917 LDValues.clear();
918 LDValues = std::move(TmpLDValues);
919 NumElement *= 2;
920 }
921
922 DstVal = Builder.CreateBitCast(LDValues[0], DstTy);
923 } else {
924 //
925 // Consider below case.
926 //
927 // Original IR (float4* --> int4*)
928 // 1. src_addr = bitcast float4*, int4*
929 // 2. element_addr = gep (int4*) src_addr, idx, 0
930 // 3. load (int) element_addr
931 //
932 // Transformed IR
933 // 1. element_addr = gep (float4*) src_addr, idx, 0
934 // 2. src_val = load (float*) element_addr
935 // 3. val = bitcast (float) src_val to (int)
936 //
937 Value *SrcAddr = Src;
938 if (IsGEPUser) {
939 SmallVector<Value *, 4> Idxs;
940 for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
941 Idxs.push_back(GEP->getOperand(i));
942 }
943 SrcAddr = Builder.CreateGEP(Src, Idxs);
944 }
945 LoadInst *SrcVal = Builder.CreateLoad(SrcAddr, "src_val");
946
947 Type *TmpDstTy = DstTy;
948 if (IsGEPUser) {
949 if (GEP->getNumOperands() > 2) {
950 TmpDstTy = DstEleTy;
951 }
952 }
953 DstVal = Builder.CreateBitCast(SrcVal, TmpDstTy);
954 }
955
956 // Update LD's users with DstVal.
957 LD->replaceAllUsesWith(DstVal);
958 } else {
959 U->print(errs());
960 llvm_unreachable(
961 "Handle above user of gep on ReplacePointerBitcastPass");
962 }
963
964 ToBeDeleted.push_back(cast<Instruction>(U));
965 }
966
967 if (IsGEPUser) {
968 ToBeDeleted.push_back(GEP);
969 }
970 }
971
972 ToBeDeleted.push_back(Inst);
973 }
974
975 for (Instruction *Inst : ScalarWorkList) {
David Neto8e138142018-05-29 10:19:21 -0400976 // Some tests have a stray bitcast from pointer-to-array to
977 // pointer to i8*, but the bitcast has no uses. Exit early
978 // but be sure to delete it later.
979 //
980 // Example:
981 // %1 = bitcast [25 x float]* %dst to i8*
982
983 // errs () << " Scalar bitcast is " << *Inst << "\n";
984
985 if (!Inst->hasNUsesOrMore(1)) {
986 ToBeDeleted.push_back(Inst);
987 continue;
988 }
989
David Neto22f144c2017-06-12 14:26:21 -0400990 Value *Src = Inst->getOperand(0);
David Neto8e138142018-05-29 10:19:21 -0400991 Type *SrcTy; // Original type
992 Type *DstTy; // Type that SrcTy is cast to.
993 unsigned SrcTyBitWidth;
994 unsigned DstTyBitWidth;
995
alan-baker1b13e8f2019-08-08 17:56:51 -0400996 bool BailOut = false;
David Neto8e138142018-05-29 10:19:21 -0400997 SrcTy = Src->getType()->getPointerElementType();
998 DstTy = Inst->getType()->getPointerElementType();
999 int iter_count = 0;
1000 while (++iter_count) {
1001 SrcTyBitWidth = unsigned(DL.getTypeStoreSizeInBits(SrcTy));
1002 DstTyBitWidth = unsigned(DL.getTypeStoreSizeInBits(DstTy));
1003#if 0
1004 errs() << " Try Src " << *Src << "\n";
1005 errs() << " SrcTy elem " << *SrcTy << " bit width " << SrcTyBitWidth
1006 << "\n";
1007 errs() << " DstTy elem " << *DstTy << " bit width " << DstTyBitWidth
1008 << "\n";
1009#endif
1010
1011 // The normal case that we can handle is source type is smaller than
1012 // the dest type.
1013 if (SrcTyBitWidth <= DstTyBitWidth)
1014 break;
1015
1016 // The Source type is bigger than the destination type.
1017 // Walk into the source type to break it down.
1018 if (SrcTy->isArrayTy()) {
1019 // If it's an array, consider only the first element.
1020 Value *Zero = ConstantInt::get(Type::getInt32Ty(M.getContext()), 0);
Diego Novillo3cc8d7a2019-04-10 13:30:34 -04001021 Instruction *NewSrc =
1022 GetElementPtrInst::CreateInBounds(Src, {Zero, Zero});
alan-baker1b13e8f2019-08-08 17:56:51 -04001023 Changed = true;
David Neto8e138142018-05-29 10:19:21 -04001024 // errs() << "NewSrc is " << *NewSrc << "\n";
1025 if (auto *SrcInst = dyn_cast<Instruction>(Src)) {
1026 // errs() << " instruction case\n";
1027 NewSrc->insertAfter(SrcInst);
1028 } else {
1029 // Could be a parameter.
1030 auto where = Inst->getParent()
1031 ->getParent()
1032 ->getEntryBlock()
1033 .getFirstInsertionPt();
Diego Novillo3cc8d7a2019-04-10 13:30:34 -04001034 Instruction &whereInst = *where;
David Neto8e138142018-05-29 10:19:21 -04001035 // errs() << "insert " << *NewSrc << " before " << whereInst << "\n";
1036 NewSrc->insertBefore(&whereInst);
1037 }
1038 Src = NewSrc;
1039 SrcTy = Src->getType()->getPointerElementType();
1040 } else {
alan-baker1b13e8f2019-08-08 17:56:51 -04001041 BailOut = true;
1042 break;
David Neto8e138142018-05-29 10:19:21 -04001043 }
1044 if (iter_count > 1000) {
1045 llvm_unreachable("ReplacePointerBitcastPass: Too many iterations!");
1046 }
1047 };
1048#if 0
1049 errs() << " Src is " << *Src << "\n";
1050 errs() << " Dst is " << *Inst << "\n";
1051 errs() << " SrcTy elem " << *SrcTy << " bit width " << SrcTyBitWidth
1052 << "\n";
1053 errs() << " DstTy elem " << *DstTy << " bit width " << DstTyBitWidth
1054 << "\n";
1055#endif
David Neto22f144c2017-06-12 14:26:21 -04001056
alan-baker1b13e8f2019-08-08 17:56:51 -04001057 // Only dead code has been generated up to this point so it is safe to bail
1058 // out.
1059 if (BailOut) {
1060 continue;
1061 }
1062
David Neto22f144c2017-06-12 14:26:21 -04001063 for (User *BitCastUser : Inst->users()) {
1064 Value *NewAddrIdx = ConstantInt::get(Type::getInt32Ty(M.getContext()), 0);
1065 // It consist of User* and bool whether user is gep or not.
1066 SmallVector<std::pair<User *, bool>, 32> Users;
1067
1068 GetElementPtrInst *GEP = nullptr;
1069 Value *OrgGEPIdx = nullptr;
Jason Gavrise44af072018-08-14 20:44:50 -04001070 if ((GEP = dyn_cast<GetElementPtrInst>(BitCastUser))) {
David Neto22f144c2017-06-12 14:26:21 -04001071 IRBuilder<> Builder(GEP);
1072
1073 // Build new src/dst address.
1074 OrgGEPIdx = GEP->getOperand(1);
1075 NewAddrIdx = CalculateNewGEPIdx(SrcTyBitWidth, DstTyBitWidth, GEP);
1076
1077 // If bitcast's user is gep, investigate gep's users too.
1078 for (User *GEPUser : GEP->users()) {
1079 Users.push_back(std::make_pair(GEPUser, true));
1080 }
1081 } else {
1082 Users.push_back(std::make_pair(BitCastUser, false));
1083 }
1084
1085 // Handle users.
1086 bool IsGEPUser = false;
1087 for (auto UserIter : Users) {
1088 User *U = UserIter.first;
1089 IsGEPUser = UserIter.second;
1090
1091 IRBuilder<> Builder(cast<Instruction>(U));
1092
1093 // Handle store instruction with gep.
1094 if (StoreInst *ST = dyn_cast<StoreInst>(U)) {
Diego Novillo3cc8d7a2019-04-10 13:30:34 -04001095 // errs() << " store is " << *ST << "\n";
David Neto22f144c2017-06-12 14:26:21 -04001096 if (SrcTyBitWidth == DstTyBitWidth) {
alan-baker32014272019-05-22 08:07:18 -04001097 auto STVal = ConvertValue(ST->getValueOperand(), SrcTy, Builder);
David Neto22f144c2017-06-12 14:26:21 -04001098 Value *DstAddr = Builder.CreateGEP(Src, NewAddrIdx);
1099 Builder.CreateStore(STVal, DstAddr);
1100 } else if (SrcTyBitWidth < DstTyBitWidth) {
1101 unsigned NumElement = DstTyBitWidth / SrcTyBitWidth;
1102
David Neto22f144c2017-06-12 14:26:21 -04001103 // Create store values.
1104 Value *STVal = ST->getValueOperand();
1105 SmallVector<Value *, 8> STValues;
1106 for (unsigned i = 0; i < NumElement; i++) {
1107 Type *TmpTy = Type::getIntNTy(M.getContext(), DstTyBitWidth);
1108 Value *TmpVal = Builder.CreateBitCast(STVal, TmpTy);
James Price51952282020-02-14 09:41:11 -05001109 TmpVal = Builder.CreateLShr(
1110 TmpVal, Builder.getIntN(DstTyBitWidth, i * SrcTyBitWidth));
David Neto22f144c2017-06-12 14:26:21 -04001111 TmpVal = Builder.CreateTrunc(TmpVal, SrcTy);
1112 STValues.push_back(TmpVal);
1113 }
1114
1115 // Generate stores.
1116 Value *SrcAddrIdx = NewAddrIdx;
1117 Value *BaseAddr = Src;
1118 for (unsigned i = 0; i < NumElement; i++) {
1119 // Calculate store address.
1120 Value *DstAddr = Builder.CreateGEP(BaseAddr, SrcAddrIdx);
1121 Builder.CreateStore(STValues[i], DstAddr);
1122
1123 if (i + 1 < NumElement) {
1124 // Calculate next store address
1125 SrcAddrIdx = Builder.CreateAdd(SrcAddrIdx, Builder.getInt32(1));
1126 }
1127 }
1128
1129 } else {
1130 Inst->print(errs());
1131 llvm_unreachable("Handle different size store with scalar "
1132 "bitcast on ReplacePointerBitcastPass");
1133 }
1134 } else if (LoadInst *LD = dyn_cast<LoadInst>(U)) {
1135 if (SrcTyBitWidth == DstTyBitWidth) {
1136 Value *SrcAddr = Builder.CreateGEP(Src, NewAddrIdx);
1137 LoadInst *SrcVal = Builder.CreateLoad(SrcAddr, "src_val");
alan-baker32014272019-05-22 08:07:18 -04001138 LD->replaceAllUsesWith(ConvertValue(SrcVal, DstTy, Builder));
David Neto22f144c2017-06-12 14:26:21 -04001139 } else if (SrcTyBitWidth < DstTyBitWidth) {
1140 Value *SrcAddrIdx = NewAddrIdx;
1141
1142 // Load value from src.
1143 unsigned NumIter = CalculateNumIter(SrcTyBitWidth, DstTyBitWidth);
1144 SmallVector<Value *, 8> LDValues;
1145 for (unsigned i = 1; i <= NumIter; i++) {
1146 Value *SrcAddr = Builder.CreateGEP(Src, SrcAddrIdx);
1147 LoadInst *SrcVal = Builder.CreateLoad(SrcAddr, "src_val");
1148 LDValues.push_back(SrcVal);
1149
1150 if (i + 1 <= NumIter) {
1151 // Calculate next SrcAddrIdx.
1152 SrcAddrIdx = Builder.CreateAdd(SrcAddrIdx, Builder.getInt32(1));
1153 }
1154 }
1155
1156 // Merge Load.
1157 Type *TmpSrcTy = Type::getIntNTy(M.getContext(), SrcTyBitWidth);
1158 Value *DstVal = Builder.CreateBitCast(LDValues[0], TmpSrcTy);
1159 Type *TmpDstTy = Type::getIntNTy(M.getContext(), DstTyBitWidth);
1160 DstVal = Builder.CreateZExt(DstVal, TmpDstTy);
1161 for (unsigned i = 1; i < LDValues.size(); i++) {
1162 Value *TmpVal = Builder.CreateBitCast(LDValues[i], TmpSrcTy);
1163 TmpVal = Builder.CreateZExt(TmpVal, TmpDstTy);
Kévin Petit0c9cd042020-04-06 17:32:41 +01001164 TmpVal = Builder.CreateShl(
1165 TmpVal, Builder.getIntN(DstTyBitWidth, i * SrcTyBitWidth));
David Neto22f144c2017-06-12 14:26:21 -04001166 DstVal = Builder.CreateOr(DstVal, TmpVal);
1167 }
1168
1169 DstVal = Builder.CreateBitCast(DstVal, DstTy);
1170 LD->replaceAllUsesWith(DstVal);
1171
1172 } else {
1173 Inst->print(errs());
1174 llvm_unreachable("Handle different size load with scalar "
1175 "bitcast on ReplacePointerBitcastPass");
1176 }
1177 } else {
David Neto22f144c2017-06-12 14:26:21 -04001178 Inst->print(errs());
1179 llvm_unreachable("Handle above user of scalar bitcast with gep on "
1180 "ReplacePointerBitcastPass");
1181 }
1182
1183 ToBeDeleted.push_back(cast<Instruction>(U));
1184 }
1185
1186 if (IsGEPUser) {
1187 ToBeDeleted.push_back(GEP);
1188 }
1189 }
1190
1191 ToBeDeleted.push_back(Inst);
1192 }
1193
1194 for (Instruction *Inst : ToBeDeleted) {
1195 Inst->eraseFromParent();
1196 }
1197
1198 return Changed;
1199}