[llvm] [SPIR-V] Fix some GEP legalization (PR #150943)
Nathan Gauër via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 29 05:53:28 PDT 2025
================
@@ -1588,7 +1721,22 @@ void SPIRVEmitIntrinsics::insertPtrCastOrAssignTypeInstr(Instruction *I,
}
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
Value *Pointer = GEPI->getPointerOperand();
- Type *OpTy = GEPI->getSourceElementType();
+ Type *OpTy = nullptr;
+
+ // Knowing the accessed type is mandatory for logical SPIR-V. Sadly,
+ // the GEP source element type should not be used for this purpose, and
+ // the alternative type-scavenging method is not working.
+ // Physical SPIR-V can work around this, but not logical, hence still
+ // try to rely on the broken type scavenging for logical.
+ if (TM->getSubtargetImpl()->isLogicalSPIRV()) {
+ Value *Src = getPointerRoot(Pointer);
+ OpTy = GR->findDeducedElementType(Src);
+ }
----------------
Keenuts wrote:
Adding a switch to only change this for i8 GEP.
As for the given code, this is another issue impacting structured GEPs (non-i8) when accessing nested fields:
```
struct S {
int arr[10];
};
-> s.arr[index]
```
In this case, the generated GEP is something like:
`getelementptr [10 x int], %ptr, i32 0, i32 %index` instead of
`getelementptr [10 x int], %ptr, i32 0, i32 0, i32 %index`
-> The first index is usually not used to index into a nested field, but to index into the implicit array represented by the pointer. For this reason, our GEP lowering usually discards the first index. But here, this means we'd generate:
`OpAccessChain %v4f %ptr %index` instead of the required `OpAccessChain %v4f %ptr %index`.
I should work on some kind of "fixOpAccessChainDepth` step or something like that. But since this impacts structured GEP and not i8 gep, I'd move this to another PR.
https://github.com/llvm/llvm-project/pull/150943
More information about the llvm-commits
mailing list