|
77 | 77 | #include "llvm/Analysis/ScalarEvolutionNormalization.h"
|
78 | 78 | #include "llvm/Analysis/TargetLibraryInfo.h"
|
79 | 79 | #include "llvm/Analysis/TargetTransformInfo.h"
|
| 80 | +#include "llvm/Analysis/ValueTracking.h" |
80 | 81 | #include "llvm/Config/llvm-config.h"
|
81 | 82 | #include "llvm/IR/BasicBlock.h"
|
82 | 83 | #include "llvm/IR/Constant.h"
|
@@ -5570,33 +5571,37 @@ void LSRInstance::ImplementSolution(
|
5570 | 5571 | // chosen a non-optimal result for the actual schedule. (And yes, this
|
5571 | 5572 | // scheduling decision does impact later codegen.)
|
5572 | 5573 | for (PHINode &PN : L->getHeader()->phis()) {
|
5573 |
| - // First, filter out anything not an obvious addrec |
5574 |
| - if (!SE.isSCEVable(PN.getType()) || !isa<SCEVAddRecExpr>(SE.getSCEV(&PN))) |
5575 |
| - continue; |
5576 |
| - Instruction *IncV = |
5577 |
| - dyn_cast<Instruction>(PN.getIncomingValueForBlock(L->getLoopLatch())); |
5578 |
| - if (!IncV) |
| 5574 | + BinaryOperator *BO = nullptr; |
| 5575 | + Value *Start = nullptr, *Step = nullptr; |
| 5576 | + if (!matchSimpleRecurrence(&PN, BO, Start, Step)) |
5579 | 5577 | continue;
|
5580 | 5578 |
|
5581 |
| - if (IncV->getOpcode() != Instruction::Add && |
5582 |
| - IncV->getOpcode() != Instruction::Sub) |
| 5579 | + switch (BO->getOpcode()) { |
| 5580 | + case Instruction::Sub: |
| 5581 | + if (BO->getOperand(0) != &PN) |
| 5582 | + // sub is non-commutative - match handling elsewhere in LSR |
| 5583 | + continue; |
| 5584 | + break; |
| 5585 | + case Instruction::Add: |
| 5586 | + break; |
| 5587 | + default: |
5583 | 5588 | continue;
|
| 5589 | + }; |
5584 | 5590 |
|
5585 |
| - if (IncV->getOperand(0) != &PN && |
5586 |
| - !isa<Constant>(IncV->getOperand(1))) |
| 5591 | + if (!isa<Constant>(Step)) |
5587 | 5592 | // If not a constant step, might increase register pressure
|
5588 | 5593 | // (We assume constants have been canonicalized to RHS)
|
5589 | 5594 | continue;
|
5590 | 5595 |
|
5591 |
| - if (IncV->getParent() == IVIncInsertPos->getParent()) |
| 5596 | + if (BO->getParent() == IVIncInsertPos->getParent()) |
5592 | 5597 | // Only bother moving across blocks. Isel can handle block local case.
|
5593 | 5598 | continue;
|
5594 | 5599 |
|
5595 | 5600 | // Can we legally schedule inc at the desired point?
|
5596 |
| - if (!llvm::all_of(IncV->uses(), |
| 5601 | + if (!llvm::all_of(BO->uses(), |
5597 | 5602 | [&](Use &U) {return DT.dominates(IVIncInsertPos, U);}))
|
5598 | 5603 | continue;
|
5599 |
| - IncV->moveBefore(IVIncInsertPos); |
| 5604 | + BO->moveBefore(IVIncInsertPos); |
5600 | 5605 | Changed = true;
|
5601 | 5606 | }
|
5602 | 5607 |
|
|
0 commit comments