Skip to content

Commit 005c343

Browse files
vmustyaigcbot
authored andcommitted
Support null register to be used in general register category
In some cases we need to emit `%null` vISA register as an operand for a vISA instruction consuming the vector operand. Before the change, only raw operand could be used as a null operand.
1 parent d1939de commit 005c343

File tree

3 files changed

+53
-25
lines changed

3 files changed

+53
-25
lines changed

IGC/VectorCompiler/lib/GenXCodeGen/GenXCisaBuilder.cpp

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -508,17 +508,17 @@ class GenXKernelBuilder {
508508
VISA_VectorOpnd *createDestination(Value *Dest,
509509
genx::Signedness Signed,
510510
unsigned *Offset = nullptr);
511-
VISA_VectorOpnd *createSourceOperand(Instruction *Inst,
512-
genx::Signedness Signed,
513-
unsigned OperandNum, genx::BaleInfo BI,
514-
unsigned Mod = 0,
515-
genx::Signedness *SignedRes = nullptr,
516-
unsigned MaxWidth = 16);
511+
VISA_VectorOpnd *
512+
createSourceOperand(Instruction *Inst, genx::Signedness Signed,
513+
unsigned OperandNum, genx::BaleInfo BI, unsigned Mod = 0,
514+
genx::Signedness *SignedRes = nullptr,
515+
unsigned MaxWidth = 16, bool IsNullAllowed = false);
517516
VISA_VectorOpnd *createSource(Value *V, genx::Signedness Signed, bool Baled,
518517
unsigned Mod = 0,
519518
genx::Signedness *SignedRes = nullptr,
520519
unsigned MaxWidth = 16,
521-
unsigned *Offset = nullptr, bool IsBF = false);
520+
unsigned *Offset = nullptr, bool IsBF = false,
521+
bool IsNullAllowed = false);
522522
VISA_VectorOpnd *createSource(Value *V, genx::Signedness Signed,
523523
unsigned MaxWidth = 16,
524524
unsigned *Offset = nullptr);
@@ -1718,15 +1718,17 @@ GenXKernelBuilder::createDestination(Value *Dest, genx::Signedness Signed,
17181718
}
17191719
}
17201720

1721-
VISA_VectorOpnd *GenXKernelBuilder::createSourceOperand(
1722-
Instruction *Inst, Signedness Signed, unsigned OperandNum,
1723-
genx::BaleInfo BI, unsigned Mod, Signedness *SignedRes, unsigned MaxWidth) {
1721+
VISA_VectorOpnd *
1722+
GenXKernelBuilder::createSourceOperand(Instruction *Inst, Signedness Signed,
1723+
unsigned OperandNum, genx::BaleInfo BI,
1724+
unsigned Mod, Signedness *SignedRes,
1725+
unsigned MaxWidth, bool IsNullAllowed) {
17241726
Value *V = Inst->getOperand(OperandNum);
17251727
auto IID = vc::InternalIntrinsic::getInternalIntrinsicID(Inst);
17261728
bool IsBF = IID == vc::InternalIntrinsic::cast_from_bf16;
17271729

17281730
return createSource(V, Signed, BI.isOperandBaled(OperandNum), Mod, SignedRes,
1729-
MaxWidth, nullptr, IsBF);
1731+
MaxWidth, nullptr, IsBF, IsNullAllowed);
17301732
}
17311733

