@@ -1518,7 +1518,9 @@ Address TypeInfo::indexArray(IRGenFunction &IGF, Address base,
1518
1518
// do a byte-level GEP with the proper stride.
1519
1519
const FixedTypeInfo *fixedTI = dyn_cast<FixedTypeInfo>(this );
1520
1520
1521
- Address dest;
1521
+ llvm::Value *destValue = nullptr ;
1522
+ Size stride (1 );
1523
+
1522
1524
// TODO: Arrays currently lower-bound the stride to 1.
1523
1525
if (!fixedTI
1524
1526
|| std::max (Size (1 ), fixedTI->getFixedStride ()) != fixedTI->getFixedSize ()) {
@@ -1528,15 +1530,21 @@ Address TypeInfo::indexArray(IRGenFunction &IGF, Address base,
1528
1530
if (size->getType () != index->getType ())
1529
1531
size = IGF.Builder .CreateZExtOrTrunc (size, index->getType ());
1530
1532
llvm::Value *distance = IGF.Builder .CreateNSWMul (index, size);
1531
- llvm::Value * destValue = IGF.Builder .CreateInBoundsGEP (byteAddr, distance);
1533
+ destValue = IGF.Builder .CreateInBoundsGEP (byteAddr, distance);
1532
1534
destValue = IGF.Builder .CreateBitCast (destValue, base.getType ());
1533
- return Address (destValue, base.getAlignment ());
1534
1535
} else {
1535
1536
// We don't expose a non-inbounds GEP operation.
1536
- llvm::Value *destValue = IGF.Builder .CreateInBoundsGEP (base.getAddress (),
1537
- index);
1538
- return Address (destValue, base.getAlignment ());
1537
+ destValue = IGF.Builder .CreateInBoundsGEP (base.getAddress (), index);
1538
+ stride = fixedTI->getFixedStride ();
1539
1539
}
1540
+ if (auto *IndexConst = dyn_cast<llvm::ConstantInt>(index)) {
1541
+ // If we know the indexing value, we can get a better guess on the
1542
+ // alignment.
1543
+ // This even works if the stride is not known (and assumed to be 1).
1544
+ stride *= IndexConst->getValue ().getZExtValue ();
1545
+ }
1546
+ Alignment Align = base.getAlignment ().alignmentAtOffset (stride);
1547
+ return Address (destValue, Align);
1540
1548
}
1541
1549
1542
1550
Address TypeInfo::roundUpToTypeAlignment (IRGenFunction &IGF, Address base,
0 commit comments