diff options
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64ISelLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index c35fa4df757..a262b1d2b3f 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -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::insertCopiesSplitCSR( .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(); +} |

