[X86] LowerRotate - use X86::isConstantSplat to detect constant splat rotation amounts.
Avoid code duplication and matches what we do for the similar LowerFunnelShift and LowerScalarImmediateShift methods.
This commit is contained in:
parent
67d25914b2
commit
ac4609cb1d
|
|
@ -27359,30 +27359,19 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget,
|
||||||
int NumElts = VT.getVectorNumElements();
|
int NumElts = VT.getVectorNumElements();
|
||||||
|
|
||||||
// Check for constant splat rotation amount.
|
// Check for constant splat rotation amount.
|
||||||
APInt UndefElts;
|
APInt CstSplatValue;
|
||||||
SmallVector<APInt, 32> EltBits;
|
bool IsCstSplat = X86::isConstantSplat(Amt, CstSplatValue);
|
||||||
int CstSplatIndex = -1;
|
|
||||||
if (getTargetConstantBitsFromNode(Amt, EltSizeInBits, UndefElts, EltBits))
|
|
||||||
for (int i = 0; i != NumElts; ++i)
|
|
||||||
if (!UndefElts[i]) {
|
|
||||||
if (CstSplatIndex < 0 || EltBits[i] == EltBits[CstSplatIndex]) {
|
|
||||||
CstSplatIndex = i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CstSplatIndex = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for splat rotate by zero.
|
// Check for splat rotate by zero.
|
||||||
if (0 <= CstSplatIndex && EltBits[CstSplatIndex].urem(EltSizeInBits) == 0)
|
if (IsCstSplat && CstSplatValue.urem(EltSizeInBits) == 0)
|
||||||
return R;
|
return R;
|
||||||
|
|
||||||
// AVX512 implicitly uses modulo rotation amounts.
|
// AVX512 implicitly uses modulo rotation amounts.
|
||||||
if (Subtarget.hasAVX512() && 32 <= EltSizeInBits) {
|
if (Subtarget.hasAVX512() && 32 <= EltSizeInBits) {
|
||||||
// Attempt to rotate by immediate.
|
// Attempt to rotate by immediate.
|
||||||
if (0 <= CstSplatIndex) {
|
if (IsCstSplat) {
|
||||||
unsigned RotOpc = (Opcode == ISD::ROTL ? X86ISD::VROTLI : X86ISD::VROTRI);
|
unsigned RotOpc = (Opcode == ISD::ROTL ? X86ISD::VROTLI : X86ISD::VROTRI);
|
||||||
uint64_t RotAmt = EltBits[CstSplatIndex].urem(EltSizeInBits);
|
uint64_t RotAmt = CstSplatValue.urem(EltSizeInBits);
|
||||||
return DAG.getNode(RotOpc, DL, VT, R,
|
return DAG.getNode(RotOpc, DL, VT, R,
|
||||||
DAG.getTargetConstant(RotAmt, DL, MVT::i8));
|
DAG.getTargetConstant(RotAmt, DL, MVT::i8));
|
||||||
}
|
}
|
||||||
|
|
@ -27402,10 +27391,10 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget,
|
||||||
assert(VT.is128BitVector() && "Only rotate 128-bit vectors!");
|
assert(VT.is128BitVector() && "Only rotate 128-bit vectors!");
|
||||||
|
|
||||||
// Attempt to rotate by immediate.
|
// Attempt to rotate by immediate.
|
||||||
if (0 <= CstSplatIndex) {
|
if (IsCstSplat) {
|
||||||
uint64_t RotateAmt = EltBits[CstSplatIndex].urem(EltSizeInBits);
|
uint64_t RotAmt = CstSplatValue.urem(EltSizeInBits);
|
||||||
return DAG.getNode(X86ISD::VROTLI, DL, VT, R,
|
return DAG.getNode(X86ISD::VROTLI, DL, VT, R,
|
||||||
DAG.getTargetConstant(RotateAmt, DL, MVT::i8));
|
DAG.getTargetConstant(RotAmt, DL, MVT::i8));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use general rotate by variable (per-element).
|
// Use general rotate by variable (per-element).
|
||||||
|
|
@ -27422,7 +27411,7 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget,
|
||||||
"Only vXi32/vXi16/vXi8 vector rotates supported");
|
"Only vXi32/vXi16/vXi8 vector rotates supported");
|
||||||
|
|
||||||
// Rotate by an uniform constant - expand back to shifts.
|
// Rotate by an uniform constant - expand back to shifts.
|
||||||
if (0 <= CstSplatIndex)
|
if (IsCstSplat)
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
bool IsSplatAmt = DAG.isSplatValue(Amt);
|
bool IsSplatAmt = DAG.isSplatValue(Amt);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue