Skip to content

Commit 36debf9

Browse files
Dimus77igcbot
authored andcommitted
Revert Specify pointer arithmetic to avoid tagging #377
1 parent b5491c5 commit 36debf9

File tree

3 files changed

+200
-29
lines changed

3 files changed

+200
-29
lines changed

IGC/Compiler/CISACodeGen/EmitVISAPass.cpp

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8748,6 +8748,22 @@ void EmitPass::emitGEP(llvm::Instruction* I)
87488748
void EmitPass::emitIntToPtr(llvm::IntToPtrInst* I2P)
87498749
{
87508750
CVariable* src = GetSymbol(I2P->getOperand(0));
8751+
unsigned addrSpace = I2P->getAddressSpace();
8752+
8753+
MDNode* genericMD = I2P->getMetadata("generic.arithmetic");
8754+
8755+
// Check if tag needs to be added before emitting I2P
8756+
if (addrSpace == ADDRESS_SPACE_GENERIC && genericMD)
8757+
{
8758+
// If the target address space is generic and the var was used for pointer arithmetic
8759+
// the private/local tag must be added at this time.
8760+
ConstantAsMetadata* MD = cast<ConstantAsMetadata>(genericMD->getOperand(0));
8761+
unsigned srcAddrSpace = (unsigned)dyn_cast<ConstantInt>(MD->getValue())->getZExtValue();
8762+
CVariable* taggedSrc = createAddressSpaceTag(src, srcAddrSpace);
8763+
if (taggedSrc)
8764+
src = taggedSrc;
8765+
}
8766+
87518767
CVariable* IntVar = m_currShader->BitCast(src, GetUnsignedType(src->GetType()));
87528768
m_encoder->Cast(m_destination, IntVar);
87538769
m_encoder->Push();
@@ -9080,6 +9096,153 @@ void EmitPass::emitAddrSpaceCast(llvm::AddrSpaceCastInst* addrSpaceCast)
90809096
}
90819097
}
90829098

