Changes to MismatchDetected

MismatchDetect wasn't detecting type size mismatch in this case

```llvm
%0 = alloca [2 x double]
%1 = getelementptr inbounds [2 x double], ptr %0, i64 0, i64 0
%2 = load <2 x i32>, ptr %1
```

As it was comparing number of bits allocated by load instruction type --
<2 x i32> to allocated bits of alloca scalar type -- double, resulting
in not detecting size mismatch as 64 == 64. I've changed approach to
using LLVM API getScalarSizeInBits() type method to compare scalar
sizes, similarily to what was done in typed pointers path (see
SOALayoutChecker::visitBitCastInst). Refactored control flow.
This commit is contained in:
Kreczko, Konrad
2025-09-30 13:05:10 +00:00
committed by igcbot
parent e4b64c1e55
commit 3e2f5492aa
2 changed files with 19 additions and 32 deletions

View File

@ -558,9 +558,6 @@ bool SOALayoutChecker::visitIntrinsicInst(IntrinsicInst &II) {
// Return true to disable SOA promotion.
bool IGC::SOALayoutChecker::MismatchDetected(Instruction &I) {
if (!isa<LoadInst>(I) && !isa<StoreInst>(I))
return false;
// Skip when we see an i8-based GEP with a non-constant (dynamic) byte offset. The legacy (old) algorithm assumes byte
// offsets map exactly to whole promoted elements (e.g. multiples of the lane size) and cannot safely reconstruct
// subelement (inter-lane or unaligned) accesses. Using it would risk incorrect indexing. The new byte-precise
@ -576,44 +573,28 @@ bool IGC::SOALayoutChecker::MismatchDetected(Instruction &I) {
}
}
// Apply the following mismatch checks only with opaque pointers.
if (!IGC::AreOpaquePointersEnabled())
return false;
if (!pInfo->baseType)
return false;
Type *allocaTy = allocaRef.getAllocatedType();
bool allocaIsVecOrArr = allocaTy->isVectorTy() || allocaTy->isArrayTy();
if (!allocaIsVecOrArr)
return false;
auto DL = I.getParent()->getParent()->getParent()->getDataLayout();
Type *pUserTy = I.getType();
if (auto *pgep = dyn_cast<GetElementPtrInst>(parentLevelInst))
allocaTy = pgep->getResultElementType();
if (auto *arrTy = dyn_cast<ArrayType>(allocaTy))
allocaTy = arrTy->getElementType();
if (auto *vec = dyn_cast<IGCLLVM::FixedVectorType>(allocaTy))
allocaTy = vec->getElementType();
Type *pUserTy = nullptr;
if (auto *storeInst = dyn_cast<StoreInst>(&I))
pUserTy = storeInst->getValueOperand()->getType();
else if (auto *loadInst = dyn_cast<LoadInst>(&I))
pUserTy = loadInst->getType();
else
return false;
if (auto *pgep = dyn_cast<GetElementPtrInst>(parentLevelInst)) {
allocaTy = pgep->getResultElementType();
} else {
if (auto *arrTy = dyn_cast<ArrayType>(allocaTy)) {
allocaTy = arrTy->getElementType();
} else if (auto *vec = dyn_cast<IGCLLVM::FixedVectorType>(allocaTy)) {
allocaTy = vec->getElementType();
}
if (auto *arrTy = dyn_cast<ArrayType>(pUserTy)) {
pUserTy = arrTy->getElementType();
} else if (auto *vec = dyn_cast<IGCLLVM::FixedVectorType>(pUserTy)) {
pUserTy = vec->getElementType();
}
}
auto allocaSize = DL.getTypeAllocSize(allocaTy);
auto vecTySize = DL.getTypeAllocSize(pUserTy);
auto allocaSize = allocaTy->getScalarSizeInBits();
auto vecTySize = pUserTy->getScalarSizeInBits();
if (vecTySize != allocaSize) {
pInfo->canUseSOALayout = false;

View File

@ -45,6 +45,12 @@ exit:
%arr3 = alloca [512 x i32]
%load2 = load i8, ptr %arr3
; This case tests whether load the size of allocas scalar type isn't marked as possible SOA layout
; CHECK: [[LOAD:%.*]] = load <2 x i32>, ptr {{.*}}, align 4
%arr4 = alloca [2 x double], align 8
%gep4 = getelementptr inbounds [2 x double], ptr %arr4, i64 0, i64 0
%load3 = load <2 x i32>, ptr %gep4, align 4
; Case Alloca->Store->Gep->Store: This case is not valid due to different sizes
; CHECK: store <4 x i32> zeroinitializer, ptr {{.*}}