summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Vectorize
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2019-03-29 15:28:25 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2019-03-29 15:28:25 +0000
commit6a75c36ea9bd2bbc8b58fa8732a843477a5fbd69 (patch)
treeca6ec5c87f9adcf41bd5c4c1e67b4d7ed1982463 /llvm/lib/Transforms/Vectorize
parent8da6a6cec31f287a98362cbd097394b1e2dead20 (diff)
downloadbcm5719-llvm-6a75c36ea9bd2bbc8b58fa8732a843477a5fbd69.tar.gz
bcm5719-llvm-6a75c36ea9bd2bbc8b58fa8732a843477a5fbd69.zip
[SLP] Add support for commutative icmp/fcmp predicates
For the cases where the icmp/fcmp predicate is commutative, use reorderInputsAccordingToOpcode to collect and commute the operands. This requires a helper to recognise commutativity in both general Instruction and CmpInstr types - the CmpInst::isCommutative doesn't overload the Instruction::isCommutative method for reasons I'm not clear on (maybe because its based on predicate not opcode?!?). Differential Revision: https://reviews.llvm.org/D59992 llvm-svn: 357266
Diffstat (limited to 'llvm/lib/Transforms/Vectorize')
-rw-r--r--llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp42
1 files changed, 28 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index e56c9f48f7d..9bed86b16bd 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -206,6 +206,13 @@ static bool isSplat(ArrayRef<Value *> VL) {
return true;
}
+/// \returns True if \p I is commutative, handles CmpInst as well as Instruction.
+static bool isCommutative(Instruction *I) {
+ if (auto *IC = dyn_cast<CmpInst>(I))
+ return IC->isCommutative();
+ return I->isCommutative();
+}
+
/// Checks if the vector of instructions can be represented as a shuffle, like:
/// %x0 = extractelement <4 x i8> %x, i32 0
/// %x3 = extractelement <4 x i8> %x, i32 3
@@ -1854,16 +1861,23 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
newTreeEntry(VL, true, UserTreeIdx, ReuseShuffleIndicies);
LLVM_DEBUG(dbgs() << "SLP: added a vector of compares.\n");
- // Collect operands - commute if it uses the swapped predicate.
ValueList Left, Right;
- for (Value *V : VL) {
- auto *Cmp = cast<CmpInst>(V);
- Value *LHS = Cmp->getOperand(0);
- Value *RHS = Cmp->getOperand(1);
- if (Cmp->getPredicate() != P0)
- std::swap(LHS, RHS);
- Left.push_back(LHS);
- Right.push_back(RHS);
+ if (cast<CmpInst>(VL0)->isCommutative()) {
+ // Commutative predicate - collect + sort operands of the instructions
+ // so that each side is more likely to have the same opcode.
+ assert(P0 == SwapP0 && "Commutative Predicate mismatch");
+ reorderInputsAccordingToOpcode(S, VL, Left, Right);
+ } else {
+ // Collect operands - commute if it uses the swapped predicate.
+ for (Value *V : VL) {
+ auto *Cmp = cast<CmpInst>(V);
+ Value *LHS = Cmp->getOperand(0);
+ Value *RHS = Cmp->getOperand(1);
+ if (Cmp->getPredicate() != P0)
+ std::swap(LHS, RHS);
+ Left.push_back(LHS);
+ Right.push_back(RHS);
+ }
}
UserTreeIdx.EdgeIdx = 0;
@@ -2884,7 +2898,7 @@ void BoUpSLP::reorderInputsAccordingToOpcode(const InstructionsState &S,
Instruction *I = cast<Instruction>(VL[i]);
// Commute to favor either a splat or maximizing having the same opcodes on
// one side.
- if (I->isCommutative() &&
+ if (isCommutative(I) &&
shouldReorderOperands(i, Left, Right, AllSameOpcodeLeft,
AllSameOpcodeRight, SplatLeft, SplatRight))
std::swap(Left[i], Right[i]);
@@ -2925,11 +2939,11 @@ void BoUpSLP::reorderInputsAccordingToOpcode(const InstructionsState &S,
if (isConsecutiveAccess(L, L1, *DL, *SE)) {
auto *VL1 = cast<Instruction>(VL[j]);
auto *VL2 = cast<Instruction>(VL[j + 1]);
- if (VL2->isCommutative()) {
+ if (isCommutative(VL2)) {
std::swap(Left[j + 1], Right[j + 1]);
continue;
}
- if (VL1->isCommutative()) {
+ if (isCommutative(VL1)) {
std::swap(Left[j], Right[j]);
continue;
}
@@ -2941,11 +2955,11 @@ void BoUpSLP::reorderInputsAccordingToOpcode(const InstructionsState &S,
if (isConsecutiveAccess(L, L1, *DL, *SE)) {
auto *VL1 = cast<Instruction>(VL[j]);
auto *VL2 = cast<Instruction>(VL[j + 1]);
- if (VL2->isCommutative()) {
+ if (isCommutative(VL2)) {
std::swap(Left[j + 1], Right[j + 1]);
continue;
}
- if (VL1->isCommutative()) {
+ if (isCommutative(VL1)) {
std::swap(Left[j], Right[j]);
continue;
}
OpenPOWER on IntegriCloud