Skip to content

Commit 763ce29

Browse files
paigealeigcbot
authored andcommitted
Now appropriately handling shl instructions with unsupported types.
Fixing and adding more use cases for cleanupTruncInst including cases where we have chained trunc instructions or when a trunc is followed by a zext/sext. All cases verified by Alive tool
1 parent 7fdbe0b commit 763ce29

File tree

1 file changed

+51
-7
lines changed

1 file changed

+51
-7
lines changed

IGC/Compiler/Legalizer/PeepholeTypeLegalizer.cpp

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,11 @@ void PeepholeTypeLegalizer::legalizeBinaryOperator(Instruction& I) {
461461
NewLargeRes = m_builder->CreateAShr(NewLargeSrc1, NewLargeSrc2);
462462
break;
463463
}
464+
case Instruction::Shl:
465+
{
466+
NewLargeRes = m_builder->CreateShl(NewLargeSrc1, NewLargeSrc2);
467+
break;
468+
}
464469
default:
465470
printf("Binary Instruction seen with illegal int type. Legalization support missing. Inst opcode:%d", I.getOpcode());
466471
IGC_ASSERT_MESSAGE(0, "Binary Instruction seen with illegal int type. Legalization support missing.");
@@ -895,20 +900,59 @@ void PeepholeTypeLegalizer::cleanupTruncInst(Instruction& I) {
895900
I.hasOneUse() &&
896901
isLegalInteger(I.getOperand(0)->getType()->getScalarSizeInBits()))
897902
{
898-
//Need to see if it is safe to wipe it out. It is safe only if the user is a
899-
//SExt or ZExt and the trunc starting bitwidth is less than the
900-
//users bitwidth.
903+
//Need to see if it is safe to replace, combine, or wipe out
901904
Value* new_inst = NULL;
902905
Instruction* castInst = I.user_back();
903906
auto Src = I.getOperand(0);
904907
auto Src_bitsize = Src->getType()->getScalarSizeInBits();
908+
auto Trunc_bitsize = I.getType()->getScalarSizeInBits();
905909
auto castInst_bitsize = castInst->getType()->getScalarSizeInBits();
906-
if (Src_bitsize < castInst_bitsize)
910+
if (Src_bitsize <= castInst_bitsize)
907911
{
912+
//Example 1:
913+
//%a = trunc i8 %in to i5
914+
//%out = sext i5 %a to i32
915+
//=>
916+
//%q = zext i8 %in to i32
917+
//%s = shl i32 %q, 27
918+
//%out = ashr i32 %s, 27
919+
920+
//Example 2:
921+
//%a = trunc i8 %in to i5
922+
//%out = zext i5 %a to i32
923+
//=>
924+
//%q = and i8 %in, 31
925+
//%out = zext i8 %q to i32
926+
908927
if (isa<SExtInst>(castInst))
909-
new_inst = m_builder->CreateSExt(Src, castInst->getType());
910-
if (isa<ZExtInst>(castInst))
911-
new_inst = m_builder->CreateZExt(Src, castInst->getType());
928+
{
929+
auto shiftAmt = castInst_bitsize - Trunc_bitsize;
930+
auto inst1 = m_builder->CreateZExt(Src, castInst->getType());
931+
auto inst2 = m_builder->CreateShl(inst1, shiftAmt);
932+
new_inst = m_builder->CreateAShr(inst2, shiftAmt);
933+
}
934+
else if (isa<ZExtInst>(castInst))
935+
{
936+
auto inst1 = m_builder->CreateAnd(Src, (1 << Trunc_bitsize) - 1);
937+
new_inst = m_builder->CreateZExt(inst1, castInst->getType());
938+
}
939+
}
940+
else if (Src_bitsize > castInst_bitsize)
941+
{
942+
//Most likely a trunc instruction lets combine these two truncs and try again
943+
//Example:
944+
//%261 = trunc i8 %260 to i5
945+
//%262 = trunc i5 %261 to i3
946+
//------>
947+
//%out = trunc i8 %260 to i3
948+
if (isa<TruncInst>(castInst))
949+
{
950+
auto new_val = m_builder->CreateTrunc(Src, castInst->getType());
951+
castInst->replaceAllUsesWith(new_val);
952+
if (auto *new_trunc = dyn_cast<TruncInst>(new_val))
953+
cleanupTruncInst(*new_trunc);
954+
Changed = true;
955+
}
912956
}
913957

914958
if (new_inst != NULL)

0 commit comments

Comments
 (0)