Skip to content

Commit 7954c57

Browse files
jasilvanusnikic
andauthored
[IR] Fix GEP offset computations for vector GEPs (#75448)
Vectors are always bit-packed and don't respect the elements' alignment requirements. This is different from arrays. This means offsets of vector GEPs need to be computed differently than offsets of array GEPs. This PR fixes many places that rely on an incorrect pattern that always relies on `DL.getTypeAllocSize(GTI.getIndexedType())`. We replace these by usages of `GTI.getSequentialElementStride(DL)`, which is a new helper function added in this PR. This changes behavior for GEPs into vectors with element types for which the (bit) size and alloc size is different. This includes two cases: * Types with a bit size that is not a multiple of a byte, e.g. i1. GEPs into such vectors are questionable to begin with, as some elements are not even addressable. * Overaligned types, e.g. i16 with 32-bit alignment. Existing tests are unaffected, but a miscompilation of a new test is fixed. --------- Co-authored-by: Nikita Popov <github@npopov.com>
1 parent 87f1cf0 commit 7954c57

28 files changed

+109
-54
lines changed

clang/lib/CodeGen/CGExprScalar.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -5292,8 +5292,8 @@ static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal,
52925292
} else {
52935293
// Otherwise this is array-like indexing. The local offset is the index
52945294
// multiplied by the element size.
5295-
auto *ElementSize = llvm::ConstantInt::get(
5296-
IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType()));
5295+
auto *ElementSize =
5296+
llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
52975297
auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true);
52985298
LocalOffset = eval(BO_Mul, ElementSize, IndexS);
52995299
}

