Skip to content

Commit d559301

Browse files
Jay-Jiewu-Lugfxbot
authored andcommitted
Fix immediate constant buffer issue
Change-Id: Ic3f88119cf22ca1ea47a48e3db2913bda1271e50
1 parent 2dc0b9f commit d559301

File tree

3 files changed

+95
-41
lines changed

3 files changed

+95
-41
lines changed

IGC/Compiler/CISACodeGen/CISABuilder.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -852,17 +852,18 @@ Common_VISA_EMask_Ctrl CEncoder::GetAluEMask(CVariable* dst)
852852
{
853853
e_mask mask = m_encoderState.m_mask;
854854
bool noMask = m_encoderState.m_noMask;
855-
if (dst && dst->GetVarType() == EVARTYPE_ADDRESS)
855+
if (dst && (dst->IsUniform() || m_encoderState.m_SubSpanDestination))
856856
{
857-
if (dst->IsVectorUniform() && dst->IsUniform())
857+
if (dst->GetVarType() == EVARTYPE_ADDRESS)
858+
{
859+
noMask |= dst->IsVectorUniform();
860+
}
861+
else
858862
{
859863
noMask = true;
860864
}
861865
}
862-
else if (dst && (dst->IsUniform() || m_encoderState.m_SubSpanDestination))
863-
{
864-
noMask = true;
865-
}
866+
866867
return ConvertMaskToVisaType(mask, noMask);
867868
}
868869

IGC/Compiler/CustomSafeOptPass.cpp

Lines changed: 83 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,8 @@ namespace {
19181918
AU.setPreservesCFG();
19191919
AU.addRequired<CodeGenContextWrapper>();
19201920
}
1921+
private:
1922+
bool isICBOffseted(llvm::LoadInst* inst, uint offset);
19211923
};
19221924

