Skip to content

Commit 53e28e8

Browse files
kychendevigcbot
authored andcommitted
Bug fix in splitting addc/subb instruction.
When addc/subb instruction gets splitted after vISA translation, the corresponding acc mov instruction should be splitted as well.
1 parent a18baec commit 53e28e8

File tree

1 file changed

+72
-2
lines changed

1 file changed

+72
-2
lines changed

visa/InstSplit.cpp

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,41 @@ INST_LIST_ITER InstSplitPass::splitInstruction(INST_LIST_ITER it,
245245
}
246246
}
247247

248+
// Special handling for vISA ADDC (SUBB) instruction,
249+
// which is translated to addc (subb)/mov acc pair
250+
// and should be splitted together.
251+
G4_INST *carryMovInst = nullptr;
252+
G4_Predicate* newCarryMovPred = NULL;
253+
G4_CondMod* newCarryMovCondMod = NULL;
254+
INST_LIST_ITER nextIter = std::next(it);
255+
if (inst->opcode() == G4_addc || inst->opcode() == G4_subb) {
256+
G4_INST *nextInst = *nextIter;
257+
if (nextInst->opcode() == G4_mov && nextInst->isAccSrcInst() &&
258+
nextInst->getExecSize() == inst->getExecSize()) {
259+
carryMovInst = nextInst;
260+
261+
if (carryMovInst->getPredicate()) {
262+
newCarryMovPred = carryMovInst->getPredicate();
263+
newCarryMovPred->splitPred();
264+
}
265+
266+
if (carryMovInst->getCondMod()) {
267+
newCarryMovCondMod = carryMovInst->getCondMod();
268+
newCarryMovCondMod->splitCondMod();
269+
}
270+
}
271+
}
272+
273+
G4_SrcRegRegion* accSrcRegion = NULL;
274+
if (inst->getImplAccSrc()) {
275+
accSrcRegion = inst->getImplAccSrc()->asSrcRegRegion();
276+
}
277+
278+
G4_DstRegRegion* accDstRegion = NULL;
279+
if (inst->getImplAccDst()) {
280+
accDstRegion = inst->getImplAccDst();
281+
}
282+
248283
// Create new predicate
249284
G4_Predicate *newPred = NULL;
250285
if (inst->getPredicate()) {
@@ -319,12 +354,47 @@ INST_LIST_ITER InstSplitPass::splitInstruction(INST_LIST_ITER it,
319354
newInst->setMaskOption(newMask);
320355
}
321356

322-
// Call recursive splitting function
323-
newInstIterator = splitInstruction(newInstIterator, instList);
357+
if (accDstRegion)
358+
newInst->setImplAccDst(m_builder->duplicateOperand(accDstRegion));
359+
360+
if (accSrcRegion)
361+
newInst->setImplAccSrc(m_builder->duplicateOperand(accSrcRegion));
362+
363+
if (carryMovInst) {
364+
G4_INST* newCarryMovInst = m_builder->makeSplittingInst(carryMovInst, newExecSize);
365+
366+
G4_DstRegRegion* carryMovDst = carryMovInst->getDst();
367+
G4_DstRegRegion* newCarryMovDst;
368+
if (carryMovDst && !carryMovInst->hasNULLDst()) {
369+
newCarryMovDst = m_builder->createSubDstOperand(carryMovDst, (uint16_t)i, newExecSize);
370+
}
371+
else {
372+
newCarryMovDst = newCarryMovDst;
373+
}
374+
375+
newCarryMovInst->setDest(newCarryMovDst);
376+
newCarryMovInst->setPredicate(m_builder->duplicateOperand(newCarryMovPred));
377+
newCarryMovInst->setCondMod(m_builder->duplicateOperand(newCarryMovCondMod));
378+
newCarryMovInst->setSrc(m_builder->duplicateOperand(carryMovInst->getSrc(0)), 0);
379+
auto prevInstIterator = newInstIterator;
380+
newInstIterator = instList.insert(it, newCarryMovInst);
381+
382+
// Call recursive splitting function
383+
newInstIterator = splitInstruction(prevInstIterator, instList);
384+
}
385+
else {
386+
// Call recursive splitting function
387+
newInstIterator = splitInstruction(newInstIterator, instList);
388+
}
324389
}
325390

326391
// remove original instruction
327392
instList.erase(it);
393+
394+
if (carryMovInst) {
395+
instList.erase(nextIter);
396+
}
397+
328398
return newInstIterator;
329399
}
330400

0 commit comments

Comments
 (0)