[X86] Do not lower scalar sdiv/udiv to a shifts + mul sequence when optimizing for...
authorMichael Kuperstein <michael.m.kuperstein@intel.com>
Wed, 19 Aug 2015 11:21:43 +0000 (11:21 +0000)
committerMichael Kuperstein <michael.m.kuperstein@intel.com>
Wed, 19 Aug 2015 11:21:43 +0000 (11:21 +0000)
There are some cases where the mul sequence is smaller, but for the most part,
using a div is preferable. This does not apply to vectors, since x86 doesn't
have vector idiv, and a vector mul/shifts sequence ought to be smaller than a
scalarized division.

Differential Revision: http://reviews.llvm.org/D12082

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245431 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
test/CodeGen/X86/divide-by-constant.ll
test/CodeGen/X86/vec_sdiv_to_shift.ll

index 642fe904735ccc7bab50f1af247912e4478617b4..f3012d59f0cc5812be86198611cfa84b646b4435 100644 (file)
@@ -26427,3 +26427,14 @@ int X86TargetLowering::getScalingFactorCost(const DataLayout &DL,
 bool X86TargetLowering::isTargetFTOL() const {
   return Subtarget->isTargetKnownWindowsMSVC() && !Subtarget->is64Bit();
 }
+
+bool X86TargetLowering::isIntDivCheap(EVT VT, bool OptSize) const {
+  // Integer division on x86 is expensive. However, when aggressively optimizing
+  // for code size, we prefer to use a div instruction, as it is usually smaller
+  // than the alternative sequence.
+  // The exception to this is vector division. Since x86 doesn't have vector
+  // integer division, leaving the division as-is is a loss even in terms of
+  // size, because it will have to be scalarized, while the alternative code
+  // sequence can be performed in vector form.
+  return OptSize && !VT.isVector();
+}
index 837fe8cfcf739f945759751a1b1397850eca0120..c0abf0beb0d736cec790a81e7e8e08f37b9c0ff0 100644 (file)
@@ -902,6 +902,8 @@ namespace llvm {
     /// \brief Customize the preferred legalization strategy for certain types.
     LegalizeTypeAction getPreferredVectorAction(EVT VT) const override;
 
+    bool isIntDivCheap(EVT VT, bool OptSize) const override;
+
   protected:
     std::pair<const TargetRegisterClass *, uint8_t>
     findRepresentativeClass(const TargetRegisterInfo *TRI,
index fd07a3f551001c761981bd9d1889fd279ae2bedb..9543d6c4d74988bf71390f3c315e2b8df9d33fe4 100644 (file)
@@ -94,3 +94,35 @@ define i8 @test9(i8 %x) nounwind {
 ; CHECK: shrl $11
 ; CHECK: ret
 }
+
+define i32 @testsize1(i32 %x) minsize nounwind {
+entry:
+       %div = sdiv i32 %x, 32
+       ret i32 %div
+; CHECK-LABEL: testsize1:
+; CHECK: divl
+}
+
+define i32 @testsize2(i32 %x) minsize nounwind {
+entry:
+       %div = sdiv i32 %x, 33
+       ret i32 %div
+; CHECK-LABEL: testsize2:
+; CHECK: divl
+}
+
+define i32 @testsize3(i32 %x) minsize nounwind {
+entry:
+       %div = udiv i32 %x, 32
+       ret i32 %div
+; CHECK-LABEL: testsize3:
+; CHECK: shrl
+}
+
+define i32 @testsize4(i32 %x) minsize nounwind {
+entry:
+       %div = udiv i32 %x, 33
+       ret i32 %div
+; CHECK-LABEL: testsize4:
+; CHECK: divl
+}
index 56855d3c44ebcfb362cd88bf377bb20b8eddef4c..7f71a0c2ea5b3ef61944d7fead1cfe9791be9aaa 100644 (file)
@@ -13,6 +13,19 @@ entry:
   ret <8 x i16> %0
 }
 
+define <8 x i16> @sdiv_vec8x16_minsize(<8 x i16> %var) minsize {
+entry:
+; CHECK: sdiv_vec8x16_minsize
+; CHECK: psraw  $15
+; CHECK: vpsrlw  $11
+; CHECK: vpaddw
+; CHECK: vpsraw  $5
+; CHECK: ret
+  %0 = sdiv <8 x i16> %var, <i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32>
+  ret <8 x i16> %0
+}
+
+
 define <4 x i32> @sdiv_zero(<4 x i32> %var) {
 entry:
 ; CHECK: sdiv_zero