Index: lib/Transforms/Scalar/LoopInstSimplify.cpp =================================================================== --- lib/Transforms/Scalar/LoopInstSimplify.cpp +++ lib/Transforms/Scalar/LoopInstSimplify.cpp @@ -22,8 +22,8 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopIterator.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" #include "llvm/IR/DataLayout.h" @@ -36,6 +36,7 @@ #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include #include @@ -47,8 +48,8 @@ STATISTIC(NumSimplified, "Number of redundant instructions simplified"); static bool simplifyLoopInst(Loop &L, DominatorTree &DT, LoopInfo &LI, - AssumptionCache &AC, - const TargetLibraryInfo &TLI) { + AssumptionCache &AC, const TargetLibraryInfo &TLI, + ScalarEvolution *SE) { const DataLayout &DL = L.getHeader()->getModule()->getDataLayout(); SimplifyQuery SQ(DL, &TLI, &DT, &AC); @@ -157,6 +158,11 @@ DeadInsts.clear(); } + // If ScalarEvolution is around and knows anything about values in this loop, + // tell it to forget them, because we simplifed the in-loop instructions. + if (SE && Changed) + SE->forgetLoop(&L); + return Changed; } @@ -180,14 +186,17 @@ *L->getHeader()->getParent()); const TargetLibraryInfo &TLI = getAnalysis().getTLI(); + auto *SEWP = getAnalysisIfAvailable(); + ScalarEvolution *SE = SEWP ? &SEWP->getSE() : nullptr; - return simplifyLoopInst(*L, DT, LI, AC, TLI); + return simplifyLoopInst(*L, DT, LI, AC, TLI, SE); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.addRequired(); AU.addRequired(); + AU.addPreserved(); AU.setPreservesCFG(); getLoopAnalysisUsage(AU); } @@ -198,11 +207,16 @@ PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &) { - if (!simplifyLoopInst(L, AR.DT, AR.LI, AR.AC, AR.TLI)) + const auto &FAM = + AM.getResult(L, AR).getManager(); + Function *F = L.getHeader()->getParent(); + ScalarEvolution *SE = FAM.getCachedResult(*F); + if (!simplifyLoopInst(L, AR.DT, AR.LI, AR.AC, AR.TLI, SE)) return PreservedAnalyses::all(); auto PA = getLoopPassPreservedAnalyses(); PA.preserveSet(); + PA.preserve(); return PA; } Index: test/Other/new-pm-defaults.ll =================================================================== --- test/Other/new-pm-defaults.ll +++ test/Other/new-pm-defaults.ll @@ -146,10 +146,10 @@ ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Starting Loop pass manager run. ; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass +; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}FunctionAnalysisManager{{.*}}> ; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass ; CHECK-O-NEXT: Running pass: LoopRotatePass ; CHECK-O-NEXT: Running pass: LICM -; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-O-NEXT: Running pass: SimpleLoopUnswitchPass ; CHECK-O-NEXT: Finished Loop pass manager run. ; CHECK-O-NEXT: Running pass: SimplifyCFGPass Index: test/Other/new-pm-thinlto-defaults.ll =================================================================== --- test/Other/new-pm-thinlto-defaults.ll +++ test/Other/new-pm-thinlto-defaults.ll @@ -130,10 +130,10 @@ ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Starting Loop pass manager run. ; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass +; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}FunctionAnalysisManager{{.*}}> ; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass ; CHECK-O-NEXT: Running pass: LoopRotatePass ; CHECK-O-NEXT: Running pass: LICM -; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-O-NEXT: Running pass: SimpleLoopUnswitchPass ; CHECK-O-NEXT: Finished Loop pass manager run. ; CHECK-O-NEXT: Running pass: SimplifyCFGPass Index: test/Transforms/LoopInstSimplify/forget-scev.ll =================================================================== --- /dev/null +++ test/Transforms/LoopInstSimplify/forget-scev.ll @@ -0,0 +1,43 @@ +; RUN: opt %s -indvars -loop-instsimplify -loop-reduce +; We are only checking that there is no crash! + +; https://bugs.llvm.org/show_bug.cgi?id=37936 + +; The problem is as follows: +; 1. indvars marks %dec as NUW. +; 2. loop-instsimplify runs instsimplify, which constant-folds %dec to -1 +; 3. loop-reduce tries to do some further modification, but crashes +; with an type assertion in cast, because %dec is no longer an Instruction, +; even though the SCEV data indicated it was. + +; If the runline is split into two, i.e. -indvars -loop-instsimplify first, that +; stored into a file, and then -loop-reduce is run on that, there is no crash. +; So it looks like the problem is due to -loop-instsimplify not discarding SCEV. + +target datalayout = "n16" + +@a = external global i16, align 1 + +define void @f1() { +entry: + br label %for.cond + +for.cond: ; preds = %land.end, %entry + %c.0 = phi i16 [ 0, %entry ], [ %dec, %land.end ] + br i1 undef, label %for.body, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.cond + ret void + +for.body: ; preds = %for.cond + %0 = load i16, i16* @a, align 1 + %cmp = icmp sgt i16 %0, %c.0 + br i1 %cmp, label %land.rhs, label %land.end + +land.rhs: ; preds = %for.body + unreachable + +land.end: ; preds = %for.body + %dec = add nsw i16 %c.0, -1 + br label %for.cond +}