summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2016-04-15 18:17:18 +0000
committerTim Northover <tnorthover@apple.com>2016-04-15 18:17:18 +0000
commit903f81ba184d45341f8f5b8b3227242cc168e535 (patch)
treece9f92d8728653aa3e465e394d818795897899b0 /llvm/lib
parent9cfd8cea6b8172e32a76a59125f13a6662a18c86 (diff)
downloadbcm5719-llvm-903f81ba184d45341f8f5b8b3227242cc168e535.tar.gz
bcm5719-llvm-903f81ba184d45341f8f5b8b3227242cc168e535.zip
ARM: don't try to hoist constant RHS out of a division.
Divisions by a constant can be converted into multiplies which are usually cheaper, but this isn't possible if the constant gets separated (particularly in loops). Fix this by telling ConstantHoisting that the immediate in a DIV is cheap. I considered making the check generic, but neither AArch64 (strangely) nor x86 showed any benefit on the tests I had. llvm-svn: 266464
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp15
-rw-r--r--llvm/lib/Target/ARM/ARMTargetTransformInfo.h4
2 files changed, 16 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp b/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp
index 932ec2d46da..aaec3107aec 100644
--- a/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp
@@ -47,6 +47,21 @@ int ARMTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty) {
return 3;
}
+int ARMTTIImpl::getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
+ Type *Ty) {
+ // Division by a constant can be turned into multiplication, but only if we
+ // know it's constant. So it's not so much that the immediate is cheap (it's
+ // not), but that the alternative is worse.
+ // FIXME: this is probably unneeded with GlobalISel.
+ if ((Opcode == Instruction::SDiv || Opcode == Instruction::UDiv ||
+ Opcode == Instruction::SRem || Opcode == Instruction::URem) &&
+ Idx == 1)
+ return 0;
+
+ return getIntImmCost(Imm, Ty);
+}
+
+
int ARMTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) {
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
diff --git a/llvm/lib/Target/ARM/ARMTargetTransformInfo.h b/llvm/lib/Target/ARM/ARMTargetTransformInfo.h
index 0fe964f36de..e07174eb40b 100644
--- a/llvm/lib/Target/ARM/ARMTargetTransformInfo.h
+++ b/llvm/lib/Target/ARM/ARMTargetTransformInfo.h
@@ -64,9 +64,7 @@ public:
using BaseT::getIntImmCost;
int getIntImmCost(const APInt &Imm, Type *Ty);
- int getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty) {
- return getIntImmCost(Imm, Ty);
- }
+ int getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty);
/// @}
OpenPOWER on IntegriCloud