17321734
VISA_PredOpnd *
@@ -2000,14 +2002,29 @@ VISA_VectorOpnd *GenXKernelBuilder::createSource(Value *V, Signedness Signed,
20002002
bool Baled, unsigned Mod,
20012003
Signedness *SignedRes,
20022004
unsigned MaxWidth,
2003-
unsigned *Offset, bool IsBF) {
2005+
unsigned *Offset, bool IsBF,
2006+
bool IsNullAllowed) {
20042007
LLVM_DEBUG(dbgs() << "createSource for " << (Baled ? "baled" : "non-baled")
20052008
<< (IsBF ? " brain" : " non-brain") << " value: ");
20062009
LLVM_DEBUG(V->dump());
20072010
LLVM_DEBUG(dbgs() << "\n");
20082011
if (SignedRes)
20092012
*SignedRes = Signed;
2010-
if (auto C = dyn_cast<Constant>(V)) {
2013+
// Null register is required
2014+
if (IsNullAllowed && isa<UndefValue>(V)) {
2015+
Region R(V);
2016+
if (Offset)
2017+
R.Offset = *Offset;
2018+
if (R.NumElements == 1)
2019+
R.VStride = R.Stride = 0;
2020+
2021+
VISA_GenVar *NullDecl = nullptr;
2022+
CISA_CALL(Kernel->GetPredefinedVar(NullDecl, PREDEFINED_NULL));
2023+
2024+
return createRegionOperand(&R, NullDecl, Signed, Mod, false /*IsDst*/,
2025+
MaxWidth);
2026+
}
2027+
if (auto *C = dyn_cast<Constant>(V)) {
20112028
if (Mod) {
20122029
// Need to negate constant.
20132030
IGC_ASSERT_MESSAGE(Mod == MODIFIER_NEG, "unexpected modifier");
@@ -3387,8 +3404,9 @@ void GenXKernelBuilder::buildIntrinsic(CallInst *CI, unsigned IntrinID,
33873404
MaxWidth =
33883405
cast<IGCLLVM::FixedVectorType>(CI->getType())->getNumElements();
33893406
}
3390-
ResultOperand = createSourceOperand(CI, Signed, AI.getArgIdx(), BI, 0,
3391-
nullptr, MaxWidth);
3407+
ResultOperand =
3408+
createSourceOperand(CI, Signed, AI.getArgIdx(), BI, 0, nullptr,
3409+
MaxWidth, AI.generalNullAllowed());
33923410
}
33933411
return ResultOperand;
33943412
};

IGC/VectorCompiler/lib/GenXCodeGen/GenXConstants.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -531,16 +531,14 @@ bool ConstantLoadHelper::visitCallInst(CallInst &CI) {
531531
// Allow constant if intrinsic descriptor allows it for this arg.
532532
if (AI.getCategory() == GenXIntrinsicInfo::CACHEOPTS)
533533
continue;
534+
// Allow constant, if it's undefined, and null register is allowed.
535+
if (isa<UndefValue>(C) && AI.isNullAllowed())
536+
continue;
534537
// If it is a RAW operand, allow the constant if it's in the trailing
535-
// null region (it must be a null constant if so), or if the value
536-
// is undefined and RAW_NULLALLOWED is enabled.
537-
if (AI.isRaw()) {
538-
if ((unsigned)AI.getArgIdx() >= MaxRawOperands) {
539-
IGC_ASSERT(C->isNullValue());
540-
continue;
541-
}
542-
if (isa<UndefValue>(C) && AI.rawNullAllowed())
543-
continue;
538+
// null region (it must be a null constant if so).
539+
if (AI.isRaw() && (unsigned)AI.getArgIdx() >= MaxRawOperands) {
540+
IGC_ASSERT(C->isNullValue());
541+
continue;
544542
}
545543
// Also allow constant if it is undef in a TWOADDR
546544
if (isa<UndefValue>(C) && AI.getCategory() == GenXIntrinsicInfo::TWOADDR)

IGC/VectorCompiler/lib/GenXCodeGen/GenXIntrinsics.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class GenXIntrinsicInfo {
5353
// currently the maximum needed is 5.
5454
//
5555
// At the moment, the GENERAL category has 4 unused flag bits available
56-
// to it, the RAW category has 13 unused bits, and the ARGCOUNT category
56+
// to it, the RAW category has 11 unused bits, and the ARGCOUNT category
5757
// has 13 unused bits. No other categories make use of the flags yet,
5858
// so it should be a good while yet before it's necessary to resize
5959
// the bitfields.
@@ -172,6 +172,7 @@ class GenXIntrinsicInfo {
172172
MODIFIER_EXTONLY = GENX_ITR_FLAGENUM(8, 3), // src modifier: extend only
173173
DIRECTONLY = GENX_ITR_FLAGVAL(10), // indirect region not allowed
174174
IMM16ONLY = GENX_ITR_FLAGVAL(11), // source allowed to be only 16 bit immediate
175+
NULLALLOWED = GENX_ITR_FLAGVAL(12), // source allowed to be null register
175176

176177
};
177178
struct ArgInfo {
@@ -217,6 +218,17 @@ class GenXIntrinsicInfo {
217218
IGC_ASSERT(isRaw());
218219
return Info & RAW_NULLALLOWED;
219220
}
221+
bool generalNullAllowed() const {
222+
IGC_ASSERT(isGeneral());
223+
return Info & NULLALLOWED;
224+
}
225+
bool isNullAllowed() const {
226+
if (isGeneral())
227+
return generalNullAllowed();
228+
if (isRaw())
229+
return rawNullAllowed();
230+
return false;
231+
}
220232
// isArgOrRet : test whether this field has an arg index
221233
bool isArgOrRet() const {
222234
if (isGeneral()) return true;

0 commit comments

Comments
 (0)