Skip to content

Commit

Permalink
[AArch64] Adjust the cost of integer vector division
Browse files Browse the repository at this point in the history
Since there is no instruction for integer vector division, factor in the
cost of singling out each element to be used with the scalar division
instruction.

Differential revision: https://reviews.llvm.org/D43974

llvm-svn: 326955
  • Loading branch information
Evandro Menezes committed Mar 7, 2018
1 parent f62e1cc commit f9bd871
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 22 deletions.
60 changes: 38 additions & 22 deletions llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
Expand Up @@ -493,32 +493,48 @@ int AArch64TTIImpl::getArithmeticInstrCost(

int ISD = TLI->InstructionOpcodeToISD(Opcode);

if (ISD == ISD::SDIV &&
Opd2Info == TargetTransformInfo::OK_UniformConstantValue &&
Opd2PropInfo == TargetTransformInfo::OP_PowerOf2) {
// On AArch64, scalar signed division by constants power-of-two are
// normally expanded to the sequence ADD + CMP + SELECT + SRA.
// The OperandValue properties many not be same as that of previous
// operation; conservatively assume OP_None.
Cost += getArithmeticInstrCost(Instruction::Add, Ty, Opd1Info, Opd2Info,
TargetTransformInfo::OP_None,
TargetTransformInfo::OP_None);
Cost += getArithmeticInstrCost(Instruction::Sub, Ty, Opd1Info, Opd2Info,
TargetTransformInfo::OP_None,
TargetTransformInfo::OP_None);
Cost += getArithmeticInstrCost(Instruction::Select, Ty, Opd1Info, Opd2Info,
TargetTransformInfo::OP_None,
TargetTransformInfo::OP_None);
Cost += getArithmeticInstrCost(Instruction::AShr, Ty, Opd1Info, Opd2Info,
TargetTransformInfo::OP_None,
TargetTransformInfo::OP_None);
return Cost;
}

switch (ISD) {
default:
return Cost + BaseT::getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info,
Opd1PropInfo, Opd2PropInfo);
case ISD::SDIV:
if (Opd2Info == TargetTransformInfo::OK_UniformConstantValue &&
Opd2PropInfo == TargetTransformInfo::OP_PowerOf2) {
// On AArch64, scalar signed division by constants power-of-two are
// normally expanded to the sequence ADD + CMP + SELECT + SRA.
// The OperandValue properties many not be same as that of previous
// operation; conservatively assume OP_None.
Cost += getArithmeticInstrCost(Instruction::Add, Ty, Opd1Info, Opd2Info,
TargetTransformInfo::OP_None,
TargetTransformInfo::OP_None);
Cost += getArithmeticInstrCost(Instruction::Sub, Ty, Opd1Info, Opd2Info,
TargetTransformInfo::OP_None,
TargetTransformInfo::OP_None);
Cost += getArithmeticInstrCost(Instruction::Select, Ty, Opd1Info, Opd2Info,
TargetTransformInfo::OP_None,
TargetTransformInfo::OP_None);
Cost += getArithmeticInstrCost(Instruction::AShr, Ty, Opd1Info, Opd2Info,
TargetTransformInfo::OP_None,
TargetTransformInfo::OP_None);
return Cost;
}
LLVM_FALLTHROUGH;
case ISD::UDIV:
Cost += BaseT::getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info,
Opd1PropInfo, Opd2PropInfo);
if (Ty->isVectorTy()) {
// On AArch64, vector divisions are not supported natively and are
// expanded into scalar divisions of each pair of elements.
Cost += getArithmeticInstrCost(Instruction::ExtractElement, Ty, Opd1Info,
Opd2Info, Opd1PropInfo, Opd2PropInfo);
Cost += getArithmeticInstrCost(Instruction::InsertElement, Ty, Opd1Info,
Opd2Info, Opd1PropInfo, Opd2PropInfo);
// TODO: if one of the arguments is scalar, then it's not necessary to
// double the cost of handling the vector elements.
Cost += Cost;
}
return Cost;

case ISD::ADD:
case ISD::MUL:
case ISD::XOR:
Expand Down
38 changes: 38 additions & 0 deletions llvm/test/Analysis/CostModel/AArch64/div.ll
@@ -0,0 +1,38 @@
; RUN: opt -cost-model -analyze -mtriple=aarch64--linux-gnu < %s | FileCheck %s

; Verify the cost of integer division instructions.

define i32 @sdivs1i32(i32 %a, i32 %b) {
; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivs1i32':
; CHECK: Found an estimated cost of 1 for instruction: %c = sdiv i32 %a, %b
%c = sdiv i32 %a, %b
ret i32 %c
}

define i64 @sdivs1i64(i64 %a, i64 %b) {
; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivs1i64':
; CHECK: Found an estimated cost of 1 for instruction: %c = sdiv i64 %a, %b
%c = sdiv i64 %a, %b
ret i64 %c
}

define <2 x i32> @sdivv2i32(<2 x i32> %a, <2 x i32> %b) {
; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivv2i32':
; CHECK: Found an estimated cost of 24 for instruction: %c = sdiv <2 x i32> %a, %b
%c = sdiv <2 x i32> %a, %b
ret <2 x i32> %c
}

define <2 x i64> @sdivv2i64(<2 x i64> %a, <2 x i64> %b) {
; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivv2i64':
; CHECK: Found an estimated cost of 24 for instruction: %c = sdiv <2 x i64> %a, %b
%c = sdiv <2 x i64> %a, %b
ret <2 x i64> %c
}

define <4 x i32> @sdivv4i32(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivv4i32':
; CHECK: Found an estimated cost of 52 for instruction: %c = sdiv <4 x i32> %a, %b
%c = sdiv <4 x i32> %a, %b
ret <4 x i32> %c
}

0 comments on commit f9bd871

Please sign in to comment.