[clang] [llvm] Explicit types in cbuffer layouts (PR #156919)
Steven Perron via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 3 07:04:39 PDT 2025
================
@@ -4678,6 +4678,26 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
emitArraySubscriptGEP(*this, Int8Ty, Addr.emitRawPointer(*this),
ScaledIdx, false, SignedIndices, E->getExprLoc());
Addr = Address(EltPtr, OrigBaseElemTy, EltAlign);
+ } else if (E->getType().getAddressSpace() == LangAS::hlsl_constant) {
+ // This is an array inside of a cbuffer.
+ Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
+ auto *Idx = EmitIdxAfterBase(/*Promote*/true);
+
+ // ...
+ CharUnits RowAlignedSize = getContext()
+ .getTypeSizeInChars(E->getType())
+ .alignTo(CharUnits::fromQuantity(16));
+
+ llvm::Value *RowAlignedSizeVal =
+ llvm::ConstantInt::get(Idx->getType(), RowAlignedSize.getQuantity());
+ llvm::Value *ScaledIdx = Builder.CreateMul(Idx, RowAlignedSizeVal);
+
+ CharUnits EltAlign =
+ getArrayElementAlign(Addr.getAlignment(), Idx, RowAlignedSize);
+ llvm::Value *EltPtr =
+ emitArraySubscriptGEP(*this, Int8Ty, Addr.emitRawPointer(*this),
+ ScaledIdx, false, SignedIndices, E->getExprLoc());
----------------
s-perron wrote:
@bogner You are still generating this GEP with an i8. Can we change this to a GEP on the array type.
Start with the test at the end. Compile with `clang-dxc test_minimal_peeling.hlsl -T cs_6_8 -spirv -fcgl`
The access to myArray is:
```
%3 = load i32, ptr %index, align 4, !tbaa !4
%idxprom = zext i32 %3 to i64
%4 = mul i64 %idxprom, 16
%arrayidx = getelementptr i8, ptr addrspace(12) @myArray, i64 %4 ; <-- problem for SPIR-V.
%f = getelementptr inbounds nuw %struct.OrigType, ptr addrspace(12) %arrayidx, i32 0, i32 0
%5 = load float, ptr addrspace(12) %f, align 1, !tbaa !14
```
It would be better if it could be
```
%3 = load i32, ptr %index, align 4, !tbaa !4
%idxprom = zext i32 %3 to i64
%arrayidx = getelementptr [4 x <{ %OrigType, target("spirv.Padding", 12) }>], ptr addrspace(12) @myArray, i64 %idxprom ; <-- Explicit array
%f = getelementptr inbounds nuw %struct.OrigType, ptr addrspace(12) %arrayidx, i32 0, i32 0
%5 = load float, ptr addrspace(12) %f, align 1, !tbaa !14
```
You use the original array size with the padding.
```
struct OrigType {
float f;
};
cbuffer MyCBuffer {
OrigType myArray[4];
float anotherValue;
};
RWBuffer<float4> output;
[numthreads(1, 1, 1)]
void main(uint3 DTid : SV_DispatchThreadID) {
uint index = DTid.x % 4;
float v = myArray[index].f;
float f = anotherValue;
output[0] = float4(v, f, 0, 0);
}
```
https://github.com/llvm/llvm-project/pull/156919
More information about the llvm-commits
mailing list