Skip to content

Commit

Permalink
Fixing kernel arg alignment
Browse files Browse the repository at this point in the history
The change fixes kernel arg alignment setting.
If a kernel argument has align attribute set then
the align value is used for initialization.
Next if appropriate attributes are available
the align value is calculated from these
attributes types.
  • Loading branch information
ViacheslavRb authored and igcbot committed Nov 26, 2024
1 parent 2e759fb commit 6ee988a
Show file tree
Hide file tree
Showing 3 changed files with 310 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ SPDX-License-Identifier: MIT
#include "llvm/Support/MathExtras.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvmWrapper/Support/Alignment.h"
#include "llvmWrapper/IR/Argument.h"
#include "common/LLVMWarningsPop.hpp"
#include <deque>
#include <set>
Expand Down Expand Up @@ -147,9 +148,20 @@ auto AlignmentAnalysis::getAlignValue(Value* V) const
{
if (arg->getType()->isPointerTy())
{

if (arg->hasAttribute(llvm::Attribute::Alignment)) {
uint64_t align = arg->getParamAlign().valueOrOne().value();
// Note that align 1 has no effect on non-byval, non-preallocated arguments.
if (align != 1 || arg->hasPreallocatedAttr() || arg->hasByValAttr())
return align;
}

Type* pointedTo = IGCLLVM::getArgAttrEltTy(arg);
if (pointedTo == nullptr && !IGCLLVM::isOpaquePointerTy(arg->getType()))
pointedTo = IGCLLVM::getNonOpaquePtrEltTy(arg->getType());

// Pointer arguments are guaranteed to be aligned on the ABI alignment
Type* pointedTo = IGCLLVM::getNonOpaquePtrEltTy(arg->getType());
if (pointedTo->isSized())
if (pointedTo != nullptr && pointedTo->isSized())
{
return m_DL->getABITypeAlign(pointedTo).value();
}
Expand Down
16 changes: 14 additions & 2 deletions IGC/Compiler/Optimizer/OpenCLPasses/KernelArgs/KernelArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ SPDX-License-Identifier: MIT
#include "Compiler/Optimizer/OpenCLPasses/KernelArgs/KernelArgs.hpp"
#include "AdaptorCommon/ImplicitArgs.hpp"
#include "llvmWrapper/IR/DerivedTypes.h"
#include "llvmWrapper/IR/Argument.h"
#include "common/LLVMWarningsPush.hpp"
#include <llvm/IR/Argument.h>
#include <llvm/IR/DataLayout.h>
Expand Down Expand Up @@ -102,15 +103,26 @@ alignment_t KernelArg::calcAlignment(const Argument* arg, const DataLayout* DL)
// If we don't need to allocate, we certainly don't need alignment
if (!needsAllocation()) return 0;

if (arg->hasAttribute(llvm::Attribute::Alignment)) {
uint64_t align = arg->getParamAlign().valueOrOne().value();
// Note that align 1 has no effect on non-byval, non-preallocated arguments.
if (align != 1 || arg->hasPreallocatedAttr() || arg->hasByValAttr())
return align;
}

Type* typeToAlign = arg->getType();
// Usually, we return the alignment of the parameter type.
// For local pointers, we need the alignment of the *contained* type.
if (m_argType == ArgType::PTR_LOCAL)
{
typeToAlign = IGCLLVM::getNonOpaquePtrEltTy(typeToAlign);
typeToAlign = IGCLLVM::getArgAttrEltTy(arg);
if (typeToAlign == nullptr && !IGCLLVM::isOpaquePointerTy(arg->getType()))
typeToAlign = IGCLLVM::getNonOpaquePtrEltTy(arg->getType());
}

return DL->getABITypeAlign(typeToAlign).value();
if (typeToAlign != nullptr)
return DL->getABITypeAlign(typeToAlign).value();
return /*MinimumAlignment*/1;
}

unsigned int KernelArg::calcElemAllocateSize(const Argument* arg, const DataLayout* DL) const
Expand Down
Loading

0 comments on commit 6ee988a

Please sign in to comment.