llvm/include/llvm/Analysis/TargetTransformInfoImpl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ class TargetTransformInfoImplCRTPBase : public TargetTransformInfoImplBase {
10481048
if (TargetType->isScalableTy())
10491049
return TTI::TCC_Basic;
10501050
int64_t ElementSize =
1051-
DL.getTypeAllocSize(GTI.getIndexedType()).getFixedValue();
1051+
GTI.getSequentialElementStride(DL).getFixedValue();
10521052
if (ConstIdx) {
10531053
BaseOffset +=
10541054
ConstIdx->getValue().sextOrTrunc(PtrSizeBits) * ElementSize;

llvm/include/llvm/IR/GetElementPtrTypeIterator.h

+54-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "llvm/ADT/ArrayRef.h"
1818
#include "llvm/ADT/PointerUnion.h"
19+
#include "llvm/IR/DataLayout.h"
1920
#include "llvm/IR/DerivedTypes.h"
2021
#include "llvm/IR/Operator.h"
2122
#include "llvm/IR/User.h"
@@ -30,7 +31,39 @@ template <typename ItTy = User::const_op_iterator>
3031
class generic_gep_type_iterator {
3132

3233
ItTy OpIt;
33-
PointerUnion<StructType *, Type *> CurTy;
34+
// We use two different mechanisms to store the type a GEP index applies to.
35+
// In some cases, we need to know the outer aggregate type the index is
36+
// applied within, e.g. a struct. In such cases, we store the aggregate type
37+
// in the iterator, and derive the element type on the fly.
38+
//
39+
// However, this is not always possible, because for the outermost index there
40+
// is no containing type. In such cases, or if the containing type is not
41+
// relevant, e.g. for arrays, the element type is stored as Type* in CurTy.
42+
//
43+
// If CurTy contains a Type* value, this does not imply anything about the
44+
// type itself, because it is the element type and not the outer type.
45+
// In particular, Type* can be a struct type.
46+
//
47+
// Consider this example:
48+
//
49+
// %my.struct = type { i32, [ 4 x float ] }
50+
// [...]
51+
// %gep = getelementptr %my.struct, ptr %ptr, i32 10, i32 1, 32 3
52+
//
53+
// Iterating over the indices of this GEP, CurTy will contain the following
54+
// values:
55+
// * i32 10: The outer index always operates on the GEP value type.
56+
// CurTy contains a Type* pointing at `%my.struct`.
57+
// * i32 1: This index is within a struct.
58+
// CurTy contains a StructType* pointing at `%my.struct`.
59+
// * i32 3: This index is within an array. We reuse the "flat" indexing
60+
// for arrays which is also used in the top level GEP index.
61+
// CurTy contains a Type* pointing at `float`.
62+
//
63+
// Vectors are handled separately because the layout of vectors is different
64+
// for overaligned elements: Vectors are always bit-packed, whereas arrays
65+
// respect ABI alignment of the elements.
66+
PointerUnion<StructType *, VectorType *, Type *> CurTy;
3467

3568
generic_gep_type_iterator() = default;
3669

@@ -69,6 +102,8 @@ class generic_gep_type_iterator {
69102
Type *getIndexedType() const {
70103
if (auto *T = dyn_cast_if_present<Type *>(CurTy))
71104
return T;
105+
if (auto *VT = dyn_cast_if_present<VectorType *>(CurTy))
106+
return VT->getElementType();
72107
return cast<StructType *>(CurTy)->getTypeAtIndex(getOperand());
73108
}
74109

@@ -79,7 +114,7 @@ class generic_gep_type_iterator {
79114
if (auto *ATy = dyn_cast<ArrayType>(Ty))
80115
CurTy = ATy->getElementType();
81116
else if (auto *VTy = dyn_cast<VectorType>(Ty))
82-
CurTy = VTy->getElementType();
117+
CurTy = VTy;
83118
else
84119
CurTy = dyn_cast<StructType>(Ty);
85120
++OpIt;
@@ -108,7 +143,23 @@ class generic_gep_type_iterator {
108143
// that.
109144

110145
bool isStruct() const { return isa<StructType *>(CurTy); }
111-
bool isSequential() const { return isa<Type *>(CurTy); }
146+
bool isVector() const { return isa<VectorType *>(CurTy); }
147+
bool isSequential() const { return !isStruct(); }
148+
149+
// For sequential GEP indices (all except those into structs), the index value
150+
// can be translated into a byte offset by multiplying with an element stride.
151+
// This function returns this stride, which both depends on the element type,
152+
// and the containing aggregate type, as vectors always tightly bit-pack their
153+
// elements.
154+
TypeSize getSequentialElementStride(const DataLayout &DL) const {
155+
assert(isSequential());
156+
Type *ElemTy = getIndexedType();
157+
if (isVector()) {
158+
assert(DL.typeSizeEqualsStoreSize(ElemTy) && "Not byte-addressable");
159+
return DL.getTypeStoreSize(ElemTy);
160+
}
161+
return DL.getTypeAllocSize(ElemTy);
162+
}
112163

113164
StructType *getStructType() const { return cast<StructType *>(CurTy); }
114165

llvm/lib/Analysis/BasicAliasAnalysis.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
639639
continue;
640640

641641
// Don't attempt to analyze GEPs if the scalable index is not zero.
642-
TypeSize AllocTypeSize = DL.getTypeAllocSize(GTI.getIndexedType());
642+
TypeSize AllocTypeSize = GTI.getSequentialElementStride(DL);
643643
if (AllocTypeSize.isScalable()) {
644644
Decomposed.Base = V;
645645
return Decomposed;
@@ -650,7 +650,7 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
650650
continue;
651651
}
652652

653-
TypeSize AllocTypeSize = DL.getTypeAllocSize(GTI.getIndexedType());
653+
TypeSize AllocTypeSize = GTI.getSequentialElementStride(DL);
654654
if (AllocTypeSize.isScalable()) {
655655
Decomposed.Base = V;
656656
return Decomposed;

llvm/lib/Analysis/InlineCost.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,7 @@ bool CallAnalyzer::accumulateGEPOffset(GEPOperator &GEP, APInt &Offset) {
14291429
continue;
14301430
}
14311431

1432-
APInt TypeSize(IntPtrWidth, DL.getTypeAllocSize(GTI.getIndexedType()));
1432+
APInt TypeSize(IntPtrWidth, GTI.getSequentialElementStride(DL));
14331433
Offset += OpC->getValue().sextOrTrunc(IntPtrWidth) * TypeSize;
14341434
}
14351435
return true;

llvm/lib/Analysis/Local.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Value *llvm::emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL,
6464
// Convert to correct type.
6565
if (Op->getType() != IntIdxTy)
6666
Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName() + ".c");
67-
TypeSize TSize = DL.getTypeAllocSize(GTI.getIndexedType());
67+
TypeSize TSize = GTI.getSequentialElementStride(DL);
6868
if (TSize != TypeSize::getFixed(1)) {
6969
Value *Scale = Builder->CreateTypeSize(IntIdxTy->getScalarType(), TSize);
7070
if (IntIdxTy->isVectorTy())

llvm/lib/Analysis/LoopAccessAnalysis.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -2703,7 +2703,10 @@ static unsigned getGEPInductionOperand(const GetElementPtrInst *Gep) {
27032703

27042704
// If it's a type with the same allocation size as the result of the GEP we
27052705
// can peel off the zero index.
2706-
if (DL.getTypeAllocSize(GEPTI.getIndexedType()) != GEPAllocSize)
2706+
TypeSize ElemSize = GEPTI.isStruct()
2707+
? DL.getTypeAllocSize(GEPTI.getIndexedType())
2708+
: GEPTI.getSequentialElementStride(DL);
2709+
if (ElemSize != GEPAllocSize)
27072710
break;
27082711
--LastOperand;
27092712
}

llvm/lib/Analysis/ValueTracking.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
11961196
unsigned IndexBitWidth = Index->getType()->getScalarSizeInBits();
11971197
KnownBits IndexBits(IndexBitWidth);
11981198
computeKnownBits(Index, IndexBits, Depth + 1, Q);
1199-
TypeSize IndexTypeSize = Q.DL.getTypeAllocSize(IndexedTy);
1199+
TypeSize IndexTypeSize = GTI.getSequentialElementStride(Q.DL);
12001200
uint64_t TypeSizeInBytes = IndexTypeSize.getKnownMinValue();
12011201
KnownBits ScalingFactor(IndexBitWidth);
12021202
// Multiply by current sizeof type.
@@ -2128,7 +2128,7 @@ static bool isGEPKnownNonNull(const GEPOperator *GEP, unsigned Depth,
21282128
}
21292129

21302130
// If we have a zero-sized type, the index doesn't matter. Keep looping.
2131-
if (Q.DL.getTypeAllocSize(GTI.getIndexedType()).isZero())
2131+
if (GTI.getSequentialElementStride(Q.DL).isZero())
21322132
continue;
21332133

21342134
// Fast path the constant operand case both for efficiency and so we don't

llvm/lib/CodeGen/CodeGenPrepare.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -4776,7 +4776,7 @@ bool AddressingModeMatcher::matchOperationAddr(User *AddrInst, unsigned Opcode,
47764776
cast<ConstantInt>(AddrInst->getOperand(i))->getZExtValue();
47774777
ConstantOffset += SL->getElementOffset(Idx);
47784778
} else {
4779-
TypeSize TS = DL.getTypeAllocSize(GTI.getIndexedType());
4779+
TypeSize TS = GTI.getSequentialElementStride(DL);
47804780
if (TS.isNonZero()) {
47814781
// The optimisations below currently only work for fixed offsets.
47824782
if (TS.isScalable())

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,7 @@ bool IRTranslator::translateGetElementPtr(const User &U,
15451545
Offset += DL->getStructLayout(StTy)->getElementOffset(Field);
15461546
continue;
15471547
} else {
1548-
uint64_t ElementSize = DL->getTypeAllocSize(GTI.getIndexedType());
1548+
uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
15491549

15501550
// If this is a scalar constant or a splat vector of constants,
15511551
// handle it quickly.

llvm/lib/CodeGen/SelectionDAG/FastISel.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -560,15 +560,13 @@ bool FastISel::selectGetElementPtr(const User *I) {
560560
}
561561
}
562562
} else {
563-
Type *Ty = GTI.getIndexedType();
564-
565563
// If this is a constant subscript, handle it quickly.
566564
if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
567565
if (CI->isZero())
568566
continue;
569567
// N = N + Offset
570568
uint64_t IdxN = CI->getValue().sextOrTrunc(64).getSExtValue();
571-
TotalOffs += DL.getTypeAllocSize(Ty) * IdxN;
569+
TotalOffs += GTI.getSequentialElementStride(DL) * IdxN;
572570
if (TotalOffs >= MaxOffs) {
573571
N = fastEmit_ri_(VT, ISD::ADD, N, TotalOffs, VT);
574572
if (!N) // Unhandled operand. Halt "fast" selection and bail.
@@ -585,7 +583,7 @@ bool FastISel::selectGetElementPtr(const User *I) {
585583
}
586584

587585
// N = N + Idx * ElementSize;
588-
uint64_t ElementSize = DL.getTypeAllocSize(Ty);
586+
uint64_t ElementSize = GTI.getSequentialElementStride(DL);
589587
Register IdxN = getRegForGEPIndex(Idx);
590588
if (!IdxN) // Unhandled operand. Halt "fast" selection and bail.
591589
return false;

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -4114,7 +4114,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
41144114
unsigned IdxSize = DAG.getDataLayout().getIndexSizeInBits(AS);
41154115
MVT IdxTy = MVT::getIntegerVT(IdxSize);
41164116
TypeSize ElementSize =
4117-
DAG.getDataLayout().getTypeAllocSize(GTI.getIndexedType());
4117+
GTI.getSequentialElementStride(DAG.getDataLayout());
41184118
// We intentionally mask away the high bits here; ElementSize may not
41194119
// fit in IdxTy.
41204120
APInt ElementMul(IdxSize, ElementSize.getKnownMinValue());

llvm/lib/ExecutionEngine/Interpreter/Execution.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I,
10741074
assert(BitWidth == 64 && "Invalid index type for getelementptr");
10751075
Idx = (int64_t)IdxGV.IntVal.getZExtValue();
10761076
}
1077-
Total += getDataLayout().getTypeAllocSize(I.getIndexedType()) * Idx;
1077+
Total += I.getSequentialElementStride(getDataLayout()) * Idx;
10781078
}
10791079
}
10801080

llvm/lib/IR/DataLayout.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -936,9 +936,8 @@ int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
936936
// Add in the offset, as calculated by the structure layout info...
937937
Result += Layout->getElementOffset(FieldNo);
938938
} else {
939-
// Get the array index and the size of each array element.
940-
if (int64_t arrayIdx = cast<ConstantInt>(Idx)->getSExtValue())
941-
Result += arrayIdx * getTypeAllocSize(GTI.getIndexedType());
939+
if (int64_t ArrayIdx = cast<ConstantInt>(Idx)->getSExtValue())
940+
Result += ArrayIdx * GTI.getSequentialElementStride(*this);
942941
}
943942
}
944943

llvm/lib/IR/Operator.cpp

+5-7
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Align GEPOperator::getMaxPreservedAlignment(const DataLayout &DL) const {
8787
/// If the index isn't known, we take 1 because it is the index that will
8888
/// give the worse alignment of the offset.
8989
const uint64_t ElemCount = OpC ? OpC->getZExtValue() : 1;
90-
Offset = DL.getTypeAllocSize(GTI.getIndexedType()) * ElemCount;
90+
Offset = GTI.getSequentialElementStride(DL) * ElemCount;
9191
}
9292
Result = Align(MinAlign(Offset, Result.value()));
9393
}
@@ -157,7 +157,7 @@ bool GEPOperator::accumulateConstantOffset(
157157
continue;
158158
}
159159
if (!AccumulateOffset(ConstOffset->getValue(),
160-
DL.getTypeAllocSize(GTI.getIndexedType())))
160+
GTI.getSequentialElementStride(DL)))
161161
return false;
162162
continue;
163163
}
@@ -170,8 +170,7 @@ bool GEPOperator::accumulateConstantOffset(
170170
if (!ExternalAnalysis(*V, AnalysisIndex))
171171
return false;
172172
UsedExternalAnalysis = true;
173-
if (!AccumulateOffset(AnalysisIndex,
174-
DL.getTypeAllocSize(GTI.getIndexedType())))
173+
if (!AccumulateOffset(AnalysisIndex, GTI.getSequentialElementStride(DL)))
175174
return false;
176175
}
177176
return true;
@@ -218,14 +217,13 @@ bool GEPOperator::collectOffset(
218217
continue;
219218
}
220219
CollectConstantOffset(ConstOffset->getValue(),
221-
DL.getTypeAllocSize(GTI.getIndexedType()));
220+
GTI.getSequentialElementStride(DL));
222221
continue;
223222
}
224223

