Skip to content

Commit 6d508fb

Browse files
[AArch64][LV][SLP] Vectorizers use call cost for vectorized frem
getArithmeticInstrCost is used by both LoopVectorizer and SLPVectorizer to compute the cost of frem, which becomes a call cost on AArch64 when TLI has a vector library function. Add tests that do SLP vectorization for code that contains 2x double and 4x float frem instructions.
1 parent ecd7da7 commit 6d508fb

File tree

4 files changed

+27
-42
lines changed

4 files changed

+27
-42
lines changed

llvm/include/llvm/Analysis/TargetTransformInfo.h

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,26 +1247,17 @@ class TargetTransformInfo {
12471247
/// cases or optimizations based on those values.
12481248
/// \p CxtI is the optional original context instruction, if one exists, to
12491249
/// provide even more information.
1250+
/// \p TLibInfo use to search for platform specific vector library functions
1251+
/// for instructions that might be converted to calls. The only known case
1252+
/// currently is frem.
12501253
InstructionCost getArithmeticInstrCost(
12511254
unsigned Opcode, Type *Ty,
12521255
TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
12531256
TTI::OperandValueInfo Opd1Info = {TTI::OK_AnyValue, TTI::OP_None},
12541257
TTI::OperandValueInfo Opd2Info = {TTI::OK_AnyValue, TTI::OP_None},
12551258
ArrayRef<const Value *> Args = ArrayRef<const Value *>(),
1256-
const Instruction *CxtI = nullptr) const;
1257-
1258-
/// Returns the cost of a vector instruction based on the assumption that frem
1259-
/// will be later transformed (by ReplaceWithVecLib) into a call to a
1260-
/// platform specific frem vector math function.
1261-
/// Returns the same cost as getArithmeticInstrCost when no math function is
1262-
/// available.
1263-
InstructionCost getFRemInstrCost(
1264-
const TargetLibraryInfo *TLI, Type *Ty,
1265-
TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
1266-
TTI::OperandValueInfo Opd1Info = {TTI::OK_AnyValue, TTI::OP_None},
1267-
TTI::OperandValueInfo Opd2Info = {TTI::OK_AnyValue, TTI::OP_None},
1268-
ArrayRef<const Value *> Args = ArrayRef<const Value *>(),
1269-
const Instruction *CxtI = nullptr) const;
1259+
const Instruction *CxtI = nullptr,
1260+
const TargetLibraryInfo *TLibInfo = nullptr) const;
12701261

12711262
/// Returns the cost estimation for alternating opcode pattern that can be
12721263
/// lowered to a single instruction on the target. In X86 this is for the

llvm/lib/Analysis/TargetTransformInfo.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,22 @@ TargetTransformInfo::getOperandInfo(const Value *V) {
875875
InstructionCost TargetTransformInfo::getArithmeticInstrCost(
876876
unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
877877
OperandValueInfo Op1Info, OperandValueInfo Op2Info,
878-
ArrayRef<const Value *> Args, const Instruction *CxtI) const {
878+
ArrayRef<const Value *> Args, const Instruction *CxtI,
879+
const TargetLibraryInfo *TLibInfo) const {
880+
881+
// Use call cost for frem intructions that have platform specific vector math
882+
// functions, as those will be replaced with calls later by SelectionDAG or
883+
// ReplaceWithVecLib pass.
884+
if (TLibInfo && Opcode == Instruction::FRem) {
885+
VectorType *VecTy = dyn_cast<VectorType>(Ty);
886+
LibFunc Func;
887+
if (VecTy &&
888+
TLibInfo->getLibFunc(Instruction::FRem, Ty->getScalarType(), Func) &&
889+
TLibInfo->isFunctionVectorizable(TLibInfo->getName(Func),
890+
VecTy->getElementCount()))
891+
return getCallInstrCost(nullptr, VecTy, {VecTy, VecTy}, CostKind);
892+
}
893+
879894
InstructionCost Cost =
880895
TTIImpl->getArithmeticInstrCost(Opcode, Ty, CostKind,
881896
Op1Info, Op2Info,
@@ -884,20 +899,6 @@ InstructionCost TargetTransformInfo::getArithmeticInstrCost(
884899
return Cost;
885900
}
886901

887-
InstructionCost TargetTransformInfo::getFRemInstrCost(
888-
const TargetLibraryInfo *TLI, Type *Ty, TTI::TargetCostKind CostKind,
889-
OperandValueInfo Op1Info, OperandValueInfo Op2Info,
890-
ArrayRef<const Value *> Args, const Instruction *CxtI) const {
891-
VectorType *VecTy = dyn_cast<VectorType>(Ty);
892-
LibFunc Func;
893-
if (VecTy && TLI->getLibFunc(Instruction::FRem, Ty->getScalarType(), Func) &&
894-
TLI->isFunctionVectorizable(TLI->getName(Func), VecTy->getElementCount()))
895-
return getCallInstrCost(nullptr, VecTy, {VecTy, VecTy}, CostKind);
896-
897-
return getArithmeticInstrCost(Instruction::FRem, Ty, CostKind, Op1Info,
898-
Op2Info, Args, CxtI);
899-
}
900-
901902
InstructionCost TargetTransformInfo::getAltInstrCost(
902903
VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
903904
const SmallBitVector &OpcodeMask, TTI::TargetCostKind CostKind) const {

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6911,14 +6911,10 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
69116911
Op2Info.Kind = TargetTransformInfo::OK_UniformValue;
69126912

69136913
SmallVector<const Value *, 4> Operands(I->operand_values());
6914-
TTI::OperandValueInfo Op1Info{TargetTransformInfo::OK_AnyValue,
6915-
TargetTransformInfo::OP_None};
6916-
if (I->getOpcode() == Instruction::FRem)
6917-
return TTI.getFRemInstrCost(TLI, VectorTy, CostKind, Op1Info, Op2Info,
6918-
Operands, I);
6919-
6920-
return TTI.getArithmeticInstrCost(I->getOpcode(), VectorTy, CostKind,
6921-
Op1Info, Op2Info, Operands, I);
6914+
return TTI.getArithmeticInstrCost(
6915+
I->getOpcode(), VectorTy, CostKind,
6916+
{TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None},
6917+
Op2Info, Operands, I, TLI);
69226918
}
69236919
case Instruction::FNeg: {
69246920
return TTI.getArithmeticInstrCost(

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8851,12 +8851,9 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals,
88518851
unsigned OpIdx = isa<UnaryOperator>(VL0) ? 0 : 1;
88528852
TTI::OperandValueInfo Op1Info = getOperandInfo(E->getOperand(0));
88538853
TTI::OperandValueInfo Op2Info = getOperandInfo(E->getOperand(OpIdx));
8854-
if (ShuffleOrOp == Instruction::FRem)
8855-
return TTI->getFRemInstrCost(TLI, VecTy, CostKind, Op1Info, Op2Info) +
8856-
CommonCost;
8857-
88588854
return TTI->getArithmeticInstrCost(ShuffleOrOp, VecTy, CostKind, Op1Info,
8859-
Op2Info) +
8855+
Op2Info, ArrayRef<const Value *>(),
8856+
nullptr, TLI) +
88608857
CommonCost;
88618858
};
88628859
return GetCostDiff(GetScalarCost, GetVectorCost);

0 commit comments

Comments
 (0)