[llvm] [SLP]Make PHICompare comparator follow weak strict ordering requirement (PR #110529)
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 2 00:02:03 PDT 2024
================
@@ -5454,21 +5481,58 @@ BoUpSLP::getReorderingData(const TreeEntry &TE, bool TopToBottom) {
return false;
auto *FirstUserOfPhi1 = cast<Instruction>(*V1->user_begin());
auto *FirstUserOfPhi2 = cast<Instruction>(*V2->user_begin());
- if (auto *IE1 = dyn_cast<InsertElementInst>(FirstUserOfPhi1))
- if (auto *IE2 = dyn_cast<InsertElementInst>(FirstUserOfPhi2)) {
- if (!areTwoInsertFromSameBuildVector(
- IE1, IE2,
- [](InsertElementInst *II) { return II->getOperand(0); }))
- return I1 < I2;
+ if (FirstUserOfPhi1->getParent() != FirstUserOfPhi2->getParent())
+ return CompareByBasicBlocks(FirstUserOfPhi1->getParent(),
+ FirstUserOfPhi2->getParent());
+ auto *IE1 = dyn_cast<InsertElementInst>(FirstUserOfPhi1);
+ auto *IE2 = dyn_cast<InsertElementInst>(FirstUserOfPhi2);
+ auto *EE1 = dyn_cast<ExtractElementInst>(FirstUserOfPhi1);
+ auto *EE2 = dyn_cast<ExtractElementInst>(FirstUserOfPhi2);
+ if (IE1 && !IE2)
+ return true;
+ if (!IE1 && IE2)
+ return false;
+ if (IE1 && IE2) {
+ if (UserBVHead[I1] && !UserBVHead[I2])
+ return true;
+ if (!UserBVHead[I1])
+ return false;
+ if (UserBVHead[I1] == UserBVHead[I2])
return getElementIndex(IE1) < getElementIndex(IE2);
- }
- if (auto *EE1 = dyn_cast<ExtractElementInst>(FirstUserOfPhi1))
- if (auto *EE2 = dyn_cast<ExtractElementInst>(FirstUserOfPhi2)) {
- if (EE1->getOperand(0) != EE2->getOperand(0))
- return I1 < I2;
+ if (UserBVHead[I1]->getParent() != UserBVHead[I2]->getParent())
+ return CompareByBasicBlocks(UserBVHead[I1]->getParent(),
+ UserBVHead[I2]->getParent());
+ return UserBVHead[I1]->comesBefore(UserBVHead[I2]);
+ }
+ if (EE1 && !EE2)
+ return true;
+ if (!EE1 && EE2)
+ return false;
+ if (EE1 && EE2) {
+ if (EE1->getOperand(0) == EE2->getOperand(0))
return getElementIndex(EE1) < getElementIndex(EE2);
+ auto *Inst1 = dyn_cast<Instruction>(EE1->getOperand(0));
+ if (Inst1 && !I2)
+ return true;
+ if (!Inst1 && I2)
+ return false;
+ auto *Inst2 = dyn_cast<Instruction>(EE2->getOperand(0));
+ if (Inst1 && Inst2) {
+ if (Inst1->getParent() != Inst2->getParent())
+ return CompareByBasicBlocks(Inst1->getParent(), Inst2->getParent());
+ return Inst1->comesBefore(Inst2);
}
- return I1 < I2;
+ auto *P1 = dyn_cast<Argument>(EE1->getOperand(0));
+ auto *P2 = dyn_cast<Argument>(EE2->getOperand(0));
+ if (P1 && !P2)
+ return true;
+ if (!P1 && P2)
+ return false;
+ if (P1 && P2)
+ return P1->getArgNo() < P2->getArgNo();
+ return false;
+ }
+ return false;
----------------
efriedma-quic wrote:
This doesn't quite work... if the first operand isn't an instruction or an argument, we have to always return false. So this needs to happen before the `if (EE1->getOperand(0) == EE2->getOperand(0))`.
https://github.com/llvm/llvm-project/pull/110529
More information about the llvm-commits
mailing list