@@ -1154,26 +1154,7 @@ bool HWConformity::fixOpndType(INST_LIST_ITER it, G4_BB *bb) {
11541154 }
11551155 }
11561156 }
1157- if (inst->opcode () == G4_bfn) {
1158- // BFN requires its operands to be UD/UW
1159- // ToDo: anyway to generalize this to all instructions requiring
1160- // signed/unsigned int type? IGA doesn't seem to have API to query supported
1161- // types
1162- auto dst = inst->getDst ();
1163- if (dst->getType () == Type_D || dst->getType () == Type_W) {
1164- dst->setType (builder, dst->getType () == Type_D ? Type_UD : Type_UW);
1165- }
1166- auto changeSrcToUnsigned = [this ](G4_Operand *opnd) {
1167- if (opnd->isSrcRegRegion () &&
1168- (opnd->getType () == Type_D || opnd->getType () == Type_W)) {
1169- opnd->asSrcRegRegion ()->setType (
1170- builder, opnd->getType () == Type_D ? Type_UD : Type_UW);
1171- }
1172- };
1173- changeSrcToUnsigned (inst->getSrc (0 ));
1174- changeSrcToUnsigned (inst->getSrc (1 ));
1175- changeSrcToUnsigned (inst->getSrc (2 ));
1176- }
1157+
11771158 return changed;
11781159}
11791160
@@ -6483,6 +6464,12 @@ void HWConformity::chkHWConformity() {
64836464#ifdef _DEBUG
64846465 verifyG4Kernel (kernel, Optimizer::PI_HWConformityChk, false );
64856466#endif
6467+
6468+ fixBfnInst (bb);
6469+ #ifdef _DEBUG
6470+ verifyG4Kernel (kernel, Optimizer::PI_HWConformityChk, false );
6471+ #endif
6472+
64866473 // fix source operand first to avoid redundant MOVs if this fix is done
64876474 // after reducing execution size. used by 3d. Mainly to fix sel with two imm
64886475 // sources
@@ -9960,3 +9947,47 @@ void HWConformity::fixImmAddrOffsetOOB(INST_LIST_ITER it, G4_BB *bb) {
99609947 -immAddrOff, G4_ExecSize (execSize)));
99619948 }
99629949}
9950+
9951+ void HWConformity::fixBfnInst (G4_BB* bb) {
9952+ INST_LIST_ITER it = bb->begin ();
9953+
9954+ for (auto iterEnd = bb->end (); it != iterEnd; ++it) {
9955+ G4_INST *inst = *it;
9956+ if (inst->opcode () != G4_bfn) {
9957+ continue ;
9958+ }
9959+
9960+ // BFN requires its operands to be UD/UW
9961+ // ToDo: anyway to generalize this to all instructions requiring
9962+ // signed/unsigned int type? IGA doesn't seem to have API to query supported
9963+ // types
9964+ auto dst = inst->getDst ();
9965+ if (dst->getType () == Type_D || dst->getType () == Type_W) {
9966+ dst->setType (builder, dst->getType () == Type_D ? Type_UD : Type_UW);
9967+ }
9968+
9969+ // When create visa immediate operand, we will lower immediate type.
9970+ // For example:
9971+ // bfn.xd8 (M1_NM, 1) V0042(0,0)<1> 0xffff8089:d 0xffffb4d8:d 0xffff895b:d
9972+ // lower to:
9973+ // (W) bfn.0xD8 (1) V0042(0,0)<1>:d 0x8089:w 0xb4d8:w 0x895b:w
9974+ // In this case, the dst is dword type, the immediate source operand should
9975+ // be dword as well. Since HW can only support 16b immediate value, we need
9976+ // to insert mov instruction to resolve it.
9977+ for (int i = 0 ; i < inst->getNumSrc (); i++)
9978+ if (inst->getSrc (i)->isImm () && IS_DTYPE (inst->getDst ()->getType ()) &&
9979+ inst->getSrc (i)->getType () == Type_W)
9980+ inst->setSrc (insertMovBefore (it, i, Type_D, bb), i);
9981+
9982+ auto changeSrcToUnsigned = [this ](G4_Operand *opnd) {
9983+ if (opnd->isSrcRegRegion () &&
9984+ (opnd->getType () == Type_D || opnd->getType () == Type_W)) {
9985+ opnd->asSrcRegRegion ()->setType (
9986+ builder, opnd->getType () == Type_D ? Type_UD : Type_UW);
9987+ }
9988+ };
9989+ changeSrcToUnsigned (inst->getSrc (0 ));
9990+ changeSrcToUnsigned (inst->getSrc (1 ));
9991+ changeSrcToUnsigned (inst->getSrc (2 ));
9992+ }
9993+ }
0 commit comments