19231925
} // namespace
@@ -1949,47 +1951,78 @@ bool IGCIndirectICBPropagaion::runOnFunction(Function &F)
19491951
bool directBuf;
19501952
unsigned bufId;
19511953
BufferType bufType = IGC::DecodeAS4GFXResource(as, directBuf, bufId);
1952-
if (bufType == CONSTANT_BUFFER && directBuf && bufId == modMD->pushInfo.inlineConstantBufferSlot)
1954+
bool bICBNoOffset =
1955+
(IGC::INVALID_CONSTANT_BUFFER_INVALID_ADDR == modMD->pushInfo.inlineConstantBufferOffset && bufType == CONSTANT_BUFFER && directBuf && bufId == modMD->pushInfo.inlineConstantBufferSlot);
1956+
bool bICBOffseted =
1957+
(IGC::INVALID_CONSTANT_BUFFER_INVALID_ADDR != modMD->pushInfo.inlineConstantBufferOffset && ADDRESS_SPACE_CONSTANT == as && isICBOffseted(inst, modMD->pushInfo.inlineConstantBufferOffset));
1958+
if (bICBNoOffset || bICBOffseted)
19531959
{
19541960
Value *ptrVal = inst->getPointerOperand();
1955-
ConstantExpr *ptrExpr = dyn_cast<ConstantExpr>(ptrVal);
1956-
IntToPtrInst *i2p = dyn_cast<IntToPtrInst>(ptrVal);
1957-
if (ptrExpr == nullptr && i2p)
1961+
Value *eltPtr = nullptr;
1962+
Value *eltIdx = nullptr;
1963+
if (IntToPtrInst *i2p = dyn_cast<IntToPtrInst>(ptrVal))
19581964
{
1959-
m_builder.SetInsertPoint(inst);
1965+
eltPtr = i2p->getOperand(0);
1966+
}
1967+
else if (GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(ptrVal))
1968+
{
1969+
if (gep->getNumOperands() != 3)
1970+
{
1971+
continue;
1972+
}
1973+
1974+
Type* eleType = gep->getPointerOperandType()->getPointerElementType();
1975+
if (!eleType->isArrayTy() ||
1976+
!(eleType->getArrayElementType()->isFloatTy() || eleType->getArrayElementType()->isIntegerTy(32)))
1977+
{
1978+
continue;
1979+
}
1980+
1981+
eltIdx = gep->getOperand(2);
1982+
}
1983+
else
1984+
{
1985+
continue;
1986+
}
1987+
1988+
m_builder.SetInsertPoint(inst);
1989+
1990+
unsigned int size_in_bytes = inst->getType()->getPrimitiveSizeInBits() / 8;
1991+
if (size_in_bytes)
1992+
{
1993+
Value* ICBbuffer = UndefValue::get(VectorType::get(inst->getType(), maxImmConstantSizePushed / size_in_bytes));
1994+
if (inst->getType()->isFloatTy())
1995+
{
1996+
float returnConstant = 0;
1997+
for (unsigned int i = 0; i < maxImmConstantSizePushed; i += size_in_bytes)
1998+
{
1999+
memcpy_s(&returnConstant, size_in_bytes, offset + i, size_in_bytes);
2000+
Value *fp = ConstantFP::get(inst->getType(), returnConstant);
2001+
ICBbuffer = m_builder.CreateInsertElement(ICBbuffer, fp, m_builder.getInt32(i / size_in_bytes));
2002+
}
19602003

1961-
unsigned int size_in_bytes = inst->getType()->getPrimitiveSizeInBits() / 8;
1962-
if (size_in_bytes)
2004+
if (eltPtr)
2005+
{
2006+
eltIdx = m_builder.CreateLShr(eltPtr, m_builder.getInt32(2));
2007+
}
2008+
Value *ICBvalue = m_builder.CreateExtractElement(ICBbuffer, eltIdx);
2009+
inst->replaceAllUsesWith(ICBvalue);
2010+
}
2011+
else if (inst->getType()->isIntegerTy(32))
19632012
{
1964-
Value* ICBbuffer = UndefValue::get(VectorType::get(inst->getType(), maxImmConstantSizePushed / size_in_bytes));
1965-
if (inst->getType()->isFloatingPointTy())
2013+
int returnConstant = 0;
2014+
for (unsigned int i = 0; i < maxImmConstantSizePushed; i += size_in_bytes)
19662015
{
1967-
float returnConstant = 0;
1968-
for (unsigned int i = 0; i < maxImmConstantSizePushed; i += size_in_bytes)
1969-
{
1970-
memcpy_s(&returnConstant, size_in_bytes, offset + i, size_in_bytes);
1971-
Value *fp = ConstantFP::get(inst->getType(), returnConstant);
1972-
ICBbuffer = m_builder.CreateInsertElement(ICBbuffer, fp, m_builder.getInt32(i / size_in_bytes));
1973-
}
1974-
Value *eltIdxVal = i2p->getOperand(0);
1975-
Value *div = m_builder.CreateLShr(eltIdxVal, m_builder.getInt32(2));
1976-
Value *ICBvalue = m_builder.CreateExtractElement(ICBbuffer, div);
1977-
inst->replaceAllUsesWith(ICBvalue);
2016+
memcpy_s(&returnConstant, size_in_bytes, offset + i, size_in_bytes);
2017+
Value *fp = ConstantInt::get(inst->getType(), returnConstant);
2018+
ICBbuffer = m_builder.CreateInsertElement(ICBbuffer, fp, m_builder.getInt32(i / size_in_bytes));
19782019
}
1979-
else if (inst->getType()->isIntegerTy())
2020+
if (eltPtr)
19802021
{
1981-
int returnConstant = 0;
1982-
for (unsigned int i = 0; i < maxImmConstantSizePushed; i += size_in_bytes)
1983-
{
1984-
memcpy_s(&returnConstant, size_in_bytes, offset + i, size_in_bytes);
1985-
Value *fp = ConstantInt::get(inst->getType(), returnConstant);
1986-
ICBbuffer = m_builder.CreateInsertElement(ICBbuffer, fp, m_builder.getInt32(i / size_in_bytes));
1987-
}
1988-
Value *eltIdxVal = i2p->getOperand(0);
1989-
Value *div = m_builder.CreateLShr(eltIdxVal, m_builder.getInt32(2));
1990-
Value *ICBvalue = m_builder.CreateExtractElement(ICBbuffer, div);
1991-
inst->replaceAllUsesWith(ICBvalue);
2022+
eltIdx = m_builder.CreateLShr(eltPtr, m_builder.getInt32(2));
19922023
}
2024+
Value *ICBvalue = m_builder.CreateExtractElement(ICBbuffer, eltIdx);
2025+
inst->replaceAllUsesWith(ICBvalue);
19932026
}
19942027
}
19952028
}
@@ -2001,6 +2034,24 @@ bool IGCIndirectICBPropagaion::runOnFunction(Function &F)
20012034
return false;
20022035
}
20032036

