Skip to content

Commit 92bd225

Browse files
committed
wip: Index into padded arrays
This is a bit tricky - when we have a padded array we have a struct with a slightly smaller array followed by the last element, since that last element doesn't itself have padding. Here, we create an imaginary array type with the padding on every element and index into that - this looks like we index out of bounds of the smaller array for the last element but this is okay because we only read the memory of the value that is legitimately there.
1 parent c73d2a3 commit 92bd225

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4681,22 +4681,27 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
46814681
} else if (E->getType().getAddressSpace() == LangAS::hlsl_constant) {
46824682
// This is an array inside of a cbuffer.
46834683
Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
4684-
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
46854684

4686-
// ...
4687-
CharUnits RowAlignedSize = getContext()
4688-
.getTypeSizeInChars(E->getType())
4689-
.alignTo(CharUnits::fromQuantity(16));
4685+
SmallVector<llvm::Value *, 2> Indices;
4686+
Indices.push_back(EmitIdxAfterBase(/*Promote*/true));
4687+
4688+
CharUnits ElementSize = getContext().getTypeSizeInChars(E->getType());
4689+
CharUnits RowAlignedSize = ElementSize.alignTo(CharUnits::fromQuantity(16));
46904690

4691-
llvm::Value *RowAlignedSizeVal =
4692-
llvm::ConstantInt::get(Idx->getType(), RowAlignedSize.getQuantity());
4693-
llvm::Value *ScaledIdx = Builder.CreateMul(Idx, RowAlignedSizeVal);
4691+
llvm::Type *EltTyToIndex = Addr.getElementType();
4692+
if (RowAlignedSize > ElementSize) {
4693+
llvm::Type *Padding = CGM.getTargetCodeGenInfo().getHLSLPadding(
4694+
CGM, RowAlignedSize - ElementSize);
4695+
EltTyToIndex = llvm::StructType::get(
4696+
getLLVMContext(), {EltTyToIndex, Padding}, /*isPacked=*/true);
4697+
Indices.push_back(llvm::ConstantInt::get(Indices[0]->getType(), 0));
4698+
}
46944699

46954700
CharUnits EltAlign =
4696-
getArrayElementAlign(Addr.getAlignment(), Idx, RowAlignedSize);
4701+
getArrayElementAlign(Addr.getAlignment(), Indices[0], RowAlignedSize);
46974702
llvm::Value *EltPtr =
4698-
emitArraySubscriptGEP(*this, Int8Ty, Addr.emitRawPointer(*this),
4699-
ScaledIdx, false, SignedIndices, E->getExprLoc());
4703+
emitArraySubscriptGEP(*this, EltTyToIndex, Addr.emitRawPointer(*this),
4704+
Indices, false, SignedIndices, E->getExprLoc());
47004705
Addr = Address(EltPtr, Addr.getElementType(), EltAlign);
47014706
} else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
47024707
// If this is A[i] where A is an array, the frontend will have decayed the

0 commit comments

Comments
 (0)