Skip to content

Commit

Permalink
If a ptr arg is misaligned (ptr to 8bit/16bit, etc), we must
Browse files Browse the repository at this point in the history
use buffer offset to convert them to stateful; otherwise, they
must remain stateless.

This is due to the fact that surface state's base must be DW-aligned.
This bug was not exposed in ocl tests (probably due to less coverage).

THis code is off by default now.

Change-Id: I4721642454ad74559a47ff8afbf115100efc2e34
  • Loading branch information
jgu222 authored and sys_zuul committed Mar 7, 2020
1 parent 350842a commit fcfd6f6
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,20 @@ bool StatelessToStatefull::getOffsetFromGEP(
bool StatelessToStatefull::pointerIsPositiveOffsetFromKernelArgument(
Function* F, Value* V, Value*& offset, unsigned int& argNumber)
{
auto getPointeeAlign = [](const DataLayout* DL, Value* ptrVal)-> unsigned {
if (PointerType* PTy = dyn_cast<PointerType>(ptrVal->getType()))
{
Type* pointeeTy = PTy->getElementType();
if (!pointeeTy->isSized()) {
return 0;
}
return DL->getABITypeAlignment(pointeeTy);
}
return 0;
};

const DataLayout* DL = &F->getParent()->getDataLayout();

AssumptionCache* AC = getAC(F);

PointerType* ptrType = dyn_cast<PointerType>(V->getType());
Expand Down Expand Up @@ -370,18 +384,38 @@ bool StatelessToStatefull::pointerIsPositiveOffsetFromKernelArgument(
argNumber = arg->getAssociatedArgNo();
bool gepProducesPositivePointer = true;

// An address needs to be DW-aligned in order to be a base
// in a surface state. In another word, a unaligned argument
// cannot be used as a surface base unless buffer_offset is
// used, in which "argument + buffer_offset" is instead used
// as a surface base. (argument + buffer_offset is the original
// base of buffer created on host side, the original buffer is
// guarantted to be DW-aligned.)
//
// Note that implicit arg is always aligned.
bool isAlignedPointee =
(IGC_IS_FLAG_DISABLED(UseSubDWAlignedPtrArg) || arg->isImplicitArg())
? true
: (getPointeeAlign(DL, base) >= 4);

// If m_hasBufferOffsetArg is true, the offset argument is added to
// the final offset, and the final offset must be positive. Thus
// skip checking if an offset is positive.
// the final offset to make it definitely positive. Thus skip checking
// if an offset is positive.
//
// Howerver, if m_hasoptionalBufferOffsetArg is true, the buffer offset
// is not generated if all offsets can be proven positive (this has
// performance benefit as adding buffer offset is an additional add).
// Also, if an argument is unaligned, buffer offset must be ON and used;
// otherwise, no stateful conversion for the argument can be carried out.
//
// Note that offset should be positive for any implicit ptr argument
// Note that offset should be positive for any implicit ptr argument,
// so no need to prove it!
if (!arg->isImplicitArg() &&
isAlignedPointee &&
(!m_hasBufferOffsetArg || m_hasOptionalBufferOffsetArg) &&
IGC_IS_FLAG_DISABLED(SToSProducesPositivePointer))
{
// [This is conservative path]
// Need to verify if there is a negative offset,
// If so, no stateful message is generated.
// This is for proving that the offset is positive.
for (int i = 0, sz = GEPs.size(); i < sz; ++i)
{
GetElementPtrInst* tgep = GEPs[i];
Expand All @@ -398,7 +432,8 @@ bool StatelessToStatefull::pointerIsPositiveOffsetFromKernelArgument(
updateArgInfo(arg, gepProducesPositivePointer);
}
}
if ((gepProducesPositivePointer || m_hasBufferOffsetArg) &&
if ((m_hasBufferOffsetArg ||
(gepProducesPositivePointer && isAlignedPointee)) &&
getOffsetFromGEP(F, GEPs, argNumber, arg->isImplicitArg(), offset))
{
return true;
Expand Down
5 changes: 3 additions & 2 deletions IGC/common/igc_flags.def
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,9 @@ DECLARE_IGC_REGKEY(debugString, SIPOverrideFilePath, 0, "This key when en
DECLARE_IGC_REGKEY(bool, DumpPayloadToScratch, false, "Setting this to 1/true dumps thread payload to scartch space. Used for workloads which doesnt use scartch space for other purposes", false)
DECLARE_IGC_REGKEY(DWORD, DebugInternalSwitch, 0, "Code pass selection, debug only", false)
DECLARE_IGC_REGKEY(bool, SToSProducesPositivePointer, false, "This key is for StatelessToStatefull optimization if the user knows the pointer offset is postive to the kernel argument.", false)
DECLARE_IGC_REGKEY(bool, EnableSupportBufferOffset, false, "[Temporary]For StatelessToStatefull optimization [OCL], support implicit buffer offset argument (same as -cl-intel-has-buffer-offset-arg).", false)
DECLARE_IGC_REGKEY(bool, EnableOptionalBufferOffset, true, "[Temporary]For StatelessToStatefull optimization [OCL], if true, make buffer offset optional. Valid only if buffer offset is supported.", true)
DECLARE_IGC_REGKEY(bool, EnableSupportBufferOffset, false, "[debugging]For StatelessToStatefull optimization [OCL], support implicit buffer offset argument (same as -cl-intel-has-buffer-offset-arg).", false)
DECLARE_IGC_REGKEY(bool, EnableOptionalBufferOffset, true, "For StatelessToStatefull optimization [OCL], if true, make buffer offset optional. Valid only if buffer offset is supported.", true)
DECLARE_IGC_REGKEY(bool, UseSubDWAlignedPtrArg, false, "[OCL]If set, for kernel pointer arg such as ptr to char or short, the arg is not necessarily DW aligned", false)
DECLARE_IGC_REGKEY(bool, EnableTestIGCBuiltin, false, "Enable testing igc builtin (precompiled kernels) using OCL.", false)
DECLARE_IGC_REGKEY(bool, EnableCSSIMD32, false, "Enable computer shader SIMD32 mode, and fall back to lower SIMD when spill", false)
DECLARE_IGC_REGKEY(bool, ForceCSSIMD32, false, "Force computer shader SIMD32 mode", false)
Expand Down

0 comments on commit fcfd6f6

Please sign in to comment.