9099+
CVariable* EmitPass::createAddressSpaceTag(CVariable* src, unsigned int addrSpace)
9100+
{
9101+
CVariable* taggedSrc = nullptr;
9102+
if (addrSpace == ADDRESS_SPACE_PRIVATE)
9103+
{
9104+
if (m_pCtx->m_hasEmu64BitInsts && m_currShader->m_Platform->hasNoFullI64Support())
9105+
{
9106+
if (m_currShader->GetContext()->getRegisterPointerSizeInBits(addrSpace) == 32)
9107+
{
9108+
// Add tag to high part
9109+
taggedSrc = m_currShader->BitCast(m_destination, ISA_TYPE_UD);
9110+
// Low:
9111+
m_encoder->SetDstRegion(2);
9112+
m_encoder->Copy(taggedSrc, src);
9113+
m_encoder->Push();
9114+
// High:
9115+
m_encoder->SetDstSubReg(1);
9116+
m_encoder->SetDstRegion(2);
9117+
m_encoder->Copy(taggedSrc, m_currShader->ImmToVariable(0x20000000, ISA_TYPE_UD));
9118+
m_encoder->Push();
9119+
}
9120+
else
9121+
{
9122+
// Src
9123+
CVariable* srcAlias = m_currShader->GetNewAlias(src, ISA_TYPE_UD, 0, 0);
9124+
CVariable* srcLow = m_currShader->GetNewVariable(
9125+
numLanes(m_currShader->m_SIMDSize),
9126+
ISA_TYPE_UD, EALIGN_GRF, m_destination->IsUniform(),
9127+
CName(src->getName(), "Lo"));
9128+
CVariable* srcHigh = m_currShader->GetNewVariable(
9129+
numLanes(m_currShader->m_SIMDSize),
9130+
ISA_TYPE_UD, EALIGN_GRF, m_destination->IsUniform(),
9131+
CName(src->getName(), "Hi"));
9132+
9133+
// Split Src into {Low, High}
9134+
// Low:
9135+
m_encoder->SetSrcSubReg(0, 0);
9136+
m_encoder->SetSrcRegion(0, 2, 1, 0);
9137+
m_encoder->Copy(srcLow, srcAlias);
9138+
m_encoder->Push();
9139+
// High:
9140+
m_encoder->SetSrcSubReg(0, 1);
9141+
m_encoder->SetSrcRegion(0, 2, 1, 0);
9142+
m_encoder->Copy(srcHigh, srcAlias);
9143+
m_encoder->Push();
9144+
9145+
// Add tag to high part
9146+
m_encoder->Or(srcHigh, srcHigh, m_currShader->ImmToVariable(0x20000000, ISA_TYPE_UD));
9147+
m_encoder->Push();
9148+
9149+
// Copy result to Dst
9150+
taggedSrc = m_currShader->BitCast(m_destination, ISA_TYPE_UD);
9151+
// Low:
9152+
m_encoder->SetDstRegion(2);
9153+
m_encoder->Copy(taggedSrc, srcLow);
9154+
m_encoder->Push();
9155+
// High:
9156+
m_encoder->SetDstSubReg(1);
9157+
m_encoder->SetDstRegion(2);
9158+
m_encoder->Copy(taggedSrc, srcHigh);
9159+
m_encoder->Push();
9160+
}
9161+
}
9162+
else
9163+
{
9164+
taggedSrc = m_currShader->GetNewVariable(
9165+
numLanes(m_currShader->m_SIMDSize),
9166+
ISA_TYPE_UQ, m_currShader->getGRFAlignment(),
9167+
m_destination->IsUniform(), CName::NONE);
9168+
m_encoder->Or(taggedSrc, src, m_currShader->ImmToVariable(1ULL << 61, ISA_TYPE_UQ));
9169+
m_encoder->Push();
9170+
}
9171+
}
9172+
else if (addrSpace == ADDRESS_SPACE_LOCAL)
9173+
{
9174+
if (m_pCtx->m_hasEmu64BitInsts && m_currShader->m_Platform->hasNoFullI64Support())
9175+
{
9176+
if (m_currShader->GetContext()->getRegisterPointerSizeInBits(addrSpace) == 32)
9177+
{
9178+
// Add tag to high part
9179+
taggedSrc = m_currShader->BitCast(m_destination, ISA_TYPE_UD);
9180+
// Low:
9181+
m_encoder->SetDstRegion(2);
9182+
m_encoder->Copy(taggedSrc, src);
9183+
m_encoder->Push();
9184+
// High:
9185+
m_encoder->SetDstSubReg(1);
9186+
m_encoder->SetDstRegion(2);
9187+
m_encoder->Copy(taggedSrc, m_currShader->ImmToVariable(0x40000000, ISA_TYPE_UD));
9188+
m_encoder->Push();
9189+
}
9190+
else
9191+
{
9192+
// Src
9193+
CVariable* srcAlias = m_currShader->GetNewAlias(src, ISA_TYPE_UD, 0, 0);
9194+
CVariable* srcLow = m_currShader->GetNewVariable(
9195+
numLanes(m_currShader->m_SIMDSize),
9196+
ISA_TYPE_UD, EALIGN_GRF, m_destination->IsUniform(),
9197+
CName(src->getName(), "Lo"));
9198+
CVariable* srcHigh = m_currShader->GetNewVariable(
9199+
numLanes(m_currShader->m_SIMDSize),
9200+
ISA_TYPE_UD, EALIGN_GRF, m_destination->IsUniform(),
9201+
CName(src->getName(), "Hi"));
9202+
9203+
// Split Src into {Low, High}
9204+
// Low:
9205+
m_encoder->SetSrcSubReg(0, 0);
9206+
m_encoder->SetSrcRegion(0, 2, 1, 0);
9207+
m_encoder->Copy(srcLow, srcAlias);
9208+
m_encoder->Push();
9209+
// High:
9210+
m_encoder->SetSrcSubReg(0, 1);
9211+
m_encoder->SetSrcRegion(0, 2, 1, 0);
9212+
m_encoder->Copy(srcHigh, srcAlias);
9213+
m_encoder->Push();
9214+
9215+
// Add tag to high part
9216+
m_encoder->Or(srcHigh, srcHigh, m_currShader->ImmToVariable(0x40000000, ISA_TYPE_UD));
9217+
m_encoder->Push();
9218+
9219+
// Copy result to Dst
9220+
taggedSrc = m_currShader->BitCast(m_destination, ISA_TYPE_UD);
9221+
// Low:
9222+
m_encoder->SetDstRegion(2);
9223+
m_encoder->Copy(taggedSrc, srcLow);
9224+
m_encoder->Push();
9225+
// High:
9226+
m_encoder->SetDstSubReg(1);
9227+
m_encoder->SetDstRegion(2);
9228+
m_encoder->Copy(taggedSrc, srcHigh);
9229+
m_encoder->Push();
9230+
}
9231+
}
9232+
else
9233+
{
9234+
taggedSrc = m_currShader->GetNewVariable(
9235+
numLanes(m_currShader->m_SIMDSize),
9236+
ISA_TYPE_UQ, m_currShader->getGRFAlignment(),
9237+
m_destination->IsUniform(),
9238+
CName::NONE);
9239+
m_encoder->Or(taggedSrc, src, m_currShader->ImmToVariable(1ULL << 62, ISA_TYPE_UQ));
9240+
m_encoder->Push();
9241+
}
9242+
}
9243+
return taggedSrc;
9244+
}
9245+
90839246
void EmitPass::emitExtract(llvm::Instruction* inst)
90849247
{
90859248
IGC_ASSERT(llvm::isa<llvm::ExtractElementInst>(inst));

IGC/Compiler/CISACodeGen/EmitVISAPass.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,9 @@ class EmitPass : public llvm::FunctionPass
706706

707707
void emitFeedbackEnable();
708708

709+
// Helper function to create address space tag on generic pointers
710+
CVariable* createAddressSpaceTag(CVariable* src, unsigned int addrSpace);
711+
709712
// used for loading/storing uniform value using scatter/gather messages.
710713
CVariable* prepareAddressForUniform(
711714
CVariable* AddrVar, uint32_t EltBytes, uint32_t NElts, uint32_t ExecSz, e_alignment Align);

IGC/Compiler/Optimizer/OpenCLPasses/GenericAddressResolution/GenericAddressDynamicResolution.cpp

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -490,51 +490,56 @@ bool GenericAddressDynamicResolution::visitIntrinsicCall(CallInst& I)
490490
bool GenericAddressDynamicResolution::allowArithmeticOnGenericAddressSpace(Function& F)
491491
{
492492
LLVMContext& C = F.getContext();
493+
493494
bool modified = false;
494495

496+
SmallVector<AddrSpaceCastInst*, 8> ASCInsts;
497+
SmallVector<IntToPtrInst*, 8> ITPInsts;
498+
495499
// iterate for all addrspacecast to generic pointers
496500
for (inst_iterator i = inst_begin(F); i != inst_end(F); ++i)
497501
{
498-
AddrSpaceCastInst* addrSpaceCastInst = dyn_cast<AddrSpaceCastInst>(&*i);
499-
bool multipleUses = false;
500-
bool pointerArith = false;
501-
502+
AddrSpaceCastInst* addrSpaceCastInst = llvm::dyn_cast<AddrSpaceCastInst>(&*i);
503+
IntToPtrInst* intToPtrInst = llvm::dyn_cast<IntToPtrInst>(&*i);
502504
if (addrSpaceCastInst && addrSpaceCastInst->getDestAddressSpace() == ADDRESS_SPACE_GENERIC)
503505
{
504-
multipleUses = !addrSpaceCastInst->hasOneUse();
505-
506506
for (auto ui : addrSpaceCastInst->users())
507507
{
508508
Instruction* useInst = dyn_cast<Instruction>(ui);
509-
PHINode* phi = dyn_cast<PHINode>(useInst);
510-
GetElementPtrInst* gepInst = dyn_cast<GetElementPtrInst>(useInst);
511-
while (phi || gepInst)
512-
{
513-
multipleUses |= !useInst->hasOneUse();
514-
useInst = useInst->user_back();
515-
phi = dyn_cast<PHINode>(useInst);
516-
gepInst = dyn_cast<GetElementPtrInst>(useInst);
517-
}
518-
519-
PtrToIntInst* ptiInst = dyn_cast<PtrToIntInst>(useInst);
509+
PtrToIntInst* ptiInst = llvm::dyn_cast<PtrToIntInst>(&*useInst);
520510
if (ptiInst && ptiInst->getPointerAddressSpace() == ADDRESS_SPACE_GENERIC)
521511
{
522-
Instruction* ptiUser = ptiInst->user_back();
523-
// We only skip tags on generic pointers if there is an arithmetic operation
524-
// after the addrspacecast->ptrtoint.
525-
if (ptiUser->isBinaryOp() || ptiUser->isShift() || ptiUser->isBitwiseLogicOp())
526-
{
527-
pointerArith = true;
528-
}
512+
// add metadata to avoid tagging when emitting
513+
MDNode* N = MDNode::get(C, MDString::get(C, "generic.arith"));
514+
addrSpaceCastInst->setMetadata("generic.arith", N);
515+
ASCInsts.push_back(addrSpaceCastInst);
516+
modified = true;
529517
}
530518
}
519+
}
520+
else if (intToPtrInst && intToPtrInst->getAddressSpace() == ADDRESS_SPACE_GENERIC)
521+
{
522+
ITPInsts.push_back(intToPtrInst);
523+
}
524+
}
531525

532-
if (pointerArith && !multipleUses)
526+
// for every IntToPtr find its origin Addrspacecast and source AS if it exists.
527+
// Assumption: the first Addrspacecast found is used to determine the original
528+
// source AS as arithmetic of pointers with different AS is not allowed.
529+
for (auto I2P : ITPInsts)
530+
{
531+
AddrSpaceCastInst* ASCDef = findAddressSpaceCastDef(I2P, 8);
532+
if (ASCDef)
533+
{
534+
for (auto ASC : ASCInsts)
533535
{
534-
// Add metadata to avoid tagging when emitting addrspacecast
535-
MDNode* N = MDNode::get(C, MDString::get(C, "generic.arith"));
536-
addrSpaceCastInst->setMetadata("generic.arith", N);
537-
modified = true;
536+
if (ASC == ASCDef)
537+
{
538+
MDNode* N = MDNode::get(C, ConstantAsMetadata::get(
539+
ConstantInt::get(Type::getInt32Ty(C), ASC->getSrcAddressSpace())));
540+
I2P->setMetadata("generic.arith", N);
541+
break;
542+
}
538543
}
539544
}
540545
}

0 commit comments

Comments
 (0)