[llvm] r326955 - [AArch64] Adjust the cost of integer vector division

Evandro Menezes via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 7 14:35:32 PST 2018


Author: evandro
Date: Wed Mar  7 14:35:32 2018
New Revision: 326955

URL: http://llvm.org/viewvc/llvm-project?rev=326955&view=rev
Log:
[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

Added:
    llvm/trunk/test/Analysis/CostModel/AArch64/div.ll
Modified:
    llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp?rev=326955&r1=326954&r2=326955&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp Wed Mar  7 14:35:32 2018
@@ -493,32 +493,48 @@ int AArch64TTIImpl::getArithmeticInstrCo
 
   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:

Added: llvm/trunk/test/Analysis/CostModel/AArch64/div.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/CostModel/AArch64/div.ll?rev=326955&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/CostModel/AArch64/div.ll (added)
+++ llvm/trunk/test/Analysis/CostModel/AArch64/div.ll Wed Mar  7 14:35:32 2018
@@ -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
+}




More information about the llvm-commits mailing list