forked from OSchip/llvm-project
[InstCombine] Moved SSE vector shift constant folding into its own helper function. NFCI.
This will make some upcoming bugfixes + improvements easier to manage. llvm-svn: 243962
This commit is contained in:
parent
706f37e8df
commit
dcfd7a3fba
|
@ -194,12 +194,44 @@ Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) {
|
|||
return MI;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static Value *SimplifyX86extend(const IntrinsicInst &II,
|
||||
InstCombiner::BuilderTy &Builder,
|
||||
bool SignExtend) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static Value *SimplifyX86immshift(const IntrinsicInst &II,
|
||||
InstCombiner::BuilderTy &Builder,
|
||||
bool ShiftLeft) {
|
||||
// Simplify if count is constant. To 0 if >= BitWidth,
|
||||
// otherwise to shl/lshr.
|
||||
auto CDV = dyn_cast<ConstantDataVector>(II.getArgOperand(1));
|
||||
auto CInt = dyn_cast<ConstantInt>(II.getArgOperand(1));
|
||||
if (!CDV && !CInt)
|
||||
return nullptr;
|
||||
ConstantInt *Count;
|
||||
if (CDV)
|
||||
Count = cast<ConstantInt>(CDV->getElementAsConstant(0));
|
||||
else
|
||||
Count = CInt;
|
||||
|
||||
auto Vec = II.getArgOperand(0);
|
||||
auto VT = cast<VectorType>(Vec->getType());
|
||||
auto SVT = VT->getElementType();
|
||||
if (Count->getZExtValue() > (SVT->getPrimitiveSizeInBits() - 1))
|
||||
return ConstantAggregateZero::get(VT);
|
||||
|
||||
unsigned VWidth = VT->getNumElements();
|
||||
|
||||
// Get a constant vector of the same type as the first operand.
|
||||
auto VTCI = ConstantInt::get(VT->getElementType(), Count->getZExtValue());
|
||||
|
||||
if (ShiftLeft)
|
||||
return Builder.CreateShl(Vec, Builder.CreateVectorSplat(VWidth, VTCI));
|
||||
|
||||
return Builder.CreateLShr(Vec, Builder.CreateVectorSplat(VWidth, VTCI));
|
||||
}
|
||||
|
||||
static Value *SimplifyX86extend(const IntrinsicInst &II,
|
||||
InstCombiner::BuilderTy &Builder,
|
||||
bool SignExtend) {
|
||||
VectorType *SrcTy = cast<VectorType>(II.getArgOperand(0)->getType());
|
||||
VectorType *DstTy = cast<VectorType>(II.getType());
|
||||
unsigned NumDstElts = DstTy->getNumElements();
|
||||
|
@ -718,86 +750,46 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||
II->setArgOperand(0, V);
|
||||
return II;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Constant fold <A x Bi> << Ci.
|
||||
// FIXME: We don't handle _dq because it's a shift of an i128, but is
|
||||
// represented in the IR as <2 x i64>. A per element shift is wrong.
|
||||
case Intrinsic::x86_sse2_psll_d:
|
||||
case Intrinsic::x86_sse2_psll_q:
|
||||
case Intrinsic::x86_sse2_psll_w:
|
||||
break;
|
||||
}
|
||||
|
||||
// Constant fold lshr( <A x Bi>, Ci ).
|
||||
case Intrinsic::x86_sse2_psrl_d:
|
||||
case Intrinsic::x86_sse2_psrl_q:
|
||||
case Intrinsic::x86_sse2_psrl_w:
|
||||
case Intrinsic::x86_sse2_psrli_d:
|
||||
case Intrinsic::x86_sse2_psrli_q:
|
||||
case Intrinsic::x86_sse2_psrli_w:
|
||||
case Intrinsic::x86_avx2_psrl_d:
|
||||
case Intrinsic::x86_avx2_psrl_q:
|
||||
case Intrinsic::x86_avx2_psrl_w:
|
||||
case Intrinsic::x86_avx2_psrli_d:
|
||||
case Intrinsic::x86_avx2_psrli_q:
|
||||
case Intrinsic::x86_avx2_psrli_w:
|
||||
if (Value *V = SimplifyX86immshift(*II, *Builder, false))
|
||||
return ReplaceInstUsesWith(*II, V);
|
||||
break;
|
||||
|
||||
// Constant fold shl( <A x Bi>, Ci ).
|
||||
case Intrinsic::x86_sse2_psll_d:
|
||||
case Intrinsic::x86_sse2_psll_q:
|
||||
case Intrinsic::x86_sse2_psll_w:
|
||||
case Intrinsic::x86_sse2_pslli_d:
|
||||
case Intrinsic::x86_sse2_pslli_q:
|
||||
case Intrinsic::x86_sse2_pslli_w:
|
||||
case Intrinsic::x86_avx2_psll_d:
|
||||
case Intrinsic::x86_avx2_psll_q:
|
||||
case Intrinsic::x86_avx2_psll_w:
|
||||
case Intrinsic::x86_avx2_pslli_d:
|
||||
case Intrinsic::x86_avx2_pslli_q:
|
||||
case Intrinsic::x86_avx2_pslli_w:
|
||||
case Intrinsic::x86_sse2_psrl_d:
|
||||
case Intrinsic::x86_sse2_psrl_q:
|
||||
case Intrinsic::x86_sse2_psrl_w:
|
||||
case Intrinsic::x86_sse2_psrli_d:
|
||||
case Intrinsic::x86_sse2_psrli_q:
|
||||
case Intrinsic::x86_sse2_psrli_w:
|
||||
case Intrinsic::x86_avx2_psrl_d:
|
||||
case Intrinsic::x86_avx2_psrl_q:
|
||||
case Intrinsic::x86_avx2_psrl_w:
|
||||
case Intrinsic::x86_avx2_psrli_d:
|
||||
case Intrinsic::x86_avx2_psrli_q:
|
||||
case Intrinsic::x86_avx2_psrli_w: {
|
||||
// Simplify if count is constant. To 0 if >= BitWidth,
|
||||
// otherwise to shl/lshr.
|
||||
auto CDV = dyn_cast<ConstantDataVector>(II->getArgOperand(1));
|
||||
auto CInt = dyn_cast<ConstantInt>(II->getArgOperand(1));
|
||||
if (!CDV && !CInt)
|
||||
break;
|
||||
ConstantInt *Count;
|
||||
if (CDV)
|
||||
Count = cast<ConstantInt>(CDV->getElementAsConstant(0));
|
||||
else
|
||||
Count = CInt;
|
||||
|
||||
auto Vec = II->getArgOperand(0);
|
||||
auto VT = cast<VectorType>(Vec->getType());
|
||||
if (Count->getZExtValue() >
|
||||
VT->getElementType()->getPrimitiveSizeInBits() - 1)
|
||||
return ReplaceInstUsesWith(
|
||||
CI, ConstantAggregateZero::get(Vec->getType()));
|
||||
|
||||
bool isPackedShiftLeft = true;
|
||||
switch (II->getIntrinsicID()) {
|
||||
default : break;
|
||||
case Intrinsic::x86_sse2_psrl_d:
|
||||
case Intrinsic::x86_sse2_psrl_q:
|
||||
case Intrinsic::x86_sse2_psrl_w:
|
||||
case Intrinsic::x86_sse2_psrli_d:
|
||||
case Intrinsic::x86_sse2_psrli_q:
|
||||
case Intrinsic::x86_sse2_psrli_w:
|
||||
case Intrinsic::x86_avx2_psrl_d:
|
||||
case Intrinsic::x86_avx2_psrl_q:
|
||||
case Intrinsic::x86_avx2_psrl_w:
|
||||
case Intrinsic::x86_avx2_psrli_d:
|
||||
case Intrinsic::x86_avx2_psrli_q:
|
||||
case Intrinsic::x86_avx2_psrli_w: isPackedShiftLeft = false; break;
|
||||
}
|
||||
|
||||
unsigned VWidth = VT->getNumElements();
|
||||
// Get a constant vector of the same type as the first operand.
|
||||
auto VTCI = ConstantInt::get(VT->getElementType(), Count->getZExtValue());
|
||||
if (isPackedShiftLeft)
|
||||
return BinaryOperator::CreateShl(Vec,
|
||||
Builder->CreateVectorSplat(VWidth, VTCI));
|
||||
|
||||
return BinaryOperator::CreateLShr(Vec,
|
||||
Builder->CreateVectorSplat(VWidth, VTCI));
|
||||
}
|
||||
|
||||
case Intrinsic::x86_sse41_pmovsxbd:
|
||||
case Intrinsic::x86_sse41_pmovsxbq:
|
||||
case Intrinsic::x86_sse41_pmovsxbw:
|
||||
case Intrinsic::x86_avx2_pslli_d:
|
||||
case Intrinsic::x86_avx2_pslli_q:
|
||||
case Intrinsic::x86_avx2_pslli_w:
|
||||
if (Value *V = SimplifyX86immshift(*II, *Builder, true))
|
||||
return ReplaceInstUsesWith(*II, V);
|
||||
break;
|
||||
|
||||
case Intrinsic::x86_sse41_pmovsxbd:
|
||||
case Intrinsic::x86_sse41_pmovsxbq:
|
||||
case Intrinsic::x86_sse41_pmovsxbw:
|
||||
case Intrinsic::x86_sse41_pmovsxdq:
|
||||
case Intrinsic::x86_sse41_pmovsxwd:
|
||||
case Intrinsic::x86_sse41_pmovsxwq:
|
||||
|
|
Loading…
Reference in New Issue