Index: lib/Transforms/Scalar/LICM.cpp =================================================================== --- lib/Transforms/Scalar/LICM.cpp +++ lib/Transforms/Scalar/LICM.cpp @@ -1596,6 +1596,13 @@ /// Simple Analysis hook. Delete value L from alias set map. /// void LegacyLICMPass::deleteAnalysisLoop(Loop *L) { + // If the loop being deleted is outermost, or removed from its parent loop, + // then the alias information saved by its subloops need to be cleared. + // Otherwise, the alias information is cached, later collected and erased + // by the nearest outer loop. + if (!L->getParentLoop()) + LICM.getLoopToAliasSetMap().clear(); + if (!LICM.getLoopToAliasSetMap().count(L)) return; Index: test/Transforms/LICM/outer-loop-fully-unrolled.ll =================================================================== --- /dev/null +++ test/Transforms/LICM/outer-loop-fully-unrolled.ll @@ -0,0 +1,46 @@ +; RUN: opt -S -loop-unroll -licm < %s | FileCheck %s + +; Check that when the outer most loop is fully unrolled, the alias information +; saved in the LoopToAliasSetMap is cleared, without triggering an assertion in +; doFinalizaton(). + +; CHECK: store double %{{.+}}, double* %{{.+}} +; CHECK: store double %{{.+}}, double* %{{.+}} +; CHECK: store double %{{.+}}, double* %{{.+}} +; CHECK: store double %{{.+}}, double* %{{.+}} +; CHECK: store double %{{.+}}, double* %{{.+}} +; CHECK: store double %{{.+}}, double* %{{.+}} +; CHECK: store double %{{.+}}, double* %{{.+}} +; CHECK: store double %{{.+}}, double* %{{.+}} + +define void @foo(double** %A) { +entry: + br label %for.cond1.preheader + +for.cond1.preheader: + %i = phi i32 [ 1, %entry ], [ %inc.i, %for.cond.cleanup3 ] + %arrayidx1 = getelementptr inbounds double*, double** %A, i32 %i + %t0 = load double*, double** %arrayidx1, align 4 + br label %for.body4 + +for.cond.cleanup: + ret void + +for.cond.cleanup3: + %inc.i = add nuw nsw i32 %i, 1 + %exitcond = icmp eq i32 %inc.i, 9 + br i1 %exitcond, label %for.cond.cleanup, label %for.cond1.preheader + +for.body4: + %j = phi i32 [ 0, %for.cond1.preheader ], [ %inc.j, %for.body4 ] + %arrayidx2 = getelementptr inbounds double*, double** %A, i32 %j + %t1 = load double*, double** %arrayidx2, align 4 + %arrayidx3 = getelementptr inbounds double, double* %t1, i32 %i + %t2 = load double, double* %arrayidx3, align 8 + %arrayidx4 = getelementptr inbounds double, double* %t0, i32 %j + store double %t2, double* %arrayidx4, align 8 + %inc.j = add nuw nsw i32 %j, 1 + %cmp2 = icmp eq i32 %inc.j, %i + br i1 %cmp2, label %for.cond.cleanup3, label %for.body4 +} +