225224
if (STy || ScalableType)
226225
return false;
227-
APInt IndexedSize =
228-
APInt(BitWidth, DL.getTypeAllocSize(GTI.getIndexedType()));
226+
APInt IndexedSize = APInt(BitWidth, GTI.getSequentialElementStride(DL));
229227
// Insert an initial offset of 0 for V iff none exists already, then
230228
// increment the offset by IndexedSize.
231229
if (!IndexedSize.isZero()) {

llvm/lib/IR/Value.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ getOffsetFromIndex(const GEPOperator *GEP, unsigned Idx, const DataLayout &DL) {
10151015

10161016
// Otherwise, we have a sequential type like an array or fixed-length
10171017
// vector. Multiply the index by the ElementSize.
1018-
TypeSize Size = DL.getTypeAllocSize(GTI.getIndexedType());
1018+
TypeSize Size = GTI.getSequentialElementStride(DL);
10191019
if (Size.isScalable())
10201020
return std::nullopt;
10211021
Offset += Size.getFixedValue() * OpC->getSExtValue();

llvm/lib/Target/AArch64/AArch64FastISel.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ bool AArch64FastISel::computeAddress(const Value *Obj, Address &Addr, Type *Ty)
645645
unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
646646
TmpOffset += SL->getElementOffset(Idx);
647647
} else {
648-
uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
648+
uint64_t S = GTI.getSequentialElementStride(DL);
649649
while (true) {
650650
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
651651
// Constant-offset addressing.
@@ -4978,15 +4978,13 @@ bool AArch64FastISel::selectGetElementPtr(const Instruction *I) {
49784978
if (Field)
49794979
TotalOffs += DL.getStructLayout(StTy)->getElementOffset(Field);
49804980
} else {
4981-
Type *Ty = GTI.getIndexedType();
4982-
49834981
// If this is a constant subscript, handle it quickly.
49844982
if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
49854983
if (CI->isZero())
49864984
continue;
49874985
// N = N + Offset
4988-
TotalOffs +=
4989-
DL.getTypeAllocSize(Ty) * cast<ConstantInt>(CI)->getSExtValue();
4986+
TotalOffs += GTI.getSequentialElementStride(DL) *
4987+
cast<ConstantInt>(CI)->getSExtValue();
49904988
continue;
49914989
}
49924990
if (TotalOffs) {
@@ -4997,7 +4995,7 @@ bool AArch64FastISel::selectGetElementPtr(const Instruction *I) {
49974995
}
49984996

49994997
// N = N + Idx * ElementSize;
5000-
uint64_t ElementSize = DL.getTypeAllocSize(Ty);
4998+
uint64_t ElementSize = GTI.getSequentialElementStride(DL);
50014999
unsigned IdxN = getRegForGEPIndex(Idx);
50025000
if (!IdxN)
50035001
return false;

llvm/lib/Target/ARM/ARMFastISel.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ bool ARMFastISel::ARMComputeAddress(const Value *Obj, Address &Addr) {
747747
unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
748748
TmpOffset += SL->getElementOffset(Idx);
749749
} else {
750-
uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
750+
uint64_t S = GTI.getSequentialElementStride(DL);
751751
while (true) {
752752
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
753753
// Constant-offset addressing.

llvm/lib/Target/Mips/MipsFastISel.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {
492492
unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
493493
TmpOffset += SL->getElementOffset(Idx);
494494
} else {
495-
uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
495+
uint64_t S = GTI.getSequentialElementStride(DL);
496496
while (true) {
497497
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
498498
// Constant-offset addressing.

llvm/lib/Target/PowerPC/PPCFastISel.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ bool PPCFastISel::PPCComputeAddress(const Value *Obj, Address &Addr) {
350350
unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
351351
TmpOffset += SL->getElementOffset(Idx);
352352
} else {
353-
uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
353+
uint64_t S = GTI.getSequentialElementStride(DL);
354354
for (;;) {
355355
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
356356
// Constant-offset addressing.

llvm/lib/Target/RISCV/RISCVGatherScatterLowering.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ RISCVGatherScatterLowering::determineBaseAndStride(Instruction *Ptr,
362362

363363
VecOperand = i;
364364

365-
TypeSize TS = DL->getTypeAllocSize(GTI.getIndexedType());
365+
TypeSize TS = GTI.getSequentialElementStride(*DL);
366366
if (TS.isScalable())
367367
return std::make_pair(nullptr, nullptr);
368368

llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ bool WebAssemblyFastISel::computeAddress(const Value *Obj, Address &Addr) {
278278
unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
279279
TmpOffset += SL->getElementOffset(Idx);
280280
} else {
281-
uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
281+
uint64_t S = GTI.getSequentialElementStride(DL);
282282
for (;;) {
283283
if (const auto *CI = dyn_cast<ConstantInt>(Op)) {
284284
// Constant-offset addressing.

llvm/lib/Target/X86/X86FastISel.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ bool X86FastISel::X86SelectAddress(const Value *V, X86AddressMode &AM) {
916916

917917
// A array/variable index is always of the form i*S where S is the
918918
// constant scale size. See if we can push the scale into immediates.
919-
uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
919+
uint64_t S = GTI.getSequentialElementStride(DL);
920920
for (;;) {
921921
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
922922
// Constant-offset addressing.

0 commit comments

Comments
 (0)