[llvm] r245921 - Pass function attributes instead of boolean in isIntDivCheap().
Steve King via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 19:31:22 PDT 2015
Author: srking
Date: Mon Aug 24 21:31:21 2015
New Revision: 245921
URL: http://llvm.org/viewvc/llvm-project?rev=245921&view=rev
Log:
Pass function attributes instead of boolean in isIntDivCheap().
Added:
llvm/trunk/test/CodeGen/X86/sdiv-pow2.ll
Modified:
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.h
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=245921&r1=245920&r2=245921&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Mon Aug 24 21:31:21 2015
@@ -228,7 +228,7 @@ public:
/// several shifts, adds, and multiplies for this target.
/// The definition of "cheaper" may depend on whether we're optimizing
/// for speed or for size.
- virtual bool isIntDivCheap(EVT VT, bool OptSize) const {
+ virtual bool isIntDivCheap(EVT VT, AttributeSet Attr) const {
return false;
}
@@ -2719,11 +2719,14 @@ public:
SDValue BuildUDIV(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
bool IsAfterLegalization,
std::vector<SDNode *> *Created) const;
+
+ /// Targets may override this function to provide custom SDIV lowering for
+ /// power-of-2 denominators. If the target returns an empty SDValue, LLVM
+ /// assumes SDIV is expensive and replaces it with a series of other integer
+ /// operations.
virtual SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor,
SelectionDAG &DAG,
- std::vector<SDNode *> *Created) const {
- return SDValue();
- }
+ std::vector<SDNode *> *Created) const;
/// Indicate whether this target prefers to combine FDIVs with the same
/// divisor. If the transform should never be done, return zero. If the
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=245921&r1=245920&r2=245921&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Aug 24 21:31:21 2015
@@ -2183,7 +2183,6 @@ SDValue DAGCombiner::visitSDIV(SDNode *N
N0, N1);
}
- bool MinSize = DAG.getMachineFunction().getFunction()->optForMinSize();
// fold (sdiv X, pow2) -> simple ops after legalize
// FIXME: We check for the exact bit here because the generic lowering gives
// better results in that case. The target-specific lowering should learn how
@@ -2192,10 +2191,6 @@ SDValue DAGCombiner::visitSDIV(SDNode *N
!cast<BinaryWithFlagsSDNode>(N)->Flags.hasExact() &&
(N1C->getAPIntValue().isPowerOf2() ||
(-N1C->getAPIntValue()).isPowerOf2())) {
- // If integer division is cheap, then don't perform the following fold.
- if (TLI.isIntDivCheap(N->getValueType(0), MinSize))
- return SDValue();
-
// Target-specific implementation of sdiv x, pow2.
if (SDValue Res = BuildSDIVPow2(N))
return Res;
@@ -2232,8 +2227,10 @@ SDValue DAGCombiner::visitSDIV(SDNode *N
}
// If integer divide is expensive and we satisfy the requirements, emit an
- // alternate sequence.
- if (N1C && !TLI.isIntDivCheap(N->getValueType(0), MinSize))
+ // alternate sequence. Targets may check function attributes for size/speed
+ // trade-offs.
+ AttributeSet Attr = DAG.getMachineFunction().getFunction()->getAttributes();
+ if (N1C && !TLI.isIntDivCheap(N->getValueType(0), Attr))
if (SDValue Op = BuildSDIV(N))
return Op;
@@ -2289,8 +2286,8 @@ SDValue DAGCombiner::visitUDIV(SDNode *N
}
// fold (udiv x, c) -> alternate
- bool MinSize = DAG.getMachineFunction().getFunction()->optForMinSize();
- if (N1C && !TLI.isIntDivCheap(N->getValueType(0), MinSize))
+ AttributeSet Attr = DAG.getMachineFunction().getFunction()->getAttributes();
+ if (N1C && !TLI.isIntDivCheap(N->getValueType(0), Attr))
if (SDValue Op = BuildUDIV(N))
return Op;
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=245921&r1=245920&r2=245921&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Mon Aug 24 21:31:21 2015
@@ -2725,6 +2725,16 @@ static SDValue BuildExactSDIV(const Targ
return Mul;
}
+SDValue TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
+ SelectionDAG &DAG,
+ std::vector<SDNode *> *Created) const {
+ AttributeSet Attr = DAG.getMachineFunction().getFunction()->getAttributes();
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (TLI.isIntDivCheap(N->getValueType(0), Attr))
+ return SDValue(N,0); // Lower SDIV as SDIV
+ return SDValue();
+}
+
/// \brief Given an ISD::SDIV node expressing a divide by constant,
/// return a DAG expression to select that will generate the same value by
/// multiplying by a magic number.
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=245921&r1=245920&r2=245921&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Aug 24 21:31:21 2015
@@ -26511,7 +26511,7 @@ bool X86TargetLowering::isTargetFTOL() c
return Subtarget->isTargetKnownWindowsMSVC() && !Subtarget->is64Bit();
}
-bool X86TargetLowering::isIntDivCheap(EVT VT, bool OptSize) const {
+bool X86TargetLowering::isIntDivCheap(EVT VT, AttributeSet Attr) 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.
@@ -26519,5 +26519,7 @@ bool X86TargetLowering::isIntDivCheap(EV
// 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/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=245921&r1=245920&r2=245921&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Aug 24 21:31:21 2015
@@ -902,7 +902,7 @@ 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;
+ bool isIntDivCheap(EVT VT, AttributeSet Attr) const override;
protected:
std::pair<const TargetRegisterClass *, uint8_t>
Added: llvm/trunk/test/CodeGen/X86/sdiv-pow2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sdiv-pow2.ll?rev=245921&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/sdiv-pow2.ll (added)
+++ llvm/trunk/test/CodeGen/X86/sdiv-pow2.ll Mon Aug 24 21:31:21 2015
@@ -0,0 +1,33 @@
+; RUN: llc -march=x86 < %s | FileCheck %s
+
+; No attributes, should not use idiv
+define i32 @test1(i32 inreg %x) {
+entry:
+ %div = sdiv i32 %x, 16
+ ret i32 %div
+; CHECK-LABEL: test1:
+; CHECK-NOT: idivl
+; CHECK: ret
+}
+
+; Has minsize (-Oz) attribute, should generate idiv
+define i32 @test2(i32 inreg %x) minsize {
+entry:
+ %div = sdiv i32 %x, 16
+ ret i32 %div
+; CHECK-LABEL: test2:
+; CHECK: idivl
+; CHECK: ret
+}
+
+; Has optsize (-Os) attribute, should not generate idiv
+define i32 @test3(i32 inreg %x) optsize {
+entry:
+ %div = sdiv i32 %x, 16
+ ret i32 %div
+; CHECK-LABEL: test3:
+; CHECK-NOT: idivl
+; CHECK: ret
+}
+
+
More information about the llvm-commits
mailing list