Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions lib/SPIRVProducerPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2735,17 +2735,19 @@ SPIRVProducerPassImpl::getSPIRVPointerOperand(Value *PtrVal,
if (!PtrVal->getType()->isPointerTy()) {
return PtrID;
}
if (Option::UntypedPointerAddressSpace(
PtrVal->getType()->getPointerAddressSpace())) {
// Resolve rehoming so the expected pointer type carries the emitted
// storage class; a stale Global address space would register a spurious
// PhysicalStorageBuffer type and force an invalid OpBitcast.
auto AddrSpace = GetPointerAddressSpace(PtrVal);
if (Option::UntypedPointerAddressSpace(AddrSpace)) {
return PtrID;
}
SPIRVID ExpectedPtrTypeID =
getSPIRVPointerType(PtrVal->getType(), ExpectedPointeeTy);
auto *PtrTy = PointerType::get(module->getContext(), AddrSpace);
SPIRVID ExpectedPtrTypeID = getSPIRVPointerType(PtrTy, ExpectedPointeeTy);
auto it = IDTypeMap.find(PtrID.get());
if (it != IDTypeMap.end() && it->second.isValid() &&
it->second != ExpectedPtrTypeID) {
auto storage_class =
GetStorageClass(PtrVal->getType()->getPointerAddressSpace());
auto storage_class = GetStorageClass(AddrSpace);
if (storage_class == spv::StorageClassPhysicalStorageBuffer) {
SPIRVOperandVec Ops;
Ops << ExpectedPtrTypeID << PtrID;
Expand Down
21 changes: 21 additions & 0 deletions test/physical_bitcast_logical_pointer.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// A rehomed lookup table must keep its Private pointer: bitcasting it to a
// PhysicalStorageBuffer pointer would be invalid SPIR-V.

// RUN: clspv %target %s -physical-storage-buffers -arch=spirv64 -O2 -global-offset -std430-ubo-layout -module-constants-in-storage-buffer -o %t.spv
// RUN: spirv-dis -o %t.spvasm %t.spv
// RUN: FileCheck %s < %t.spvasm
// RUN: spirv-val --target-env vulkan1.2 %t.spv

// CHECK: OpVariable %_ptr_Private__arr_uint_uint_4 Private %{{[0-9]+}}
// CHECK-NOT: OpBitcast %_ptr_PhysicalStorageBuffer %{{[0-9]+}}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because typed pointers are used here, spirv-dis prints %_ptr_PhysicalStorageBuffer_uint, so CHECK-NOT: OpBitcast %_ptr_PhysicalStorageBuffer %{{[0-9]+}} (with a space before %) won't actually match OpBitcast %_ptr_PhysicalStorageBuffer_uint %<id>.

Suggested change
// CHECK-NOT: OpBitcast %_ptr_PhysicalStorageBuffer %{{[0-9]+}}
// CHECK-NOT: OpBitcast

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, the check had no teeth. Applied in f708cab: the CHECK-NOT is now any OpBitcast. On this branch the disassembly contains zero OpBitcast at all, and the pre-fix output I captured from main yesterday (one OpBitcast with the typed pointer name) now fails the check as it should.


kernel void repro(global int* out, int seed) {
uint t = 0;
switch (seed & 3) {
case 0: t = 0u; break;
case 1: t = 16777216u; break;
case 2: t = 65536u; break;
case 3: t = 256u; break;
}
out[3] = t;
}
Loading