summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvandro Menezes <e.menezes@samsung.com>2018-03-07 22:35:32 +0000
committerEvandro Menezes <e.menezes@samsung.com>2018-03-07 22:35:32 +0000
commitf9bd871d32059680c1dbad3fb934bb8a94ac3aa5 (patch)
treea076838e77b3b15923f861b26588c82329a879e0
parentf62e1ccbeb891e6ebd1765770d36912b58e2f360 (diff)
downloadbcm5719-llvm-f9bd871d32059680c1dbad3fb934bb8a94ac3aa5.tar.gz
bcm5719-llvm-f9bd871d32059680c1dbad3fb934bb8a94ac3aa5.zip
[AArch64] Adjust the cost of integer vector division
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
-rw-r--r--llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp60
-rw-r--r--llvm/test/Analysis/CostModel/AArch64/div.ll38
2 files changed, 76 insertions, 22 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index aafcd7fe19f..c2204af533c 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -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:
diff --git a/llvm/test/Analysis/CostModel/AArch64/div.ll b/llvm/test/Analysis/CostModel/AArch64/div.ll
new file mode 100644
index 00000000000..50f7117c0f8
--- /dev/null
+++ b/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
+}
OpenPOWER on IntegriCloud