2037+
bool IGCIndirectICBPropagaion::isICBOffseted(llvm::LoadInst* inst, uint offset) {
2038+
Value *ptrVal = inst->getPointerOperand();
2039+
std::vector<Value*> srcInstList;
2040+
IGC::TracePointerSource(ptrVal, false, true, srcInstList);
2041+
if (srcInstList.size())
2042+
{
2043+
CallInst* inst = dyn_cast<CallInst>(srcInstList.back());
2044+
GenIntrinsicInst* genIntr = inst ? dyn_cast<GenIntrinsicInst>(inst) : nullptr;
2045+
if (!genIntr || (genIntr->getIntrinsicID() != GenISAIntrinsic::GenISA_RuntimeValue))
2046+
return false;
2047+
2048+
llvm::ConstantInt* ci = dyn_cast<llvm::ConstantInt>(inst->getOperand(0));
2049+
return ci && (uint)ci->getZExtValue() == offset;
2050+
}
2051+
2052+
return false;
2053+
}
2054+
20042055
IGC_INITIALIZE_PASS_BEGIN(IGCIndirectICBPropagaion, "IGCIndirectICBPropagaion",
20052056
"IGCIndirectICBPropagaion", false, false)
20062057
IGC_INITIALIZE_PASS_END(IGCIndirectICBPropagaion, "IGCIndirectICBPropagaion",

IGC/common/MDFrameWork.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ const unsigned int NUM_SHADER_RESOURCE_VIEW_SIZE = (INPUT_RESOURCE_SLOT_COUNT +
1818

1919
const unsigned int g_c_maxNumberOfBufferPushed = 4;
2020

21-
2221
namespace IGC
2322
{
23+
const unsigned int INVALID_CONSTANT_BUFFER_INVALID_ADDR = 0xFFFFFFFF;
24+
2425
enum FunctionTypeMD
2526
{
2627
UnknownFunction,
@@ -157,14 +158,15 @@ namespace IGC
157158
bool isStatic = false;
158159
};
159160

160-
// simplePushInfoArr needs to be initialized to a vector of size g_c_maxNumberOfBufferPushed, which we are doing in module MD initialization done in code gen context
161+
// simplePushInfoArr needs to be initialized to a vector of size g_c_maxNumberOfBufferPushed, which we are doing in module MD initialization done in code gen context
161162
// All the pushinfo below is mapping to an argument number (int) so that we can retrieve relevant Argument as a value pointer from Function
162163
struct PushInfo
163164
{
164165
std::vector<StatelessPushInfo> pushableAddresses;
165166
unsigned int MaxNumberOfPushedBuffers = 0; ///> specifies the maximum number of buffers available for the simple push mechanism for current shader.
166167

167-
unsigned int inlineConstantBufferSlot = 0xFFFFFFFF; // slot of the inlined constant buffer
168+
unsigned int inlineConstantBufferSlot = INVALID_CONSTANT_BUFFER_INVALID_ADDR; // slot of the inlined constant buffer
169+
unsigned int inlineConstantBufferOffset = INVALID_CONSTANT_BUFFER_INVALID_ADDR; // offset of the inlined constant buffer
168170

169171
std::map<ConstantAddress, int> constants;
170172
std::map<unsigned int, SInputDesc> inputs;

0 commit comments

Comments
 (0)