summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2014-09-18 07:26:26 +0000
committerJuergen Ributzka <juergen@apple.com>2014-09-18 07:26:26 +0000
commit0f3076785f521b802d47bc096d82cea1a1a2744d (patch)
tree09b66b4314a58b1224c05ebefd826ba6d0c3ef8d /llvm/lib/Target/AArch64
parent2964b832efe5d2a52ad2677009c318419281d62e (diff)
downloadbcm5719-llvm-0f3076785f521b802d47bc096d82cea1a1a2744d.tar.gz
bcm5719-llvm-0f3076785f521b802d47bc096d82cea1a1a2744d.zip
Fix previous commit: [FastISel][AArch64] Simplify XALU multiplies.
When folding the intrinsic flag into the branch or select we also have to consider the fact if the intrinsic got simplified, because it changes the flag we have to check for. llvm-svn: 218034
Diffstat (limited to 'llvm/lib/Target/AArch64')
-rw-r--r--llvm/lib/Target/AArch64/AArch64FastISel.cpp50
1 files changed, 42 insertions, 8 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index e64f1bdacd8..88038ff0844 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -2833,15 +2833,49 @@ bool AArch64FastISel::foldXALUIntrinsic(AArch64CC::CondCode &CC,
if (RetVT != MVT::i32 && RetVT != MVT::i64)
return false;
+ const Value *LHS = II->getArgOperand(0);
+ const Value *RHS = II->getArgOperand(1);
+
+ // Canonicalize immediate to the RHS.
+ if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) &&
+ isCommutativeIntrinsic(II))
+ std::swap(LHS, RHS);
+
+ // Simplify multiplies.
+ unsigned IID = II->getIntrinsicID();
+ switch (IID) {
+ default:
+ break;
+ case Intrinsic::smul_with_overflow:
+ if (const auto *C = dyn_cast<ConstantInt>(RHS))
+ if (C->getValue() == 2)
+ IID = Intrinsic::sadd_with_overflow;
+ break;
+ case Intrinsic::umul_with_overflow:
+ if (const auto *C = dyn_cast<ConstantInt>(RHS))
+ if (C->getValue() == 2)
+ IID = Intrinsic::uadd_with_overflow;
+ break;
+ }
+
AArch64CC::CondCode TmpCC;
- switch (II->getIntrinsicID()) {
- default: return false;
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::ssub_with_overflow: TmpCC = AArch64CC::VS; break;
- case Intrinsic::uadd_with_overflow: TmpCC = AArch64CC::HS; break;
- case Intrinsic::usub_with_overflow: TmpCC = AArch64CC::LO; break;
- case Intrinsic::smul_with_overflow:
- case Intrinsic::umul_with_overflow: TmpCC = AArch64CC::NE; break;
+ switch (IID) {
+ default:
+ return false;
+ case Intrinsic::sadd_with_overflow:
+ case Intrinsic::ssub_with_overflow:
+ TmpCC = AArch64CC::VS;
+ break;
+ case Intrinsic::uadd_with_overflow:
+ TmpCC = AArch64CC::HS;
+ break;
+ case Intrinsic::usub_with_overflow:
+ TmpCC = AArch64CC::LO;
+ break;
+ case Intrinsic::smul_with_overflow:
+ case Intrinsic::umul_with_overflow:
+ TmpCC = AArch64CC::NE;
+ break;
}
// Check if both instructions are in the same basic block.
OpenPOWER on IntegriCloud