summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-lower-buffer-element-type.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-10-21 08:49:15 -0700
committerGitHub <noreply@github.com>2024-10-21 08:49:15 -0700
commit3e84726f45c66b477569be9e62da71956ab78e94 (patch)
tree8c69306133ee04b6acd14dd07d12a0ed47bf0079 /source/slang/slang-ir-lower-buffer-element-type.cpp
parent20fa42e82dfa8398c9c818773fa40817883fb7ec (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.cpp31
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);