@@ -213,26 +213,38 @@ getScalarSpecConstMetadata(const Instruction *I) {
213
213
// / Recursively iterates over a composite type in order to collect information
214
214
// / about its scalar elements.
215
215
void collectCompositeElementsInfoRecursive (
216
- const Type *Ty, unsigned &Index, unsigned &Offset,
216
+ const Module *M, Type *Ty, unsigned &Index, unsigned &Offset,
217
217
std::vector<CompositeSpecConstElementDescriptor> &Result) {
218
218
if (auto *ArrTy = dyn_cast<ArrayType>(Ty)) {
219
219
for (size_t I = 0 ; I < ArrTy->getNumElements (); ++I) {
220
220
// TODO: this is a spot for potential optimization: for arrays we could
221
221
// just make a single recursive call here and use it to populate Result
222
222
// in a loop.
223
- collectCompositeElementsInfoRecursive (ArrTy->getElementType (), Index,
223
+ collectCompositeElementsInfoRecursive (M, ArrTy->getElementType (), Index,
224
224
Offset, Result);
225
225
}
226
226
} else if (auto *StructTy = dyn_cast<StructType>(Ty)) {
227
- for (Type *ElTy : StructTy->elements ()) {
228
- collectCompositeElementsInfoRecursive (ElTy, Index, Offset, Result);
227
+ const StructLayout *SL = M->getDataLayout ().getStructLayout (StructTy);
228
+ for (size_t I = 0 , E = StructTy->getNumElements (); I < E; ++I) {
229
+ auto *ElTy = StructTy->getElementType (I);
230
+ // When handling elements of a structure, we do not use manually
231
+ // calculated offsets (which are sum of sizes of all previously
232
+ // encountered elements), but instead rely on data provided for us by
233
+ // DataLayout, because the structure can be unpacked, i.e. padded in
234
+ // order to ensure particular alignment of its elements.
235
+ unsigned LocalOffset = Offset + SL->getElementOffset (I);
236
+ collectCompositeElementsInfoRecursive (M, ElTy, Index, LocalOffset,
237
+ Result);
229
238
}
239
+ // Update "global" offset according to the total size of a handled struct
240
+ // type.
241
+ Offset += SL->getSizeInBytes ();
230
242
} else if (auto *VecTy = dyn_cast<FixedVectorType>(Ty)) {
231
243
for (size_t I = 0 ; I < VecTy->getNumElements (); ++I) {
232
244
// TODO: this is a spot for potential optimization: for vectors we could
233
245
// just make a single recursive call here and use it to populate Result
234
246
// in a loop.
235
- collectCompositeElementsInfoRecursive (VecTy->getElementType (), Index,
247
+ collectCompositeElementsInfoRecursive (M, VecTy->getElementType (), Index,
236
248
Offset, Result);
237
249
}
238
250
} else { // Assume that we encountered some scalar element
@@ -256,7 +268,8 @@ getCompositeSpecConstMetadata(const Instruction *I) {
256
268
std::vector<CompositeSpecConstElementDescriptor> Result (N->getNumOperands () -
257
269
1 );
258
270
unsigned Index = 0 , Offset = 0 ;
259
- collectCompositeElementsInfoRecursive (I->getType (), Index, Offset, Result);
271
+ collectCompositeElementsInfoRecursive (I->getModule (), I->getType (), Index,
272
+ Offset, Result);
260
273
261
274
for (unsigned I = 1 ; I < N->getNumOperands (); ++I) {
262
275
const auto *MDInt = cast<ConstantAsMetadata>(N->getOperand (I));
0 commit comments