-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[NFC] SLVectorizer comparator refactoring that preserves behavior #84966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Spinning off from llvm#79321 / 35f4592 - looked like the comparator could be simplified & made more clear/less risk of leaving hidden bugs.
@llvm/pr-subscribers-llvm-transforms Author: David Blaikie (dwblaikie) ChangesSpinning off from #79321 / 35f4592 - looked like the comparator could be Full diff: https://github.com/llvm/llvm-project/pull/84966.diff 1 Files Affected:
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 36dc9094538ae9..8e01a81e1304b1 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -16615,36 +16615,11 @@ bool SLPVectorizerPass::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
if (Opcodes1.size() > Opcodes2.size())
return false;
for (int I = 0, E = Opcodes1.size(); I < E; ++I) {
- // Undefs are compatible with any other value.
- if (isa<UndefValue>(Opcodes1[I]) || isa<UndefValue>(Opcodes2[I])) {
- if (isa<UndefValue>(Opcodes1[I]) && isa<UndefValue>(Opcodes2[I]))
- continue;
- if (isa<Instruction>(Opcodes1[I])) {
- assert(isa<UndefValue>(Opcodes2[I]) && "Expected 2nd undef value");
- return true;
- }
- if (isa<Instruction>(Opcodes2[I])) {
- assert(isa<UndefValue>(Opcodes1[I]) && "Expected 1st undef value");
- return false;
- }
- if (isa<Constant>(Opcodes1[I]) && !isa<UndefValue>(Opcodes1[I])) {
- assert(isa<UndefValue>(Opcodes2[I]) && "Expected 2nd undef value");
- return true;
- }
- if (isa<Constant>(Opcodes2[I]) && !isa<UndefValue>(Opcodes2[I])) {
- assert(isa<UndefValue>(Opcodes1[I]) && "Expected 1st undef value");
- return false;
- }
- if (!isa<UndefValue>(Opcodes2[I])) {
- assert(isa<UndefValue>(Opcodes1[I]) && "Expected 1st undef value");
- return false;
- }
- assert(!isa<UndefValue>(Opcodes1[I]) && isa<UndefValue>(Opcodes2[I]) &&
- "Expected 1st non-undef and 2nd undef value");
- return true;
- }
- if (auto *I1 = dyn_cast<Instruction>(Opcodes1[I]))
- if (auto *I2 = dyn_cast<Instruction>(Opcodes2[I])) {
+ {
+ // Instructions come first.
+ auto *I1 = dyn_cast<Instruction>(Opcodes1[I]);
+ auto *I2 = dyn_cast<Instruction>(Opcodes2[I]);
+ if (I1 && I2) {
DomTreeNodeBase<BasicBlock> *NodeI1 = DT->getNode(I1->getParent());
DomTreeNodeBase<BasicBlock> *NodeI2 = DT->getNode(I2->getParent());
if (!NodeI1)
@@ -16661,20 +16636,44 @@ bool SLPVectorizerPass::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
continue;
return I1->getOpcode() < I2->getOpcode();
}
- if (isa<Constant>(Opcodes1[I]) && isa<Constant>(Opcodes2[I]))
- continue;
- if (isa<Instruction>(Opcodes1[I]) && !isa<Instruction>(Opcodes2[I]))
- return true;
- if (!isa<Instruction>(Opcodes1[I]) && isa<Instruction>(Opcodes2[I]))
- return false;
- if (isa<Constant>(Opcodes1[I]) && !isa<Constant>(Opcodes2[I]))
- return true;
- if (!isa<Constant>(Opcodes1[I]) && isa<Constant>(Opcodes2[I]))
- return false;
- if (Opcodes1[I]->getValueID() < Opcodes2[I]->getValueID())
- return true;
- if (Opcodes1[I]->getValueID() > Opcodes2[I]->getValueID())
- return false;
+ if (I1)
+ return true;
+ if (I2)
+ return false;
+ }
+ {
+ // Non-undef constants come next.
+ bool C1 = isa<Constant>(Opcodes1[I]) && !isa<UndefValue>(Opcodes1[I]);
+ bool C2 = isa<Constant>(Opcodes2[I]) && !isa<UndefValue>(Opcodes2[I]);
+ if (C1 && C2)
+ continue;
+ if (C1)
+ return true;
+ if (C2)
+ return false;
+ }
+ bool U1 = isa<UndefValue>(Opcodes1[I]);
+ bool U2 = isa<UndefValue>(Opcodes2[I]);
+ {
+ // Non-constant non-instructions come next.
+ if (!U1 && !U2) {
+ auto ValID1 = Opcodes1[I]->getValueID();
+ auto ValID2 = Opcodes2[I]->getValueID();
+ if (ValID1 == ValID2)
+ continue;
+ if (ValID1 < ValID2)
+ return true;
+ if (ValID1 > ValID2)
+ return false;
+ }
+ if (!U1)
+ return true;
+ if (!U2)
+ return false;
+ }
+ // Undefs come last.
+ assert(U1 && U2);
+ continue;
}
return false;
};
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG, thanks!
return false; | ||
} | ||
// Undefs come last. | ||
assert(U1 && U2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a message here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, sure - added in 9ac0315
Spinning off from #79321 / 35f4592 - looked like the comparator could be
simplified & made more clear/less risk of leaving hidden bugs.