|
16 | 16 | #include "llvm/ADT/SmallVector.h"
|
17 | 17 | #include "llvm/ADT/Statistic.h"
|
18 | 18 | #include "llvm/Analysis/LoopInfo.h"
|
| 19 | +#include "llvm/Analysis/ValueTracking.h" |
19 | 20 | #include "llvm/IR/Dominators.h"
|
20 | 21 | #include "llvm/IR/IRBuilder.h"
|
21 | 22 | #include "llvm/IR/Instructions.h"
|
@@ -713,8 +714,11 @@ bool SimplifyIndvar::replaceFloatIVWithIntegerIV(Instruction *UseInst) {
|
713 | 714 | bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst,
|
714 | 715 | Instruction *IVOperand) {
|
715 | 716 | if (!SE->isSCEVable(UseInst->getType()) ||
|
716 |
| - (UseInst->getType() != IVOperand->getType()) || |
717 |
| - (SE->getSCEV(UseInst) != SE->getSCEV(IVOperand))) |
| 717 | + UseInst->getType() != IVOperand->getType()) |
| 718 | + return false; |
| 719 | + |
| 720 | + const SCEV *UseSCEV = SE->getSCEV(UseInst); |
| 721 | + if (UseSCEV != SE->getSCEV(IVOperand)) |
718 | 722 | return false;
|
719 | 723 |
|
720 | 724 | // getSCEV(X) == getSCEV(Y) does not guarantee that X and Y are related in the
|
@@ -742,6 +746,16 @@ bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst,
|
742 | 746 | if (!LI->replacementPreservesLCSSAForm(UseInst, IVOperand))
|
743 | 747 | return false;
|
744 | 748 |
|
| 749 | + // Make sure the operand is not more poisonous than the instruction. |
| 750 | + if (!impliesPoison(IVOperand, UseInst)) { |
| 751 | + SmallVector<Instruction *> DropPoisonGeneratingInsts; |
| 752 | + if (!SE->canReuseInstruction(UseSCEV, IVOperand, DropPoisonGeneratingInsts)) |
| 753 | + return false; |
| 754 | + |
| 755 | + for (Instruction *I : DropPoisonGeneratingInsts) |
| 756 | + I->dropPoisonGeneratingFlagsAndMetadata(); |
| 757 | + } |
| 758 | + |
745 | 759 | LLVM_DEBUG(dbgs() << "INDVARS: Eliminated identity: " << *UseInst << '\n');
|
746 | 760 |
|
747 | 761 | SE->forgetValue(UseInst);
|
|
0 commit comments