GenXStructSplitter opaque pointers fix

Handle the special opaque pointers case when a GEP user indexing into a
non-structure type because leading zero indices are omitted.
This commit is contained in:
Shelegov, Maksim
2025-08-21 13:54:11 +00:00
committed by igcbot
parent 5e4a7b9e87
commit 9e80e069bb
2 changed files with 62 additions and 8 deletions

View File

@ -1,6 +1,6 @@
/*========================== begin_copyright_notice ============================
Copyright (C) 2021-2024 Intel Corporation
Copyright (C) 2021-2025 Intel Corporation
SPDX-License-Identifier: MIT
@ -1582,6 +1582,16 @@ bool Substituter::processGEP(GetElementPtrInst &GEPI,
unsigned PlainTyIdx = FindIt - GottenTypeArr.begin();
if (PlainTyIdx == Size) {
Type *PrevType = IdxPath.getTyAt(Size - 1);
// In case of opaque pointers, GEP's leading zero indices can be omitted and
// in this case previous type is not a structure type
if (!isa<StructType>(PrevType)) {
Type *PlainType = getBaseTy(GottenTypeArr[Size - 1]);
Instruction *ToInsert =
generateNewGEPs(GEPI, *PlainType, IdxPath, NewInstr, Size - 1);
InstToInst.emplace_back(cast<Instruction>(&GEPI), ToInsert);
return true;
}
// Case of FE1
auto InstUses = getInstUses(GEPI);
if (!InstUses)
@ -1590,7 +1600,6 @@ bool Substituter::processGEP(GetElementPtrInst &GEPI,
// That means that we are getting split struct so we need to create GEPs.
// STyToBeSplit is the result of the instruction.
Type *PrevType = IdxPath.getTyAt(Size - 1);
unsigned Idx = IdxPath.getIdxAt(Size - 1);
StructType *STyToBeSplit = cast<StructType>(PrevType);
const ListOfSplitElements &ListOfPossibleTypes =
@ -1621,14 +1630,18 @@ bool Substituter::processGEP(GetElementPtrInst &GEPI,
return false;
} else {
Type *PrevType = IdxPath.getTyAt(PlainTyIdx);
unsigned Idx = IdxPath.getIdxAt(PlainTyIdx);
StructType *STyToBeSplit = cast<StructType>(PrevType);
IGC_ASSERT_MESSAGE(
Graph.getElementsListOfSTyAtIdx(*STyToBeSplit, Idx).size() == 1,
"Access to element of Struct does not get unsplit type.");
Type *PlainType = getBaseTy(GottenTypeArr[PlainTyIdx]);
// In case of opaque pointers, GEP's leading zero indices can be omitted and
// in this case previous type is not a structure type
if (auto *STyToBeSplit = dyn_cast<StructType>(PrevType)) {
unsigned Idx = IdxPath.getIdxAt(PlainTyIdx);
IGC_ASSERT_MESSAGE(
Graph.getElementsListOfSTyAtIdx(*STyToBeSplit, Idx).size() == 1,
"Access to element of Struct does not get unsplit type.");
PlainTyIdx += 1;
}
Instruction *ToInsert =
generateNewGEPs(GEPI, *PlainType, IdxPath, NewInstr, PlainTyIdx + 1);
generateNewGEPs(GEPI, *PlainType, IdxPath, NewInstr, PlainTyIdx);
InstToInst.emplace_back(cast<Instruction>(&GEPI), ToInsert);
}
return true;

View File

@ -0,0 +1,41 @@
;=========================== begin_copyright_notice ============================
;
; Copyright (C) 2025 Intel Corporation
;
; SPDX-License-Identifier: MIT
;
;============================ end_copyright_notice =============================
; RUN: %opt_opaque_ptrs %use_old_pass_manager% -GenXStructSplitter -dce -vc-struct-splitting=1 -march=genx64 -mcpu=XeLP -S < %s | FileCheck %s --check-prefixes=CHECK
%struct1 = type { [6 x %struct2] }
%struct2 = type { [129 x float] }
; CHECK-LABEL: @test1
define dllexport spir_kernel void @test1(float %val, i64 %idx1, i64 %idx2) {
entry:
; CHECK: [[ALLOCA_F:%.*]] = alloca [6 x %struct2]
%alloca = alloca %struct1
; CHECK-NEXT: [[GEP1_SPLIT:%.*]] = getelementptr [6 x %struct2], ptr [[ALLOCA_F]], i64 0, i64 %idx1
%gep1 = getelementptr [6 x %struct2], ptr %alloca, i64 0, i64 %idx1
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr [129 x float], ptr [[GEP1_SPLIT]], i64 0, i64 %idx2
%gep2 = getelementptr [129 x float], ptr %gep1, i64 0, i64 %idx2
; CHECK-NEXT: store float %val, ptr [[GEP2]]
store float %val, ptr %gep2
; CHECK-NEXT: ret void
ret void
}
; CHECK-LABEL: @test2
define dllexport spir_kernel void @test2(float %val, i64 %idx) {
entry:
; CHECK: [[ALLOCA_F:%.*]] = alloca [6 x %struct2]
%alloca = alloca %struct1
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr [129 x float], ptr [[ALLOCA_F]], i64 0, i64 %idx
%gep = getelementptr [129 x float], ptr %alloca, i64 0, i64 %idx
; CHECK-NEXT: store float %val, ptr [[GEP_SPLIT]]
store float %val, ptr %gep
; CHECK-NEXT: ret void
ret void
}