Skip to content

Commit 0f97222

Browse files
jgu222igcbot
authored andcommitted
As a rotate is matched in a pass via llvm funnel shift, the matchRotate()
in PatternMatch is no longer needed. This change remove matchRotate() from PatternMatch not should not have any functional change.
1 parent 61afe6d commit 0f97222

File tree

2 files changed

+1
-230
lines changed

2 files changed

+1
-230
lines changed

IGC/Compiler/CISACodeGen/PatternMatchPass.cpp

Lines changed: 1 addition & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -846,9 +846,7 @@ namespace IGC
846846
}
847847
else if (I.getOpcode() == Instruction::Trunc)
848848
{
849-
match =
850-
MatchRotate(I) ||
851-
MatchModifier(I);
849+
match = MatchModifier(I);
852850
}
853851
else
854852
{
@@ -1025,7 +1023,6 @@ namespace IGC
10251023
case Instruction::Or:
10261024
match =
10271025
MatchBoolOp(I) ||
1028-
MatchRotate(I) ||
10291026
MatchLogicAlu(I);
10301027
break;
10311028
case Instruction::Xor:
@@ -3542,231 +3539,6 @@ namespace IGC
35423539
return found;
35433540
}
35443541

3545-
//
3546-
// Assume that V is of type T (integer) with N bits;
3547-
// and amt is of integer type too.
3548-
//
3549-
// rol (V, amt) = (V << amt) | ((unsigned(V) >> (N - amt))
3550-
// The function first finds the following generic pattern, note that
3551-
// [insts] denotes that "insts" are optional.
3552-
// [amt = and amt, N-1]
3553-
// high = shl V0, amt
3554-
// [amt0 = sub 0, amt || amt0 = sub N, amt]
3555-
// ; if amt is constant && amt + amt0 == N, this is unneeded
3556-
// [amt0 = and amt0, N-1]
3557-
// low = lshr V1, amt0
3558-
// R = or high, low
3559-
//
3560-
// case 0: [ likely, V is i32 or i64]
3561-
// V0 == V1 (V == V0 == V1)
3562-
//
3563-
// case 1: [ likely V is i16 or i8]
3564-
// V0 = sext V || zext V
3565-
// V1 = zext V
3566-
// Res = trunc R
3567-
//
3568-
// Res's type == V's type
3569-
//
3570-
// ror can be handled similarly. Note that
3571-
// ror (x, amt) = ((unsigned)x >> amt) | ( x << (N - amt))
3572-
// = rol (x, N - amt);
3573-
//
3574-
bool CodeGenPatternMatch::MatchRotate(llvm::Instruction& I)
3575-
{
3576-
using namespace llvm::PatternMatch;
3577-
3578-
struct RotatePattern : public Pattern
3579-
{
3580-
SSource sources[2];
3581-
e_opcode rotateOPCode;
3582-
llvm::Instruction* instruction;
3583-
virtual void Emit(EmitPass* pass, const DstModifier& modifier)
3584-
{
3585-
pass->Binary(rotateOPCode, sources, modifier);
3586-
}
3587-
};
3588-
3589-
if (!m_Platform.supportRotateInstruction())
3590-
{
3591-
return false;
3592-
}
3593-
3594-
// Sanity check:
3595-
// make sure that rotate is supported and "I" is a scalar "or" instruction
3596-
IGC_ASSERT_MESSAGE(false == I.getType()->isVectorTy(), "Vector type not expected here");
3597-
3598-
uint64_t typeWidth = I.getType()->getScalarSizeInBits();
3599-
Instruction* OrInst = nullptr;
3600-
if (I.getOpcode() == Instruction::Trunc)
3601-
{
3602-
if (BinaryOperator * tmp = dyn_cast<BinaryOperator>(I.getOperand(0)))
3603-
{
3604-
if (tmp->getOpcode() != Instruction::Or)
3605-
{
3606-
return false;
3607-
}
3608-
OrInst = tmp;
3609-
}
3610-
else
3611-
{
3612-
return false;
3613-
}
3614-
}
3615-
else if (I.getOpcode() == Instruction::Or)
3616-
{
3617-
OrInst = cast<BinaryOperator>(&I);
3618-
}
3619-
else
3620-
{
3621-
IGC_ASSERT_MESSAGE(0, "Should be invoked with Or/Trunc instruction");
3622-
}
3623-
3624-
// Do rotate only if
3625-
// 1) type is W/DW (HW only supports W/DW); and
3626-
// 2) both operands are instructions.
3627-
Instruction* LHS = dyn_cast<Instruction>(OrInst->getOperand(0));
3628-
Instruction* RHS = dyn_cast<Instruction>(OrInst->getOperand(1));
3629-
bool typeWidthSupported = typeWidth == 16 || typeWidth == 32;
3630-
3631-
if (!LHS || !RHS || !typeWidthSupported)
3632-
{
3633-
return false;
3634-
}
3635-
3636-
// Make adjustment so that LHS is shl.
3637-
if (LHS->getOpcode() == Instruction::LShr)
3638-
{
3639-
Instruction* t = LHS;
3640-
LHS = RHS;
3641-
RHS = t;
3642-
}
3643-
if (LHS->getOpcode() != Instruction::Shl ||
3644-
RHS->getOpcode() != Instruction::LShr)
3645-
{
3646-
return false;
3647-
}
3648-
3649-
// first: find V
3650-
Value* V0 = LHS->getOperand(0);
3651-
Value* V1 = RHS->getOperand(0);
3652-
Value* V = nullptr;
3653-
if (I.getOpcode() == Instruction::Or)
3654-
{
3655-
if (V0 == V1)
3656-
{
3657-
V = V0;
3658-
}
3659-
}
3660-
else
3661-
{
3662-
Value* X0, * X1;
3663-
if ((match(V0, m_ZExt(m_Value(X0))) || match(V0, m_SExt(m_Value(X0)))) &&
3664-
match(V1, m_ZExt(m_Value(X1))))
3665-
{
3666-
if (X0 == X1 && X0->getType()->getScalarSizeInBits() == typeWidth)
3667-
{
3668-
V = X0;
3669-
}
3670-
}
3671-
}
3672-
3673-
if (!V)
3674-
{
3675-
return false;
3676-
}
3677-
3678-
// Second: find amt
3679-
uint64_t typeMask = typeWidth - 1;
3680-
Value* LAmt = LHS->getOperand(1);
3681-
Value* RAmt = RHS->getOperand(1);
3682-
ConstantInt* C_LAmt = dyn_cast<ConstantInt>(LAmt);
3683-
ConstantInt* C_RAmt = dyn_cast<ConstantInt>(RAmt);
3684-
Value* X0, * X1;
3685-
Value* Amt = nullptr;
3686-
bool isROL = true;
3687-
if (C_LAmt || C_RAmt)
3688-
{
3689-
// If only one of shift-amounts is constant, it cannot be rotate.
3690-
if (C_LAmt && C_RAmt)
3691-
{
3692-
// For shift amount that is beyond the typewidth, the result is
3693-
// undefined. Here, we just use the LSB.
3694-
uint64_t c0 = C_LAmt->getZExtValue() & typeMask;
3695-
uint64_t c1 = C_RAmt->getZExtValue() & typeMask;
3696-
if ((c0 + c1) == typeWidth)
3697-
{
3698-
Amt = LAmt;
3699-
isROL = true;
3700-
}
3701-
}
3702-
}
3703-
else
3704-
{
3705-
if (match(RAmt, m_And(m_Sub(m_Zero(), m_Value(X1)), m_SpecificInt(typeMask))) ||
3706-
match(RAmt, m_And(m_Sub(m_SpecificInt(typeWidth), m_Value(X1)), m_SpecificInt(typeMask))) ||
3707-
match(RAmt, m_Sub(m_Zero(), m_Value(X1))) ||
3708-
match(RAmt, m_Sub(m_SpecificInt(typeWidth), m_Value(X1))))
3709-
{
3710-
if (LAmt == X1 ||
3711-
(match(LAmt, m_And(m_Value(X0), m_SpecificInt(typeMask))) && (X1 == X0)))
3712-
{
3713-
Amt = X1;
3714-
isROL = true;
3715-
}
3716-
}
3717-
if (!Amt &&
3718-
(match(LAmt, m_And(m_Sub(m_Zero(), m_Value(X1)), m_SpecificInt(typeMask))) ||
3719-
match(LAmt, m_And(m_Sub(m_SpecificInt(typeWidth), m_Value(X1)), m_SpecificInt(typeMask))) ||
3720-
match(LAmt, m_Sub(m_Zero(), m_Value(X1))) ||
3721-
match(LAmt, m_Sub(m_SpecificInt(typeWidth), m_Value(X1)))))
3722-
{
3723-
if (RAmt == X1 ||
3724-
(match(RAmt, m_And(m_Value(X0), m_SpecificInt(typeMask))) && (X1 == X0)))
3725-
{
3726-
Amt = X1;
3727-
isROL = false;
3728-
}
3729-
}
3730-
3731-
if (Amt)
3732-
{
3733-
Value* X0, * X1, * X2;
3734-
// 1) simple case: amt = 32 - X0; use amt1 as shift amount.
3735-
bool isReverse = match(Amt, m_Sub(m_SpecificInt(typeWidth), m_Value(X0)));
3736-
3737-
// 2) t = 16 - X0 | t = 0 - X0 ; for example, t is i16/i8, etc
3738-
// t1 = t & 15
3739-
// amt = zext t1, i32
3740-
isReverse = isReverse ||
3741-
(match(Amt, m_ZExt(m_Value(X1))) &&
3742-
match(X1, m_And(m_Value(X2), m_SpecificInt(typeMask))) &&
3743-
(match(X2, m_Sub(m_SpecificInt(typeWidth), m_Value(X0))) ||
3744-
match(X2, m_Sub(m_Zero(), m_Value(X0)))));
3745-
3746-
if (isReverse)
3747-
{
3748-
Amt = X0;
3749-
isROL = !isROL;
3750-
}
3751-
}
3752-
}
3753-
3754-
if (!Amt)
3755-
{
3756-
return false;
3757-
}
3758-
3759-
// Found the pattern.
3760-
RotatePattern* pattern = new (m_allocator) RotatePattern();
3761-
pattern->instruction = &I;
3762-
pattern->sources[0] = GetSource(V, true, false);
3763-
pattern->sources[1] = GetSource(Amt, true, false);
3764-
pattern->rotateOPCode = isROL ? EOPCODE_ROL : EOPCODE_ROR;
3765-
3766-
AddPattern(pattern);
3767-
return true;
3768-
}
3769-
37703542
bool CodeGenPatternMatch::MatchFunnelShiftRotate(llvm::IntrinsicInst& I)
37713543
{
37723544
// Hanlde only funnel shift that can be turned into rotate.

IGC/Compiler/CISACodeGen/PatternMatchPass.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ namespace IGC
211211
bool MatchPow(llvm::IntrinsicInst& I);
212212
bool MatchCondModifier(llvm::CmpInst& I);
213213
bool MatchBoolOp(llvm::BinaryOperator& I);
214-
bool MatchRotate(llvm::Instruction& I);
215214
bool MatchFunnelShiftRotate(llvm::IntrinsicInst& I);
216215
bool MatchDp4a(llvm::GenIntrinsicInst& I);
217216
bool MatchLogicAlu(llvm::BinaryOperator& I);

0 commit comments

Comments
 (0)