forked from OSchip/llvm-project
[RISCV] Separate out helper for checking if vector splat supported for operand [nfc]
This commit is contained in:
parent
93196654f5
commit
b25672ba82
|
@ -1283,6 +1283,69 @@ bool RISCVTargetLowering::
|
|||
return !XC;
|
||||
}
|
||||
|
||||
bool RISCVTargetLowering::canSplatOperand(Instruction *I, int Operand) const {
|
||||
if (!I->getType()->isVectorTy() || !Subtarget.hasVInstructions())
|
||||
return false;
|
||||
|
||||
switch (I->getOpcode()) {
|
||||
case Instruction::Add:
|
||||
case Instruction::Sub:
|
||||
case Instruction::Mul:
|
||||
case Instruction::And:
|
||||
case Instruction::Or:
|
||||
case Instruction::Xor:
|
||||
case Instruction::FAdd:
|
||||
case Instruction::FSub:
|
||||
case Instruction::FMul:
|
||||
case Instruction::FDiv:
|
||||
case Instruction::ICmp:
|
||||
case Instruction::FCmp:
|
||||
return true;
|
||||
case Instruction::Shl:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
case Instruction::UDiv:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::URem:
|
||||
case Instruction::SRem:
|
||||
return Operand == 1;
|
||||
case Instruction::Call:
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
|
||||
switch (II->getIntrinsicID()) {
|
||||
case Intrinsic::fma:
|
||||
case Intrinsic::vp_fma:
|
||||
return Operand == 0 || Operand == 1;
|
||||
case Intrinsic::vp_shl:
|
||||
case Intrinsic::vp_lshr:
|
||||
case Intrinsic::vp_ashr:
|
||||
case Intrinsic::vp_udiv:
|
||||
case Intrinsic::vp_sdiv:
|
||||
case Intrinsic::vp_urem:
|
||||
case Intrinsic::vp_srem:
|
||||
return Operand == 1;
|
||||
// These intrinsics are commutative.
|
||||
case Intrinsic::vp_add:
|
||||
case Intrinsic::vp_mul:
|
||||
case Intrinsic::vp_and:
|
||||
case Intrinsic::vp_or:
|
||||
case Intrinsic::vp_xor:
|
||||
case Intrinsic::vp_fadd:
|
||||
case Intrinsic::vp_fmul:
|
||||
// These intrinsics have 'vr' versions.
|
||||
case Intrinsic::vp_sub:
|
||||
case Intrinsic::vp_fsub:
|
||||
case Intrinsic::vp_fdiv:
|
||||
return Operand == 0 || Operand == 1;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if sinking \p I's operands to I's basic block is profitable, because
|
||||
/// the operands can be folded into a target instruction, e.g.
|
||||
/// splats of scalars can fold into vector instructions.
|
||||
|
@ -1293,68 +1356,8 @@ bool RISCVTargetLowering::shouldSinkOperands(
|
|||
if (!I->getType()->isVectorTy() || !Subtarget.hasVInstructions())
|
||||
return false;
|
||||
|
||||
auto IsSinker = [&](Instruction *I, int Operand) {
|
||||
switch (I->getOpcode()) {
|
||||
case Instruction::Add:
|
||||
case Instruction::Sub:
|
||||
case Instruction::Mul:
|
||||
case Instruction::And:
|
||||
case Instruction::Or:
|
||||
case Instruction::Xor:
|
||||
case Instruction::FAdd:
|
||||
case Instruction::FSub:
|
||||
case Instruction::FMul:
|
||||
case Instruction::FDiv:
|
||||
case Instruction::ICmp:
|
||||
case Instruction::FCmp:
|
||||
return true;
|
||||
case Instruction::Shl:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
case Instruction::UDiv:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::URem:
|
||||
case Instruction::SRem:
|
||||
return Operand == 1;
|
||||
case Instruction::Call:
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
|
||||
switch (II->getIntrinsicID()) {
|
||||
case Intrinsic::fma:
|
||||
case Intrinsic::vp_fma:
|
||||
return Operand == 0 || Operand == 1;
|
||||
case Intrinsic::vp_shl:
|
||||
case Intrinsic::vp_lshr:
|
||||
case Intrinsic::vp_ashr:
|
||||
case Intrinsic::vp_udiv:
|
||||
case Intrinsic::vp_sdiv:
|
||||
case Intrinsic::vp_urem:
|
||||
case Intrinsic::vp_srem:
|
||||
return Operand == 1;
|
||||
// These intrinsics are commutative.
|
||||
case Intrinsic::vp_add:
|
||||
case Intrinsic::vp_mul:
|
||||
case Intrinsic::vp_and:
|
||||
case Intrinsic::vp_or:
|
||||
case Intrinsic::vp_xor:
|
||||
case Intrinsic::vp_fadd:
|
||||
case Intrinsic::vp_fmul:
|
||||
// These intrinsics have 'vr' versions.
|
||||
case Intrinsic::vp_sub:
|
||||
case Intrinsic::vp_fsub:
|
||||
case Intrinsic::vp_fdiv:
|
||||
return Operand == 0 || Operand == 1;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
for (auto OpIdx : enumerate(I->operands())) {
|
||||
if (!IsSinker(I, OpIdx.index()))
|
||||
if (!canSplatOperand(I, OpIdx.index()))
|
||||
continue;
|
||||
|
||||
Instruction *Op = dyn_cast<Instruction>(OpIdx.value().get());
|
||||
|
@ -1371,7 +1374,7 @@ bool RISCVTargetLowering::shouldSinkOperands(
|
|||
// and vector registers
|
||||
for (Use &U : Op->uses()) {
|
||||
Instruction *Insn = cast<Instruction>(U.getUser());
|
||||
if (!IsSinker(Insn, U.getOperandNo()))
|
||||
if (!canSplatOperand(Insn, U.getOperandNo()))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -362,6 +362,9 @@ public:
|
|||
SDValue X, ConstantSDNode *XC, ConstantSDNode *CC, SDValue Y,
|
||||
unsigned OldShiftOpcode, unsigned NewShiftOpcode,
|
||||
SelectionDAG &DAG) const override;
|
||||
/// Return true if the (vector) instruction I will be lowered to an instruction
|
||||
/// with a scalar splat operand for the given Operand number.
|
||||
bool canSplatOperand(Instruction *I, int Operand) const;
|
||||
bool shouldSinkOperands(Instruction *I,
|
||||
SmallVectorImpl<Use *> &Ops) const override;
|
||||
bool shouldScalarizeBinop(SDValue VecOp) const override;
|
||||
|
|
Loading…
Reference in New Issue