diff --git a/lib/SimplifyPointerBitcastPass.cpp b/lib/SimplifyPointerBitcastPass.cpp index 25d9a38f5..41d21166a 100644 --- a/lib/SimplifyPointerBitcastPass.cpp +++ b/lib/SimplifyPointerBitcastPass.cpp @@ -391,6 +391,7 @@ bool clspv::SimplifyPointerBitcastPass::runOnImplicitGEP(Module &M) const { SmallVector GEPBeforeStoreList; SmallVector GEPBeforeLoadList; SmallVector GEPCastList; + SmallVector GEPGVList; for (auto &F : M) { for (auto &BB : F) { for (auto &I : BB) { @@ -429,6 +430,9 @@ bool clspv::SimplifyPointerBitcastPass::runOnImplicitGEP(Module &M) const { } else if (auto gep = dyn_cast(&I)) { if (IsClspvResourceOrLocal(gep->getPointerOperand())) { GEPCastList.push_back(dyn_cast(&I)); + } else if (isa(gep->getPointerOperand()) && + gep->hasAllConstantIndices()) { + GEPGVList.push_back(dyn_cast(&I)); } } } @@ -549,6 +553,24 @@ bool clspv::SimplifyPointerBitcastPass::runOnImplicitGEP(Module &M) const { gep->eraseFromParent(); changed = true; } + for (auto gep : GEPGVList) { + auto ptr = gep->getPointerOperand(); + auto ty = InferType(ptr, M.getContext(), &type_cache); + IRBuilder<> Builder{gep}; + uint64_t cstVal; + Value *dynVal; + size_t smallerBitWidths; + ExtractOffsetFromGEP(DL, Builder, gep, cstVal, dynVal, smallerBitWidths); + auto new_gep_idxs = GetIdxsForTyFromOffset(DL, Builder, ty, nullptr, cstVal, + dynVal, smallerBitWidths, ptr); + auto new_gep = GetElementPtrInst::Create(ty, ptr, new_gep_idxs, "", gep); + LLVM_DEBUG(dbgs() << "\n##runOnImplicitGEP (from GV):\nreplacing: "; + gep->dump()); + LLVM_DEBUG(dbgs() << "by: "; new_gep->dump();); + gep->replaceAllUsesWith(new_gep); + gep->eraseFromParent(); + changed = true; + } return changed; } diff --git a/test/PhysicalStorageBuffers/physical_constant_ptrtoint.cl b/test/PhysicalStorageBuffers/physical_constant_ptrtoint.cl index d647df4dd..e74d30235 100644 --- a/test/PhysicalStorageBuffers/physical_constant_ptrtoint.cl +++ b/test/PhysicalStorageBuffers/physical_constant_ptrtoint.cl @@ -3,9 +3,6 @@ // RUN: FileCheck %s < %t2.spvasm // RUN: spirv-val --target-env vulkan1.0 %t.spv -// TODO(#1358): Invalid SPIR-V trying to extract the 5th element of a 4-element vector -// XFAIL: * - constant char myconst[5] = { 42 }; kernel void test(global ulong *a, constant int *b) @@ -19,25 +16,25 @@ kernel void test(global ulong *a, constant int *b) // CHECK-DAG: [[uint:%[a-zA-Z0-9_]+]] = OpTypeInt 32 // CHECK-DAG: [[ulong:%[a-zA-Z0-9_]+]] = OpTypeInt 64 // CHECK-DAG: [[ptr_physical_ulong:%[a-zA-Z0-9_]+]] = OpTypePointer PhysicalStorageBuffer [[ulong]] -// CHECK-DAG: [[ptr_physical_uint:%[a-zA-Z0-9_]+]] = OpTypePointer PhysicalStorageBuffer [[uint]] -// CHECK-DAG: OpDecorate [[ptr_physical_uint]] ArrayStride 4 // CHECK-DAG: OpDecorate [[ptr_physical_ulong]] ArrayStride 8 // CHECK-DAG: OpDecorate [[global_id:%[a-zA-Z0-9_]+]] BuiltIn GlobalInvocationId // CHECK-DAG: [[uchar:%[a-zA-Z0-9_]+]] = OpTypeInt 8 // CHECK-DAG: [[uint_0:%[a-zA-Z0-9_]+]] = OpConstant [[uint]] 0 // CHECK-DAG: [[uint_5:%[a-zA-Z0-9_]+]] = OpConstant [[uint]] 5 +// CHECK-DAG: [[ulong_2:%[a-zA-Z0-9_]+]] = OpConstant [[ulong]] 2 // CHECK-DAG: [[arr_uchar_5:%[a-zA-Z0-9_]+]] = OpTypeArray [[uchar]] [[uint_5]] // CHECK-DAG: [[arr_uchar_5_struct:%[a-zA-Z0-9_]+]] = OpTypeStruct [[arr_uchar_5]] // CHECK-DAG: [[ptr_physical_arr_uchar_5:%[a-zA-Z0-9_]+]] = OpTypePointer PhysicalStorageBuffer [[arr_uchar_5_struct]] // CHECK-DAG: [[ptr_physical_uchar:%[a-zA-Z0-9_]+]] = OpTypePointer PhysicalStorageBuffer [[uchar]] -// CHECK: [[ptr_a:%[a-zA-Z0-9_]+]] = OpConvertUToPtr [[ptr_physical_ulong]] -// CHECK: [[ptr_b:%[a-zA-Z0-9_]+]] = OpConvertUToPtr [[ptr_physical_uint]] +// CHECK: [[ptr_a_int:%[a-zA-Z0-9_]+]] = OpBitwiseOr [[ulong]] +// CHECK: [[ptr_b_int:%[a-zA-Z0-9_]+]] = OpBitwiseOr [[ulong]] +// CHECK: [[ptr_a:%[a-zA-Z0-9_]+]] = OpConvertUToPtr [[ptr_physical_ulong]] [[ptr_a_int]] // CHECK: [[gid_x_ptr:%[a-zA-Z0-9_]+]] = OpAccessChain %{{[a-zA-Z0-9_]+}} [[global_id]] [[uint_0]] // CHECK: [[gid_x_load:%[a-zA-Z0-9_]+]] = OpLoad [[uint]] [[gid_x_ptr]] // CHECK: [[gid_x:%[a-zA-Z0-9_]+]] = OpUConvert [[ulong]] [[gid_x_load]] -// CHECK: [[ptr_b_offset:%[a-zA-Z0-9_]+]] = OpPtrAccessChain [[ptr_physical_uint]] [[ptr_b]] [[gid_x]] -// CHECK: [[ptr_b_offset_int:%[a-zA-Z0-9_]+]] = OpConvertPtrToU [[ulong]] [[ptr_b_offset]] +// CHECK: [[gid_x_shift:%[a-zA-Z0-9_]+]] = OpShiftLeftLogical [[ulong]] [[gid_x]] [[ulong_2]] +// CHECK: [[ptr_b_offset_int:%[a-zA-Z0-9_]+]] = OpIAdd [[ulong]] [[ptr_b_int]] [[gid_x_shift]] // CHECK: [[ptr_a_offset:%[a-zA-Z0-9_]+]] = OpPtrAccessChain [[ptr_physical_ulong]] [[ptr_a]] [[gid_x]] // CHECK: OpStore [[ptr_a_offset]] [[ptr_b_offset_int]] Aligned 8 // CHECK: [[ptr_consts:%[a-zA-Z0-9_]+]] = OpConvertUToPtr [[ptr_physical_arr_uchar_5]]