Skip to content

Commit a674209

Browse files
authored
[RISCV][TTI] Model the cost of insert/extractelt when the vector split into multiple register group and idx exceed single group. (#118401)
This patch implements the cost when the size of the vector need to split into multiple groups and the index exceed single vector group. For extract element, we need to store split vectors to stack and load the target element. For insert element, we need to store split vectors to stack and store the target element and load vectors back. After this patch, the cost of insert/extract element will close to the generated assembly.
1 parent 44c05a6 commit a674209

File tree

3 files changed

+114
-86
lines changed

3 files changed

+114
-86
lines changed

llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,34 @@ InstructionCost RISCVTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val,
19801980
SlideCost = 1; // With a constant index, we do not need to use addi.
19811981
}
19821982

1983+
// When the vector needs to split into multiple register groups and the index
1984+
// exceeds single vector register group, we need to insert/extract the element
1985+
// via stack.
1986+
if (LT.first > 1 &&
1987+
((Index == -1U) || (Index >= LT.second.getVectorMinNumElements() &&
1988+
LT.second.isScalableVector()))) {
1989+
Type *ScalarType = Val->getScalarType();
1990+
Align VecAlign = DL.getPrefTypeAlign(Val);
1991+
Align SclAlign = DL.getPrefTypeAlign(ScalarType);
1992+
// Extra addi for unknown index.
1993+
InstructionCost IdxCost = Index == -1U ? 1 : 0;
1994+
1995+
// Store all split vectors into stack and load the target element.
1996+
if (Opcode == Instruction::ExtractElement)
1997+
return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
1998+
getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
1999+
CostKind) +
2000+
IdxCost;
2001+
2002+
// Store all split vectors into stack and store the target element and load
2003+
// vectors back.
2004+
return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
2005+
getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind) +
2006+
getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
2007+
CostKind) +
2008+
IdxCost;
2009+
}
2010+
19832011
// Extract i64 in the target that has XLEN=32 need more instruction.
19842012
if (Val->getScalarType()->isIntegerTy() &&
19852013
ST->getXLen() < Val->getScalarSizeInBits()) {

0 commit comments

Comments
 (0)