Skip to content

Commit 4c2e31a

Browse files
fangliu2020igcbot
authored andcommitted
Fix the bug of verifying if an operand access exceeds the declared variable size for madw instruction
When verifying if an operand access exceeds the declared variable size, we should do special handling for madw instruction as this instruction write both the low and high results to GRFs.
1 parent 941ba38 commit 4c2e31a

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

visa/IsaVerification.cpp

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,8 @@ void vISAVerifier::verifyRegion(const CISA_INST *inst, unsigned i) {
661661
(exec_sz - 1) * h_stride_val * VN_size + VN_size - 1;
662662
}
663663

664+
unsigned grfSize = irBuilder->getGRFSize();
665+
664666
// Check if the operand may touch more than 2 GRFs due to bad alignment
665667
// So far vISA is able to handle the splitting of:
666668
// moves, logic, cmp and arithmetic instructions
@@ -669,35 +671,43 @@ void vISAVerifier::verifyRegion(const CISA_INST *inst, unsigned i) {
669671
ISA_Inst_Table[opcode].type != ISA_Inst_Compare &&
670672
ISA_Inst_Table[opcode].type != ISA_Inst_Arith) {
671673
REPORT_INSTRUCTION(
672-
options, (irBuilder->getGRFSize() * 2u) > last_region_elt_byte,
674+
options, (grfSize * 2u) > last_region_elt_byte,
673675
"CISA operand region access out of 2 GRF boundary (within %d "
674676
"bytes): %d",
675-
(irBuilder->getGRFSize() * 2), last_region_elt_byte);
677+
(grfSize * 2), last_region_elt_byte);
676678

677679
// check if the operand may touch more than 2 GRFs due to bad alignment
678680
unsigned startByte =
679681
getStartByteOffset(header, var, numPreDefinedVars) +
680-
row_offset * irBuilder->getGRFSize() +
682+
row_offset * grfSize +
681683
col_offset * CISATypeTable[var->getType()].typeSize;
682684
unsigned endByte = startByte + last_region_elt_byte;
683-
unsigned startGRF = startByte / irBuilder->getGRFSize();
684-
unsigned endGRF = endByte / irBuilder->getGRFSize();
685+
unsigned startGRF = startByte / grfSize;
686+
unsigned endGRF = endByte / grfSize;
685687
REPORT_INSTRUCTION(
686688
options, endGRF == startGRF || endGRF == (startGRF + 1),
687689
"CISA operand accesses more than 2 GRF due to mis-alignment: start "
688690
"byte offset = %d, end byte offset = %d",
689691
startByte, endByte);
690692
}
691693

692-
unsigned firstElementIndex =
693-
row_offset * irBuilder->getGRFSize() + col_offset * VN_size;
694+
unsigned firstElementIndex = row_offset * grfSize + col_offset * VN_size;
694695

695696
for (int i = 0; i < exec_sz / width_val; i++) {
696697
for (int j = 0; j < width_val; j++) {
697698
unsigned region_offset =
698699
firstElementIndex +
699700
(((i * v_stride_val) + (j * h_stride_val)) * VN_size);
700701

702+
// Madw instruction has both low and high results. So, need to check
703+
// the offset of high result.
704+
unsigned hiOffset = 0;
705+
if (inst->opcode == ISA_MADW) {
706+
hiOffset = (region_offset - firstElementIndex + 1 + grfSize - 1) &
707+
(~(grfSize - 1)); // GRF-aligned
708+
region_offset += hiOffset;
709+
}
710+
701711
if (region_offset >= var_size) {
702712
#ifndef DLL_MODE
703713
std::cout << "WARNING: CISA region and offset cause an out of "
@@ -709,15 +719,28 @@ void vISAVerifier::verifyRegion(const CISA_INST *inst, unsigned i) {
709719
std::cout << " The access fails the following check to determine "
710720
"correct bounds (see CISA manual section 5.1 "
711721
"Region-based Addressing):\n";
712-
std::cout << " (row_offset * GRF_SIZE + col_offset * type_size) + "
713-
"(((i * v_stride) + (j * h_stride)) * type_size) < "
714-
"type_size * num_elements:\n";
715-
std::cout << "(" << (int)row_offset << " * "
716-
<< (int)irBuilder->getGRFSize() << " + "
717-
<< (int)col_offset << " * " << VN_size << ") + (((" << i
718-
<< " * " << v_stride_val << ") + (" << j << " * "
719-
<< h_stride_val << ")) * " << VN_size << ") < " << VN_size
720-
<< " * " << num_elements << "\n";
722+
if (inst->opcode == ISA_MADW) {
723+
std::cout
724+
<< "(row_offset * GRF_SIZE + col_offset * type_size) + "
725+
"(((i * v_stride) + (j * h_stride)) * type_size) + "
726+
"high_offset < type_size * num_elements:\n";
727+
std::cout << "(" << (int)row_offset << " * " << grfSize << " + "
728+
<< (int)col_offset << " * " << VN_size << ") + (((" << i
729+
<< " * " << v_stride_val << ") + (" << j << " * "
730+
<< h_stride_val << ")) * " << VN_size << ") + "
731+
<< hiOffset << " < " << VN_size << " * "
732+
<< num_elements << "\n";
733+
} else {
734+
std::cout
735+
<< " (row_offset * GRF_SIZE + col_offset * type_size) + "
736+
"(((i * v_stride) + (j * h_stride)) * type_size) < "
737+
"type_size * num_elements:\n";
738+
std::cout << "(" << (int)row_offset << " * " << grfSize << " + "
739+
<< (int)col_offset << " * " << VN_size << ") + (((" << i
740+
<< " * " << v_stride_val << ") + (" << j << " * "
741+
<< h_stride_val << ")) * " << VN_size << ") < "
742+
<< VN_size << " * " << num_elements << "\n";
743+
}
721744
std::cout << "Violating Instruction: "
722745
<< header->printInstruction(inst, options)
723746
<< "\n";

0 commit comments

Comments
 (0)