diff options
| author | Yong He <yonghe@outlook.com> | 2024-10-21 08:49:15 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-21 08:49:15 -0700 |
| commit | 3e84726f45c66b477569be9e62da71956ab78e94 (patch) | |
| tree | 8c69306133ee04b6acd14dd07d12a0ed47bf0079 /source/slang/slang-ir-lower-buffer-element-type.cpp | |
| parent | 20fa42e82dfa8398c9c818773fa40817883fb7ec (diff) | |
Fix spirv codegen for pointer to empty structs. (#5355)
Diffstat (limited to 'source/slang/slang-ir-lower-buffer-element-type.cpp')
| -rw-r--r-- | source/slang/slang-ir-lower-buffer-element-type.cpp | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp index 29999017a..9ea41e3b4 100644 --- a/source/slang/slang-ir-lower-buffer-element-type.cpp +++ b/source/slang/slang-ir-lower-buffer-element-type.cpp @@ -671,7 +671,26 @@ namespace Slang if (auto unsizedArrayType = as<IRUnsizedArrayType>(ptrType->getValueType())) { builder.setInsertBefore(ptrVal); - auto newArrayPtrVal = builder.emitGetOffsetPtr(fieldAddr->getBase(), builder.getIntValue(builder.getIntType(), 1)); + auto newArrayPtrVal = fieldAddr->getBase(); + // Is base a pointer to an empty struct? If so, don't offset it. + // For example, if the user has written: + // ``` + // struct S {int arr[]}; + // uniform S* p; + // void test() { p->arr[1]; } + // ``` + // Then `S` will become an empty struct after we remove `arr[]`. + // And `p` will be come a `void*`. + // We don't want to offset `p` to `p+1` to get the starting address of the array in this case. + IRSizeAndAlignment parentStructSize = {}; + getNaturalSizeAndAlignment( + target->getOptionSet(), + tryGetPointedToType(&builder, fieldAddr->getBase()->getDataType()), + &parentStructSize); + if (parentStructSize.size != 0) + { + newArrayPtrVal = builder.emitGetOffsetPtr(fieldAddr->getBase(), builder.getIntValue(builder.getIntType(), 1)); + } auto loweredInnerType = getLoweredTypeInfo(unsizedArrayType->getElementType(), layoutRules); IRSizeAndAlignment arrayElementSizeAlignment; @@ -685,12 +704,14 @@ namespace Slang &baseSizeAlignment); // Convert pointer to uint64 and adjust offset. - auto rawPtr = builder.emitBitCast(builder.getUInt64Type(), newArrayPtrVal); IRIntegerValue offset = baseSizeAlignment.size; offset = align(offset, arrayElementSizeAlignment.alignment); - newArrayPtrVal = builder.emitAdd(rawPtr->getFullType(), rawPtr, - builder.getIntValue(builder.getUInt64Type(), offset)); - + if (offset != 0) + { + auto rawPtr = builder.emitBitCast(builder.getUInt64Type(), newArrayPtrVal); + newArrayPtrVal = builder.emitAdd(rawPtr->getFullType(), rawPtr, + builder.getIntValue(builder.getUInt64Type(), offset)); + } newArrayPtrVal = builder.emitBitCast( builder.getPtrType(loweredInnerType.loweredType, ptrType->getAddressSpace()), newArrayPtrVal); |
