20
20
#include " llvm/IR/InstVisitor.h"
21
21
#include " llvm/IR/ReplaceConstant.h"
22
22
#include " llvm/Support/Casting.h"
23
+ #include " llvm/Support/MathExtras.h"
23
24
#include " llvm/Transforms/Utils/Local.h"
24
25
#include < cassert>
25
26
#include < cstddef>
@@ -305,6 +306,8 @@ bool DXILFlattenArraysVisitor::visitGetElementPtrInst(GetElementPtrInst &GEP) {
305
306
unsigned BytesPerElem = Info.RootFlattenedArrayType ->getArrayElementType ()
306
307
->getPrimitiveSizeInBits () /
307
308
8 ;
309
+ assert (isPowerOf2_32 (BytesPerElem) &&
310
+ " Bytes per element should be a power of 2" );
308
311
309
312
// Compute the 32-bit index for this flattened GEP from the constant and
310
313
// variable byte offsets in the GEPInfo
@@ -316,14 +319,23 @@ bool DXILFlattenArraysVisitor::visitGetElementPtrInst(GetElementPtrInst &GEP) {
316
319
" Constant byte offset for flat GEP index must fit within 32 bits" );
317
320
Value *FlattenedIndex = Builder.getInt32 (ConstantOffset);
318
321
for (auto [VarIndex, Multiplier] : Info.VariableOffsets ) {
319
- uint64_t Mul = Multiplier.udiv (BytesPerElem).getZExtValue ();
320
- assert (Mul < UINT32_MAX &&
321
- " Multiplier for flat GEP index must fit within 32 bits" );
322
+ assert (Multiplier.getActiveBits () <= 32 &&
323
+ " The multiplier for a flat GEP index must fit within 32 bits" );
322
324
assert (VarIndex->getType ()->isIntegerTy (32 ) &&
323
325
" Expected i32-typed GEP indices" );
324
- Value *ConstIntMul = Builder.getInt32 (Mul);
325
- Value *MulVarIndex = Builder.CreateMul (VarIndex, ConstIntMul);
326
- FlattenedIndex = Builder.CreateAdd (FlattenedIndex, MulVarIndex);
326
+ Value *VI;
327
+ if (Multiplier.getZExtValue () % BytesPerElem != 0 ) {
328
+ // This can happen, e.g., with i8 GEPs. To handle this we just divide
329
+ // by BytesPerElem using an instruction after multiplying VarIndex by
330
+ // Multiplier.
331
+ VI = Builder.CreateMul (VarIndex,
332
+ Builder.getInt32 (Multiplier.getZExtValue ()));
333
+ VI = Builder.CreateLShr (VI, Builder.getInt32 (Log2_32 (BytesPerElem)));
334
+ } else
335
+ VI = Builder.CreateMul (
336
+ VarIndex,
337
+ Builder.getInt32 (Multiplier.getZExtValue () / BytesPerElem));
338
+ FlattenedIndex = Builder.CreateAdd (FlattenedIndex, VI);
327
339
}
328
340
329
341
// Construct a new GEP for the flattened array to replace the current GEP
0 commit comments