return ValidIndices.contains(IdxRange);
}
+/// The memory operation on a vector of \p ScalarType had alignment of
+/// \p VectorAlignment. Compute the maximal, but conservatively correct,
+/// alignment that will be valid for the memory operation on a single scalar
+/// element of the same type with index \p Idx.
+static Align computeAlignmentAfterScalarization(Align VectorAlignment,
+ Type *ScalarType, Value *Idx,
+ const DataLayout &DL) {
+ if (auto *C = dyn_cast<ConstantInt>(Idx))
+ return commonAlignment(VectorAlignment,
+ C->getZExtValue() * DL.getTypeStoreSize(ScalarType));
+ return commonAlignment(VectorAlignment, DL.getTypeStoreSize(ScalarType));
+}
+
// Combine patterns like:
// %0 = load <4 x i32>, <4 x i32>* %a
// %1 = insertelement <4 x i32> %0, i32 %b, i32 1
Builder.Insert(GEP);
StoreInst *NSI = Builder.CreateStore(NewElement, GEP);
NSI->copyMetadata(*SI);
- Align NewAlignment = std::max(SI->getAlign(), Load->getAlign());
- if (auto *C = dyn_cast<ConstantInt>(Idx))
- NewAlignment = commonAlignment(
- NewAlignment,
- C->getZExtValue() * DL.getTypeStoreSize(NewElement->getType()));
- else
- NewAlignment = commonAlignment(
- NewAlignment, DL.getTypeStoreSize(NewElement->getType()));
- NSI->setAlignment(NewAlignment);
+ Align ScalarOpAlignment = computeAlignmentAfterScalarization(
+ std::max(SI->getAlign(), Load->getAlign()), NewElement->getType(), Idx,
+ DL);
+ NSI->setAlignment(ScalarOpAlignment);
replaceValue(I, *NSI);
// Need erasing the store manually.
I.eraseFromParent();