Skip to content

Commit 17918c7

Browse files
petechouigcbot
authored andcommitted
Fix type conversion in integer division inst.
To calculate a correct signedness of the division, we should take the type ranks of source operands into account as well.
1 parent 403072b commit 17918c7

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

visa/HWConformity.cpp

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -546,15 +546,39 @@ bool HWConformity::fixMathInst(INST_LIST_ITER it, G4_BB* bb)
546546
newType = src->getType();
547547
if (isIntDivide)
548548
{
549-
// cases:
550-
// math.quot r10:w r20:ub -r30:ub
551-
// Make sure newType is D, not UD. The correct code is:
552-
// mov r22:d r20:ub
553-
// mov r32:d -r30:ub
554-
// math.quot r10:w r22:d r32:d
555-
bool src0Unsigned = IS_UNSIGNED_INT(inst->getSrc(0)->getType()) && !hasModMinus(inst->getSrc(0));
556-
bool src1Unsigned = IS_UNSIGNED_INT(inst->getSrc(1)->getType()) && !hasModMinus(inst->getSrc(1));
557-
G4_Type divType = (src0Unsigned && src1Unsigned) ? Type_UD : Type_D;
549+
// case 1: Perform a signed division if there's any minus src modifier.
550+
// math.quot r10:w r20:ub -r30:ub
551+
// Make sure newType is D, not UD. The correct code is:
552+
// mov r22:d r20:ub
553+
// mov r32:d -r30:ub
554+
// math.quot r10:w r22:d r32:d
555+
// case 2: Perform an appropriate type conversion based on the type ranks of both sources.
556+
// math.quot r6:ud r3:b r4:ud
557+
// Make sure it's still an unsigned division.
558+
// mov r11:ud r3:b
559+
// math.quot r6:ud r11:ud r4:ud
560+
G4_Type src0Type = inst->getSrc(0)->getType();
561+
G4_Type src1Type = inst->getSrc(1)->getType();
562+
G4_Type divType = Type_UNDEF;
563+
if (hasModMinus(inst->getSrc(0)) || hasModMinus(inst->getSrc(1)))
564+
{
565+
// If there's any minus source modifier, do a signed division.
566+
divType = Type_D;
567+
}
568+
else if (TypeSize(src0Type) != TypeSize(src1Type))
569+
{
570+
// If src0 and src1 have different ranks, get the signedness of the
571+
// division from the higher rank src.
572+
G4_Type higherRankType = TypeSize(src0Type) > TypeSize(src1Type) ? src0Type : src1Type;
573+
divType = IS_SIGNED_INT(higherRankType) ? Type_D : Type_UD;
574+
}
575+
else
576+
{
577+
// If both sources have the same rank, do a signed division only
578+
// when both are signed. Otherwise, do an unsigned division.
579+
divType = IS_SIGNED_INT(src0Type) && IS_SIGNED_INT(src1Type) ? Type_D : Type_UD;
580+
}
581+
assert(divType == Type_D || divType == Type_UD);
558582
if (newType != divType)
559583
{
560584
newType = divType;

0 commit comments

Comments
 (0)