[llvm] r264606 - [AArch64] Do not lower scalar sdiv/udiv to a shifts + mul sequence when optimizing for minsize

Haicheng Wu via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 28 11:17:07 PDT 2016


Author: haicheng
Date: Mon Mar 28 13:17:07 2016
New Revision: 264606

URL: http://llvm.org/viewvc/llvm-project?rev=264606&view=rev
Log:
[AArch64] Do not lower scalar sdiv/udiv to a shifts + mul sequence when optimizing for minsize

Mimic what x86 does when optimizing sdiv/udiv for minsize.

Added:
    llvm/trunk/test/CodeGen/AArch64/div_minsize.ll
Modified:
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h

Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=264606&r1=264605&r2=264606&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Mon Mar 28 13:17:07 2016
@@ -7516,6 +7516,10 @@ SDValue
 AArch64TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
                                      SelectionDAG &DAG,
                                      std::vector<SDNode *> *Created) const {
+  AttributeSet Attr = DAG.getMachineFunction().getFunction()->getAttributes();
+  if (isIntDivCheap(N->getValueType(0), Attr))
+    return SDValue(N,0); // Lower SDIV as SDIV
+
   // fold (sdiv X, pow2)
   EVT VT = N->getValueType(0);
   if ((VT != MVT::i32 && VT != MVT::i64) ||
@@ -10298,3 +10302,16 @@ void AArch64TargetLowering::insertCopies
           .addReg(NewVR);
   }
 }
+
+bool AArch64TargetLowering::isIntDivCheap(EVT VT, AttributeSet Attr) const {
+  // Integer division on AArch64 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 AArch64 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.
+  bool OptSize =
+      Attr.hasAttribute(AttributeSet::FunctionIndex, Attribute::MinSize);
+  return OptSize && !VT.isVector();
+}

Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h?rev=264606&r1=264605&r2=264606&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h Mon Mar 28 13:17:07 2016
@@ -378,6 +378,8 @@ public:
     return AArch64::X1;
   }
 
+  bool isIntDivCheap(EVT VT, AttributeSet Attr) const override;
+
   bool isCheapToSpeculateCttz() const override {
     return true;
   }

Added: llvm/trunk/test/CodeGen/AArch64/div_minsize.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/div_minsize.ll?rev=264606&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/div_minsize.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/div_minsize.ll Mon Mar 28 13:17:07 2016
@@ -0,0 +1,45 @@
+; RUN: llc < %s -march=aarch64 -mtriple=aarch64-linux-gnu | FileCheck %s
+
+define i32 @testsize1(i32 %x) minsize nounwind {
+entry:
+       %div = sdiv i32 %x, 32
+       ret i32 %div
+; CHECK-LABEL: testsize1
+; CHECK: sdiv 
+}
+
+define i32 @testsize2(i32 %x) minsize nounwind {
+entry:
+       %div = sdiv i32 %x, 33
+       ret i32 %div
+; CHECK-LABEL: testsize2
+; CHECK: sdiv
+}
+
+define i32 @testsize3(i32 %x) minsize nounwind {
+entry:
+       %div = udiv i32 %x, 32
+       ret i32 %div
+; CHECK-LABEL: testsize3
+; CHECK: lsr
+}
+
+define i32 @testsize4(i32 %x) minsize nounwind {
+entry:
+       %div = udiv i32 %x, 33
+       ret i32 %div
+; CHECK-LABEL: testsize4
+; CHECK: udiv 
+}
+
+define <8 x i16> @sdiv_vec8x16_minsize(<8 x i16> %var) minsize {
+entry:
+; CHECK: sdiv_vec8x16_minsize
+; CHECK: sshr 	v1.8h, v0.8h, #15 
+; CHECK: usra	v0.8h, v1.8h, #11
+; CHECK: sshr	v0.8h, v0.8h, #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
+}
+




More information about the llvm-commits mailing list